query.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. var Utils = require("../../utils")
  2. , AbstractQuery = require('../abstract/query')
  3. , QueryTypes = require('../../query-types')
  4. module.exports = (function() {
  5. var Query = function(database, sequelize, callee, options) {
  6. this.database = database
  7. this.sequelize = sequelize
  8. this.callee = callee
  9. this.options = Utils._.extend({
  10. logging: console.log,
  11. plain: false,
  12. raw: false
  13. }, options || {})
  14. this.checkLoggingOption()
  15. }
  16. Utils.inherit(Query, AbstractQuery)
  17. Query.prototype.getInsertIdField = function() {
  18. return 'lastID'
  19. }
  20. Query.prototype.run = function(sql) {
  21. var self = this
  22. this.sql = sql
  23. if (this.options.logging !== false) {
  24. this.options.logging('Executing (' + this.options.uuid + '): ' + this.sql)
  25. }
  26. var columnTypes = {}
  27. this.database.serialize(function() {
  28. var executeSql = function() {
  29. if (self.sql.indexOf('-- ') === 0) {
  30. // the sql query starts with a comment. don't bother the server with that ...
  31. Utils.tick(function() {
  32. self.emit('sql', self.sql)
  33. self.emit('success', null)
  34. })
  35. } else {
  36. self.database[getDatabaseMethod.call(self)](self.sql, function(err, results) {
  37. // allow clients to listen to sql to do their own logging or whatnot
  38. self.emit('sql', self.sql)
  39. if (err) {
  40. err.sql = self.sql
  41. onFailure.call(self, err)
  42. } else {
  43. this.columnTypes = columnTypes
  44. onSuccess.call(self, results, this)
  45. }
  46. })
  47. }
  48. }
  49. if ((getDatabaseMethod.call(self) === 'all')) {
  50. var tableNames = []
  51. if (self.options && self.options.tableNames) {
  52. tableNames = self.options.tableNames
  53. } else if (/FROM `(.*?)`/i.exec(self.sql)) {
  54. tableNames.push(/FROM `(.*?)`/i.exec(self.sql)[1])
  55. }
  56. if (!tableNames.length) {
  57. executeSql()
  58. } else {
  59. var execute = Utils._.after(tableNames.length, executeSql)
  60. tableNames.forEach(function (tableName) {
  61. if (tableName !== 'sqlite_master') {
  62. // get the column types
  63. self.database.all("PRAGMA table_info(" + tableName + ")", function(err, results) {
  64. if (!err) {
  65. for (var i=0, l=results.length; i<l; i++) {
  66. columnTypes[tableName + '.' + results[i].name] = columnTypes[results[i].name] = results[i].type
  67. }
  68. }
  69. execute()
  70. });
  71. } else {
  72. execute()
  73. }
  74. })
  75. }
  76. } else {
  77. executeSql()
  78. }
  79. })
  80. return this
  81. }
  82. //private
  83. var getDatabaseMethod = function() {
  84. if (this.send('isInsertQuery') || this.send('isUpdateQuery') || (this.sql.toLowerCase().indexOf('CREATE TEMPORARY TABLE'.toLowerCase()) !== -1) || this.options.type === QueryTypes.BULKDELETE) {
  85. return 'run'
  86. } else {
  87. return 'all'
  88. }
  89. }
  90. var onSuccess = function(results, metaData) {
  91. var result = this.callee
  92. // add the inserted row id to the instance
  93. if (this.send('isInsertQuery', results, metaData)) {
  94. this.send('handleInsertQuery', results, metaData)
  95. }
  96. if (this.sql.indexOf('sqlite_master') !== -1) {
  97. result = results.map(function(resultSet) { return resultSet.name })
  98. } else if (this.send('isSelectQuery')) {
  99. if(!this.options.raw) {
  100. results = results.map(function(result) {
  101. for (var name in result) {
  102. if (result.hasOwnProperty(name) && metaData.columnTypes[name]) {
  103. if (metaData.columnTypes[name] === 'DATETIME') {
  104. // we need to convert the timestamps into actual date objects
  105. var val = result[name]
  106. if (val !== null) {
  107. result[name] = new Date(val+'Z') // Z means UTC
  108. }
  109. } else if (metaData.columnTypes[name].lastIndexOf('BLOB') !== -1) {
  110. if (result[name]) {
  111. result[name] = new Buffer(result[name])
  112. }
  113. }
  114. }
  115. }
  116. return result
  117. })
  118. }
  119. result = this.send('handleSelectQuery', results)
  120. } else if (this.send('isShowOrDescribeQuery')) {
  121. result = results
  122. } else if (this.sql.indexOf('PRAGMA INDEX_LIST') !== -1) {
  123. // this is the sqlite way of getting the indexes of a table
  124. result = results.map(function(result) {
  125. return {
  126. name: result.name,
  127. tableName: result.name.split('_')[0],
  128. unique: (result.unique === 0)
  129. }
  130. })
  131. } else if (this.sql.indexOf('PRAGMA TABLE_INFO') !== -1) {
  132. // this is the sqlite way of getting the metadata of a table
  133. result = {}
  134. results.forEach(function(_result) {
  135. result[_result.name] = {
  136. type: _result.type,
  137. allowNull: (_result.notnull === 0),
  138. defaultValue: _result.dflt_value
  139. }
  140. if (result[_result.name].type === 'TINYINT(1)') {
  141. result[_result.name].defaultValue = { '0': false, '1': true }[result[_result.name].defaultValue]
  142. }
  143. if (result[_result.name].defaultValue === undefined) {
  144. result[_result.name].defaultValue = null
  145. }
  146. if (typeof result[_result.name].defaultValue === 'string') {
  147. result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, "")
  148. }
  149. })
  150. } else if (this.sql.indexOf('PRAGMA foreign_keys;') !== -1) {
  151. result = results[0]
  152. } else if (this.sql.indexOf('PRAGMA foreign_keys') !== -1) {
  153. result = results
  154. } else if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].indexOf(this.options.type) !== -1) {
  155. result = metaData.changes
  156. }
  157. this.emit('success', result)
  158. }
  159. var onFailure = function(err) {
  160. this.emit('error', err, this.callee)
  161. }
  162. return Query
  163. })()