query.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. var Utils = require("../../utils")
  2. , AbstractQuery = require('../abstract/query')
  3. , DataTypes = require('../../data-types')
  4. , hstore = require('./hstore')
  5. , QueryTypes = require('../../query-types')
  6. module.exports = (function() {
  7. var Query = function(client, sequelize, callee, options) {
  8. this.client = client
  9. this.sequelize = sequelize
  10. this.callee = callee
  11. this.options = Utils._.extend({
  12. logging: console.log,
  13. plain: false,
  14. raw: false
  15. }, options || {})
  16. this.checkLoggingOption()
  17. }
  18. Utils.inherit(Query, AbstractQuery)
  19. Query.prototype.run = function(sql) {
  20. this.sql = sql
  21. var self = this
  22. , receivedError = false
  23. , query = this.client.query(sql)
  24. , rows = []
  25. if (this.options.logging !== false) {
  26. this.options.logging('Executing (' + this.options.uuid + '): ' + this.sql)
  27. }
  28. query.on('row', function(row) {
  29. rows.push(row)
  30. })
  31. query.on('error', function(err) {
  32. receivedError = true
  33. err.sql = sql
  34. self.emit('sql', sql)
  35. self.emit('error', err, self.callee)
  36. })
  37. query.on('end', function(result) {
  38. self.emit('sql', self.sql)
  39. if (receivedError) {
  40. return
  41. }
  42. onSuccess.call(self, rows, sql, result)
  43. })
  44. return this
  45. }
  46. Query.prototype.getInsertIdField = function() {
  47. return 'id'
  48. }
  49. var onSuccess = function(rows, sql, result) {
  50. var results = rows
  51. , self = this
  52. , isTableNameQuery = (sql.indexOf('SELECT table_name FROM information_schema.tables') === 0)
  53. , isRelNameQuery = (sql.indexOf('SELECT relname FROM pg_class WHERE oid IN') === 0)
  54. if (isTableNameQuery || isRelNameQuery) {
  55. if (isRelNameQuery) {
  56. results = rows.map(function(row) {
  57. return {
  58. name: row.relname,
  59. tableName: row.relname.split('_')[0]
  60. }
  61. })
  62. } else {
  63. results = rows.map(function(row) { return Utils._.values(row) })
  64. }
  65. return this.emit('success', results)
  66. }
  67. if (this.send('isSelectQuery')) {
  68. if (this.sql.toLowerCase().indexOf('select c.column_name') === 0) {
  69. var result = {}
  70. rows.forEach(function(_result) {
  71. result[_result.Field] = {
  72. type: _result.Type.toUpperCase(),
  73. allowNull: (_result.Null === 'YES'),
  74. defaultValue: _result.Default,
  75. special: (!!_result.special ? self.sequelize.queryInterface.QueryGenerator.fromArray(_result.special) : [])
  76. }
  77. if (result[_result.Field].type === 'BOOLEAN') {
  78. result[_result.Field].defaultValue = { 'false': false, 'true': true }[result[_result.Field].defaultValue]
  79. if (result[_result.Field].defaultValue === undefined) {
  80. result[_result.Field].defaultValue = null
  81. }
  82. }
  83. if (typeof result[_result.Field].defaultValue === 'string') {
  84. result[_result.Field].defaultValue = result[_result.Field].defaultValue.replace(/'/g, "")
  85. if (result[_result.Field].defaultValue.indexOf('::') > -1) {
  86. var split = result[_result.Field].defaultValue.split('::')
  87. if (split[1].toLowerCase() !== "regclass)") {
  88. result[_result.Field].defaultValue = split[0]
  89. }
  90. }
  91. }
  92. })
  93. this.emit('success', result)
  94. } else {
  95. // Postgres will treat tables as case-insensitive, so fix the case
  96. // of the returned values to match attributes
  97. if(this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) {
  98. var attrsMap = Utils._.reduce(this.callee.attributes, function(m, v, k) { m[k.toLowerCase()] = k; return m}, {})
  99. rows.forEach(function(row) {
  100. Utils._.keys(row).forEach(function(key) {
  101. var targetAttr = attrsMap[key]
  102. if(targetAttr != key) {
  103. row[targetAttr] = row[key]
  104. delete row[key]
  105. }
  106. })
  107. })
  108. }
  109. this.emit('success', this.send('handleSelectQuery', rows))
  110. }
  111. } else if (this.send('isShowOrDescribeQuery')) {
  112. this.emit('success', results)
  113. } else if (this.send('isInsertQuery')) {
  114. if(this.callee !== null) { // may happen for bulk inserts
  115. for (var key in rows[0]) {
  116. if (rows[0].hasOwnProperty(key)) {
  117. var record = rows[0][key]
  118. 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) {
  119. record = hstore.parse(record)
  120. }
  121. this.callee.dataValues[key] = record
  122. }
  123. }
  124. }
  125. this.emit('success', this.callee)
  126. } else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(this.options.type) !== -1) {
  127. this.emit('success', result.rowCount)
  128. } else if (this.send('isUpdateQuery')) {
  129. if(this.callee !== null) { // may happen for bulk updates
  130. for (var key in rows[0]) {
  131. if (rows[0].hasOwnProperty(key)) {
  132. var record = rows[0][key]
  133. 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) {
  134. record = hstore.parse(record)
  135. }
  136. this.callee.dataValues[key] = record
  137. }
  138. }
  139. }
  140. this.emit('success', this.callee)
  141. } else {
  142. this.emit('success', results)
  143. }
  144. }
  145. return Query
  146. })()