diff --git a/Documentation/Authenticators/Authentication-Modules.md b/Documentation/Authenticators/Authentication-Modules.md index b8f953c07..96f233c7c 100644 --- a/Documentation/Authenticators/Authentication-Modules.md +++ b/Documentation/Authenticators/Authentication-Modules.md @@ -24,7 +24,7 @@ connection data. The return value of this function is stored in the `destroy` entry point and the value returned by `create` will be given as the first parameter. -# MySQL Authentication Moduels +# MySQL Authentication Modules The MySQL protocol authentication starts when the server sends the [handshake packet](https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 5aeeb1639..208cd24ee 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -82,7 +82,7 @@ For more details, please refer to [MariaDB MaxScale 1.3 Release Notes](Release-N * Firewall filter * Multi-Master monitor * RabbitMQ logging filter - * Schema Sharding router + * Schema Sharding router * Added option to use high precision timestamps in logging. * Readwritesplit router now returns the master server's response. * New readwritesplit router option added. It is now possible to control the amount of memory readwritesplit sessions will consume by limiting the amount of session modifying statements they can execute. diff --git a/Documentation/Design-Documents/assets/js/less-1.7.0.min.js b/Documentation/Design-Documents/assets/js/less-1.7.0.min.js index 3cecd957d..a812c26c1 100644 --- a/Documentation/Design-Documents/assets/js/less-1.7.0.min.js +++ b/Documentation/Design-Documents/assets/js/less-1.7.0.min.js @@ -1,14 +1,14 @@ -/*! - * LESS - Leaner CSS v1.7.0 - * http://lesscss.org - * - * Copyright (c) 2009-2014, Alexis Sellier - * Licensed under the Apache v2 License. - * - */ +/*! + * LESS - Leaner CSS v1.7.0 + * http://lesscss.org + * + * Copyright (c) 2009-2014, Alexis Sellier + * Licensed under the Apache v2 License. + * + */ /** * @license Apache v2 - */ + */ !function(a,b){function c(b){return a.less[b.split("/")[1]]}function d(a,b){"undefined"!=typeof console&&w.logLevel>=b&&console.log("less: "+a)}function e(a){return a.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function f(a,c){var e="{line} {content}",f=a.filename||c,g=[],h=(a.type||"Syntax")+"Error: "+(a.message||"There is an error in your .less file")+" in "+f+" ",i=function(a,c,d){a.extract[c]!==b&&g.push(e.replace(/\{line\}/,(parseInt(a.line,10)||0)+(c-1)).replace(/\{class\}/,d).replace(/\{content\}/,a.extract[c]))};a.extract?(i(a,0,""),i(a,1,"line"),i(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":\n"+g.join("\n")):a.stack&&(h+=a.stack),d(h,z.errors)}function g(a,b,c){var f=b.href||"",g="less:"+(b.title||e(f)),h=document.getElementById(g),i=!1,j=document.createElement("style");if(j.setAttribute("type","text/css"),b.media&&j.setAttribute("media",b.media),j.id=g,j.styleSheet)try{j.styleSheet.cssText=a}catch(k){throw new Error("Couldn't reassign styleSheet.cssText.")}else j.appendChild(document.createTextNode(a)),i=null!==h&&h.childNodes.length>0&&j.childNodes.length>0&&h.firstChild.nodeValue===j.firstChild.nodeValue;var l=document.getElementsByTagName("head")[0];if(null===h||i===!1){var m=b&&b.nextSibling||null;m?m.parentNode.insertBefore(j,m):l.appendChild(j)}if(h&&i===!1&&h.parentNode.removeChild(h),c&&D){d("saving "+f+" to cache.",z.info);try{D.setItem(f,a),D.setItem(f+":timestamp",c)}catch(k){d("failed to save",z.errors)}}}function h(a){return w.postProcessor&&"function"==typeof w.postProcessor&&(a=w.postProcessor.call(a,a)||a),a}function i(a,c){var d,f,h="less-error-message:"+e(c||""),i='
  • {content}
  • ',j=document.createElement("div"),k=[],l=a.filename||c,m=l.match(/([^\/]+(\?.*)?)$/)[1];j.id=h,j.className="less-error-message",f="

    "+(a.type||"Syntax")+"Error: "+(a.message||"There is an error in your .less file")+'

    in '+m+" ";var n=function(a,c,d){a.extract[c]!==b&&k.push(i.replace(/\{line\}/,(parseInt(a.line,10)||0)+(c-1)).replace(/\{class\}/,d).replace(/\{content\}/,a.extract[c]))};a.extract?(n(a,0,""),n(a,1,"line"),n(a,2,""),f+="on line "+a.line+", column "+(a.column+1)+":

    "):a.stack&&(f+="
    "+a.stack.split("\n").slice(1).join("
    ")),j.innerHTML=f,g([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),j.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),"development"==w.env&&(d=setInterval(function(){document.body&&(document.getElementById(h)?document.body.replaceChild(j,document.getElementById(h)):document.body.insertBefore(j,document.body.firstChild),clearInterval(d))},10))}function j(a,b){w.errorReporting&&"html"!==w.errorReporting?"console"===w.errorReporting?f(a,b):"function"==typeof w.errorReporting&&w.errorReporting("add",a,b):i(a,b)}function k(a){var b=document.getElementById("less-error-message:"+e(a));b&&b.parentNode.removeChild(b)}function l(){}function m(a){w.errorReporting&&"html"!==w.errorReporting?"console"===w.errorReporting?l(a):"function"==typeof w.errorReporting&&w.errorReporting("remove",a):k(a)}function n(a){for(var b,c=document.getElementsByTagName("style"),d=0;d0&&(h.splice(c-1,2),c-=2)}return g.hostPart=f[1],g.directories=h,g.path=f[1]+h.join("/"),g.fileUrl=g.path+(f[4]||""),g.url=g.fileUrl+(f[5]||""),g}function p(a,b){var c,d,e,f,g=o(a),h=o(b),i="";if(g.hostPart!==h.hostPart)return"";for(d=Math.max(h.directories.length,g.directories.length),c=0;d>c&&h.directories[c]===g.directories[c];c++);for(f=h.directories.slice(c),e=g.directories.slice(c),c=0;c=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):"function"==typeof d&&d(b.status,a)}var g=q(),h=y?w.fileAsync:w.async;"function"==typeof g.overrideMimeType&&g.overrideMimeType("text/css"),d("XHR: Getting '"+a+"'",z.debug),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),y&&!w.fileAsync?0===g.status||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){4==g.readyState&&f(g,c,e)}:f(g,c,e)}function s(b,c,d,e){c&&c.currentDirectory&&!/^([a-z-]+:)?\//.test(b)&&(b=c.currentDirectory+b);var f=o(b,a.location.href),g=f.url,h={currentDirectory:f.path,filename:g};if(c?(h.entryPath=c.entryPath,h.rootpath=c.rootpath,h.rootFilename=c.rootFilename,h.relativeUrls=c.relativeUrls):(h.entryPath=f.path,h.rootpath=w.rootpath||f.path,h.rootFilename=g,h.relativeUrls=e.relativeUrls),h.relativeUrls&&(h.rootpath=e.rootpath?o(e.rootpath+p(f.path,h.entryPath)).path:f.path),e.useFileCache&&E[g])try{var i=E[g];d(null,i,g,h,{lastModified:new Date})}catch(j){d(j,null,g)}else r(g,e.mime,function(a,b){E[g]=a;try{d(null,a,g,h,{lastModified:b})}catch(c){d(c,null,g)}},function(a,b){d({type:"File",message:"'"+b+"' wasn't found ("+a+")"},null,g)})}function t(a,b,c,d,e){var f=new w.tree.parseEnv(w);f.mime=a.type,(e||w.globalVars)&&(f.useFileCache=!0),s(a.href,null,function(h,i,j,k,l){if(l){l.remaining=d;var n=D&&D.getItem(j),o=D&&D.getItem(j+":timestamp");if(!c&&o&&l.lastModified&&new Date(l.lastModified).valueOf()===new Date(o).valueOf())return g(n,a),l.local=!0,void b(null,null,i,a,l,j)}m(j),i?(f.currentFileInfo=k,new w.Parser(f).parse(i,function(c,d){if(c)return b(c,null,null,a);try{b(c,d,i,a,l,j)}catch(c){b(c,null,null,a)}},{modifyVars:e,globalVars:w.globalVars})):b(h,null,null,a,l,j)},f,e)}function u(a,b,c){for(var d=0;dD&&(C=C.slice(y-D),D=y)}function h(a,b){var c=a.charCodeAt(0|b);return 32>=c&&(32===c||10===c||9===c)}function i(a){var b,c,d=typeof a;return"string"===d?v.charAt(y)!==a?null:(l(1),a):(g(),(b=a.exec(C))?(c=b[0].length,l(c),"string"==typeof b?b:1===b.length?b[0]:b):null)}function j(a){y>D&&(C=C.slice(y-D),D=y);var b=a.exec(C);return b?(l(b[0].length),"string"==typeof b?b:1===b.length?b[0]:b):null}function k(a){return v.charAt(y)!==a?null:(l(1),a)}function l(a){for(var b,c=y,d=z,e=y-D,f=y+C.length-e,g=y+=a,h=v;f>y&&(b=h.charCodeAt(y),!(b>32))&&(32===b||10===b||9===b||13===b);y++);return C=C.slice(a+y-g+e),D=y,!C.length&&z=0&&"\n"!==b.charAt(c);)e++;return"number"==typeof a&&(d=(b.slice(0,a).match(/\n/g)||"").length),{line:d,column:e}}function t(a,b,d){var e=d.currentFileInfo.filename;return"browser"!==w.mode&&"rhino"!==w.mode&&(e=c("path").resolve(e)),{lineNumber:s(a,b).line+1,fileName:e}}function u(a,b){var c=r(a,b),d=s(a.index,c),e=d.line,f=d.column,g=a.call&&s(a.call,c).line,h=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.currentFileInfo.filename,this.index=a.index,this.line="number"==typeof e?e+1:null,this.callLine=g+1,this.callExtract=h[g],this.stack=a.stack,this.column=f,this.extract=[h[e-1],h[e],h[e+1]]}var v,y,z,A,B,C,D,E,F,G=[],H=a&&a.filename;a instanceof x.parseEnv||(a=new x.parseEnv(a));var I=this.imports={paths:a.paths||[],queue:[],files:a.files,contents:a.contents,contentsIgnoredChars:a.contentsIgnoredChars,mime:a.mime,error:null,push:function(b,c,d,e){var f=this;this.queue.push(b);var g=function(a,c,d){f.queue.splice(f.queue.indexOf(b),1);var g=d===H;f.files[d]=c,a&&!f.error&&(f.error=a),e(a,c,g,d)};w.Parser.importer?w.Parser.importer(b,c,g,a):w.Parser.fileLoader(b,c,function(b,e,f,h){if(b)return void g(b);var i=new x.parseEnv(a);i.currentFileInfo=h,i.processImports=!1,i.contents[f]=e,(c.reference||d.reference)&&(h.reference=!0),d.inline?g(null,e,f):new w.Parser(i).parse(e,function(a,b){g(a,b,f)})},a)}},J=j;return u.prototype=new Error,u.prototype.constructor=u,this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,E={imports:I,parse:function(d,e,f){var g,h,i,j,k,l=null,m="";if(y=z=D=A=0,j=f&&f.globalVars?w.Parser.serializeVars(f.globalVars)+"\n":"",k=f&&f.modifyVars?"\n"+w.Parser.serializeVars(f.modifyVars):"",(j||f&&f.banner)&&(m=(f&&f.banner?f.banner:"")+j,E.imports.contentsIgnoredChars[a.currentFileInfo.filename]=m.length),d=d.replace(/\r\n/g,"\n"),v=d=m+d.replace(/^\uFEFF/,"")+k,E.imports.contents[a.currentFileInfo.filename]=d,B=function(b){function c(b,c){l=new u({index:c||i,type:"Parse",message:b,filename:a.currentFileInfo.filename},a)}function d(a){var c=i-s;512>c&&!a||!c||(r.push(b.slice(s,i+1)),s=i+1)}var e,f,g,h,i,j,k,m,n,o=b.length,p=0,q=0,r=[],s=0;for(i=0;o>i;i++)if(k=b.charCodeAt(i),!(k>=97&&122>=k||34>k))switch(k){case 40:q++,f=i;continue;case 41:if(--q<0)return c("missing opening `(`");continue;case 59:q||d();continue;case 123:p++,e=i;continue;case 125:if(--p<0)return c("missing opening `{`");p||q||d();continue;case 92:if(o-1>i){i++;continue}return c("unescaped `\\`");case 34:case 39:case 96:for(n=0,j=i,i+=1;o>i;i++)if(m=b.charCodeAt(i),!(m>96)){if(m==k){n=1;break}if(92==m){if(i==o-1)return c("unescaped `\\`");i++}}if(n)continue;return c("unmatched `"+String.fromCharCode(k)+"`",j);case 47:if(q||i==o-1)continue;if(m=b.charCodeAt(i+1),47==m)for(i+=2;o>i&&(m=b.charCodeAt(i),!(13>=m)||10!=m&&13!=m);i++);else if(42==m){for(g=j=i,i+=2;o-1>i&&(m=b.charCodeAt(i),125==m&&(h=i),42!=m||47!=b.charCodeAt(i+1));i++);if(i==o-1)return c("missing closing `*/`",j);i++}continue;case 42:if(o-1>i&&47==b.charCodeAt(i+1))return c("unmatched `/*`");continue}return 0!==p?g>e&&h>g?c("missing closing `}` or `*/`",e):c("missing closing `}`",e):0!==q?c("missing closing `)`",f):(d(!0),r)}(d),l)return e(new u(l,a));C=B[0];try{g=new x.Ruleset(null,this.parsers.primary()),g.root=!0,g.firstRoot=!0}catch(n){return e(new u(n,a))}if(g.toCSS=function(d){return function(e,f){e=e||{};var g,h,i=new x.evalEnv(e);"object"!=typeof f||Array.isArray(f)||(f=Object.keys(f).map(function(a){var b=f[a];return b instanceof x.Value||(b instanceof x.Expression||(b=new x.Expression([b])),b=new x.Value([b])),new x.Rule("@"+a,b,!1,null,0)}),i.frames=[new x.Ruleset(null,f)]);try{var j,k=[],l=[new x.joinSelectorVisitor,new x.processExtendsVisitor,new x.toCSSVisitor({compress:Boolean(e.compress)})],m=this;if(e.plugins)for(j=0;j57||43>b||47===b||44==b))return a=j(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/),a?new x.Dimension(a[1],a[2]):void 0},unicodeDescriptor:function(){var a;return a=j(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/),a?new x.UnicodeDescriptor(a[0]):void 0},javascript:function(){var c,d,e=y;return"~"===v.charAt(e)&&(e++,d=!0),"`"===v.charAt(e)?(a.javascriptEnabled===b||a.javascriptEnabled||o("You are using JavaScript, which has been disabled."),d&&k("~"),c=j(/^`([^`]*)`/),c?new x.JavaScript(c[1],y,d):void 0):void 0}},variable:function(){var a;return"@"===v.charAt(y)&&(a=j(/^(@[\w-]+)\s*:/))?a[1]:void 0},rulesetCall:function(){var a;return"@"===v.charAt(y)&&(a=j(/^(@[\w-]+)\s*\(\s*\)\s*;/))?new x.RulesetCall(a[1]):void 0},extend:function(a){var b,c,d,e,f,g=y;if(j(a?/^&:extend\(/:/^:extend\(/)){do{for(d=null,b=null;!(d=j(/^(all)(?=\s*(\)|,))/))&&(c=this.element());)b?b.push(c):b=[c];d=d&&d[1],f=new x.Extend(new x.Selector(b),d,g),e?e.push(f):e=[f]}while(k(","));return m(/^\)/),a&&m(/^;/),e}},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var b,c,g,h,i,l,m=v.charAt(y),o=!1,p=y;if("."===m||"#"===m){for(d();;){if(b=y,h=j(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/),!h)break;g=new x.Element(i,h,b,a.currentFileInfo),c?c.push(g):c=[g],i=k(">")}return c&&(k("(")&&(l=this.args(!0).args,n(")")),F.important()&&(o=!0),F.end())?(f(),new x.mixin.Call(c,l,p,a.currentFileInfo,o)):void e()}},args:function(a){var b,c,g,h,i,l,m=E.parsers,n=m.entities,p={args:null,variadic:!1},q=[],r=[],s=[];for(d();;){if(a)l=m.detachedRuleset()||m.expression();else{if(m.comments(),"."===v.charAt(y)&&j(/^\.{3}/)){p.variadic=!0,k(";")&&!b&&(b=!0),(b?r:s).push({variadic:!0});break}l=n.variable()||n.literal()||n.keyword()}if(!l)break;h=null,l.throwAwayComments&&l.throwAwayComments(),i=l;var t=null;if(a?l.value&&1==l.value.length&&(t=l.value[0]):t=l,t&&t instanceof x.Variable)if(k(":")){if(q.length>0&&(b&&o("Cannot mix ; and , as delimiter types"),c=!0),i=a&&m.detachedRuleset()||m.expression(),!i){if(!a)return e(),p.args=[],p;o("could not understand value for named argument")}h=g=t.name}else{if(!a&&j(/^\.{3}/)){p.variadic=!0,k(";")&&!b&&(b=!0),(b?r:s).push({name:l.name,variadic:!0});break}a||(g=h=t.name,i=null)}i&&q.push(i),s.push({name:h,value:i}),k(",")||(k(";")||b)&&(c&&o("Cannot mix ; and , as delimiter types"),b=!0,q.length>1&&(i=new x.Value(q)),r.push({name:g,value:i}),g=null,q=[],c=!1)}return f(),p.args=b?r:s,p},definition:function(){var a,b,c,g,h=[],i=!1;if(!("."!==v.charAt(y)&&"#"!==v.charAt(y)||p(/^[^{]*\}/)))if(d(),b=j(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){a=b[1];var l=this.args(!1);if(h=l.args,i=l.variadic,!k(")"))return A=y,void e();if(F.comments(),j(/^when/)&&(g=m(F.conditions,"expected condition")),c=F.block())return f(),new x.mixin.Definition(a,h,c,g,i);e()}else f()}},entity:function(){var a=this.entities;return a.literal()||a.variable()||a.url()||a.call()||a.keyword()||a.javascript()||this.comment()},end:function(){return k(";")||q("}")},alpha:function(){var a;if(j(/^\(opacity=/i))return a=j(/^\d+/)||this.entities.variable(),a?(n(")"),new x.Alpha(a)):void 0},element:function(){var b,c,g,h=y;return c=this.combinator(),b=j(/^(?:\d+\.\d+|\d+)%/)||j(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||k("*")||k("&")||this.attribute()||j(/^\([^()@]+\)/)||j(/^[\.#](?=@)/)||this.entities.variableCurly(),b||(d(),k("(")?(g=this.selector())&&k(")")?(b=new x.Paren(g),f()):e():f()),b?new x.Element(c,b,h,a.currentFileInfo):void 0},combinator:function(){var a=v.charAt(y);if(">"===a||"+"===a||"~"===a||"|"===a||"^"===a){for(y++,"^"===v.charAt(y)&&(a="^^",y++);h(v,y);)y++;return new x.Combinator(a)}return new x.Combinator(h(v,y-1)?" ":null)},lessSelector:function(){return this.selector(!0)},selector:function(b){for(var c,d,e,f,g,h,i,j=y,k=J;(b&&(g=this.extend())||b&&(h=k(/^when/))||(f=this.element()))&&(h?i=m(this.conditions,"expected condition"):i?o("CSS guard can only be used at the end of selector"):g?d?d.push(g):d=[g]:(d&&o("Extend can only be used at the end of selector"),e=v.charAt(y),c?c.push(f):c=[f],f=null),"{"!==e&&"}"!==e&&";"!==e&&","!==e&&")"!==e););return c?new x.Selector(c,d,i,j,a.currentFileInfo):void(d&&o("Extend must be used to extend a selector, it cannot be used on its own"))},attribute:function(){if(k("[")){var a,b,c,d=this.entities;return(a=d.variableCurly())||(a=m(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/)),c=j(/^[|~*$^]?=/),c&&(b=d.quoted()||j(/^[0-9]+%/)||j(/^[\w-]+/)||d.variableCurly()),n("]"),new x.Attribute(a,c,b)}},block:function(){var a;return k("{")&&(a=this.primary())&&k("}")?a:void 0},blockRuleset:function(){var a=this.block();return a&&(a=new x.Ruleset(null,a)),a},detachedRuleset:function(){var a=this.blockRuleset();return a?new x.DetachedRuleset(a):void 0},ruleset:function(){var b,c,g,h;for(d(),a.dumpLineNumbers&&(h=t(y,v,a));;){if(c=this.lessSelector(),!c)break;if(b?b.push(c):b=[c],this.comments(),c.condition&&b.length>1&&o("Guards are only currently allowed on a single selector."),!k(","))break;c.condition&&o("Guards are only currently allowed on a single selector."),this.comments()}if(b&&(g=this.block())){f();var i=new x.Ruleset(b,g,a.strictImports);return a.dumpLineNumbers&&(i.debugInfo=h),i}A=y,e()},rule:function(b){var c,g,h,i,j,k=y,l=v.charAt(k);if("."!==l&&"#"!==l&&"&"!==l)if(d(),c=this.variable()||this.ruleProperty()){if(j="string"==typeof c,j&&(g=this.detachedRuleset()),g||(g=b||!a.compress&&!j?this.anonymousValue()||this.value():this.value()||this.anonymousValue(),h=this.important(),i=!j&&c.pop().value),g&&this.end())return f(),new x.Rule(c,g,h,i,k,a.currentFileInfo);if(A=y,e(),g&&!b)return this.rule(!0)}else f()},anonymousValue:function(){var a;return a=/^([^@+\/'"*`(;{}-]*);/.exec(C),a?(y+=a[0].length-1,new x.Anonymous(a[1])):void 0},"import":function(){var b,c,g=y;d();var h=j(/^@import?\s+/),i=(h?this.importOptions():null)||{};return h&&(b=this.entities.quoted()||this.entities.url())&&(c=this.mediaFeatures(),k(";"))?(f(),c=c&&new x.Value(c),new x.Import(b,c,i,g,a.currentFileInfo)):void e()},importOptions:function(){var a,b,c,d={};if(!k("("))return null;do if(a=this.importOption()){switch(b=a,c=!0,b){case"css":b="less",c=!1;break;case"once":b="multiple",c=!1}if(d[b]=c,!k(","))break}while(a);return n(")"),d},importOption:function(){var a=j(/^(less|css|multiple|once|inline|reference)/);return a?a[1]:void 0},mediaFeature:function(){var b,c,d=this.entities,e=[];do if(b=d.keyword()||d.variable())e.push(b);else if(k("(")){if(c=this.property(),b=this.value(),!k(")"))return null;if(c&&b)e.push(new x.Paren(new x.Rule(c,b,null,null,y,a.currentFileInfo,!0)));else{if(!b)return null;e.push(new x.Paren(b))}}while(b);return e.length>0?new x.Expression(e):void 0},mediaFeatures:function(){var a,b=this.entities,c=[];do if(a=this.mediaFeature()){if(c.push(a),!k(","))break}else if(a=b.variable(),a&&(c.push(a),!k(",")))break;while(a);return c.length>0?c:null},media:function(){var b,c,d,e;return a.dumpLineNumbers&&(e=t(y,v,a)),j(/^@media/)&&(b=this.mediaFeatures(),c=this.block())?(d=new x.Media(c,b,y,a.currentFileInfo),a.dumpLineNumbers&&(d.debugInfo=e),d):void 0},directive:function(){var b,c,g,h,i,l,m,n=y,p=!0;if("@"===v.charAt(y)){if(c=this["import"]()||this.media())return c;if(d(),b=j(/^@[a-z-]+/)){switch(h=b,"-"==b.charAt(1)&&b.indexOf("-",2)>0&&(h="@"+b.slice(b.indexOf("-",2)+1)),h){case"@charset":i=!0,p=!1;break;case"@namespace":l=!0,p=!1;break;case"@keyframes":i=!0;break;case"@host":case"@page":case"@document":case"@supports":m=!0}return i?(c=this.entity(),c||o("expected "+b+" identifier")):l?(c=this.expression(),c||o("expected "+b+" expression")):m&&(c=(j(/^[^{;]+/)||"").trim(),c&&(c=new x.Anonymous(c))),p&&(g=this.blockRuleset()),g||!p&&c&&k(";")?(f(),new x.Directive(b,c,g,n,a.currentFileInfo,a.dumpLineNumbers?t(n,v,a):null)):void e()}}},value:function(){var a,b=[];do if(a=this.expression(),a&&(b.push(a),!k(",")))break;while(a);return b.length>0?new x.Value(b):void 0},important:function(){return"!"===v.charAt(y)?j(/^! *important/):void 0},sub:function(){var a,b;return k("(")&&(a=this.addition())?(b=new x.Expression([a]),n(")"),b.parens=!0,b):void 0},multiplication:function(){var a,b,c,d,e;if(a=this.operand()){for(e=h(v,y-1);;){if(p(/^\/[*\/]/))break;if(c=k("/")||k("*"),!c)break;if(b=this.operand(),!b)break;a.parensInOp=!0,b.parensInOp=!0,d=new x.Operation(c,[d||a,b],e),e=h(v,y-1)}return d||a}},addition:function(){var a,b,c,d,e;if(a=this.multiplication()){for(e=h(v,y-1);;){if(c=j(/^[-+]\s+/)||!e&&(k("+")||k("-")),!c)break;if(b=this.multiplication(),!b)break;a.parensInOp=!0,b.parensInOp=!0,d=new x.Operation(c,[d||a,b],e),e=h(v,y-1)}return d||a}},conditions:function(){var a,b,c,d=y;if(a=this.condition()){for(;;){if(!p(/^,\s*(not\s*)?\(/)||!k(","))break;if(b=this.condition(),!b)break;c=new x.Condition("or",c||a,b,d)}return c||a}},condition:function(){var a,b,c,d,e=this.entities,f=y,g=!1;return j(/^not/)&&(g=!0),n("("),a=this.addition()||e.keyword()||e.quoted(),a?(d=j(/^(?:>=|<=|=<|[<=>])/),d?(b=this.addition()||e.keyword()||e.quoted(),b?c=new x.Condition(d,a,b,f,g):o("expected expression")):c=new x.Condition("=",a,new x.Keyword("true"),f,g),n(")"),j(/^and/)?new x.Condition("and",c,this.condition()):c):void 0},operand:function(){var a,b=this.entities,c=v.charAt(y+1);"-"!==v.charAt(y)||"@"!==c&&"("!==c||(a=k("-"));var d=this.sub()||b.dimension()||b.color()||b.variable()||b.call();return a&&(d.parensInOp=!0,d=new x.Negative(d)),d},expression:function(){var a,b,c=[];do a=this.addition()||this.entity(),a&&(c.push(a),p(/^\/[\/*]/)||(b=k("/"),b&&c.push(new x.Anonymous(b))));while(a);return c.length>0?new x.Expression(c):void 0},property:function(){var a=j(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);return a?a[1]:void 0},ruleProperty:function(){function b(a){var b=a.exec(e);return b?(g.push(y+h),h+=b[0].length,e=e.slice(b[1].length),f.push(b[1])):void 0}var c,d,e=C,f=[],g=[],h=0;for(b(/^(\*?)/);b(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/););if(f.length>1&&b(/^\s*((?:\+_|\+)?)\s*:/)){for(l(h),""===f[0]&&(f.shift(),g.shift()),d=0;dl;l++)e=b.rgb[l]/255,f=c.rgb[l]/255,h=a(e,f),g&&(h=(j*f+i*(e-j*(e+f-h)))/g),k[l]=255*h;return new d.Color(k,g)}function g(){var a,b=d.functions;for(a in l)l.hasOwnProperty(a)&&(b[a]=e.bind(null,Math[a],l[a]));for(a in m)m.hasOwnProperty(a)&&(b[a]=f.bind(null,m[a]));a=d.defaultFunc,b["default"]=a.eval.bind(a)}function h(a){return d.functions.hsla(a.h,a.s,a.l,a.a)}function i(a,b){return a instanceof d.Dimension&&a.unit.is("%")?parseFloat(a.value*b/100):j(a)}function j(a){if(a instanceof d.Dimension)return parseFloat(a.unit.is("%")?a.value/100:a.value);if("number"==typeof a)return a;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function k(a){return Math.min(1,Math.max(0,a))}d.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(a,b,c,e){var f=[a,b,c].map(function(a){return i(a,255)});return e=j(e),new d.Color(f,e)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,c,d){function e(a){return a=0>a?a+1:a>1?a-1:a,1>6*a?g+(f-g)*a*6:1>2*a?f:2>3*a?g+(f-g)*(2/3-a)*6:g}a=j(a)%360/360,b=k(j(b)),c=k(j(c)),d=k(j(d));var f=.5>=c?c*(b+1):c+b-c*b,g=2*c-f;return this.rgba(255*e(a+1/3),255*e(a),255*e(a-1/3),d)},hsv:function(a,b,c){return this.hsva(a,b,c,1)},hsva:function(a,b,c,d){a=j(a)%360/360*360,b=j(b),c=j(c),d=j(d);var e,f;e=Math.floor(a/60%6),f=a/60-e;var g=[c,c*(1-b),c*(1-f*b),c*(1-(1-f)*b)],h=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(255*g[h[e][0]],255*g[h[e][1]],255*g[h[e][2]],d)},hue:function(a){return new d.Dimension(Math.round(a.toHSL().h))},saturation:function(a){return new d.Dimension(Math.round(100*a.toHSL().s),"%")},lightness:function(a){return new d.Dimension(Math.round(100*a.toHSL().l),"%")},hsvhue:function(a){return new d.Dimension(Math.round(a.toHSV().h))},hsvsaturation:function(a){return new d.Dimension(Math.round(100*a.toHSV().s),"%")},hsvvalue:function(a){return new d.Dimension(Math.round(100*a.toHSV().v),"%")},red:function(a){return new d.Dimension(a.rgb[0])},green:function(a){return new d.Dimension(a.rgb[1])},blue:function(a){return new d.Dimension(a.rgb[2])},alpha:function(a){return new d.Dimension(a.toHSL().a)},luma:function(a){return new d.Dimension(Math.round(a.luma()*a.alpha*100),"%")},luminance:function(a){var b=.2126*a.rgb[0]/255+.7152*a.rgb[1]/255+.0722*a.rgb[2]/255;return new d.Dimension(Math.round(b*a.alpha*100),"%")},saturate:function(a,b){if(!a.rgb)return null;var c=a.toHSL();return c.s+=b.value/100,c.s=k(c.s),h(c)},desaturate:function(a,b){var c=a.toHSL();return c.s-=b.value/100,c.s=k(c.s),h(c)},lighten:function(a,b){var c=a.toHSL();return c.l+=b.value/100,c.l=k(c.l),h(c)},darken:function(a,b){var c=a.toHSL();return c.l-=b.value/100,c.l=k(c.l),h(c)},fadein:function(a,b){var c=a.toHSL();return c.a+=b.value/100,c.a=k(c.a),h(c)},fadeout:function(a,b){var c=a.toHSL();return c.a-=b.value/100,c.a=k(c.a),h(c)},fade:function(a,b){var c=a.toHSL();return c.a=b.value/100,c.a=k(c.a),h(c)},spin:function(a,b){var c=a.toHSL(),d=(c.h+b.value)%360;return c.h=0>d?360+d:d,h(c)},mix:function(a,b,c){c||(c=new d.Dimension(50));var e=c.value/100,f=2*e-1,g=a.toHSL().a-b.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[a.rgb[0]*h+b.rgb[0]*i,a.rgb[1]*h+b.rgb[1]*i,a.rgb[2]*h+b.rgb[2]*i],k=a.alpha*e+b.alpha*(1-e);return new d.Color(j,k)},greyscale:function(a){return this.desaturate(a,new d.Dimension(100))},contrast:function(a,b,c,d){if(!a.rgb)return null;if("undefined"==typeof c&&(c=this.rgba(255,255,255,1)),"undefined"==typeof b&&(b=this.rgba(0,0,0,1)),b.luma()>c.luma()){var e=c;c=b,b=e}return d="undefined"==typeof d?.43:j(d),a.luma()i.value)&&(m[f]=g);else{if(k!==b&&j!==k)throw{type:"Argument",message:"incompatible types"};n[j]=m.length,m.push(g)}else Array.isArray(c[e].value)&&Array.prototype.push.apply(c,Array.prototype.slice.call(c[e].value));return 1==m.length?m[0]:(c=m.map(function(a){return a.toCSS(this.env)}).join(this.env.compress?",":", "),new d.Anonymous((a?"min":"max")+"("+c+")"))},min:function(){return this._minmax(!0,arguments)},max:function(){return this._minmax(!1,arguments)},"get-unit":function(a){return new d.Anonymous(a.unit)},argb:function(a){return new d.Anonymous(a.toARGB())},percentage:function(a){return new d.Dimension(100*a.value,"%")},color:function(a){if(a instanceof d.Quoted){var b,c=a.value;if(b=d.Color.fromKeyword(c))return b;if(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(c))return new d.Color(c.slice(1));throw{type:"Argument",message:"argument must be a color keyword or 3/6 digit hex e.g. #FFF"}}throw{type:"Argument",message:"argument must be a string"}},iscolor:function(a){return this._isa(a,d.Color)},isnumber:function(a){return this._isa(a,d.Dimension)},isstring:function(a){return this._isa(a,d.Quoted)},iskeyword:function(a){return this._isa(a,d.Keyword)},isurl:function(a){return this._isa(a,d.URL)},ispixel:function(a){return this.isunit(a,"px")},ispercentage:function(a){return this.isunit(a,"%")},isem:function(a){return this.isunit(a,"em")},isunit:function(a,b){return a instanceof d.Dimension&&a.unit.is(b.value||b)?d.True:d.False},_isa:function(a,b){return a instanceof b?d.True:d.False},tint:function(a,b){return this.mix(this.rgb(255,255,255),a,b)},shade:function(a,b){return this.mix(this.rgb(0,0,0),a,b)},extract:function(a,b){return b=b.value-1,Array.isArray(a.value)?a.value[b]:Array(a)[b]},length:function(a){var b=Array.isArray(a.value)?a.value.length:1;return new d.Dimension(b)},"data-uri":function(b,e){if("undefined"!=typeof a)return new d.URL(e||b,this.currentFileInfo).eval(this.env);var f=b.value,g=e&&e.value,h=c("fs"),i=c("path"),j=!1;if(arguments.length<2&&(g=f),this.env.isPathRelative(g)&&(g=this.currentFileInfo.relativeUrls?i.join(this.currentFileInfo.currentDirectory,g):i.join(this.currentFileInfo.entryPath,g)),arguments.length<2){var k;try{k=c("mime")}catch(l){k=d._mime}f=k.lookup(g);var m=k.charsets.lookup(f);j=["US-ASCII","UTF-8"].indexOf(m)<0,j&&(f+=";base64")}else j=/;base64$/.test(f);var n=h.readFileSync(g),o=32,p=parseInt(n.length/1024,10);if(p>=o&&this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",g,p,o),new d.URL(e||b,this.currentFileInfo).eval(this.env);n=j?n.toString("base64"):encodeURIComponent(n);var q='"data:'+f+","+n+'"';return new d.URL(new d.Anonymous(q))},"svg-gradient":function(a){function e(){throw{type:"Argument",message:"svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]"}}arguments.length<3&&e();var f,g,h,i,j,k,l,m=Array.prototype.slice.call(arguments,1),n="linear",o='x="0" y="0" width="1" height="1"',p=!0,q={compress:!1},r=a.toCSS(q);switch(r){case"to bottom":f='x1="0%" y1="0%" x2="0%" y2="100%"';break;case"to right":f='x1="0%" y1="0%" x2="100%" y2="0%"';break;case"to bottom right":f='x1="0%" y1="0%" x2="100%" y2="100%"';break;case"to top right":f='x1="0%" y1="100%" x2="100%" y2="0%"';break;case"ellipse":case"ellipse at center":n="radial",f='cx="50%" cy="50%" r="75%"',o='x="-50" y="-50" width="101" height="101"';break;default:throw{type:"Argument",message:"svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'"}}for(g='<'+n+'Gradient id="gradient" gradientUnits="userSpaceOnUse" '+f+">",h=0;hl?' stop-opacity="'+l+'"':"")+"/>";if(g+="',p)try{g=c("./encoder").encodeBase64(g)}catch(s){p=!1}return g="'data:image/svg+xml"+(p?";base64":"")+","+g+"'",new d.URL(new d.Anonymous(g))}},d._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(a){var e=c("path").extname(a),f=d._mime._types[e];if(f===b)throw new Error('Optional dependency "mime" is required for '+e);return f},charsets:{lookup:function(a){return a&&/^text\//.test(a)?"UTF-8":""}}};var l={ceil:null,floor:null,sqrt:null,abs:null,tan:"",sin:"",cos:"",atan:"rad",asin:"rad",acos:"rad"},m={multiply:function(a,b){return a*b},screen:function(a,b){return a+b-a*b},overlay:function(a,b){return a*=2,1>=a?m.multiply(a,b):m.screen(a-1,b)},softlight:function(a,b){var c=1,d=a;return b>.5&&(d=1,c=a>.25?Math.sqrt(a):((16*a-12)*a+4)*a),a-(1-2*b)*d*(c-a)},hardlight:function(a,b){return m.overlay(b,a)},difference:function(a,b){return Math.abs(a-b)},exclusion:function(a,b){return a+b-2*a*b},average:function(a,b){return(a+b)/2},negation:function(a,b){return 1-Math.abs(a+b-1)}};d.defaultFunc={eval:function(){var a=this.value_,b=this.error_;if(b)throw b;return null!=a?a?d.True:d.False:void 0},value:function(a){this.value_=a},error:function(a){this.error_=a},reset:function(){this.value_=this.error_=null}},g(),d.fround=function(a,b){var c;return a&&null!=a.numPrecision?(c=Math.pow(10,a.numPrecision),Math.round(b*c)/c):b},d.functionCall=function(a,b){this.env=a,this.currentFileInfo=b},d.functionCall.prototype=d.functions}(c("./tree")),function(a){a.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(c("./tree")),function(a){a.debugInfo=function(b,c,d){var e="";if(b.dumpLineNumbers&&!b.compress)switch(b.dumpLineNumbers){case"comments":e=a.debugInfo.asComment(c);break;case"mediaquery":e=a.debugInfo.asMediaQuery(c);break;case"all":e=a.debugInfo.asComment(c)+(d||"")+a.debugInfo.asMediaQuery(c)}return e},a.debugInfo.asComment=function(a){return"/* line "+a.debugInfo.lineNumber+", "+a.debugInfo.fileName+" */\n"},a.debugInfo.asMediaQuery=function(a){return"@media -sass-debug-info{filename{font-family:"+("file://"+a.debugInfo.fileName).replace(/([.:\/\\])/g,function(a){return"\\"==a&&(a="/"),"\\"+a})+"}line{font-family:\\00003"+a.debugInfo.lineNumber+"}}\n"},a.find=function(a,b){for(var c,d=0;d1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)},a.toCSS=function(a){var b=[];return this.genCSS(a,{add:function(a){b.push(a)},isEmpty:function(){return 0===b.length}}),b.join("")},a.outputRuleset=function(a,b,c){var d,e=c.length;if(a.tabLevel=(0|a.tabLevel)+1,a.compress){for(b.add("{"),d=0;e>d;d++)c[d].genCSS(a,b);return b.add("}"),void a.tabLevel--}var f="\n"+Array(a.tabLevel).join(" "),g=f+" ";if(e){for(b.add(" {"+g),c[0].genCSS(a,b),d=1;e>d;d++)b.add(g),c[d].genCSS(a,b);b.add(f+"}")}else b.add(" {"+f+"}");a.tabLevel--}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={type:"Alpha",accept:function(a){this.value=a.visit(this.value)},eval:function(b){return this.value.eval?new a.Alpha(this.value.eval(b)):this},genCSS:function(a,b){b.add("alpha(opacity="),this.value.genCSS?this.value.genCSS(a,b):b.add(this.value),b.add(")")},toCSS:a.toCSS}}(c("../tree")),function(a){a.Anonymous=function(a,b,c,d){this.value=a.value||a,this.index=b,this.mapLines=d,this.currentFileInfo=c},a.Anonymous.prototype={type:"Anonymous",eval:function(){return new a.Anonymous(this.value,this.index,this.currentFileInfo,this.mapLines)},compare:function(a){if(!a.toCSS)return-1;var b=this.toCSS(),c=a.toCSS();return b===c?0:c>b?-1:1},genCSS:function(a,b){b.add(this.value,this.currentFileInfo,this.index,this.mapLines)},toCSS:a.toCSS}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={type:"Assignment",accept:function(a){this.value=a.visit(this.value)},eval:function(b){return this.value.eval?new a.Assignment(this.key,this.value.eval(b)):this},genCSS:function(a,b){b.add(this.key+"="),this.value.genCSS?this.value.genCSS(a,b):b.add(this.value)},toCSS:a.toCSS}}(c("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.currentFileInfo=d},a.Call.prototype={type:"Call",accept:function(a){this.args&&(this.args=a.visitArray(this.args))},eval:function(b){var c,d,e=this.args.map(function(a){return a.eval(b)}),f=this.name.toLowerCase();if(f in a.functions)try{if(d=new a.functionCall(b,this.currentFileInfo),c=d[f].apply(d,e),null!=c)return c}catch(g){throw{type:g.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(g.message?": "+g.message:""),index:this.index,filename:this.currentFileInfo.filename}}return new a.Call(this.name,e,this.index,this.currentFileInfo)},genCSS:function(a,b){b.add(this.name+"(",this.currentFileInfo,this.index);for(var c=0;ca?"0":"")+a.toString(16)}).join("")}function c(a,b){return Math.min(Math.max(a,0),b)}a.Color=function(a,b){this.rgb=Array.isArray(a)?a:6==a.length?a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha="number"==typeof b?b:1};var d="transparent";a.Color.prototype={type:"Color",eval:function(){return this},luma:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255;return a=.03928>=a?a/12.92:Math.pow((a+.055)/1.055,2.4),b=.03928>=b?b/12.92:Math.pow((b+.055)/1.055,2.4),c=.03928>=c?c/12.92:Math.pow((c+.055)/1.055,2.4),.2126*a+.7152*b+.0722*c},genCSS:function(a,b){b.add(this.toCSS(a))},toCSS:function(b,e){var f=b&&b.compress&&!e,g=a.fround(b,this.alpha);if(1>g)return 0===g&&this.isTransparentKeyword?d:"rgba("+this.rgb.map(function(a){return c(Math.round(a),255)}).concat(c(g,1)).join(","+(f?"":" "))+")";var h=this.toRGB();if(f){var i=h.split("");i[1]===i[2]&&i[3]===i[4]&&i[5]===i[6]&&(h="#"+i[1]+i[3]+i[5])}return h},operate:function(b,c,d){for(var e=[],f=this.alpha*(1-d.alpha)+d.alpha,g=0;3>g;g++)e[g]=a.operate(b,c,this.rgb[g],d.rgb[g]);return new a.Color(e,f)},toRGB:function(){return b(this.rgb)},toHSL:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=(g+h)/2,j=g-h;if(g===h)a=b=0;else{switch(b=i>.5?j/(2-g-h):j/(g+h),g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,l:i,a:f}},toHSV:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=g,j=g-h;if(b=0===g?0:j/g,g===h)a=0;else{switch(g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,v:i,a:f}},toARGB:function(){return b([255*this.alpha].concat(this.rgb))},compare:function(a){return a.rgb?a.rgb[0]===this.rgb[0]&&a.rgb[1]===this.rgb[1]&&a.rgb[2]===this.rgb[2]&&a.alpha===this.alpha?0:-1:-1}},a.Color.fromKeyword=function(b){if(b=b.toLowerCase(),a.colors.hasOwnProperty(b))return new a.Color(a.colors[b].slice(1));if(b===d){var c=new a.Color([0,0,0],0);return c.isTransparentKeyword=!0,c}}}(c("../tree")),function(a){a.Comment=function(a,b,c,d){this.value=a,this.silent=!!b,this.currentFileInfo=d},a.Comment.prototype={type:"Comment",genCSS:function(b,c){this.debugInfo&&c.add(a.debugInfo(b,this),this.currentFileInfo,this.index),c.add(this.value.trim())},toCSS:a.toCSS,isSilent:function(a){var b=this.currentFileInfo&&this.currentFileInfo.reference&&!this.isReferenced,c=a.compress&&!this.value.match(/^\/\*!/);return this.silent||b||c},eval:function(){return this},markReferenced:function(){this.isReferenced=!0}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype={type:"Condition",accept:function(a){this.lvalue=a.visit(this.lvalue),this.rvalue=a.visit(this.rvalue)},eval:function(a){var b,c=this.lvalue.eval(a),d=this.rvalue.eval(a),e=this.index;return b=function(a){switch(a){case"and":return c&&d;case"or":return c||d;default:if(c.compare)b=c.compare(d);else{if(!d.compare)throw{type:"Type",message:"Unable to perform comparison",index:e};b=d.compare(c)}switch(b){case-1:return"<"===a||"=<"===a||"<="===a;case 0:return"="===a||">="===a||"=<"===a||"<="===a;case 1:return">"===a||">="===a}}}(this.op),this.negate?!b:b}}}(c("../tree")),function(a){a.DetachedRuleset=function(a,b){this.ruleset=a,this.frames=b},a.DetachedRuleset.prototype={type:"DetachedRuleset",accept:function(a){this.ruleset=a.visit(this.ruleset)},eval:function(b){var c=this.frames||b.frames.slice(0);return new a.DetachedRuleset(this.ruleset,c)},callEval:function(b){return this.ruleset.eval(this.frames?new a.evalEnv(b,this.frames.concat(b.frames)):b)}}}(c("../tree")),function(a){a.Dimension=function(c,d){this.value=parseFloat(c),this.unit=d&&d instanceof a.Unit?d:new a.Unit(d?[d]:b)},a.Dimension.prototype={type:"Dimension",accept:function(a){this.unit=a.visit(this.unit)},eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},genCSS:function(b,c){if(b&&b.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var d=a.fround(b,this.value),e=String(d);if(0!==d&&1e-6>d&&d>-1e-6&&(e=d.toFixed(20).replace(/0+$/,"")),b&&b.compress){if(0===d&&this.unit.isLength())return void c.add(e);d>0&&1>d&&(e=e.substr(1))}c.add(e),this.unit.genCSS(b,c)},toCSS:a.toCSS,operate:function(b,c,d){var e=a.operate(b,c,this.value,d.value),f=this.unit.clone();if("+"===c||"-"===c)if(0===f.numerator.length&&0===f.denominator.length)f.numerator=d.unit.numerator.slice(0),f.denominator=d.unit.denominator.slice(0);else if(0===d.unit.numerator.length&&0===f.denominator.length);else{if(d=d.convertTo(this.unit.usedUnits()),b.strictUnits&&d.unit.toString()!==f.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+f.toString()+"' and '"+d.unit.toString()+"'.");e=a.operate(b,c,this.value,d.value)}else"*"===c?(f.numerator=f.numerator.concat(d.unit.numerator).sort(),f.denominator=f.denominator.concat(d.unit.denominator).sort(),f.cancel()):"/"===c&&(f.numerator=f.numerator.concat(d.unit.denominator).sort(),f.denominator=f.denominator.concat(d.unit.numerator).sort(),f.cancel());return new a.Dimension(e,f)},compare:function(b){if(b instanceof a.Dimension){var c,d,e,f;if(this.unit.isEmpty()||b.unit.isEmpty())c=this,d=b;else if(c=this.unify(),d=b.unify(),0!==c.unit.compare(d.unit))return-1;return e=c.value,f=d.value,f>e?-1:e>f?1:0}return-1},unify:function(){return this.convertTo({length:"px",duration:"s",angle:"rad"})},convertTo:function(b){var c,d,e,f,g,h=this.value,i=this.unit.clone(),j={};if("string"==typeof b){for(c in a.UnitConversions)a.UnitConversions[c].hasOwnProperty(b)&&(j={},j[c]=b);b=j}g=function(a,b){return e.hasOwnProperty(a)?(b?h/=e[a]/e[f]:h*=e[a]/e[f],f):a};for(d in b)b.hasOwnProperty(d)&&(f=b[d],e=a.UnitConversions[d],i.map(g));return i.cancel(),new a.Dimension(h,i)}},a.UnitConversions={length:{m:1,cm:.01,mm:.001,"in":.0254,px:.0254/96,pt:.0254/72,pc:.0254/72*12},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:.0025,turn:1}},a.Unit=function(a,b,c){this.numerator=a?a.slice(0).sort():[],this.denominator=b?b.slice(0).sort():[],this.backupUnit=c},a.Unit.prototype={type:"Unit",clone:function(){return new a.Unit(this.numerator.slice(0),this.denominator.slice(0),this.backupUnit)},genCSS:function(a,b){this.numerator.length>=1?b.add(this.numerator[0]):this.denominator.length>=1?b.add(this.denominator[0]):a&&a.strictUnits||!this.backupUnit||b.add(this.backupUnit)},toCSS:a.toCSS,toString:function(){var a,b=this.numerator.join("*");for(a=0;a0)for(b=0;e>b;b++)this.numerator.push(a);else if(0>e)for(b=0;-e>b;b++)this.denominator.push(a)}0===this.numerator.length&&0===this.denominator.length&&c&&(this.backupUnit=c),this.numerator.sort(),this.denominator.sort()}}}(c("../tree")),function(a){a.Directive=function(a,b,c,d,e,f){this.name=a,this.value=b,c&&(this.rules=c,this.rules.allowImports=!0),this.index=d,this.currentFileInfo=e,this.debugInfo=f},a.Directive.prototype={type:"Directive",accept:function(a){var b=this.value,c=this.rules;c&&(c=a.visit(c)),b&&(b=a.visit(b))},genCSS:function(b,c){var d=this.value,e=this.rules;c.add(this.name,this.currentFileInfo,this.index),d&&(c.add(" "),d.genCSS(b,c)),e?a.outputRuleset(b,c,[e]):c.add(";")},toCSS:a.toCSS,eval:function(b){var c=this.value,d=this.rules;return c&&(c=c.eval(b)),d&&(d=d.eval(b),d.root=!0),new a.Directive(this.name,c,d,this.index,this.currentFileInfo,this.debugInfo)},variable:function(b){return this.rules?a.Ruleset.prototype.variable.call(this.rules,b):void 0},find:function(){return this.rules?a.Ruleset.prototype.find.apply(this.rules,arguments):void 0},rulesets:function(){return this.rules?a.Ruleset.prototype.rulesets.apply(this.rules):void 0},markReferenced:function(){var a,b;if(this.isReferenced=!0,this.rules)for(b=this.rules.rules,a=0;a":" > ","|":"|","^":" ^ ","^^":" ^^ "},_outputMapCompressed:{"":""," ":" ",":":" :","+":"+","~":"~",">":">","|":"|","^":"^","^^":"^^"},genCSS:function(a,b){b.add((a.compress?this._outputMapCompressed:this._outputMap)[this.value])},toCSS:a.toCSS}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={type:"Expression",accept:function(a){this.value&&(this.value=a.visitArray(this.value))},eval:function(b){var c,d=this.parens&&!this.parensInOp,e=!1;return d&&b.inParenthesis(),this.value.length>1?c=new a.Expression(this.value.map(function(a){return a.eval(b)})):1===this.value.length?(this.value[0].parens&&!this.value[0].parensInOp&&(e=!0),c=this.value[0].eval(b)):c=this,d&&b.outOfParenthesis(),this.parens&&this.parensInOp&&!b.isMathOn()&&!e&&(c=new a.Paren(c)),c},genCSS:function(a,b){for(var c=0;c0&&c.length&&""===c[0].combinator.value&&(c[0].combinator.value=" "),d=d.concat(a[b].elements);this.selfSelectors=[{elements:d}]}}}(c("../tree")),function(a){a.Import=function(a,c,d,e,f){if(this.options=d,this.index=e,this.path=a,this.features=c,this.currentFileInfo=f,this.options.less!==b||this.options.inline)this.css=!this.options.less||this.options.inline;else{var g=this.getPath();g&&/css([\?;].*)?$/.test(g)&&(this.css=!0)}},a.Import.prototype={type:"Import",accept:function(a){this.features&&(this.features=a.visit(this.features)),this.path=a.visit(this.path),!this.options.inline&&this.root&&(this.root=a.visit(this.root))},genCSS:function(a,b){this.css&&(b.add("@import ",this.currentFileInfo,this.index),this.path.genCSS(a,b),this.features&&(b.add(" "),this.features.genCSS(a,b)),b.add(";"))},toCSS:a.toCSS,getPath:function(){if(this.path instanceof a.Quoted){var c=this.path.value;return this.css!==b||/(\.[a-z]*$)|([\?;].*)$/.test(c)?c:c+".less"}return this.path instanceof a.URL?this.path.value.value:null},evalForImport:function(b){return new a.Import(this.path.eval(b),this.features,this.options,this.index,this.currentFileInfo)},evalPath:function(b){var c=this.path.eval(b),d=this.currentFileInfo&&this.currentFileInfo.rootpath;if(!(c instanceof a.URL)){if(d){var e=c.value;e&&b.isPathRelative(e)&&(c.value=d+e)}c.value=b.normalizePath(c.value)}return c},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.skip&&("function"==typeof this.skip&&(this.skip=this.skip()),this.skip))return[];if(this.options.inline){var e=new a.Anonymous(this.root,0,{filename:this.importedFilename},!0);return this.features?new a.Media([e],this.features.value):[e]}if(this.css){var f=new a.Import(this.evalPath(b),d,this.options,this.index);if(!f.css&&this.error)throw this.error;return f}return c=new a.Ruleset(null,this.root.rules.slice(0)),c.evalImports(b),this.features?new a.Media(c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={type:"JavaScript",eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify(new a.Variable("@"+e,d.index).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: "+g.message+" from `"+f+"`",index:this.index}}var h=b.frames[0].variables();for(var i in h)h.hasOwnProperty(i)&&(e[i.slice(1)]={value:h[i].value,toJS:function(){return this.value.eval(b).toCSS()}});try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message.replace(/["]/g,"'")+"'",index:this.index}}return"number"==typeof c?new a.Dimension(c):"string"==typeof c?new a.Quoted('"'+c+'"',c,this.escaped,this.index):new a.Anonymous(Array.isArray(c)?c.join(", "):c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={type:"Keyword",eval:function(){return this},genCSS:function(a,b){if("%"===this.value)throw{type:"Syntax",message:"Invalid % without number"};b.add(this.value)},toCSS:a.toCSS,compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.Media=function(b,c,d,e){this.index=d,this.currentFileInfo=e;var f=this.emptySelectors();this.features=new a.Value(c),this.rules=[new a.Ruleset(f,b)],this.rules[0].allowImports=!0},a.Media.prototype={type:"Media",accept:function(a){this.features&&(this.features=a.visit(this.features)),this.rules&&(this.rules=a.visitArray(this.rules))},genCSS:function(b,c){c.add("@media ",this.currentFileInfo,this.index),this.features.genCSS(b,c),a.outputRuleset(b,c,this.rules)},toCSS:a.toCSS,eval:function(b){b.mediaBlocks||(b.mediaBlocks=[],b.mediaPath=[]);var c=new a.Media(null,[],this.index,this.currentFileInfo);this.debugInfo&&(this.rules[0].debugInfo=this.debugInfo,c.debugInfo=this.debugInfo);var d=!1;b.strictMath||(d=!0,b.strictMath=!0);try{c.features=this.features.eval(b)}finally{d&&(b.strictMath=!1)}return b.mediaPath.push(c),b.mediaBlocks.push(c),b.frames.unshift(this.rules[0]),c.rules=[this.rules[0].eval(b)],b.frames.shift(),b.mediaPath.pop(),0===b.mediaPath.length?c.evalTop(b):c.evalNested(b)},variable:function(b){return a.Ruleset.prototype.variable.call(this.rules[0],b)},find:function(){return a.Ruleset.prototype.find.apply(this.rules[0],arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.rules[0])},emptySelectors:function(){var b=new a.Element("","&",this.index,this.currentFileInfo),c=[new a.Selector([b],null,null,this.index,this.currentFileInfo)];return c[0].mediaEmpty=!0,c},markReferenced:function(){var a,b=this.rules[0].rules;for(this.rules[0].markReferenced(),this.isReferenced=!0,a=0;a1){var d=this.emptySelectors();c=new a.Ruleset(d,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(0===a.length)return[];if(1===a.length)return a[0];for(var b=[],c=this.permute(a.slice(1)),d=0;d`, `>=` etc.) are also considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are not considered functions. +##### Example + +Deny SUM and COUNT functions: + +``` +rule examplerule deny function sum count +``` + #### `regex` This rule blocks all queries matching a regex enclosed in single or double @@ -156,15 +180,31 @@ quotes. The regex string expects a PCRE2 syntax regular expression. For more information about the PCRE2 syntax, read the [PCRE2 documentation](http://www.pcre.org/current/doc/html/pcre2syntax.html). +##### Example + +Block selects to accounts: + +``` +rule examplerule deny regex '.*select.*from.*accounts.*' +``` + #### `limit_queries` The limit_queries rule expects three parameters. The first parameter is the number of allowed queries during the time period. The second is the time period -in seconds and the third is the amount of time for which the rule is considered -active and blocking. +in seconds and the third is the amount of time in seconds for which the rule is +considered active and blocking. **WARNING:** Using `limit_queries` in `action=allow` is not supported. +##### Example + +Over 50 queries within a window of 5 seconds will block for 100 seconds: + +``` +rule examplerule deny limit_queries 50 5 100 +``` + #### `no_where_clause` This rule inspects the query and blocks it if it has no WHERE clause. For @@ -172,6 +212,14 @@ example, this would disallow a `DELETE FROM ...` query without a `WHERE` clause. This does not prevent wrongful usage of the `WHERE` clause e.g. `DELETE FROM ... WHERE 1=1`. +##### Example + +Queries must have a where clause: + +``` +rule examplerule deny no_where_clause +``` + ### Optional rule parameters Each mandatory rule accepts one or more optional parameters. These are to be diff --git a/Documentation/Filters/Luafilter.md b/Documentation/Filters/Luafilter.md index 4bb2b2847..42082cec9 100644 --- a/Documentation/Filters/Luafilter.md +++ b/Documentation/Filters/Luafilter.md @@ -49,7 +49,7 @@ The entry points for the Lua script expect the following signatures: - The `closeSession` function in the Lua scripts will be called. - `(nil | bool | string) routeQuery(string)` - query is being routed - + - The Luafilter calls the `routeQuery` functions of both the session and the global script. The query is passed as a string parameter to the routeQuery Lua function and the return values of the session specific diff --git a/Documentation/Filters/RabbitMQ-Consumer-Client.md b/Documentation/Filters/RabbitMQ-Consumer-Client.md index 63dc4ccaf..4dc8a2216 100644 --- a/Documentation/Filters/RabbitMQ-Consumer-Client.md +++ b/Documentation/Filters/RabbitMQ-Consumer-Client.md @@ -67,7 +67,7 @@ configured into the separate `consumer.cnf` file. | user | Username for the RabbitMQ server | | passwd | Password for the RabbitMQ server | | queue | Queue to consume from | -| dbserver | Hostname of the SQL server | +| dbserver | Hostname of the SQL server | | dbport | Port of the SQL server | | dbname | Name of the SQL database to use | | dbuser | Database username | diff --git a/Documentation/Filters/Regex-Filter.md b/Documentation/Filters/Regex-Filter.md index c4cdf603c..37542a0e4 100644 --- a/Documentation/Filters/Regex-Filter.md +++ b/Documentation/Filters/Regex-Filter.md @@ -30,7 +30,7 @@ filters=MyRegexfilter ## Filter Options -The Regex filter accepts the options ignorecase or case. These define if the pattern text should take the case of the string it is matching against into consideration or not. +The Regex filter accepts the options ignorecase or case. These define if the pattern text should take the case of the string it is matching against into consideration or not. ## Filter Parameters diff --git a/Documentation/Filters/Top-N-Filter.md b/Documentation/Filters/Top-N-Filter.md index 1e2103338..f0eeefcfc 100644 --- a/Documentation/Filters/Top-N-Filter.md +++ b/Documentation/Filters/Top-N-Filter.md @@ -210,6 +210,6 @@ Average statement execution time 1.488 seconds Total connection time 46.500 seconds --bash-4.1$ +-bash-4.1$ ``` diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index 0de830ad4..b7a9d15c7 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1231,7 +1231,7 @@ MariaDB MaxScale to connect to MariaDB MaxScale. ##### `MySQLBackend` The MySQLBackend protocol module is the implementation of the protocol that -MariaDB MaxScale uses to connect to the backend MySQL, MariaDB and Percona +MariaDB MaxScale uses to connect to the backend MariaDB, MySQL and Percona Server databases. This implementation is tailored for the MariaDB MaxScale to MySQL Database traffic and is not a general purpose implementation of the MySQL protocol. @@ -1449,12 +1449,12 @@ Monitors can not be completely removed from the running MariaDB MaxScale. ## Authentication -MySQL uses username, passwords and the client host in order to authenticate a +MariaDB uses username, passwords and the client host in order to authenticate a user, so a typical user would be defined as user X at host Y and would be given -a password to connect. MariaDB MaxScale uses exactly the same rules as MySQL +a password to connect. MariaDB MaxScale uses exactly the same rules as MariaDB when users connect to the MariaDB MaxScale instance, i.e. it will check the address from which the client is connecting and treat this in exactly the same -way that MySQL would. MariaDB MaxScale will pull the authentication data from +way that MariaDB would. MariaDB MaxScale will pull the authentication data from one of the backend servers and use this to match the incoming connections, the assumption being that all the backend servers for a particular service will share the same set of user credentials. @@ -1493,10 +1493,10 @@ backends as it would also use the password *pass2* for these connections. ### Wildcard Hosts -Hostname mapping in MariaDB MaxScale works in exactly the same way as for MySQL, +Hostname mapping in MariaDB MaxScale works in exactly the same way as for MariaDB, if the wildcard is used for the host then any host other than the localhost (127.0.0.1) will match. It is important to consider that the localhost check -will be performed at the MariaDB MaxScale level and at the MySQL server level. +will be performed at the MariaDB MaxScale level and at the MariaDB server level. If MariaDB MaxScale and the databases are on separate hosts there are two important changes in behavior to consider: diff --git a/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md index 2c8c29ff0..a750ca16e 100644 --- a/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md +++ b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md @@ -92,20 +92,20 @@ what it is you want to achieve with your MariaDB MaxScale and what environment it will run in. The later is probably the easiest starting point for choosing which configuration route you wish to take. There are two distinct database environments which the first GA release -of MariaDB MaxScale supports; MySQL Master/Slave Replication clusters and Galera Cluster. +of MariaDB MaxScale supports; MariaDB Master/Slave Replication clusters and Galera Cluster. For more details, refer to the [Configuration Guide](Configuration-Guide.md). ### Master/Slave Replication Clusters There are two major configuration options available to use MariaDB MaxScale -with a MySQL Replication cluster; connection routing with separate read and +with a MariaDB Replication cluster; connection routing with separate read and write connections, or read/write splitting with a single connection. A separate tutorial is available for each of these configurations that describes how to build the configuration file for MariaDB MaxScale that will work with your environment. -Using a MySQL Master/Slave Replication cluster will provide one node server +Using a MariaDB Master/Slave Replication cluster will provide one node server within the cluster that is the master server and the remainder of the servers will be slaves. The slaves are read replicas of the master. In a replication cluster like this all write operations must be performed diff --git a/Documentation/Monitors/Galera-Monitor.md b/Documentation/Monitors/Galera-Monitor.md index a04d86aea..4014d610d 100644 --- a/Documentation/Monitors/Galera-Monitor.md +++ b/Documentation/Monitors/Galera-Monitor.md @@ -40,7 +40,7 @@ disable_master_failback=true ### `available_when_donor` -This option only has an effect if there is a single Galera node being backed up an XtraBackup instance. This causes the initial node to go into Donor state which would normally prevent if from being marked as a valid server inside MaxScale. If this option is enabled, a single node in Donor state where the method is XtraBackup will be kept in Synced state. +This option only has an effect if there is a single Galera node being backed up an XtraBackup instance. This causes the initial node to go into Donor state which would normally prevent if from being marked as a valid server inside MaxScale. If this option is enabled, a single node in Donor state where the method is XtraBackup will be kept in Synced state. ``` available_when_donor=true @@ -93,7 +93,7 @@ Example of variable being set in all slave nodes, assuming three nodes: SET GLOBAL wsrep_sst_donor = "galera001,galera000" ``` -**Note**: +**Note**: in order to set the global variable _wsrep_sst_donor_, proper privileges are required for the monitor user that connects to cluster nodes. This option is disabled by default and was introduced in MaxScale 2.1.0. @@ -147,7 +147,7 @@ In this example `node-1` is always used as the master if available. If `node-1` is not available, then the next node with the highest priority rank is used. In this case it would be `node-3`. If both `node-1` and `node-3` were down, then `node-2` would be used. Because `node-4` has a value of 0 in _priority_, it will -never be the master. Nodes without _priority_ parameter are considered as +never be the master. Nodes without _priority_ parameter are considered as having the lowest priority rank and will be used only if all nodes with _priority_ parameter are not available. diff --git a/Documentation/Protocols/CDC.md b/Documentation/Protocols/CDC.md index a20cf0e1c..0eaf13173 100644 --- a/Documentation/Protocols/CDC.md +++ b/Documentation/Protocols/CDC.md @@ -2,7 +2,7 @@ CDC is a new protocol that allows compatible clients to authenticate and register for Change Data Capture events. The new protocol must be use in -conjunction with AVRO router which currently converts MySQL binlog events into +conjunction with AVRO router which currently converts MariaDB binlog events into AVRO records. Change Data Capture protocol is used by clients in order to interact with stored AVRO file and also allows registered clients to be notified with the new events coming from MariaDB 10.0/10.1 database. diff --git a/Documentation/Protocols/CDC_users.md b/Documentation/Protocols/CDC_users.md index bb6f81da8..d1d80f1d0 100644 --- a/Documentation/Protocols/CDC_users.md +++ b/Documentation/Protocols/CDC_users.md @@ -3,7 +3,7 @@ Change Data Capture (CDC) is a new MaxScale protocol that allows compatible clients to authenticate and register for Change Data Capture events. The new protocol must be use in conjunction with AVRO router which currently converts -MySQL binlog events into AVRO records. Clients connect to CDC listener and +MariaDB binlog events into AVRO records. Clients connect to CDC listener and authenticate using credentials provided in a format described in the [CDC Protocol documentation](CDC.md). **Note**: If no users are found in that file or if it doesn't exist, the only diff --git a/Documentation/Reference/Hint-Syntax.md b/Documentation/Reference/Hint-Syntax.md index 046c822f1..69ea8446f 100644 --- a/Documentation/Reference/Hint-Syntax.md +++ b/Documentation/Reference/Hint-Syntax.md @@ -37,7 +37,7 @@ All hints must start with the `maxscale` tag. ``` -- maxscale -``` +``` The hints have two types, ones that define a server type and others that contain name-value pairs. diff --git a/Documentation/Reference/MaxAdmin.md b/Documentation/Reference/MaxAdmin.md index 82a2f149f..129287750 100644 --- a/Documentation/Reference/MaxAdmin.md +++ b/Documentation/Reference/MaxAdmin.md @@ -558,7 +558,7 @@ RWSplit | readwritesplit | 1 | 1 | server SchemaRouter | schemarouter | 1 | 1 | server1, server2, server3, server4 RWSplit-Hint | readwritesplit | 1 | 1 | server1, server2, server3, server4 ReadConn | readconnroute | 1 | 1 | server1 -CLI | cli | 2 | 2 | +CLI | cli | 2 | 2 | --------------------------+-------------------+--------+----------------+------------------- MaxScale> ``` @@ -619,7 +619,7 @@ MaxScale> show service RWSplit [127.0.0.1]:3003 Protocol: MySQLBackend Name: server4 Total connections: 1 Currently connected: 1 -MaxScale> +MaxScale> ``` This allows the set of backend servers defined by the service to be seen along @@ -635,8 +635,8 @@ command can be used to examine the user data held by MariaDB MaxScale. ``` MaxScale> show dbusers RWSplit -User names: @localhost @localhost.localdomain 14567USER@localhost monuser@localhost monuser@% 14609USER@localhost maxuser@localhost maxuser@% 14651USER@localhost maxtest@localhost maxtest@% 14693USER@localhost skysql@localhost skysql@% 14735USER@localhost cliuser@localhost cliuser@% repuser@localhost repuser@% -MaxScale> +User names: @localhost @localhost.localdomain 14567USER@localhost monuser@localhost monuser@% 14609USER@localhost maxuser@localhost maxuser@% 14651USER@localhost maxtest@localhost maxtest@% 14693USER@localhost skysql@localhost skysql@% 14735USER@localhost cliuser@localhost cliuser@% repuser@localhost repuser@% +MaxScale> ``` @@ -664,7 +664,7 @@ accepted. ``` MaxScale> shutdown service RWSplit -MaxScale> +MaxScale> ``` ## Restart A Stopped Service @@ -678,7 +678,7 @@ MaxScale> # Working With Servers -The server represents each of the instances of MySQL or MariaDB that a service +The server represents each of the instances of MariaDB or MySQL that a service may use. ## What Servers Are Configured? @@ -690,14 +690,14 @@ configured within MariaDB MaxScale. MaxScale> list servers Servers. -------------------+-----------------+-------+-------------+-------------------- -Server | Address | Port | Connections | Status +Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- server1 | 127.0.0.1 | 3000 | 0 | Master, Running server2 | 127.0.0.1 | 3001 | 0 | Slave, Running server3 | 127.0.0.1 | 3002 | 0 | Slave, Running server4 | 127.0.0.1 | 3003 | 0 | Slave, Running -------------------+-----------------+-------+-------------+-------------------- -MaxScale> +MaxScale> ``` ## Server Details @@ -715,12 +715,12 @@ Server 0x6501d0 (server2) Server Version: 10.1.22-MariaDB Node Id: 3001 Master Id: 3000 - Slave Ids: + Slave Ids: Repl Depth: 1 Number of connections: 0 Current no. of conns: 0 Current no. of operations: 0 -MaxScale> +MaxScale> ``` If the server has a non-zero value set for the server configuration item @@ -797,7 +797,7 @@ Session | Client | Service | State 11 | ::ffff:127.0.0.1 | RWSplit | Session ready for routing -----------------+-----------------+----------------+-------------------------- -MaxScale> +MaxScale> ``` This will give a list of client connections. @@ -817,7 +817,7 @@ Session 11 Connected: Thu Apr 20 09:51:31 2017 Idle: 82 seconds -MaxScale> +MaxScale> ``` # Descriptor Control Blocks @@ -842,20 +842,20 @@ Descriptor Control Blocks ------------------+----------------------------+--------------------+---------- DCB | State | Service | Remote ------------------+----------------------------+--------------------+---------- - 0x68c0a0 | DCB for listening socket | RWSplit | - 0x6e23f0 | DCB for listening socket | CLI | - 0x691710 | DCB for listening socket | SchemaRouter | + 0x68c0a0 | DCB for listening socket | RWSplit | + 0x6e23f0 | DCB for listening socket | CLI | + 0x691710 | DCB for listening socket | SchemaRouter | 0x7fffe40130f0 | DCB in the polling loop | CLI | localhost - 0x6b7540 | DCB for listening socket | RWSplit-Hint | - 0x6cd020 | DCB for listening socket | ReadConn | + 0x6b7540 | DCB for listening socket | RWSplit-Hint | + 0x6cd020 | DCB for listening socket | ReadConn | 0x7fffd80130f0 | DCB in the polling loop | RWSplit | ::ffff:127.0.0.1 - 0x7fffdc014590 | DCB in the polling loop | RWSplit | - 0x7fffdc0148d0 | DCB in the polling loop | RWSplit | - 0x7fffdc014c60 | DCB in the polling loop | RWSplit | - 0x7fffdc014ff0 | DCB in the polling loop | RWSplit | + 0x7fffdc014590 | DCB in the polling loop | RWSplit | + 0x7fffdc0148d0 | DCB in the polling loop | RWSplit | + 0x7fffdc014c60 | DCB in the polling loop | RWSplit | + 0x7fffdc014ff0 | DCB in the polling loop | RWSplit | ------------------+----------------------------+--------------------+---------- -MaxScale> +MaxScale> ``` A MariaDB MaxScale server that has activity on it will however have many more @@ -1028,7 +1028,7 @@ Monitor | Status ---------------------+--------------------- MySQL-Monitor | Running ---------------------+--------------------- -MaxScale> +MaxScale> ``` ## Details Of A Particular Monitor @@ -1057,7 +1057,7 @@ Slave configured: NO Slave IO running: NO Slave SQL running: NO Master ID: -1 -Master binlog file: +Master binlog file: Master binlog position: 0 Server: server2 @@ -1091,7 +1091,7 @@ Master binlog file: binlog.000001 Master binlog position: 435 -MaxScale> +MaxScale> ``` ## Shutting Down A Monitor @@ -1108,7 +1108,7 @@ Monitor | Status ---------------------+--------------------- MySQL-Monitor | Stopped ---------------------+--------------------- -MaxScale> +MaxScale> ``` ## Restarting A Monitor @@ -1124,7 +1124,7 @@ Monitor | Status ---------------------+--------------------- MySQL-Monitor | Running ---------------------+--------------------- -MaxScale> +MaxScale> ``` # MaxScale Status Commands @@ -1157,7 +1157,7 @@ Pending event queue length averages: 1 | Polling | | | | 2 | Processing | 1 | 0x6e0dd0 | <202400ms | IN|OUT 3 | Polling | | | | -MaxScale> +MaxScale> ``` The resultant output returns data as to the average thread utilization for the @@ -1177,7 +1177,7 @@ MaxScale> show tasks Name | Type | Frequency | Next Due --------------------------+----------+-----------+------------------------- Load Average | Repeated | 10 | Thu Apr 20 10:02:26 2017 -MaxScale> +MaxScale> ``` # Administration Commands @@ -1198,7 +1198,7 @@ MySQLAuth | Authenticator | V1.1.0 | 1.1.0 | GA MySQLClient | Protocol | V1.1.0 | 1.1.0 | GA MaxAdminAuth | Authenticator | V2.1.0 | 1.1.0 | GA maxscaled | Protocol | V2.0.0 | 1.1.0 | GA -MySQLBackendAuth | Authenticator | V1.0.0 | 1.1.0 | GA +MySQLBackendAuth| Authenticator | V1.0.0 | 1.1.0 | GA MySQLBackend | Protocol | V2.0.0 | 1.1.0 | GA mysqlmon | Monitor | V1.5.0 | 3.0.0 | GA schemarouter | Router | V1.0.0 | 2.0.0 | Beta @@ -1208,7 +1208,7 @@ readconnroute | Router | V1.1.0 | 2.0.0 | GA cli | Router | V1.0.0 | 2.0.0 | GA ----------------+-----------------+---------+-------+------------------------- -MaxScale> +MaxScale> ``` This command provides important version information for the module. Each module @@ -1319,7 +1319,7 @@ command. ``` MaxScale> shutdown maxscale -MaxScale> +MaxScale> ``` # Runtime Configuration Changes @@ -1779,7 +1779,7 @@ No of poll completions with descriptors 8 0 9 0 >= 10 0 -MaxScale> +MaxScale> ``` If the "Number of DCBs with pending events" grows rapidly it is an indication @@ -1809,38 +1809,38 @@ Average event queue length: 1 | Number of events Duration | Queued | Executed ---------------+------------+----------- - < 100ms | 27 | 26 - 100 - 200ms | 0 | 0 - 200 - 300ms | 0 | 0 - 300 - 400ms | 0 | 0 - 400 - 500ms | 0 | 0 - 500 - 600ms | 0 | 0 - 600 - 700ms | 0 | 0 - 700 - 800ms | 0 | 0 - 800 - 900ms | 0 | 0 - 900 - 1000ms | 0 | 0 - 1000 - 1100ms | 0 | 0 - 1100 - 1200ms | 0 | 0 - 1200 - 1300ms | 0 | 0 - 1300 - 1400ms | 0 | 0 - 1400 - 1500ms | 0 | 0 - 1500 - 1600ms | 0 | 0 - 1600 - 1700ms | 0 | 0 - 1700 - 1800ms | 0 | 0 - 1800 - 1900ms | 0 | 0 - 1900 - 2000ms | 0 | 0 - 2000 - 2100ms | 0 | 0 - 2100 - 2200ms | 0 | 0 - 2200 - 2300ms | 0 | 0 - 2300 - 2400ms | 0 | 0 - 2400 - 2500ms | 0 | 0 - 2500 - 2600ms | 0 | 0 - 2600 - 2700ms | 0 | 0 - 2700 - 2800ms | 0 | 0 - 2800 - 2900ms | 0 | 0 - 2900 - 3000ms | 0 | 0 - > 3000ms | 0 | 0 -MaxScale> + < 100ms | 27 | 26 + 100 - 200ms | 0 | 0 + 200 - 300ms | 0 | 0 + 300 - 400ms | 0 | 0 + 400 - 500ms | 0 | 0 + 500 - 600ms | 0 | 0 + 600 - 700ms | 0 | 0 + 700 - 800ms | 0 | 0 + 800 - 900ms | 0 | 0 + 900 - 1000ms | 0 | 0 + 1000 - 1100ms | 0 | 0 + 1100 - 1200ms | 0 | 0 + 1200 - 1300ms | 0 | 0 + 1300 - 1400ms | 0 | 0 + 1400 - 1500ms | 0 | 0 + 1500 - 1600ms | 0 | 0 + 1600 - 1700ms | 0 | 0 + 1700 - 1800ms | 0 | 0 + 1800 - 1900ms | 0 | 0 + 1900 - 2000ms | 0 | 0 + 2000 - 2100ms | 0 | 0 + 2100 - 2200ms | 0 | 0 + 2200 - 2300ms | 0 | 0 + 2300 - 2400ms | 0 | 0 + 2400 - 2500ms | 0 | 0 + 2500 - 2600ms | 0 | 0 + 2600 - 2700ms | 0 | 0 + 2700 - 2800ms | 0 | 0 + 2800 - 2900ms | 0 | 0 + 2900 - 3000ms | 0 | 0 + > 3000ms | 0 | 0 +MaxScale> ``` The statics are defined in 100ms buckets, with the count of the events that fell diff --git a/Documentation/Reference/MaxBinlogCheck.md b/Documentation/Reference/MaxBinlogCheck.md index e55f813f9..c1827719c 100644 --- a/Documentation/Reference/MaxBinlogCheck.md +++ b/Documentation/Reference/MaxBinlogCheck.md @@ -1,10 +1,10 @@ -# Maxbinlogcheck, the MySQL/MariaDB binlog check utility +# Maxbinlogcheck, the MariaDB binlog check utility # Overview Maxbinlogcheck is a command line utility for checking binlogfiles. The files may have been downloaded by the MariaDB MaxScale binlog router or they may be -MySQL/MariaDB binlog files stored in a database server acting as a master in a +MariaDB binlog files stored in a database server acting as a master in a replication environment. Maxbinlogcheck checks the binlog files against any corruption and stored incomplete transactions and reports a transaction summary after reading all the events. It may optionally truncate the binlog file. diff --git a/Documentation/Release-Notes/MaxScale-2.1.3-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.1.3-Release-Notes.md index 3fbcdc2c8..31071b8d9 100644 --- a/Documentation/Release-Notes/MaxScale-2.1.3-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.1.3-Release-Notes.md @@ -42,6 +42,7 @@ for details. [Here is a list of bugs fixed since the release of MaxScale 2.1.2.](https://jira.mariadb.org/browse/MXS-1212?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20resolution%20in%20(Fixed%2C%20Done)%20AND%20fixVersion%20%3D%202.1.3) +* [MXS-1263](https://jira.mariadb.org/browse/MXS-1263) broken TCP connections are not always cleaned properly * [MXS-1244](https://jira.mariadb.org/browse/MXS-1244) MySQL monitor "detect_replication_lag=true" doesn't work with "mysql51_replication=true" * [MXS-1227](https://jira.mariadb.org/browse/MXS-1227) Nagios Plugins broken by change in output of "show monitors" in 2.1 * [MXS-1221](https://jira.mariadb.org/browse/MXS-1221) Nagios plugin scripts does not process -S option properly diff --git a/Documentation/Routers/SchemaRouter.md b/Documentation/Routers/SchemaRouter.md index 36bef935b..d044b8ac6 100644 --- a/Documentation/Routers/SchemaRouter.md +++ b/Documentation/Routers/SchemaRouter.md @@ -25,7 +25,7 @@ passwd=mypwd The module generates the list of databases based on the servers parameter using the connecting client's credentials. The user and passwd parameters define the credentials that are used to fetch the authentication data from the database servers. The credentials used only require the same grants as mentioned in the configuration documentation. -The list of databases is built by sending a SHOW DATABASES query to all the servers. This requires the user to have at least USAGE and SELECT grants on the databases that need be sharded. +The list of databases is built by sending a SHOW DATABASES query to all the servers. This requires the user to have at least USAGE and SELECT grants on the databases that need be sharded. If you are connecting directly to a database or have different users on some of the servers, you need to get the authentication data from all the servers. You can control this with the `auth_all_servers` parameter. With this parameter, MariaDB MaxScale forms a union of all the users and their grants from all the servers. By default, the schemarouter will fetch the authentication data from all servers. diff --git a/Documentation/Tutorials/Filter-Tutorial.md b/Documentation/Tutorials/Filter-Tutorial.md index e6af4a93b..c1dc17395 100644 --- a/Documentation/Tutorials/Filter-Tutorial.md +++ b/Documentation/Tutorials/Filter-Tutorial.md @@ -121,7 +121,7 @@ When the session ends a report will be written for the session into the logfile ### Duplicate Data From Your Application Into Cassandra -The scenario we are using in this example is one in which you have an online gaming application that is designed to work with a MariaDB/MySQL database. The database schema includes a high score table which you would like to have access to in a Cassandra cluster. The application is already using MariaDB MaxScale to connect to a MariaDB Galera cluster, using a service names BubbleGame. The definition of that service is as follows +The scenario we are using in this example is one in which you have an online gaming application that is designed to work with a MariaDB database. The database schema includes a high score table which you would like to have access to in a Cassandra cluster. The application is already using MariaDB MaxScale to connect to a MariaDB Galera cluster, using a service names BubbleGame. The definition of that service is as follows ``` [BubbleGame] type=service @@ -130,7 +130,7 @@ servers=dbbubble1,dbbubble2,dbbubble3,dbbubble4,dbbubble5 user=maxscale passwd=6628C50E07CCE1F0392EDEEB9D1203F3 ``` -The table you wish to store in Cassandra in called HighScore and will contain the same columns in both the MariaDB table and the Cassandra table. The first step is to install a MariaDB instance with the Cassandra storage engine to act as a bridge server between the relational database and Cassandra. In this bridge server add a table definition for the HighScore table with the engine type set to Cassandra. +The table you wish to store in Cassandra in called HighScore and will contain the same columns in both the MariaDB table and the Cassandra table. The first step is to install a MariaDB instance with the Cassandra storage engine to act as a bridge server between the relational database and Cassandra. In this bridge server add a table definition for the HighScore table with the engine type set to Cassandra. See [Cassandra Storage Engine Overview]( https://mariadb.com/kb/en/mariadb/cassandra-storage-engine-overview/) for details. Add this server into the MariaDB MaxScale configuration and create a service that will connect to this server. ``` diff --git a/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md b/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md index 2594eb8e4..d8bf975af 100644 --- a/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md +++ b/Documentation/Tutorials/Galera-Cluster-Connection-Routing-Tutorial.md @@ -241,7 +241,7 @@ dbserv3 | 192.168.2.3 | 3306 | 0 | Running, Synced, Sl A Galera Cluster is a multi-master clustering technology, however the monitor is able to impose false notions of master and slave roles within a Galera Cluster in order to -facilitate the use of Galera as if it were a standard MySQL Replication setup. +facilitate the use of Galera as if it were a standard MariaDB Replication setup. This is merely an internal MariaDB MaxScale convenience and has no impact on the behavior of the cluster. You can control which Galera node is the master server by using the _priority_ diff --git a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md index c4c23ffa5..da3a8a74b 100644 --- a/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/Galera-Cluster-Read-Write-Splitting-Tutorial.md @@ -175,7 +175,7 @@ CLI | cli | 2 | 2 % maxadmin list servers Servers. -------------------+-----------------+-------+-------------+-------------------- -Server | Address | Port | Connections | Status +Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- dbserv1 | 192.168.2.1 | 3306 | 0 | Running, Synced, Master dbserv2 | 192.168.2.2 | 3306 | 0 | Running, Synced, Slave @@ -183,7 +183,7 @@ dbserv3 | 192.168.2.3 | 3306 | 0 | Running, Synced, Sl -------------------+-----------------+-------+-------------+-------------------- ``` -A Galera Cluster is a multi-master clustering technology, however the monitor is able to impose false notions of master and slave roles within a Galera Cluster in order to facilitate the use of Galera as if it were a standard MySQL Replication setup. This is merely an internal MariaDB MaxScale convenience and has no impact on the behavior of the cluster but does allow the monitor to create these pseudo roles which are utilized by the Read/Write Splitter. +A Galera Cluster is a multi-master clustering technology, however the monitor is able to impose false notions of master and slave roles within a Galera Cluster in order to facilitate the use of Galera as if it were a standard MariaDB Replication setup. This is merely an internal MariaDB MaxScale convenience and has no impact on the behavior of the cluster but does allow the monitor to create these pseudo roles which are utilized by the Read/Write Splitter. You can control which Galera node is the master server by using the _priority_ mechanism of the Galera Monitor module. For more details, read the [Galera Monitor](../Monitors/Galera-Monitor.md) documentation. diff --git a/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md b/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md index e41fcf559..c06af5720 100644 --- a/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md +++ b/Documentation/Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md @@ -30,7 +30,7 @@ enabled=1 gpgcheck=0 ``` -### Install the software +### Install the software ``` # yum install pacemaker corosync crmsh @@ -74,7 +74,7 @@ For each node, add all the server names into `/etc/hosts`. ### Prepare authkey for optional cryptographic use -On one of the nodes, say node2 run the corosync-keygen utility and follow +On one of the nodes, say node2 run the corosync-keygen utility and follow ``` [root@node2 ~]# corosync-keygen @@ -263,7 +263,7 @@ The Corosync / Pacemaker cluster is ready to be configured to manage resources. The MariaDB MaxScale init script in `/etc/init.d./maxscale` allows to start, stop, restart and monitor the MariaDB MaxScale process running on the system. ``` -[root@node1 ~]# /etc/init.d/maxscale +[root@node1 ~]# /etc/init.d/maxscale Usage: /etc/init.d/maxscale {start|stop|status|restart|condrestart|reload} ``` @@ -389,7 +389,7 @@ Version: 1.1.10-14.el6_5.3-368c726 Online: [ node1 node2 node3 ] - MaxScale (lsb:maxscale): Started node1 + MaxScale (lsb:maxscale): Started node1 ``` ### The resource cannot be migrated to node1 for a failure @@ -422,7 +422,7 @@ Version: 1.1.10-14.el6_5.3-368c726 Online: [ node1 node2 node3 ] - MaxScale (lsb:maxscale): Started node2 + MaxScale (lsb:maxscale): Started node2 Failed actions: @@ -519,9 +519,9 @@ Online: [ node1 node2 node3 ] Resource Group: maxscale_service - maxscale_vip (ocf::heartbeat:IPaddr2): Started node2 + maxscale_vip (ocf::heartbeat:IPaddr2): Started node2 - MaxScale (lsb:maxscale): Started node2 + MaxScale (lsb:maxscale): Started node2 ``` With both resources on node2, now MariaDB MaxScale service will be reachable via the configured VIP address 192.168.122.125. diff --git a/Documentation/Tutorials/MaxScale-HA-with-lsyncd.md b/Documentation/Tutorials/MaxScale-HA-with-lsyncd.md index ef78112d4..a66886c83 100644 --- a/Documentation/Tutorials/MaxScale-HA-with-lsyncd.md +++ b/Documentation/Tutorials/MaxScale-HA-with-lsyncd.md @@ -27,11 +27,11 @@ If you already have a SSH key generated, you can skip this next step and go to t To generate a new set of SSH keys, we will use `ssh-keygen`. ``` -[root@localhost ~]# ssh-keygen +[root@localhost ~]# ssh-keygen Generating public/private rsa key pair. -Enter file in which to save the key (/root/.ssh/id_rsa): -Enter passphrase (empty for no passphrase): -Enter same passphrase again: +Enter file in which to save the key (/root/.ssh/id_rsa): +Enter passphrase (empty for no passphrase): +Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: @@ -101,17 +101,17 @@ sync{ default.rsyncssh, -- This is where the maxscale.cnf file is copied from. -source="/etc", +source="/etc", -- This is the user and host where the maxscale.cnf is copied to. -- Change this to the user and destination host where you want maxscale.cnf to be synchronized to. -host="user@192.168.122.100", +host="user@192.168.122.100", -- This is where the maxscale.cnf is copied to on the remote host. -targetdir="/etc", +targetdir="/etc", -- This is an optional section which defines a custom SSH port. Uncomment to enable. --- ssh={port=2222}, +-- ssh={port=2222}, -- These are values passed to rsync. Only change these if you know what you are doing. rsync={ @@ -139,9 +139,9 @@ settings{ sync{ default.rsyncssh, -source="/etc", -host="maxuser@192.168.0.50", -targetdir="/etc", +source="/etc", +host="maxuser@192.168.0.50", +targetdir="/etc", rsync={ compress=true, _extra = {[[--filter=+ *maxscale.cnf]], @@ -153,9 +153,9 @@ rsync={ sync{ default.rsyncssh, -source="/etc", -host="syncuser@192.168.122.105", -targetdir="/etc", +source="/etc", +host="syncuser@192.168.122.105", +targetdir="/etc", rsync={ compress=true, _extra = {[[--filter=+ *maxscale.cnf]], diff --git a/Documentation/Tutorials/MaxScale-Information-Schema.md b/Documentation/Tutorials/MaxScale-Information-Schema.md index 66d6af869..a753e4220 100644 --- a/Documentation/Tutorials/MaxScale-Information-Schema.md +++ b/Documentation/Tutorials/MaxScale-Information-Schema.md @@ -16,7 +16,7 @@ Currently the user can connect to maxinfo from any remote IP and to localhost as type=service router=maxinfo user=monitor -passwd=EBD2F49C3B375812A8CDEBA632ED8BBC +passwd=EBD2F49C3B375812A8CDEBA632ED8BBC ``` The listener section defines the protocol, port and other information needed to create a listener for the service. To listen on a port using the MySQL protocol a section as shown below should be added to the configuration file. @@ -61,7 +61,7 @@ The maxinfo supports a small subset of SQL statements in addition to the MySQL s % mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz ping mysqld is alive % mysqladmin -hmaxscale.mariadb.com -P9003 -umonitor -pxyz status -Uptime: 72 Threads: 1 Sessions: 11 +Uptime: 72 Threads: 1 Sessions: 11 % ``` @@ -168,7 +168,7 @@ mysql> show status; +---------------------------+-------+ 22 rows in set (0.02 sec) -mysql> +mysql> ``` ## Show services @@ -191,7 +191,7 @@ mysql> show services; +----------------+----------------+--------------+----------------+ 8 rows in set (0.02 sec) -mysql> +mysql> ``` The show services command does not accept a like clause and will ignore any like clause that is given. @@ -217,7 +217,7 @@ mysql> show listeners; +----------------+-----------------+-----------+------+---------+ 9 rows in set (0.02 sec) -mysql> +mysql> ``` The show listeners command will ignore any like clause passed to it. @@ -245,7 +245,7 @@ mysql> show sessions; +-----------+---------------+----------------+---------------------------+ 11 rows in set (0.02 sec) -mysql> +mysql> ``` ## Show clients @@ -262,7 +262,7 @@ mysql> show clients; +-----------+---------------+---------+---------------------------+ 2 rows in set (0.02 sec) -mysql> +mysql> ``` ## Show servers @@ -281,7 +281,7 @@ mysql> show servers; +---------+-----------+------+-------------+---------+ 4 rows in set (0.02 sec) -mysql> +mysql> ``` ## Show modules @@ -306,7 +306,7 @@ mysql> show modules; +----------------+-------------+---------+-------------+----------------+ 10 rows in set (0.02 sec) -mysql> +mysql> ``` ## Show monitors @@ -367,7 +367,7 @@ mysql> show eventTimes; +---------------+-------------------+---------------------+ 30 rows in set (0.02 sec) -mysql> +mysql> ``` Each row represents a time interval, in 100ms increments, with the counts representing the number of events that were in the event queue for the length of time that row represents and the number of events that were executing of the time indicated by the row. @@ -422,7 +422,7 @@ $ curl http://maxscale.mariadb.com:8003/status { "Variable_name" : "Max_event_queue_length", "Value" : 1}, { "Variable_name" : "Max_event_queue_time", "Value" : 0}, { "Variable_name" : "Max_event_execution_time", "Value" : 1}] -$ +$ ``` ## Services @@ -496,7 +496,7 @@ $ curl http://maxscale.mariadb.com:8003/sessions { "Session" : "0x1a5c0b0", "Client" : , "Service" : "Filter Service", "State" : "Listener Session"}, { "Session" : "0x1a5c530", "Client" : , "Service" : "Split Service", "State" : "Listener Session"}, { "Session" : "0x19ac1c0", "Client" : , "Service" : "Test Service", "State" : "Listener Session"}] -$ +$ ``` ## Clients diff --git a/Documentation/Tutorials/MaxScale-Tutorial.md b/Documentation/Tutorials/MaxScale-Tutorial.md index 86c28c13d..8596af5bd 100644 --- a/Documentation/Tutorials/MaxScale-Tutorial.md +++ b/Documentation/Tutorials/MaxScale-Tutorial.md @@ -1,11 +1,11 @@ # Setting up MariaDB MaxScale This document is designed as a quick introduction to setting up MariaDB MaxScale -in an environment in which you have either a MySQL Master-Slave replication cluster +in an environment in which you have either a MariaDB Master-Slave replication cluster with one master and multiple slave servers or a multi-node Galera cluster. The process of setting and configuring MariaDB MaxScale will be covered within this document. -The installation and configuration of the MySQL Replication or the Galera cluster +The installation and configuration of the MariaDB Replication or the Galera cluster will not be covered nor will any discussion of installation management tools to handle automated or semi-automated failover of the replication cluster. The [Setting Up Replication](https://mariadb.com/kb/en/mariadb/setting-up-replication/) @@ -109,7 +109,7 @@ The best way to describe this process is with an example. User `'jdoe'@'192.168.0.200` has the following grant on the cluster: `GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'jdoe'@'192.168.0.200'`. -When the user connects directly to the server it will see it as +When the user connects directly to the server it will see it as `'jdoe'@'192.168.0.200` connecting to the server and it will match the grant for `'jdoe'@'192.168.0.200`. @@ -153,8 +153,8 @@ The configuration file creation is covered in different tutorials. ### Master-Slave cluster -* [MySQL Replication Connection Routing Tutorial](MySQL-Replication-Connection-Routing-Tutorial.md) -* [MySQL Replication Read-Write Splitting Tutorial](MySQL-Replication-Read-Write-Splitting-Tutorial.md) +* [MariaDB Replication Connection Routing Tutorial](MySQL-Replication-Connection-Routing-Tutorial.md) +* [MariaDB Replication Read-Write Splitting Tutorial](MySQL-Replication-Read-Write-Splitting-Tutorial.md) ### Galera cluster diff --git a/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md b/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md index c14ff8a5d..5ad3e53f6 100644 --- a/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md +++ b/Documentation/Tutorials/MySQL-Replication-Connection-Routing-Tutorial.md @@ -1,4 +1,4 @@ -# Connection Routing with MySQL Replication +# Connection Routing with MariaDB Replication # Environment & Solution Space @@ -21,7 +21,7 @@ A global, `[maxscale]`, section is included within every MariaDB MaxScale config threads=4 ``` -Since we are using MySQL Replication and connection routing we want two different ports to which the client application can connect; one that will be directed to the current master within the replication cluster and another that will load balance between the slaves. To achieve this within MariaDB MaxScale we need to define two services in the ini file; one for the read/write operations that should be executed on the master server and another for connections to one of the slaves. Create a section for each in your MariaDB MaxScale configuration file and set the type to service, the section names are the names of the services themselves and should be meaningful to the administrator. Avoid using whitespace in the section names. +Since we are using MariaDB Replication and connection routing we want two different ports to which the client application can connect; one that will be directed to the current master within the replication cluster and another that will load balance between the slaves. To achieve this within MariaDB MaxScale we need to define two services in the ini file; one for the read/write operations that should be executed on the master server and another for connections to one of the slaves. Create a section for each in your MariaDB MaxScale configuration file and set the type to service, the section names are the names of the services themselves and should be meaningful to the administrator. Avoid using whitespace in the section names. ``` [Write-Service] @@ -207,7 +207,7 @@ CLI | cli | 2 | 2 Servers. -------------------+-----------------+-------+-------------+-------------------- -Server | Address | Port | Connections | Status +Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- dbserv1 | 192.168.2.1 | 3306 | 0 | Running, Slave dbserv2 | 192.168.2.2 | 3306 | 0 | Running, Master diff --git a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md index 02f619448..711a566e4 100644 --- a/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md +++ b/Documentation/Tutorials/MySQL-Replication-Read-Write-Splitting-Tutorial.md @@ -1,4 +1,4 @@ -# Read/Write Splitting with MySQL Replication +# Read/Write Splitting with MariaDB Replication ## Environment & Solution Space @@ -228,7 +228,7 @@ Servers. -------------------+-----------------+-------+-------------+-------------------- -Server | Address | Port | Connections | Status +Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- diff --git a/Documentation/Tutorials/Nagios-Plugins.md b/Documentation/Tutorials/Nagios-Plugins.md index 02304c02c..7b302e9de 100644 --- a/Documentation/Tutorials/Nagios-Plugins.md +++ b/Documentation/Tutorials/Nagios-Plugins.md @@ -10,7 +10,7 @@ that can be run from a command line to check the status or a host or service. Nagios uses the results from plugins to determine the current status of hosts and services on your network. Nagios core executes a plugin whenever there is a need to check the status -of a service or host. +of a service or host. While MariaDB MaxScale resources and status can be monitored via CLI using maxadmin commands, Nagios Plugin provides an automated way for system administration @@ -31,7 +31,7 @@ details on respective resources. Current resources are: modules, services, listeners, servers, sessions, filters. 3. check_maxscale_monitor.pl: This command provides you status of the configured -monitor modules on MariaDB MaxScale server. +monitor modules on MariaDB MaxScale server. In order to use these scripts on your Nagios Server, you need to copy them from the MariaDB MaxScale binary package or download them from source tree on GitHub. diff --git a/Documentation/Tutorials/RabbitMQ-And-Tee-Archiving.md b/Documentation/Tutorials/RabbitMQ-And-Tee-Archiving.md index 89c9a371a..9c9fd3c33 100644 --- a/Documentation/Tutorials/RabbitMQ-And-Tee-Archiving.md +++ b/Documentation/Tutorials/RabbitMQ-And-Tee-Archiving.md @@ -1,9 +1,9 @@ # Data archiving with Mqfilter and Tee filters -This tutorial gives a quick look into how you can combine various filters to create +This tutorial gives a quick look into how you can combine various filters to create systems for archiving data for analysis. The aim of this tutorial is to show what can be done with MariaDB MaxScale's filters rather than demonstrate a proven method -of archiving data. For this tutorial you will need two MariaDB/MySQL servers, one for +of archiving data. For this tutorial you will need two MariaDB servers, one for archiving the data and one for actual use, a RabbitMQ server and a MariaDB MaxScale server. For testing purposes some of these can locate on the same server but for actual use, an HA solution is recommended. @@ -21,14 +21,14 @@ making the archive server a true archive of all data. The installation of MariaDB MaxScale is covered in the Installation chapter of the [MariaDB MaxScale Tutorial](MaxScale-Tutorial.md). -## Setting up the MariaDB/MySQL servers +## Setting up the MariaDB servers Since the archive server will not replicate from the main server, we don't need to set up replication between the two. The only thing we need to do is to create the users we will use for monitoring and authentication. -The process of creating monitoring and authentication users for MariaDB MaxScale is described -in the Creating Database Users section of the +The process of creating monitoring and authentication users for MariaDB MaxScale is described +in the Creating Database Users section of the [MariaDB MaxScale Tutorial](MaxScale-Tutorial.md#creating-database-users). ## Setting up RabbitMQ server @@ -322,7 +322,7 @@ sudo maxadmin list servers Servers. -------------------+-----------------+-------+-------------+-------------------- -Server | Address | Port | Connections | Status +Server | Address | Port | Connections | Status -------------------+-----------------+-------+-------------+-------------------- production-1 | 192.168.0.200 | 3306 | 0 | Running archive-1 | 192.168.0.201 | 3000 | 0 | Running diff --git a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md index 2d68f96ff..fdf0b1bde 100644 --- a/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md +++ b/Documentation/Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md @@ -1,11 +1,11 @@ # MariaDB MaxScale as a Binlog Server MariaDB MaxScale is a dynamic data routing platform that sits between a database layer and the clients of that database. However, the binlog router described here is somewhat different to that original concept, moving MariaDB MaxScale down to play a role within the database layer itself. -In a traditional MySQL replication setup a single master server is created and a set of slaves MySQL instances are configured to pull the binlog files from that master to the slaves. There are some problems, however, in this setup; when the number of slaves grows, an increasing load caused by the serving of binlogs to each slave, is placed on the master. When the master server fails, some action must be performed on every slave server before a new server can become the master server. +In a traditional MariaDB replication setup a single master server is created and a set of slaves MariaDB instances are configured to pull the binlog files from that master to the slaves. There are some problems, however, in this setup; when the number of slaves grows, an increasing load caused by the serving of binlogs to each slave, is placed on the master. When the master server fails, some action must be performed on every slave server before a new server can become the master server. Introducing a proxy layer between the master server and the slave servers can improve the situation, by reducing the load on the master to simply serving the proxy layer rather than all of the slaves. The slaves only need to be aware of the proxy layer and not of the real master server. Removing the need for the slaves to have knowledge of the actual master, greatly simplifies the process of replacing a failed master within a replication environment. -## MariaDB/MySQL as a Binlog Server +## MariaDB as a Binlog Server The most obvious solution to the requirement for a proxy layer within a replication environment is to use a MariaDB or MySQL database instance. The database server is designed to allow this, since a slave server is able to be configured such that it will produce binary logs for updates it has itself received via replication from the master server. This is done with the *log_slave_updates* configuration option of the server. In this case the server is known as an intermediate master, it is simultaneously a slave to the real master and a master to the other slaves in the configuration. Using an intermediate master does not, however, solve all the problems and introduces some new ones, due to the way replication is implemented. A slave server reads the binary log data and creates a relay log from that binary log. This log provides a source of SQL statements, which are executed within the slave in order to make the same changes to the databases on the slaves as were made on the master. If the *log_slave_updates* option has been enabled, new binary log entries are created for the statements executed from the relay log. @@ -348,7 +348,7 @@ Master_SSL_Verify_Server_Cert: No # Binlog router compatibility -Binlog Router Plugin is compatible with MySQL 5.6 and MariaDB 5.5, the current default. +Binlog Router Plugin is compatible with MariaDB 5.5 and MySQL 5.6, the current default. In order to use it with MySQL 5.6, the *GTID_MODE* setting must be OFF and connecting slaves must not use *MASTER_AUTO_POSITION = 1* option. diff --git a/Documentation/Tutorials/Simple-Sharding-Tutorial.md b/Documentation/Tutorials/Simple-Sharding-Tutorial.md index 7268ef64f..f4f604e8e 100644 --- a/Documentation/Tutorials/Simple-Sharding-Tutorial.md +++ b/Documentation/Tutorials/Simple-Sharding-Tutorial.md @@ -8,11 +8,11 @@ MariaDB MaxScale will appear to the client as a database server with the combina ## Environment & Solution Space -This document is designed as a simple tutorial on schema-based sharding using MariaDB MaxScale in an environment in which you have two servers. The object of this tutorial is to have a system that, to the client side, acts like a single MySQL database but actually is sharded between the two servers. +This document is designed as a simple tutorial on schema-based sharding using MariaDB MaxScale in an environment in which you have two servers. The object of this tutorial is to have a system that, to the client side, acts like a single MariaDB database but actually is sharded between the two servers. The database users should be configured according to [the configuration guide](../Getting-Started/Configuration-Guide.md). The [MaxScale Tutorial](MaxScale-Tutorial.md) contains easy to follow instructions on how to set up MaxScale. - -This tutorial will assume the user is using of the binary distributions available and has installed this in the default location. The process of configuring MariaDB MaxScale will be covered within this document. The installation and configuration of the MySQL servers will not be covered in-depth. + +This tutorial will assume the user is using of the binary distributions available and has installed this in the default location. The process of configuring MariaDB MaxScale will be covered within this document. The installation and configuration of the MariaDB servers will not be covered in-depth. ## Preparing MaxScale diff --git a/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md b/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md index fb4042e06..539adb261 100644 --- a/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md +++ b/Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md @@ -46,14 +46,14 @@ parameter to the service definition. ## Persistent Connections -The MySQL session state is reset in MaxScale 2.1 for persistent +The MariaDB session state is reset in MaxScale 2.1 for persistent connections. This means that any modifications to the session state (default database, user variable etc.) will not survive if the connection is put into the connection pool. For most users, this is the expected behavior. ## User Data Cache -The location of the MySQL user data cache was moved from +The location of the MariaDB user data cache was moved from `/var/cache/maxscale/` to `/var/cache/maxscale//`. ## Galeramon Monitoring Algorithm diff --git a/Documentation/makepdf.sh b/Documentation/makepdf.sh index 879a0bcc5..83ba3fd94 100755 --- a/Documentation/makepdf.sh +++ b/Documentation/makepdf.sh @@ -37,7 +37,7 @@ filter(){ # and we add the current date to the end of the 2 lines in the titleblock #date=$(date +"%B %e, %Y") printf -v date "%(%B %e, %Y)T" - #awk ' /^$/ {p++} p==1{printf "%% %s\n", "'"$date"'";p++} !p{printf "%% "} {print} ' + #awk ' /^$/ {p++} p==1{printf "%% %s\n", "'"$date"'";p++} !p{printf "%% "} {print} ' awk ' NR==1{ printf "%% " } # put % in front of first line NR==2{ printf " " } # put some space in front of 2nd line. pandoc requires this to continue the title NR==3{ printf "%% %s", "'"$date"'" } # 3rd line becomes the date. @@ -49,10 +49,10 @@ filter(){ pandoc_vars=( -V fontsize=12pt - -V version=1.10 - -V geometry:margin=1in + -V version=1.10 + -V geometry:margin=1in --toc - -t latex + -t latex --latex-engine=xelatex --template="$template" ) diff --git a/server/modules/protocol/examples/cdc_schema.py b/server/modules/protocol/examples/cdc_schema.py index 8b22bfd20..1f4c1bd84 100755 --- a/server/modules/protocol/examples/cdc_schema.py +++ b/server/modules/protocol/examples/cdc_schema.py @@ -33,7 +33,15 @@ opts = parser.parse_args(sys.argv[1:]) def parse_field(row): res = dict() - name = row[1].lower().split('(')[0] + parts = row[1].lower().split('(') + name = parts[0] + + res["real_type"] = name + + if len(parts) > 1: + res["length"] = int(parts[1].split(')')[0]) + else: + res["length"] = -1 if name in ("date", "datetime", "time", "timestamp", "year", "tinytext", "text", "mediumtext", "longtext", "char", "varchar", "enum", "set"): diff --git a/server/modules/routing/avrorouter/avro_schema.c b/server/modules/routing/avrorouter/avro_schema.c index a15547784..dc81d06ca 100644 --- a/server/modules/routing/avrorouter/avro_schema.c +++ b/server/modules/routing/avrorouter/avro_schema.c @@ -211,12 +211,40 @@ bool json_extract_field_names(const char* filename, TABLE_CREATE *table) } json_t *name = json_object_get(val, "name"); + if (name && json_is_string(name)) { const char *name_str = json_string_value(name); + if (not_generated_field(name_str)) { - table->column_names[columns++] = MXS_STRDUP_A(name_str); + table->column_names[columns] = MXS_STRDUP_A(name_str); + + json_t* value; + + if ((value = json_object_get(val, "real_type")) && json_is_string(value)) + { + table->column_types[columns] = MXS_STRDUP_A(json_string_value(value)); + } + else + { + table->column_types[columns] = MXS_STRDUP_A("unknown"); + MXS_WARNING("No \"real_type\" value defined. " + "Treating as unknown type field."); + } + + if ((value = json_object_get(val, "length")) && json_is_integer(value)) + { + table->column_lengths[columns] = json_integer_value(value); + } + else + { + table->column_lengths[columns] = -1; + MXS_WARNING("No \"length\" value defined. " + "Treating as default length field."); + } + + columns++; } } else