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 })()