不要怂,就是干,撸起袖子干!

Commit cb222818 by Muhammed Kalkan Committed by Sushant

fix: properly select SRID if present (#11763)

1 parent 3288225b
'use strict'; 'use strict';
const wkx = require('wkx');
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment-timezone'); const moment = require('moment-timezone');
...@@ -92,6 +93,17 @@ module.exports = BaseTypes => { ...@@ -92,6 +93,17 @@ module.exports = BaseTypes => {
this.sqlType = this.type; this.sqlType = this.type;
} }
} }
static parse(value) {
value = value.buffer();
// Empty buffer, MySQL doesn't support POINT EMPTY
// check, https://dev.mysql.com/worklog/task/?id=2381
if (!value || value.length === 0) {
return null;
}
// For some reason, discard the first 4 bytes
value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });
}
toSql() { toSql() {
return this.sqlType; return this.sqlType;
} }
......
...@@ -109,7 +109,7 @@ module.exports = BaseTypes => { ...@@ -109,7 +109,7 @@ module.exports = BaseTypes => {
} }
// For some reason, discard the first 4 bytes // For some reason, discard the first 4 bytes
value = value.slice(4); value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON(); return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });
} }
toSql() { toSql() {
return this.sqlType; return this.sqlType;
......
...@@ -306,7 +306,7 @@ module.exports = BaseTypes => { ...@@ -306,7 +306,7 @@ module.exports = BaseTypes => {
} }
static parse(value) { static parse(value) {
const b = Buffer.from(value, 'hex'); const b = Buffer.from(value, 'hex');
return wkx.Geometry.parse(b).toGeoJSON(); return wkx.Geometry.parse(b).toGeoJSON({ shortCrs: true });
} }
_stringify(value, options) { _stringify(value, options) {
return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`; return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`;
...@@ -333,7 +333,7 @@ module.exports = BaseTypes => { ...@@ -333,7 +333,7 @@ module.exports = BaseTypes => {
} }
static parse(value) { static parse(value) {
const b = Buffer.from(value, 'hex'); const b = Buffer.from(value, 'hex');
return wkx.Geometry.parse(b).toGeoJSON(); return wkx.Geometry.parse(b).toGeoJSON({ shortCrs: true });
} }
_stringify(value, options) { _stringify(value, options) {
return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`; return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`;
......
...@@ -6,6 +6,7 @@ const Support = require('../../support'); ...@@ -6,6 +6,7 @@ const Support = require('../../support');
const dialect = Support.getTestDialect(); const dialect = Support.getTestDialect();
const DataTypes = require('../../../../lib/data-types'); const DataTypes = require('../../../../lib/data-types');
if (dialect === 'postgres') { if (dialect === 'postgres') {
describe('[POSTGRES Specific] Data Types', () => { describe('[POSTGRES Specific] Data Types', () => {
describe('DATE/DATEONLY Validate and Stringify', () => { describe('DATE/DATEONLY Validate and Stringify', () => {
......
...@@ -23,7 +23,15 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -23,7 +23,15 @@ describe(Support.getTestDialectTeaser('Model'), () => {
const Pub = this.sequelize.define('Pub', { const Pub = this.sequelize.define('Pub', {
location: { field: 'coordinates', type: DataTypes.GEOGRAPHY } location: { field: 'coordinates', type: DataTypes.GEOGRAPHY }
}), }),
point = { type: 'Point', coordinates: [39.807222, -76.984722] }; point = {
type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return Pub.sync({ force: true }).then(() => { return Pub.sync({ force: true }).then(() => {
return Pub.create({ location: point }); return Pub.create({ location: point });
...@@ -35,7 +43,15 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -35,7 +43,15 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should create a geography object', function() { it('should create a geography object', function() {
const User = this.User; const User = this.User;
const point = { type: 'Point', coordinates: [39.807222, -76.984722] }; const point = {
type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geography: point }).then(newUser => { return User.create({ username: 'username', geography: point }).then(newUser => {
expect(newUser).not.to.be.null; expect(newUser).not.to.be.null;
...@@ -45,8 +61,24 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -45,8 +61,24 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should update a geography object', function() { it('should update a geography object', function() {
const User = this.User; const User = this.User;
const point1 = { type: 'Point', coordinates: [39.807222, -76.984722] }, const point1 = {
point2 = { type: 'Point', coordinates: [49.807222, -86.984722] }; type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
},
point2 = {
type: 'Point', coordinates: [49.807222, -86.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
const props = { username: 'username', geography: point1 }; const props = { username: 'username', geography: point1 };
return User.create(props).then(() => { return User.create(props).then(() => {
...@@ -71,7 +103,15 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -71,7 +103,15 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should create a geography object', function() { it('should create a geography object', function() {
const User = this.User; const User = this.User;
const point = { type: 'Point', coordinates: [39.807222, -76.984722] }; const point = {
type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geography: point }).then(newUser => { return User.create({ username: 'username', geography: point }).then(newUser => {
expect(newUser).not.to.be.null; expect(newUser).not.to.be.null;
...@@ -81,8 +121,24 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -81,8 +121,24 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should update a geography object', function() { it('should update a geography object', function() {
const User = this.User; const User = this.User;
const point1 = { type: 'Point', coordinates: [39.807222, -76.984722] }, const point1 = {
point2 = { type: 'Point', coordinates: [49.807222, -86.984722] }; type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
},
point2 = {
type: 'Point', coordinates: [49.807222, -86.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
const props = { username: 'username', geography: point1 }; const props = { username: 'username', geography: point1 };
return User.create(props).then(() => { return User.create(props).then(() => {
...@@ -107,7 +163,15 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -107,7 +163,15 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should create a geography object', function() { it('should create a geography object', function() {
const User = this.User; const User = this.User;
const point = { type: 'LineString', 'coordinates': [[100.0, 0.0], [101.0, 1.0]] }; const point = {
type: 'LineString', 'coordinates': [[100.0, 0.0], [101.0, 1.0]],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geography: point }).then(newUser => { return User.create({ username: 'username', geography: point }).then(newUser => {
expect(newUser).not.to.be.null; expect(newUser).not.to.be.null;
...@@ -117,8 +181,24 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -117,8 +181,24 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should update a geography object', function() { it('should update a geography object', function() {
const User = this.User; const User = this.User;
const point1 = { type: 'LineString', coordinates: [[100.0, 0.0], [101.0, 1.0]] }, const point1 = {
point2 = { type: 'LineString', coordinates: [[101.0, 0.0], [102.0, 1.0]] }; type: 'LineString', coordinates: [[100.0, 0.0], [101.0, 1.0]],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
},
point2 = {
type: 'LineString', coordinates: [[101.0, 0.0], [102.0, 1.0]],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
const props = { username: 'username', geography: point1 }; const props = { username: 'username', geography: point1 };
return User.create(props).then(() => { return User.create(props).then(() => {
...@@ -143,10 +223,18 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -143,10 +223,18 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should create a geography object', function() { it('should create a geography object', function() {
const User = this.User; const User = this.User;
const point = { type: 'Polygon', coordinates: [ const point = {
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], type: 'Polygon', coordinates: [
[100.0, 1.0], [100.0, 0.0]] [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
] }; [100.0, 1.0], [100.0, 0.0]]
],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geography: point }).then(newUser => { return User.create({ username: 'username', geography: point }).then(newUser => {
expect(newUser).not.to.be.null; expect(newUser).not.to.be.null;
...@@ -156,13 +244,29 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -156,13 +244,29 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should update a geography object', function() { it('should update a geography object', function() {
const User = this.User; const User = this.User;
const polygon1 = { type: 'Polygon', coordinates: [ const polygon1 = {
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]] type: 'Polygon', coordinates: [
] }, [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
polygon2 = { type: 'Polygon', coordinates: [ ],
[[100.0, 0.0], [102.0, 0.0], [102.0, 1.0], crs: {
[100.0, 1.0], [100.0, 0.0]] type: 'name',
] }; properties: {
name: 'EPSG:4326'
}
}
},
polygon2 = {
type: 'Polygon', coordinates: [
[[100.0, 0.0], [102.0, 0.0], [102.0, 1.0],
[100.0, 1.0], [100.0, 0.0]]
],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
const props = { username: 'username', geography: polygon1 }; const props = { username: 'username', geography: polygon1 };
return User.create(props).then(() => { return User.create(props).then(() => {
...@@ -188,10 +292,18 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -188,10 +292,18 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should create a geography object', function() { it('should create a geography object', function() {
const User = this.User; const User = this.User;
const point = { type: 'Polygon', coordinates: [ const point = {
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], type: 'Polygon', coordinates: [
[100.0, 1.0], [100.0, 0.0]] [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
] }; [100.0, 1.0], [100.0, 0.0]]
],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geography: point }).then(newUser => { return User.create({ username: 'username', geography: point }).then(newUser => {
expect(newUser).not.to.be.null; expect(newUser).not.to.be.null;
...@@ -201,13 +313,29 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -201,13 +313,29 @@ describe(Support.getTestDialectTeaser('Model'), () => {
it('should update a geography object', function() { it('should update a geography object', function() {
const User = this.User; const User = this.User;
const polygon1 = { type: 'Polygon', coordinates: [ const polygon1 = {
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]] type: 'Polygon', coordinates: [
] }, [[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]
polygon2 = { type: 'Polygon', coordinates: [ ],
[[100.0, 0.0], [102.0, 0.0], [102.0, 1.0], crs: {
[100.0, 1.0], [100.0, 0.0]] type: 'name',
] }; properties: {
name: 'EPSG:4326'
}
}
},
polygon2 = {
type: 'Polygon', coordinates: [
[[100.0, 0.0], [102.0, 0.0], [102.0, 1.0],
[100.0, 1.0], [100.0, 0.0]]
],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
const props = { username: 'username', geography: polygon1 }; const props = { username: 'username', geography: polygon1 };
return User.create(props).then(() => { return User.create(props).then(() => {
......
...@@ -59,6 +59,27 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -59,6 +59,27 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(user.geometry).to.be.deep.eql(point2); expect(user.geometry).to.be.deep.eql(point2);
}); });
}); });
it('works with crs field', function() {
const Pub = this.sequelize.define('Pub', {
location: { field: 'coordinates', type: DataTypes.GEOMETRY }
}),
point = { type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return Pub.sync({ force: true }).then(() => {
return Pub.create({ location: point });
}).then(pub => {
expect(pub).not.to.be.null;
expect(pub.location).to.be.deep.eql(point);
});
});
}); });
describe('GEOMETRY(POINT)', () => { describe('GEOMETRY(POINT)', () => {
...@@ -95,6 +116,23 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -95,6 +116,23 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(user.geometry).to.be.deep.eql(point2); expect(user.geometry).to.be.deep.eql(point2);
}); });
}); });
it('works with crs field', function() {
const User = this.User;
const point = { type: 'Point', coordinates: [39.807222, -76.984722],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geometry: point }).then(newUser => {
expect(newUser).not.to.be.null;
expect(newUser.geometry).to.be.deep.eql(point);
});
});
}); });
describe('GEOMETRY(LINESTRING)', () => { describe('GEOMETRY(LINESTRING)', () => {
...@@ -131,6 +169,24 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -131,6 +169,24 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(user.geometry).to.be.deep.eql(point2); expect(user.geometry).to.be.deep.eql(point2);
}); });
}); });
it('works with crs field', function() {
const User = this.User;
const point = { type: 'LineString', 'coordinates': [[100.0, 0.0], [101.0, 1.0]],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geometry: point }).then(newUser => {
expect(newUser).not.to.be.null;
expect(newUser.geometry).to.be.deep.eql(point);
});
});
}); });
describe('GEOMETRY(POLYGON)', () => { describe('GEOMETRY(POLYGON)', () => {
...@@ -156,6 +212,25 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -156,6 +212,25 @@ describe(Support.getTestDialectTeaser('Model'), () => {
}); });
}); });
it('works with crs field', function() {
const User = this.User;
const point = { type: 'Polygon', coordinates: [
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0]]],
crs: {
type: 'name',
properties: {
name: 'EPSG:4326'
}
}
};
return User.create({ username: 'username', geometry: point }).then(newUser => {
expect(newUser).not.to.be.null;
expect(newUser.geometry).to.be.deep.eql(point);
});
});
it('should update a geometry object', function() { it('should update a geometry object', function() {
const User = this.User; const User = this.User;
const polygon1 = { type: 'Polygon', coordinates: [ const polygon1 = { type: 'Polygon', coordinates: [
...@@ -202,7 +277,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { ...@@ -202,7 +277,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
// MySQL 5.7, those guys finally fixed this // MySQL 5.7, those guys finally fixed this
if (dialect === 'mysql' && semver.gte(this.sequelize.options.databaseVersion, '5.7.0')) { if (dialect === 'mysql' && semver.gte(this.sequelize.options.databaseVersion, '5.7.0')) {
return; return;
} }
return this.Model.create({ return this.Model.create({
location: { location: {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!