Skip to content
Permalink
Browse files
[CONJS-24] new option "sessionVariables" to permit setting session va…
…riable at connection
  • Loading branch information
rusher committed Sep 7, 2018
1 parent ea105f8 commit a4ac4c9
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 1 deletion.
@@ -319,6 +319,8 @@ mariadb.createConnection({
| **connectAttributes** | Sends information, (client name, version, operating system, Node.js version, and so on) to the [Performance Schema](https://mariadb.com/kb/en/library/performance-schema-session_connect_attrs-table/). When enabled, the Connector sends JSON attributes in addition to the defaults. |*boolean/json* |false|
| **metaAsArray** | Compatibility option, causes Promise to return an array object, `[rows, metadata]` rather than the rows as JSON objects with a `meta` property. |*boolean* |false|
| **permitSetMultiParamEntries** | Compatibility option to permit setting multiple value by a JSON object to replace one question mark. key values will replace the question mark with format like `key1`=val,`key2`='val2'. Since it doesn't respect the usual prepared statement format that one value is for one question mark, this can lead to incomprehension, even if badly use to possible injection.|*boolean* |false|
| **sessionVariables** | Permit to set session variables when connecting. Example: sessionVariables:{'idle_transaction_timeout':10000}|*json* |


## F.A.Q.

@@ -50,6 +50,7 @@ class ConnectionOptions {
}
this.port = opts.port || 3306;
this.socketPath = opts.socketPath;
this.sessionVariables = opts.sessionVariables;
this.supportBigNumbers = opts.supportBigNumbers || false;
this.timezone = opts.timezone || "local";
if (this.timezone !== "local") {
@@ -510,6 +510,45 @@ function Connection(options) {
_initSocket(_authFail);
};

const _addSessionVariableQuery = () => {
if (opts.sessionVariables) {
let sessionQuery = "set ";
let keys = Object.keys(opts.sessionVariables);
if (keys.length > 0) {
for (let k = 0; k < keys.length; ++k) {
sessionQuery +=
(k != 0 ? "," : "") +
"@" +
keys[k].replace(/[^a-z0-9_]/gi, "") +
"=" +
opts.sessionVariables[keys[k]];
}
const conn = this;
const errorHandling = initialErr => {
conn.emit(
"error",
Errors.createError(
"Error setting session variable (value " +
JSON.stringify(opts.sessionVariables) +
"). Error: " +
initialErr.message,
true,
info,
"08S01",
Errors.ER_SETTING_SESSION_ERROR,
null
)
);
conn.end().catch(err => {});
};

const cmd = new Query(() => {}, errorHandling, null, sessionQuery, null);
if (opts.trace) Error.captureStackTrace(cmd);
_addCommand(cmd);
}
}
};

const _getSocket = () => {
return _socket;
};
@@ -574,6 +613,7 @@ function Connection(options) {
}

if (opts.pipelining) _addCommand = _addCommandEnablePipeline;
_addSessionVariableQuery();
process.nextTick(resolve, this);
_status = Status.CONNECTED;
};
@@ -86,6 +86,7 @@ module.exports.ER_AUTHENTICATION_PLUGIN_NOT_SUPPORTED = 45025;
module.exports.ER_SOCKET_TIMEOUT = 45026;
module.exports.ER_POOL_ALREADY_CLOSED = 45027;
module.exports.ER_GET_CONNECTION_TIMEOUT = 45028;
module.exports.ER_SETTING_SESSION_ERROR = 45029;

const keys = Object.keys(module.exports);
const errByNo = {};
@@ -0,0 +1,71 @@
"use strict";

const base = require("../base.js");
const { assert } = require("chai");

describe("session variables", () => {
it("with empty session variables", function(done) {
base
.createConnection({ sessionVariables: {} })
.then(conn => {
conn
.query("SELECT 1")
.then(rows => {
assert.deepEqual(rows, [{ "1": 1 }]);
conn.end();
done();
})
.catch(done);
})
.catch(done);
});

it("with one session variables", function(done) {
base
.createConnection({ sessionVariables: { wait_timeout: 10000 } })
.then(conn => {
conn
.query("SELECT @wait_timeout")
.then(rows => {
assert.deepEqual(rows, [{ "@wait_timeout": 10000 }]);
conn.end();
done();
})
.catch(done);
})
.catch(done);
});

it("with multiple session variables", function(done) {
base
.createConnection({
sessionVariables: { wait_timeout: 10000, interactive_timeout: 2540 },
debug: true
})
.then(conn => {
conn
.query("SELECT @wait_timeout, @interactive_timeout")
.then(rows => {
assert.deepEqual(rows, [{ "@wait_timeout": 10000, "@interactive_timeout": 2540 }]);
conn.end();
done();
})
.catch(done);
})
.catch(done);
});

it("error handling", function(done) {
base
.createConnection({ sessionVariables: { wait_timeout: "String value" }, debug: true })
.then(conn => {
conn.on("error", err => {
assert(err.message.includes("Error setting session variable"));
assert.equal(err.sqlState, "08S01");
assert.equal(err.code, "ER_SETTING_SESSION_ERROR");
done();
});
})
.catch(done);
});
});
@@ -47,5 +47,4 @@ describe("packet", () => {

assert.equal(packet.pos, 534);
});

});

0 comments on commit a4ac4c9

Please sign in to comment.