Skip to content

Commit

Permalink
[CONJS-39] support geometry type : correction for MariaDB < 10.1.4 an…
Browse files Browse the repository at this point in the history
…d MySQL < 8.0.0 geometry support

report information isMariaDB() / hasMinVersion() to information level to permit use on internal functions
  • Loading branch information
rusher committed Sep 20, 2018
1 parent f289547 commit 7c2bdcb
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 126 deletions.
41 changes: 28 additions & 13 deletions lib/cmd/query.js
Expand Up @@ -86,7 +86,7 @@ class Query extends ResultSet {
// param is stream,
// now all params will be written by event
//********************************************
this.registerStreamSendEvent(out);
this.registerStreamSendEvent(out, info);
this.currentParam = i;
out.writeInt8(QUOTE); //'

Expand All @@ -108,7 +108,7 @@ class Query extends ResultSet {
//********************************************
// param isn't stream. directly write in buffer
//********************************************
this.writeParam(out, value, this.opts);
this.writeParam(out, value, this.opts, info);
out.writeString(this.queryParts[i]);
}
}
Expand Down Expand Up @@ -159,7 +159,7 @@ class Query extends ResultSet {
* Each parameter indicate that he is written to socket,
* emitting event so next parameter can be written.
*/
registerStreamSendEvent(out) {
registerStreamSendEvent(out, info) {
// note : Implementation use recursive calls, but stack won't never get near v8 max call stack size
const self = this;
this.on("param_written", function() {
Expand Down Expand Up @@ -201,7 +201,7 @@ class Query extends ResultSet {
//********************************************
// param isn't stream. directly write in buffer
//********************************************
this.writeParam(out, value, self.opts);
this.writeParam(out, value, self.opts, info);
out.writeString(self.queryParts[self.currentParam++]);
self.emit("param_written");
}
Expand All @@ -215,8 +215,9 @@ class Query extends ResultSet {
* @param out output writer
* @param value current parameter
* @param opts connection options
* @param info connection information
*/
writeParam(out, value, opts) {
writeParam(out, value, opts, info) {
switch (typeof value) {
case "boolean":
out.writeStringAscii(value ? "true" : "false");
Expand Down Expand Up @@ -247,56 +248,70 @@ class Query extends ResultSet {
].includes(value.type)
) {
//GeoJSON format.
let prefix =
(info.isMariaDB() && info.hasMinVersion(10, 1, 4)) ||
(!info.isMariaDB() && info.hasMinVersion(8, 0, 0))
? "ST_"
: "";
switch (value.type) {
case "Point":
out.writeStringAscii(
"ST_PointFromText('POINT(" + this.geoPointToString(value.coordinates) + ")')"
prefix +
"PointFromText('POINT(" +
this.geoPointToString(value.coordinates) +
")')"
);
break;

case "LineString":
out.writeStringAscii(
"ST_LineFromText('LINESTRING(" +
prefix +
"LineFromText('LINESTRING(" +
this.geoArrayPointToString(value.coordinates) +
")')"
);
break;

case "Polygon":
out.writeStringAscii(
"ST_PolygonFromText('POLYGON(" +
prefix +
"PolygonFromText('POLYGON(" +
this.geoMultiArrayPointToString(value.coordinates) +
")')"
);
break;

case "MultiPoint":
out.writeStringAscii(
"ST_MPointFromText('MULTIPOINT(" +
prefix +
"MULTIPOINTFROMTEXT('MULTIPOINT(" +
this.geoArrayPointToString(value.coordinates) +
")')"
);
break;

case "MultiLineString":
out.writeStringAscii(
"ST_MLineFromText('MULTILINESTRING(" +
prefix +
"MLineFromText('MULTILINESTRING(" +
this.geoMultiArrayPointToString(value.coordinates) +
")')"
);
break;

case "MultiPolygon":
out.writeStringAscii(
"ST_MPolyFromText('MULTIPOLYGON(" +
prefix +
"MPolyFromText('MULTIPOLYGON(" +
this.geoMultiPolygonToString(value.coordinates) +
")')"
);
break;

case "GeometryCollection":
out.writeStringAscii(
"ST_GeomCollFromText('GEOMETRYCOLLECTION(" +
prefix +
"GeomCollFromText('GEOMETRYCOLLECTION(" +
this.geometricCollectionToString(value.geometries) +
")')"
);
Expand All @@ -315,7 +330,7 @@ class Query extends ResultSet {
}
out.writeString("`" + key + "`");
out.writeStringAscii("=");
this.writeParam(out, val, opts);
this.writeParam(out, val, opts, info);
}
if (first) out.writeStringEscapeQuote(JSON.stringify(value));
} else {
Expand Down
25 changes: 1 addition & 24 deletions lib/connection.js
Expand Up @@ -89,7 +89,7 @@ function Connection(options) {
* @returns {Promise} promise
*/
this.changeUser = options => {
if (!this.isMariaDB()) {
if (!this.info.isMariaDB()) {
return Promise.reject(
Errors.createError(
"method changeUser not available for MySQL server due to Bug #83472",
Expand Down Expand Up @@ -373,29 +373,6 @@ function Connection(options) {
return info.serverVersion.raw;
};

this.isMariaDB = () => {
if (!info.serverVersion)
throw new Error("cannot know if server is MariaDB until connection is established");
return info.serverVersion.mariaDb;
};

this.hasMinVersion = (major, minor, patch) => {
if (!info.serverVersion)
throw new Error("cannot know if server version until connection is established");

if (!major) throw new Error("a major version must be set");

if (!minor) minor = 0;
if (!patch) patch = 0;

let ver = info.serverVersion;
return (
ver.major > major ||
(ver.major === major && ver.minor > minor) ||
(ver.major === major && ver.minor === minor && ver.patch >= patch)
);
};

/**
* Change option "debug" during connection.
* @param val debug value
Expand Down
23 changes: 23 additions & 0 deletions lib/misc/connection-information.js
Expand Up @@ -6,6 +6,29 @@ class ConnectionInformation {
this.status = null;
this.serverVersion = null;
}

hasMinVersion(major, minor, patch) {
if (!this.serverVersion)
throw new Error("cannot know if server version until connection is established");

if (!major) throw new Error("a major version must be set");

if (!minor) minor = 0;
if (!patch) patch = 0;

let ver = this.serverVersion;
return (
ver.major > major ||
(ver.major === major && ver.minor > minor) ||
(ver.major === major && ver.minor === minor && ver.patch >= patch)
);
}

isMariaDB() {
if (!this.serverVersion)
throw new Error("cannot know if server is MariaDB until connection is established");
return this.serverVersion.mariaDb;
}
}

module.exports = ConnectionInformation;
18 changes: 9 additions & 9 deletions test/integration/datatype/test-datetime.js
Expand Up @@ -20,13 +20,13 @@ describe("datetime", () => {

before(done => {
//MySQL 5.5 doesn't permit datetime(6)
if (!shareConn.isMariaDB() && !shareConn.hasMinVersion(5, 6)) {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) {
done();
} else {
shareConn.query("CREATE TABLE table_date (t0 DATE, t1 DATETIME(3), t2 DATETIME(6))");
shareConn.query("INSERT INTO table_date VALUES (?, ?, ?)", [date, date2, date3]);
shareConn.query("INSERT INTO table_date VALUES (?, ?, ?)", [null, null, null]).then(() => {
if (!shareConn.isMariaDB() && shareConn.hasMinVersion(5, 7)) {
if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7)) {
done();
} else {
shareConn
Expand Down Expand Up @@ -57,7 +57,7 @@ describe("datetime", () => {

it("date text", function(done) {
const date = new Date("1999-01-31 12:13:14");
if (!shareConn.isMariaDB() && !shareConn.hasMinVersion(5, 6)) this.skip();
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) this.skip();
shareConn
.query("select CAST(? as datetime) d", [date])
.then(res => {
Expand All @@ -72,7 +72,7 @@ describe("datetime", () => {
});

it("date text from row", function(done) {
if (!shareConn.isMariaDB() && !shareConn.hasMinVersion(5, 6)) this.skip();
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) this.skip();
shareConn
.query("select * from table_date")
.then(rows => {
Expand All @@ -84,7 +84,7 @@ describe("datetime", () => {
assert.isNull(rows[1].t1);
assert.isNull(rows[1].t2);

if (shareConn.isMariaDB() || !shareConn.hasMinVersion(5, 7)) {
if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7)) {
assert.isNull(rows[2].t0);
assert.isNull(rows[2].t1);
assert.isNull(rows[2].t2);
Expand All @@ -96,7 +96,7 @@ describe("datetime", () => {
});

it("date text as string", function(done) {
if (!shareConn.isMariaDB() && !shareConn.hasMinVersion(5, 6)) this.skip();
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) this.skip();

base
.createConnection({
Expand All @@ -116,7 +116,7 @@ describe("datetime", () => {
assert.isNull(rows[1].t1);
assert.isNull(rows[1].t2);

if (shareConn.isMariaDB() || !shareConn.hasMinVersion(5, 7)) {
if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7)) {
assert.equal(rows[2].t0, "0000-00-00");
assert.equal(rows[2].t1, "0000-00-00 00:00:00.000");
assert.equal(rows[2].t2, "0000-00-00 00:00:00.000000");
Expand All @@ -130,7 +130,7 @@ describe("datetime", () => {
});

it("query option : date text as string", function(done) {
if (!shareConn.isMariaDB() && !shareConn.hasMinVersion(5, 6)) this.skip();
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) this.skip();
shareConn
.query({ dateStrings: true, sql: "select * from table_date" })
.then(rows => {
Expand All @@ -143,7 +143,7 @@ describe("datetime", () => {
assert.isNull(rows[1].t1);
assert.isNull(rows[1].t2);

if (shareConn.isMariaDB() || !shareConn.hasMinVersion(5, 7)) {
if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7)) {
assert.equal(rows[2].t0, "0000-00-00");
assert.equal(rows[2].t1, "0000-00-00 00:00:00.000");
assert.equal(rows[2].t2, "0000-00-00 00:00:00.000000");
Expand Down

0 comments on commit 7c2bdcb

Please sign in to comment.