123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- var Utils = require("../../utils")
- , AbstractQuery = require('../abstract/query')
- module.exports = (function() {
- var Query = function(client, sequelize, callee, options) {
- this.client = client
- this.callee = callee
- this.sequelize = sequelize
- 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
- if (this.options.logging !== false) {
- this.options.logging('Executing (' + this.options.uuid + '): ' + this.sql)
- }
- var resultSet = [],
- errorDetected = false,
- alreadyEnded = false, // This is needed because CALL queries emit 'end' twice...
- self = this
- this.client.query(this.sql)
- .on('result', function(results) {
- results
- .on('row', function(row, metadata) {
- var type
- for (var prop in row) {
- if (row.hasOwnProperty(prop)) {
- if (row[prop] === null) {
- continue
- }
- type = metadata.types[prop]
- switch (type) {
- case "TINYINT":
- case "SMALLINT":
- case "INTEGER":
- case "MEDIUMINT":
- case "BIGINT":
- case "YEAR":
- row[prop] = parseInt(row[prop], 10)
- break
- case "DECIMAL":
- case "FLOAT":
- case "DOUBLE":
- row[prop] = parseFloat(row[prop])
- break
- case "DATE":
- case "TIMESTAMP":
- case "DATETIME":
- row[prop] = new Date(row[prop] + 'Z')
- break
- case "BIT":
- case "BLOB":
- case "TINYBLOB":
- case "MEDIUMBLOB":
- case "LONGBLOB":
- if (metadata.charsetNrs[prop] === 63) { // binary
- row[prop] = new Buffer(row[prop])
- }
- break
- case "TIME":
- case "CHAR":
- case "VARCHAR":
- case "SET":
- case "ENUM":
- case "GEOMETRY":
- case "NULL":
- break
- default:
- // blank
- }
- }
- }
- resultSet.push(row)
- })
- .on('error', function(err) {
- errorDetected = true
- self.emit('sql', self.sql)
- err.sql = sql
- self.emit('error', err, self.callee)
- })
- .on('end', function(info) {
- if (alreadyEnded || errorDetected) {
- return
- }
- alreadyEnded = true
- self.emit('sql', self.sql)
- // we need to figure out whether to send the result set
- // or info depending upon the type of query
- if (/^call/.test(self.sql.toLowerCase())) {
- self.emit('success', resultSet)
- } else if( /^show/.test(self.sql.toLowerCase()) ||
- /^select/.test(self.sql.toLowerCase()) ||
- /^describe/.test(self.sql.toLowerCase())) {
- self.emit('success', self.formatResults(resultSet))
- } else {
- self.emit('success', self.formatResults(info))
- }
- })
- })
- .on('error', function(err) {
- if (errorDetected) {
- return
- }
- errorDetected = true
- self.emit('sql', self.sql)
- self.emit('error', err, self.callee)
- })
- .setMaxListeners(100)
- return this
- }
- return Query
- })()
|