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

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) {
}).on('row', function (row) {
var type;
if (row.typname === 'geometry') {
type = dataTypes.GEOMETRY;
type = dataTypes.postgres.GEOMETRY;
} else if (row.typname === 'hstore') {
type = dataTypes.HSTORE;
type = dataTypes.postgres.HSTORE;
}
type.types.postgres.oids.push(row.oid);
type.types.postgres.array_oids.push(row.typarray);
self.$refreshTypeParser(type);
}).on('end', function () {
resolve();
});
......
......@@ -2,6 +2,7 @@
var Utils = require('../../utils')
, _ = require('lodash')
, Promise = require('../../promise')
, AbstractQuery = require('../abstract/query')
, QueryTypes = require('../../query-types')
, sequelizeErrors = require('../../errors.js')
......@@ -85,24 +86,21 @@ Query.prototype.run = function(sql, parameters) {
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 = {};
self.database.serialize(function() {
var executeSql = function() {
if (self.sql.indexOf('-- ') === 0) {
return resolve();
} else {
resolve(new Utils.Promise(function(resolve, reject) {
resolve(new Promise(function(resolve, reject) {
var afterExecute = function(err, results) {
if (err) {
err.sql = self.sql;
reject(self.formatError(err));
} else {
var metaData = this;
metaData.columnTypes = columnTypes;
var result = self.instance;
var metaData = this
, result = self.instance;
// add the inserted row id to the instance
if (self.isInsertQuery(results, metaData)) {
......@@ -134,7 +132,7 @@ Query.prototype.run = function(sql, parameters) {
}
var tableName = model.getTableName().toString().replace(/`/g, '')
, tableTypes = metaData.columnTypes[tableName];
, tableTypes = columnTypes[tableName];
if (tableTypes && !(name in tableTypes)) {
// The column is aliased
......@@ -231,26 +229,20 @@ Query.prototype.run = function(sql, parameters) {
var tableNames = [];
if (self.options && self.options.tableNames) {
tableNames = self.options.tableNames;
} else {
if (/FROM `(.*?)`/i.exec(self.sql)) {
} else if (/FROM `(.*?)`/i.exec(self.sql)) {
tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1]);
}
if (/FROM "(.*?)"/i.exec(self.sql)) {
tableNames.push(/FROM "(.*?)"/i.exec(self.sql)[1]);
}
}
if (!tableNames.length) {
return executeSql();
} else {
// If we already have the metadata for the table, there no need to ask for it again
// 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);
return !(tableName in columnTypes) && tableName !== 'sqlite_master';
});
return Utils.Promise.map(tableNames, function(tableName) {
if (tableName !== 'sqlite_master') {
return new Utils.Promise(function(resolve) {
if (!tableNames.length) {
return executeSql();
} else {
return Promise.map(tableNames, function(tableName) {
return new Promise(function(resolve) {
tableName = tableName.replace(/`/g, '');
columnTypes[tableName] = {};
......@@ -263,7 +255,6 @@ Query.prototype.run = function(sql, parameters) {
resolve();
});
});
}
}).then(executeSql);
}
} else {
......
......@@ -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)) {
this._previousDataValues[key] = originalValue;
this.changed(key, true);
......
......@@ -41,8 +41,13 @@ SqlString.escape = function(val, timeZone, dialect) {
return dataTypes.BLOB.prototype.stringify(val);
}
if (Array.isArray(val) && dialect === 'postgres') {
return dataTypes.ARRAY.prototype.stringify(val, { escape: _.partialRight(SqlString.escape, timeZone, dialect) });
if (Array.isArray(val)) {
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') {
......
......@@ -34,12 +34,12 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
require('../../node_modules/pg/node_modules/pg-types/lib/textParsers').init(function (oid, converter) {
types.setTypeParser(oid, 'text', converter);
});
this.sequelize.connectionManager.refreshTypeParser(DataTypes.postgres); // Reload custom parsers for hstore and geometry
break;
default:
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 () {
......
......@@ -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() {
var User = this.User;
var point = { type: 'Point', coordinates: [39.807222,-76.984722]};
......
......@@ -18,9 +18,9 @@ var chai = require('chai')
var qq = function(str) {
if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') {
if (dialect === 'postgres' || dialect === 'mssql') {
return '"' + str + '"';
} else if (Support.dialectIsMySQL()) {
} else if (Support.dialectIsMySQL() || dialect === 'sqlite') {
return '`' + str + '`';
} else {
return str;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!