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

Commit 785ff33e by Jan Aagaard Meier

bug(datatypes) Fix parsing of aliassed geometry field. Closes #4431

1 parent a9673fbf
...@@ -143,13 +143,15 @@ ConnectionManager.prototype.connect = function(config) { ...@@ -143,13 +143,15 @@ ConnectionManager.prototype.connect = function(config) {
}).on('row', function (row) { }).on('row', function (row) {
var type; var type;
if (row.typname === 'geometry') { if (row.typname === 'geometry') {
type = dataTypes.GEOMETRY; type = dataTypes.postgres.GEOMETRY;
} else if (row.typname === 'hstore') { } else if (row.typname === 'hstore') {
type = dataTypes.HSTORE; type = dataTypes.postgres.HSTORE;
} }
type.types.postgres.oids.push(row.oid); type.types.postgres.oids.push(row.oid);
type.types.postgres.array_oids.push(row.typarray); type.types.postgres.array_oids.push(row.typarray);
self.$refreshTypeParser(type);
}).on('end', function () { }).on('end', function () {
resolve(); resolve();
}); });
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
var Utils = require('../../utils') var Utils = require('../../utils')
, _ = require('lodash') , _ = require('lodash')
, Promise = require('../../promise')
, AbstractQuery = require('../abstract/query') , AbstractQuery = require('../abstract/query')
, QueryTypes = require('../../query-types') , QueryTypes = require('../../query-types')
, sequelizeErrors = require('../../errors.js') , sequelizeErrors = require('../../errors.js')
...@@ -85,24 +86,21 @@ Query.prototype.run = function(sql, parameters) { ...@@ -85,24 +86,21 @@ Query.prototype.run = function(sql, parameters) {
this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options); this.sequelize.log('Executing (' + (this.database.uuid || 'default') + '): ' + this.sql, this.options);
promise = new Utils.Promise(function(resolve) { promise = new Promise(function(resolve) {
var columnTypes = {}; var columnTypes = {};
self.database.serialize(function() { self.database.serialize(function() {
var executeSql = function() { var executeSql = function() {
if (self.sql.indexOf('-- ') === 0) { if (self.sql.indexOf('-- ') === 0) {
return resolve(); return resolve();
} else { } else {
resolve(new Utils.Promise(function(resolve, reject) { resolve(new Promise(function(resolve, reject) {
var afterExecute = function(err, results) { var afterExecute = function(err, results) {
if (err) { if (err) {
err.sql = self.sql; err.sql = self.sql;
reject(self.formatError(err)); reject(self.formatError(err));
} else { } else {
var metaData = this; var metaData = this
metaData.columnTypes = columnTypes; , result = self.instance;
var result = self.instance;
// add the inserted row id to the instance // add the inserted row id to the instance
if (self.isInsertQuery(results, metaData)) { if (self.isInsertQuery(results, metaData)) {
...@@ -134,7 +132,7 @@ Query.prototype.run = function(sql, parameters) { ...@@ -134,7 +132,7 @@ Query.prototype.run = function(sql, parameters) {
} }
var tableName = model.getTableName().toString().replace(/`/g, '') var tableName = model.getTableName().toString().replace(/`/g, '')
, tableTypes = metaData.columnTypes[tableName]; , tableTypes = columnTypes[tableName];
if (tableTypes && !(name in tableTypes)) { if (tableTypes && !(name in tableTypes)) {
// The column is aliased // The column is aliased
...@@ -231,39 +229,32 @@ Query.prototype.run = function(sql, parameters) { ...@@ -231,39 +229,32 @@ Query.prototype.run = function(sql, parameters) {
var tableNames = []; var tableNames = [];
if (self.options && self.options.tableNames) { if (self.options && self.options.tableNames) {
tableNames = self.options.tableNames; tableNames = self.options.tableNames;
} else { } else if (/FROM `(.*?)`/i.exec(self.sql)) {
if (/FROM `(.*?)`/i.exec(self.sql)) { tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1]);
tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1]);
}
if (/FROM "(.*?)"/i.exec(self.sql)) {
tableNames.push(/FROM "(.*?)"/i.exec(self.sql)[1]);
}
} }
// If we already have the metadata for the table, there's no need to ask for it again
tableNames = _.filter(tableNames, function (tableName) {
return !(tableName in columnTypes) && tableName !== 'sqlite_master';
});
if (!tableNames.length) { if (!tableNames.length) {
return executeSql(); return executeSql();
} else { } else {
// If we already have the metadata for the table, there no need to ask for it again return Promise.map(tableNames, function(tableName) {
tableNames = _.filter(tableNames, function (tableName) { return new Promise(function(resolve) {
return !(tableName in columnTypes); tableName = tableName.replace(/`/g, '');
}); columnTypes[tableName] = {};
return Utils.Promise.map(tableNames, function(tableName) { self.database.all('PRAGMA table_info(`' + tableName + '`)', function(err, results) {
if (tableName !== 'sqlite_master') { if (!err) {
return new Utils.Promise(function(resolve) { results.forEach(function (result) {
tableName = tableName.replace(/`/g, ''); columnTypes[tableName][result.name] = result.type;
columnTypes[tableName] = {}; });
}
self.database.all('PRAGMA table_info(`' + tableName + '`)', function(err, results) { resolve();
if (!err) {
results.forEach(function (result) {
columnTypes[tableName][result.name] = result.type;
});
}
resolve();
});
}); });
} });
}).then(executeSql); }).then(executeSql);
} }
} else { } else {
......
...@@ -368,10 +368,6 @@ Instance.prototype.set = function(key, value, options) { // testhint options:non ...@@ -368,10 +368,6 @@ Instance.prototype.set = function(key, value, options) { // testhint options:non
} }
} }
if (this.Model._hasGeometryAttributes && this.Model._isGeometryAttribute(key) && _.isString(value)) {
value = this.Model.attributes[key].type.parse(value);
}
if (!options.raw && ((!Utils.isPrimitive(value) && value !== null) || value !== originalValue)) { if (!options.raw && ((!Utils.isPrimitive(value) && value !== null) || value !== originalValue)) {
this._previousDataValues[key] = originalValue; this._previousDataValues[key] = originalValue;
this.changed(key, true); this.changed(key, true);
......
...@@ -41,8 +41,13 @@ SqlString.escape = function(val, timeZone, dialect) { ...@@ -41,8 +41,13 @@ SqlString.escape = function(val, timeZone, dialect) {
return dataTypes.BLOB.prototype.stringify(val); return dataTypes.BLOB.prototype.stringify(val);
} }
if (Array.isArray(val) && dialect === 'postgres') { if (Array.isArray(val)) {
return dataTypes.ARRAY.prototype.stringify(val, { escape: _.partialRight(SqlString.escape, timeZone, dialect) }); var escape = _.partialRight(SqlString.escape, timeZone, dialect);
if (dialect === 'postgres') {
return dataTypes.ARRAY.prototype.stringify(val, {escape: escape});
} else {
return '[' + val.map(escape) + ']';
}
} }
if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') {
......
...@@ -34,12 +34,12 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() { ...@@ -34,12 +34,12 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
require('../../node_modules/pg/node_modules/pg-types/lib/textParsers').init(function (oid, converter) { require('../../node_modules/pg/node_modules/pg-types/lib/textParsers').init(function (oid, converter) {
types.setTypeParser(oid, 'text', converter); types.setTypeParser(oid, 'text', converter);
}); });
this.sequelize.connectionManager.refreshTypeParser(DataTypes.postgres); // Reload custom parsers for hstore and geometry
break; break;
default: default:
this.sequelize.connectionManager.$clearTypeParser(); this.sequelize.connectionManager.$clearTypeParser();
} }
this.sequelize.connectionManager.refreshTypeParser(DataTypes[dialect]); // Reload custom parsers
}); });
it('allows me to return values from a custom parse function', function () { it('allows me to return values from a custom parse function', function () {
......
...@@ -23,6 +23,20 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -23,6 +23,20 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}); });
}); });
it('works with aliases fields', function () {
var Pub = this.sequelize.define('Pub', {
location: {field: 'coordinates', type: DataTypes.GEOMETRY}
})
, point = {type: 'Point', coordinates: [39.807222, -76.984722]};
return Pub.sync({ force: true }).then(function () {
return Pub.create({location: point});
}).then(function (pub) {
expect(pub).not.to.be.null;
expect(pub.location).to.be.deep.eql(point);
});
});
it('should create a geometry object', function() { it('should create a geometry object', function() {
var User = this.User; var User = this.User;
var point = { type: 'Point', coordinates: [39.807222,-76.984722]}; var point = { type: 'Point', coordinates: [39.807222,-76.984722]};
......
...@@ -18,9 +18,9 @@ var chai = require('chai') ...@@ -18,9 +18,9 @@ var chai = require('chai')
var qq = function(str) { var qq = function(str) {
if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { if (dialect === 'postgres' || dialect === 'mssql') {
return '"' + str + '"'; return '"' + str + '"';
} else if (Support.dialectIsMySQL()) { } else if (Support.dialectIsMySQL() || dialect === 'sqlite') {
return '`' + str + '`'; return '`' + str + '`';
} else { } else {
return str; return str;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!