lib/dialects/postgres/query.js
var Utils = require("../../utils")
, AbstractQuery = require('../abstract/query')
, DataTypes = require('../../data-types')
, hstore = require('./hstore')
, QueryTypes = require('../../query-types')
module.exports = (function() {
var Query = function(client, sequelize, callee, options) {
this.client = client
this.sequelize = sequelize
this.callee = callee
this.options = Utils._.extend({
logging: console.log,
plain: false,
raw: false
}, options || {})
this.checkLoggingOption()
}
Utils.inherit(Query, AbstractQuery)
Query.prototype.run = function(sql) {
this.sql = sql
var self = this
, receivedError = false
, query = this.client.query(sql)
, rows = []
if (this.options.logging !== false) {
this.options.logging('Executing (' + this.options.uuid + '): ' + this.sql)
}
query.on('row', function(row) {
rows.push(row)
})
query.on('error', function(err) {
receivedError = true
err.sql = sql
self.emit('sql', sql)
self.emit('error', err, self.callee)
})
query.on('end', function(result) {
self.emit('sql', self.sql)
if (receivedError) {
return
}
onSuccess.call(self, rows, sql, result)
})
return this
}
Query.prototype.getInsertIdField = function() {
return 'id'
}
var onSuccess = function(rows, sql, result) {
var results = rows
, self = this
, isTableNameQuery = (sql.indexOf('SELECT table_name FROM information_schema.tables') === 0)
, isRelNameQuery = (sql.indexOf('SELECT relname FROM pg_class WHERE oid IN') === 0)
if (isTableNameQuery || isRelNameQuery) {
if (isRelNameQuery) {
results = rows.map(function(row) {
return {
name: row.relname,
tableName: row.relname.split('_')[0]
}
})
} else {
results = rows.map(function(row) { return Utils._.values(row) })
}
return this.emit('success', results)
}
if (this.send('isSelectQuery')) {
if (this.sql.toLowerCase().indexOf('select c.column_name') === 0) {
var result = {}
rows.forEach(function(_result) {
result[_result.Field] = {
type: _result.Type.toUpperCase(),
allowNull: (_result.Null === 'YES'),
defaultValue: _result.Default,
special: (!!_result.special ? self.sequelize.queryInterface.QueryGenerator.fromArray(_result.special) : [])
}
if (result[_result.Field].type === 'BOOLEAN') {
result[_result.Field].defaultValue = { 'false': false, 'true': true }[result[_result.Field].defaultValue]
if (result[_result.Field].defaultValue === undefined) {
result[_result.Field].defaultValue = null
}
}
if (typeof result[_result.Field].defaultValue === 'string') {
result[_result.Field].defaultValue = result[_result.Field].defaultValue.replace(/'/g, "")
if (result[_result.Field].defaultValue.indexOf('::') > -1) {
var split = result[_result.Field].defaultValue.split('::')
if (split[1].toLowerCase() !== "regclass)") {
result[_result.Field].defaultValue = split[0]
}
}
}
})
this.emit('success', result)
} else {
// Postgres will treat tables as case-insensitive, so fix the case
// of the returned values to match attributes
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}, {})
rows.forEach(function(row) {
Utils._.keys(row).forEach(function(key) {
var targetAttr = attrsMap[key]
if(targetAttr != key) {
row[targetAttr] = row[key]
delete row[key]
}
})
})
}
this.emit('success', this.send('handleSelectQuery', rows))
}
} else if (this.send('isShowOrDescribeQuery')) {
this.emit('success', results)
} else if (this.send('isInsertQuery')) {
if(this.callee !== null) { // may happen for bulk inserts
for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key)) {
var record = rows[0][key]
if (!!this.callee.daoFactory && !!this.callee.daoFactory.rawAttributes && !!this.callee.daoFactory.rawAttributes[key] && !!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
record = hstore.parse(record)
}
this.callee.dataValues[key] = record
}
}
}
this.emit('success', this.callee)
} else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(this.options.type) !== -1) {
this.emit('success', result.rowCount)
} else if (this.send('isUpdateQuery')) {
if(this.callee !== null) { // may happen for bulk updates
for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key)) {
var record = rows[0][key]
if (!!this.callee.daoFactory && !!this.callee.daoFactory.rawAttributes && !!this.callee.daoFactory.rawAttributes[key] && !!this.callee.daoFactory.rawAttributes[key].type && !!this.callee.daoFactory.rawAttributes[key].type.type && this.callee.daoFactory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
record = hstore.parse(record)
}
this.callee.dataValues[key] = record
}
}
}
this.emit('success', this.callee)
} else {
this.emit('success', results)
}
}
return Query
})()