From dda1ed3d89b3dee65fed0dd56f36a4d6b84b1b08 Mon Sep 17 00:00:00 2001 From: rusher Date: Thu, 15 Mar 2018 16:10:14 +0100 Subject: [PATCH] remove unused conenction option. add connection option documentation. add few tests --- documentation/readme.md | 47 +++++++++++++++++++++++ src/config/connection-options.js | 4 -- src/io/Packet.js | 16 +++----- test/integration/datatype/test-buffer.js | 16 ++++++++ test/integration/datatype/test-integer.js | 25 ++++++++++-- test/integration/test-big-query.js | 46 ++++++++++++++++++++++ 6 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 test/integration/datatype/test-buffer.js create mode 100644 test/integration/test-big-query.js diff --git a/documentation/readme.md b/documentation/readme.md index 9dbcbf5..817b76f 100644 --- a/documentation/readme.md +++ b/documentation/readme.md @@ -57,6 +57,53 @@ var conn2 = mariadb.createConnection({socketPath: '/tmp/mysql.sock'}); var conn3 = mariadb.createConnection({host: 'mydb.com', port:9999}); ``` +### connection options + + +#### important option + + * `user`: string. user + * `host`: string. IP or DNS of database server. default: 'localhost' + * `port`: integer. database server port number. default: 3306 + * `database`: string. default database when establishing connection. + * `password`: string. user password + * `socketPath`: string. Permits connecting to the database via Unix domain socket or named pipe, if the server allows it. + * `compress`: boolean. exchanges with database must be gzip. (=> when database is not localhost). default: false + * `connectTimeout`: integer. connection timeout in ms. default: 10 000. + +Support for big integer: + +Javascript integer use IEEE-754 representation, meaning that integer not in ±9,007,199,254,740,991 range cannot be exactly represented. +MariaDB/MySQL server have data type that permit bigger integer. + +For those integer that are not in [safe](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger) range default implementation will return an integer that may be not the exact representation. +2 options permit to have the exact value : + + * `bigNumberStrings`: if integer is not in "safe" range, the value will be return as a string. + * `supportBigNumbers`: if integer is not in "safe" range, the value will be return as a [Long](https://www.npmjs.com/package/long) object. + +#### ssl + //TODO describe all solutions + + * `ssl`: string/object. + +#### other option + * `charset`: string. define charset exchange with server. default: UTF8MB4_UNICODE_CI + * `dateStrings`: boolean. indicate if date must be retrived as string (not as date). default: false + * `debug`: boolean. when active, log all exchange wirh servers. default: false + * `foundRows`: boolean. active, update number correspond to update rows. disable indicate real rows changed. default: true. + * `multipleStatements`: boolean. Permit multi-queries like "insert into ab (i) values (1); insert into ab (i) values (2)". this may be **security risk** in case of sql injection. default: false + * `namedPlaceholders`: boolean. Permit using named placeholder, default: false + * `permitLocalInfile`: boolean. permit using LOAD DATA INFILE command. + this (ie: loading a file from the client) may be a security problem : + + A "man in the middle" proxy server can change the actual file requested from the server so the client will send a local file to this proxy. + if someone can execute a query from the client, he can have access to any file on the client (according to the rights of the user running the client process). + default: false + * `timezone`: string. force using indicated timezone, not current node.js timezone. possible value are 'Z' (fot UTC), 'local' or '±HH:MM' format + * `nestTables`: boolean/string. resultset are presented by table to avoid results with colliding fields. default: false + * `rowsAsArray`: boolean. default rows are defined as a JSON object. when active row is an array. default false + ## Query `connection.query(sql[, values][,callback])` diff --git a/src/config/connection-options.js b/src/config/connection-options.js index a65a81b..637f0f2 100644 --- a/src/config/connection-options.js +++ b/src/config/connection-options.js @@ -25,7 +25,6 @@ class ConnectionOptions { this.collation = Collations.fromIndex(opts.charsetNumber) || Collations.fromIndex(224); //UTF8MB4_UNICODE_CI; } this.compress = opts.compress || false; - this.connectAttributes = opts.connectAttributes; this.connectTimeout = opts.connectTimeout === undefined ? 10000 : opts.connectTimeout; this.database = opts.database; this.dateStrings = opts.dateStrings || false; @@ -33,8 +32,6 @@ class ConnectionOptions { this.bigNumberStrings = opts.bigNumberStrings || false; this.foundRows = opts.foundRows === undefined || opts.foundRows; this.host = opts.host || "localhost"; - this.insecureAuth = opts.insecureAuth || false; - this.localAddress = opts.localAddress; this.maxPreparedStatements = opts.maxPreparedStatements || 128; this.multipleStatements = opts.multipleStatements || false; this.namedPlaceholders = opts.namedPlaceholders || false; @@ -61,7 +58,6 @@ class ConnectionOptions { } } - this.trace = opts.trace !== false; this.user = opts.user; this.nestTables = opts.nestTables === undefined ? undefined : opts.nestTables; this.rowsAsArray = opts.rowsAsArray || false; diff --git a/src/io/Packet.js b/src/io/Packet.js index ecdf6d5..abd0f53 100644 --- a/src/io/Packet.js +++ b/src/io/Packet.js @@ -139,12 +139,6 @@ class Packet { const len = this.readLength(false); if (len === null) return null; - if (bigNumberStrings) { - //return as string - this.off += len; - return this.buf.toString("ascii", this.off - len, this.off); - } - let result = 0; let negate = false; let begin = this.off; @@ -161,12 +155,14 @@ class Packet { let val = negate ? -1 * result : result; this.off += len; - if (!Number.isSafeInteger(val) && supportBigNumbers) { + if (!Number.isSafeInteger(val)) { const str = this.buf.toString("ascii", this.off - len, this.off); - return Long.fromString(str, unsigned, 10); - } else { - return val; + if (bigNumberStrings) return str; + if (supportBigNumbers) { + return Long.fromString(str, unsigned, 10); + } } + return val; } readDecimalLengthEncoded(supportBigNumbers, bigNumberStrings) { diff --git a/test/integration/datatype/test-buffer.js b/test/integration/datatype/test-buffer.js new file mode 100644 index 0000000..7475afe --- /dev/null +++ b/test/integration/datatype/test-buffer.js @@ -0,0 +1,16 @@ +"use strict"; + +const base = require("../../base"); +const assert = require("chai").assert; + +describe("buffer", () => { + + it("basic buffer", done => { + shareConn.query("SELECT x'FF00' val", (err, rows) => { + if (err) throw err; + assert.deepEqual(rows[0].val, Buffer.from([255, 0])); + done(); + }); + }); + +}); diff --git a/test/integration/datatype/test-integer.js b/test/integration/datatype/test-integer.js index 635fdae..dafba5b 100644 --- a/test/integration/datatype/test-integer.js +++ b/test/integration/datatype/test-integer.js @@ -45,13 +45,32 @@ describe("integer with big value", () => { shareConn.query({ bigNumberStrings: true, sql: "SELECT * FROM testBigint" }, (err, rows) => { assert.strictEqual(rows.length, 4); - assert.strictEqual(rows[0].v, "127"); - assert.strictEqual(rows[1].v, "128"); - assert.strictEqual(rows[2].v, "9007199254740991"); + assert.strictEqual(rows[0].v, 127); + assert.strictEqual(rows[1].v, 128); + assert.strictEqual(rows[2].v, 9007199254740991); assert.strictEqual(rows[3].v, "9007199254740992"); assert.strictEqual(typeof rows[3].v, "string"); done(); }); }); + + it("bigint format", done => { + shareConn.query("CREATE TEMPORARY TABLE testBigintNull (v BIGINT)"); + shareConn.query("INSERT INTO testBigintNull values (127), (null)"); + + const checkResult = (err, rows) => { + assert.strictEqual(rows.length, 2); + assert.strictEqual(rows[0].v, 127); + assert.strictEqual(rows[1].v, null); + }; + + shareConn.query("SELECT * FROM testBigintNull", checkResult); + shareConn.query({ supportBigNumbers: true, sql: "SELECT * FROM testBigintNull" }, checkResult); + shareConn.query({ bigNumberStrings: true, sql: "SELECT * FROM testBigintNull" }, (err, rows) => { + checkResult(err, rows); + done(); + }); + }); + }); diff --git a/test/integration/test-big-query.js b/test/integration/test-big-query.js new file mode 100644 index 0000000..0f90608 --- /dev/null +++ b/test/integration/test-big-query.js @@ -0,0 +1,46 @@ +const base = require("../base.js"); +const assert = require("chai").assert; + +describe('Big query', function() { + + const testSize = 16 * 1024 * 1024 + 800; // more than one packet + let maxAllowedSize, buf; + + before(function(done) { + shareConn.query('SELECT @@max_allowed_packet as t', function(err, results) { + if (err) { + done(err); + } else { + maxAllowedSize = results[0].t; + if (testSize < maxAllowedSize) { + buf = Buffer.alloc(testSize); + for (let i = 0; i < buf.length; i++) { + buf[i] = 97 + i % 10; + } + } + done(); + } + }); + }); + + it('parameter bigger than packet size', function(done) { + if (maxAllowedSize <= testSize) this.skip(); + this.timeout(10000); //can take some time + shareConn.query('CREATE TEMPORARY TABLE bigParameter (b longblob)'); + shareConn.query('insert into bigParameter(b) values(?)', [buf], function(err) { + if (err) { + done(err); + } else { + shareConn.query('SELECT * from bigParameter', function(err, rows) { + if (err) { + throw done(err); + } else { + assert.deepEqual(rows[0].b, buf); + done(); + } + }); + } + }); + }); + +});