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

Commit 199ba5f1 by Mick Hansen

Merge pull request #1560 from seegno/add-hstore-querying

Add hstore parsing
2 parents cc45eec1 88df17d9
...@@ -194,6 +194,7 @@ module.exports = (function() { ...@@ -194,6 +194,7 @@ module.exports = (function() {
this._booleanAttributes = [] this._booleanAttributes = []
this._dateAttributes = [] this._dateAttributes = []
this._hstoreAttributes = []
this._defaultValues = {} this._defaultValues = {}
this.DAO.prototype.validators = {} this.DAO.prototype.validators = {}
...@@ -204,6 +205,9 @@ module.exports = (function() { ...@@ -204,6 +205,9 @@ module.exports = (function() {
if (((definition === DataTypes.DATE) || (definition.type === DataTypes.DATE) || (definition.originalType === DataTypes.DATE))) { if (((definition === DataTypes.DATE) || (definition.type === DataTypes.DATE) || (definition.originalType === DataTypes.DATE))) {
self._dateAttributes.push(name); self._dateAttributes.push(name);
} }
if (((definition === DataTypes.HSTORE.type) || (definition.type === DataTypes.HSTORE.type) || (definition.originalType === DataTypes.HSTORE.type))) {
self._hstoreAttributes.push(name);
}
if (definition.hasOwnProperty('defaultValue')) { if (definition.hasOwnProperty('defaultValue')) {
self._defaultValues[name] = Utils._.partial( self._defaultValues[name] = Utils._.partial(
Utils.toDefaultValue, definition.defaultValue) Utils.toDefaultValue, definition.defaultValue)
...@@ -224,6 +228,11 @@ module.exports = (function() { ...@@ -224,6 +228,11 @@ module.exports = (function() {
return self._dateAttributes.indexOf(key) !== -1 return self._dateAttributes.indexOf(key) !== -1
}) })
this._hasHstoreAttributes = !!this._hstoreAttributes.length
this._isHstoreAttribute = Utils._.memoize(function (key) {
return self._hstoreAttributes.indexOf(key) !== -1
})
this.DAO.prototype.Model = this this.DAO.prototype.Model = this
this._hasDefaultValues = !Utils._.isEmpty(this._defaultValues) this._hasDefaultValues = !Utils._.isEmpty(this._defaultValues)
......
...@@ -115,12 +115,12 @@ module.exports = (function() { ...@@ -115,12 +115,12 @@ module.exports = (function() {
} else { } else {
// Postgres will treat tables as case-insensitive, so fix the case // Postgres will treat tables as case-insensitive, so fix the case
// of the returned values to match attributes // of the returned values to match attributes
if(this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) { if (this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) {
var attrsMap = Utils._.reduce(this.callee.attributes, function(m, v, k) { m[k.toLowerCase()] = k; return m}, {}) var attrsMap = Utils._.reduce(this.callee.attributes, function(m, v, k) { m[k.toLowerCase()] = k; return m}, {})
rows.forEach(function(row) { rows.forEach(function(row) {
Utils._.keys(row).forEach(function(key) { Utils._.keys(row).forEach(function(key) {
var targetAttr = attrsMap[key] var targetAttr = attrsMap[key]
if(targetAttr != key) { if (targetAttr != key) {
row[targetAttr] = row[key] row[targetAttr] = row[key]
delete row[key] delete row[key]
} }
...@@ -128,12 +128,24 @@ module.exports = (function() { ...@@ -128,12 +128,24 @@ module.exports = (function() {
}) })
} }
// Parse hstore fields if the model has any hstore fields.
// This cannot be done in the 'pg' lib because hstore is a UDT.
if (!!this.callee && !!this.callee._hasHstoreAttributes) {
rows.forEach(function(row) {
Utils._.keys(row).forEach(function(key) {
if (self.callee._isHstoreAttribute(key)) {
row[key] = hstore.parse(row[key])
}
})
})
}
this.emit('success', this.send('handleSelectQuery', rows)) this.emit('success', this.send('handleSelectQuery', rows))
} }
} else if (this.send('isShowOrDescribeQuery')) { } else if (this.send('isShowOrDescribeQuery')) {
this.emit('success', results) this.emit('success', results)
} else if (this.send('isInsertQuery')) { } else if (this.send('isInsertQuery')) {
if(this.callee !== null) { // may happen for bulk inserts if (this.callee !== null) { // may happen for bulk inserts
for (var key in rows[0]) { for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key)) { if (rows[0].hasOwnProperty(key)) {
var record = rows[0][key] var record = rows[0][key]
...@@ -148,7 +160,7 @@ module.exports = (function() { ...@@ -148,7 +160,7 @@ module.exports = (function() {
} else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(this.options.type) !== -1) { } else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(this.options.type) !== -1) {
this.emit('success', result.rowCount) this.emit('success', result.rowCount)
} else if (this.send('isUpdateQuery')) { } else if (this.send('isUpdateQuery')) {
if(this.callee !== null) { // may happen for bulk updates if (this.callee !== null) { // may happen for bulk updates
for (var key in rows[0]) { for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key)) { if (rows[0].hasOwnProperty(key)) {
var record = rows[0][key] var record = rows[0][key]
......
...@@ -254,9 +254,7 @@ if (dialect.match(/^postgres/)) { ...@@ -254,9 +254,7 @@ if (dialect.match(/^postgres/)) {
}) })
}) })
it("should handle hstore correctly", function(done) { it("should save hstore correctly", function(done) {
var self = this
this.User this.User
.create({ username: 'user', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}}) .create({ username: 'user', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}})
.success(function(newUser) { .success(function(newUser) {
...@@ -273,6 +271,45 @@ if (dialect.match(/^postgres/)) { ...@@ -273,6 +271,45 @@ if (dialect.match(/^postgres/)) {
}) })
.error(console.log) .error(console.log)
}) })
it("should read hstore correctly", function(done) {
var self = this
var data = { username: 'user', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}}
this.User
.create(data)
.success(function() {
// Check that the hstore fields are the same when retrieving the user
self.User.find({ where: { username: 'user' }})
.success(function(user) {
expect(user.settings).to.deep.equal(data.settings)
done()
})
})
.error(console.log)
})
it("should read hstore correctly from multiple rows", function(done) {
var self = this
self.User
.create({ username: 'user1', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}})
.then(function() {
return self.User.create({ username: 'user2', email: ['foo2@bar.com'], settings: { updated: { another: '"example"' }}})
})
.then(function() {
// Check that the hstore fields are the same when retrieving the user
return self.User.findAll({ order: 'username' })
})
.then(function(users) {
expect(users[0].settings).to.deep.equal({ created: { test: '"value"' }})
expect(users[1].settings).to.deep.equal({ updated: { another: '"example"' }})
done()
})
.error(console.log)
})
}) })
describe('[POSTGRES] Unquoted identifiers', function() { describe('[POSTGRES] Unquoted identifiers', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!