1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003 |
- var Utils = require(__dirname + '/utils')
- , DataTypes = require(__dirname + '/data-types')
- , SQLiteQueryInterface = require(__dirname + '/dialects/sqlite/query-interface')
- , Transaction = require(__dirname + '/transaction')
- , QueryTypes = require('./query-types')
- module.exports = (function() {
- var QueryInterface = function(sequelize) {
- this.sequelize = sequelize
- this.QueryGenerator = require('./dialects/' + this.sequelize.options.dialect + '/query-generator')
- this.QueryGenerator.options = this.sequelize.options
- this.QueryGenerator._dialect = this.sequelize.dialect
- this.QueryGenerator.sequelize = this.sequelize
- }
- Utils.addEventEmitter(QueryInterface)
- QueryInterface.prototype.createSchema = function(schema) {
- var sql = this.QueryGenerator.createSchema(schema)
- return queryAndEmit.call(this, sql, 'createSchema')
- }
- QueryInterface.prototype.dropSchema = function(schema) {
- var sql = this.QueryGenerator.dropSchema(schema)
- return queryAndEmit.call(this, sql, 'dropSchema')
- }
- QueryInterface.prototype.dropAllSchemas = function() {
- var self = this
- return new Utils.CustomEventEmitter(function(emitter) {
- var chainer = new Utils.QueryChainer()
- self.showAllSchemas().success(function(schemaNames) {
- schemaNames.forEach(function(schemaName) {
- chainer.add(self.dropSchema(schemaName))
- })
- chainer
- .run()
- .success(function() {
- self.emit('dropAllSchemas', null)
- emitter.emit('success', null)
- })
- .error(function(err) {
- self.emit('dropAllSchemas', err)
- emitter.emit('error', err)
- })
- }).error(function(err) {
- self.emit('dropAllSchemas', err)
- emitter.emit('error', err)
- })
- }).run()
- }
- QueryInterface.prototype.showAllSchemas = function(options) {
- var self = this
- options = Utils._.extend({
- transaction: null,
- raw: true
- }, options || {})
- return new Utils.CustomEventEmitter(function(emitter) {
- var showSchemasSql = self.QueryGenerator.showSchemasQuery()
- self.sequelize.query(showSchemasSql, null, options).success(function(schemaNames) {
- self.emit('showAllSchemas', null)
- emitter.emit('success', Utils._.flatten(Utils._.map(schemaNames, function(value){ return (!!value.schema_name ? value.schema_name : value) })))
- }).error(function(err) {
- self.emit('showAllSchemas', err)
- emitter.emit('error', err)
- })
- }).run()
- }
- QueryInterface.prototype.createTable = function(tableName, attributes, options) {
- var attributeHashes = {}
- , dataTypeValues = Utils._.values(DataTypes)
- , keys = Object.keys(attributes)
- , keyLen = keys.length
- , self = this
- , sql = ''
- , i = 0
- for (i = 0; i < keyLen; i++) {
- if (dataTypeValues.indexOf(attributes[keys[i]]) > -1) {
- attributeHashes[keys[i]] = { type: attributes[keys[i]], allowNull: true }
- } else {
- attributeHashes[keys[i]] = attributes[keys[i]]
- }
- }
- options = Utils._.extend({
- logging: this.sequelize.options.logging
- }, options || {})
- return new Utils.CustomEventEmitter(function(emitter) {
- // Postgres requires a special SQL command for enums
- if (self.sequelize.options.dialect === "postgres") {
- var chainer = new Utils.QueryChainer()
- // For backwards-compatibility, public schemas don't need to
- // explicitly state their schema when creating a new enum type
- , getTableName = (!options || !options.schema || options.schema === "public" ? '' : options.schema + '_') + tableName
- for (i = 0; i < keyLen; i++) {
- if (attributes[keys[i]].toString().match(/^ENUM\(/) || attributes[keys[i]].toString() === "ENUM" || (attributes[keys[i]].type && attributes[keys[i]].type.toString() === "ENUM")) {
- sql = self.QueryGenerator.pgListEnums(getTableName, keys[i], options)
- chainer.add(self.sequelize.query(sql, null, { plain: true, raw: true, type: QueryTypes.SELECT, logging: options.logging }))
- }
- }
- chainer.runSerially().success(function(results) {
- var chainer2 = new Utils.QueryChainer()
- // Find the table that we're trying to create throgh DAOFactoryManager
- , daoTable = self.sequelize.daoFactoryManager.daos.filter(function(dao) { return dao.tableName === tableName })
- , enumIdx = 0
- daoTable = daoTable.length > 0 ? daoTable[0] : null
- for (i = 0; i < keyLen; i++) {
- if (attributes[keys[i]].toString().match(/^ENUM\(/) || attributes[keys[i]].toString() === "ENUM" || (attributes[keys[i]].type && attributes[keys[i]].type.toString() === "ENUM")) {
- // If the enum type doesn't exist then create it
- if (!results[enumIdx]) {
- sql = self.QueryGenerator.pgEnum(getTableName, keys[i], attributes[keys[i]], options)
- chainer2.add(self.sequelize.query(sql, null, { raw: true, logging: options.logging }))
- } else if (!!results[enumIdx] && !!daoTable) {
- var enumVals = self.QueryGenerator.fromArray(results[enumIdx].enum_value)
- , vals = daoTable.rawAttributes[keys[i]].values
- vals.forEach(function(value, idx) {
- // reset out after/before options since it's for every enum value
- options.before = null
- options.after = null
- if (enumVals.indexOf(value) === -1) {
- if (!!vals[idx+1]) {
- options.before = vals[idx+1]
- }
- else if (!!vals[idx-1]) {
- options.after = vals[idx-1]
- }
- chainer2.add(self.sequelize.query(self.QueryGenerator.pgEnumAdd(getTableName, keys[i], value, options)))
- }
- })
- enumIdx++
- }
- }
- }
- attributes = self.QueryGenerator.attributesToSQL(attributeHashes)
- sql = self.QueryGenerator.createTableQuery(tableName, attributes, options)
- chainer2.run().success(function() {
- queryAndEmit
- .call(self, sql, 'createTable', options)
- .success(function(res) {
- self.emit('createTable', null)
- emitter.emit('success', res)
- })
- .error(function(err) {
- self.emit('createTable', err)
- emitter.emit('error', err)
- })
- .on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }).error(function(err) {
- emitter.emit('error', err)
- }).on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- })
- } else {
- attributes = self.QueryGenerator.attributesToSQL(attributeHashes)
- sql = self.QueryGenerator.createTableQuery(tableName, attributes, options)
- queryAndEmit.call(self, sql, 'createTable', options).success(function(results) {
- self.emit('createTable', null)
- emitter.emit('success', results)
- }).error(function(err) {
- self.emit('createTable', err)
- emitter.emit('error', err)
- }).on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }
- }).run()
- }
- QueryInterface.prototype.dropTable = function(tableName, options) {
- // if we're forcing we should be cascading unless explicitly stated otherwise
- options = options || {}
- options.cascade = options.cascade || options.force || false
- var sql = this.QueryGenerator.dropTableQuery(tableName, options)
- , self = this
- return new Utils.CustomEventEmitter(function(emitter) {
- var chainer = new Utils.QueryChainer()
- chainer.add(self, 'queryAndEmit', [sql, 'dropTable'], options)
- // Since postgres has a special case for enums, we should drop the related
- // enum type within the table and attribute
- if (self.sequelize.options.dialect === "postgres") {
- // Find the table that we're trying to drop
- daoTable = self.sequelize.daoFactoryManager.daos.filter(function(dao) {
- return dao.tableName === tableName
- })
- // Just in case if we're trying to drop a non-existing table
- daoTable = daoTable.length > 0 ? daoTable[0] : null
- if (!!daoTable) {
- var getTableName = (!options || !options.schema || options.schema === "public" ? '' : options.schema + '_') + tableName
- var keys = Object.keys(daoTable.rawAttributes)
- , keyLen = keys.length
- , i = 0
- for (i = 0; i < keyLen; i++) {
- if (daoTable.rawAttributes[keys[i]].type && daoTable.rawAttributes[keys[i]].type.toString() === "ENUM") {
- chainer.add(self.sequelize, 'query', [self.QueryGenerator.pgEnumDrop(getTableName, keys[i]), null, {logging: options.logging, raw: true}])
- }
- }
- }
- }
- chainer.runSerially().success(function(results) {
- emitter.emit('success', results[0])
- self.emit('dropTable', null)
- }).error(function(err) {
- emitter.emit('error', err)
- self.emit('dropTable', err)
- }).on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }).run()
- }
- QueryInterface.prototype.dropAllTables = function(options) {
- var self = this
- if (!options) {
- options = {}
- }
- var skip = options.skip || [];
- if (this.sequelize.options.dialect === 'sqlite') {
- // sqlite needs some special treatment as it cannot drop a column
- return SQLiteQueryInterface.dropAllTables.call(this, options)
- } else {
- return new Utils.CustomEventEmitter(function(dropAllTablesEmitter) {
- var events = []
- , chainer = new Utils.QueryChainer()
- , onError = function(err) {
- self.emit('dropAllTables', err)
- dropAllTablesEmitter.emit('error', err)
- }
- self.showAllTables().success(function(tableNames) {
- self.getForeignKeysForTables(tableNames).success(function(foreignKeys) {
- // add the foreign key removal query to the chainer
- Object.keys(foreignKeys).forEach(function(tableName) {
- foreignKeys[tableName].forEach(function(foreignKey) {
- var sql = self.QueryGenerator.dropForeignKeyQuery(tableName, foreignKey)
- chainer.add(self.sequelize, 'query', [ sql ])
- })
- })
- // add the table removal query to the chainer
- tableNames.forEach(function(tableName) {
- // if tableName is not in the Array of tables names then dont drop it
- if (skip.indexOf(tableName) === -1) {
- chainer.add(self, 'dropTable', [ tableName, { cascade: true } ])
- }
- })
- chainer
- .runSerially()
- .success(function() {
- self.emit('dropAllTables', null)
- dropAllTablesEmitter.emit('success', null)
- })
- .error(onError)
- }).error(onError)
- }).error(onError)
- }).run()
- }
- }
- QueryInterface.prototype.dropAllEnums = function(options) {
- if (this.sequelize.getDialect() !== 'postgres') {
- return new Utils.CustomEventEmitter(function (emitter) {
- emitter.emit('success')
- }).run()
- }
- options = options || {}
- var self = this
- , emitter = new Utils.CustomEventEmitter()
- , chainer = new Utils.QueryChainer()
- , sql = this.QueryGenerator.pgListEnums()
- this.sequelize.query(sql, null, { plain: false, raw: true, type: QueryTypes.SELECT, logging: options.logging })
- .proxy(emitter, {events: ['sql', 'error']})
- .success(function (results) {
- results.forEach(function (result) {
- chainer.add(self.sequelize.query(
- self.QueryGenerator.pgEnumDrop(null, null, result.enum_name),
- null,
- {logging: options.logging, raw: true}
- ))
- })
- chainer.run().proxy(emitter)
- })
- return emitter
- }
- QueryInterface.prototype.renameTable = function(before, after) {
- var sql = this.QueryGenerator.renameTableQuery(before, after)
- return queryAndEmit.call(this, sql, 'renameTable')
- }
- QueryInterface.prototype.showAllTables = function(options) {
- var self = this
- options = Utils._.extend({
- transaction: null,
- raw: true
- }, options || {})
- return new Utils.CustomEventEmitter(function(emitter) {
- var showTablesSql = self.QueryGenerator.showTablesQuery()
- self.sequelize.query(showTablesSql, null, options).success(function(tableNames) {
- self.emit('showAllTables', null)
- emitter.emit('success', Utils._.flatten(tableNames))
- }).error(function(err) {
- self.emit('showAllTables', err)
- emitter.emit('error', err)
- })
- }).run()
- }
- QueryInterface.prototype.describeTable = function(tableName, options) {
- var self = this
- , schema = null
- , schemaDelimiter = null
- if (typeof options === "string") {
- schema = options
- }
- else if (typeof options === "object") {
- schema = options.schema || null
- schemaDelimiter = options.schemaDelimiter || null
- }
- return new Utils.CustomEventEmitter(function(emitter) {
- var sql;
- if (self.QueryGenerator.describeTableQuery) {
- sql = self.QueryGenerator.describeTableQuery(tableName, schema, schemaDelimiter)
- } else {
- var table = self.QueryGenerator.quoteIdentifier(self.QueryGenerator.addSchema({tableName: tableName, options: {schema: schema, schemaDelimiter: schemaDelimiter}}), self.QueryGenerator.options.quoteIdentifiers)
- sql = 'DESCRIBE ' + table + ';'
- }
- self.sequelize.query(sql, null, { raw: true }).success(function(data) {
- if(Utils._.isEmpty(data)) {
- // If no data is returned from the query, then the table name may be wrong.
- // Query generators that use information_schema for retrieving table info will just return an empty result set,
- // it will not throw an error like built-ins do (e.g. DESCRIBE on MySql).
- emitter.emit('error', 'No description found for "' + tableName + '" table. Check the table name and schema; remember, they _are_ case sensitive.')
- } else {
- emitter.emit('success', data)
- }
- }).error(function(err) {
- emitter.emit('error', err)
- }).on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }).run()
- }
- QueryInterface.prototype.addColumn = function(tableName, attributeName, dataTypeOrOptions) {
- var attributes = {}
- if (Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1) {
- attributes[attributeName] = { type: dataTypeOrOptions, allowNull: true }
- } else {
- attributes[attributeName] = dataTypeOrOptions
- }
- var options = this.QueryGenerator.attributesToSQL(attributes)
- , sql = this.QueryGenerator.addColumnQuery(tableName, options)
- return queryAndEmit.call(this, sql, 'addColumn')
- }
- QueryInterface.prototype.removeColumn = function(tableName, attributeName) {
- if (this.sequelize.options.dialect === 'sqlite') {
- // sqlite needs some special treatment as it cannot drop a column
- return new Utils.CustomEventEmitter(function(emitter) {
- SQLiteQueryInterface.removeColumn.call(this, tableName, attributeName, emitter, queryAndEmit)
- }.bind(this)).run()
- } else {
- var sql = this.QueryGenerator.removeColumnQuery(tableName, attributeName)
- return queryAndEmit.call(this, sql, 'removeColumn')
- }
- }
- QueryInterface.prototype.changeColumn = function(tableName, attributeName, dataTypeOrOptions) {
- var attributes = {}
- if (Utils._.values(DataTypes).indexOf(dataTypeOrOptions) > -1) {
- attributes[attributeName] = { type: dataTypeOrOptions, allowNull: true }
- } else {
- attributes[attributeName] = dataTypeOrOptions
- }
- if (this.sequelize.options.dialect === 'sqlite') {
- // sqlite needs some special treatment as it cannot change a column
- return new Utils.CustomEventEmitter(function(emitter) {
- SQLiteQueryInterface.changeColumn.call(this, tableName, attributes, emitter, queryAndEmit)
- }.bind(this)).run()
- } else {
- var options = this.QueryGenerator.attributesToSQL(attributes)
- , sql = this.QueryGenerator.changeColumnQuery(tableName, options)
- return queryAndEmit.call(this, sql, 'changeColumn')
- }
- }
- QueryInterface.prototype.renameColumn = function(tableName, attrNameBefore, attrNameAfter) {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.describeTable(tableName).success(function(data) {
- data = data[attrNameBefore] || {}
- var options = {}
- options[attrNameAfter] = {
- attribute: attrNameAfter,
- type: data.type,
- allowNull: data.allowNull,
- defaultValue: data.defaultValue
- }
- if (this.sequelize.options.dialect === 'sqlite') {
- // sqlite needs some special treatment as it cannot rename a column
- SQLiteQueryInterface.renameColumn.call(this, tableName, attrNameBefore, attrNameAfter, emitter, queryAndEmit)
- } else {
- var sql = this.QueryGenerator.renameColumnQuery(tableName,
- attrNameBefore,
- this.QueryGenerator.attributesToSQL(options)
- )
- queryAndEmit.call(this, sql, 'renameColumn', {}, emitter)
- }
- }.bind(this))
- .error(function(err) {
- this.emit('renameColumn', err)
- emitter.emit('error', err)
- }.bind(this))
- }.bind(this)).run()
- }
- QueryInterface.prototype.addIndex = function(tableName, attributes, options) {
- var sql = this.QueryGenerator.addIndexQuery(tableName, attributes, options)
- return queryAndEmit.call(this, sql, 'addIndex')
- }
- QueryInterface.prototype.showIndex = function(tableName, options) {
- var sql = this.QueryGenerator.showIndexQuery(tableName, options)
- return queryAndEmit.call(this, sql, 'showIndex')
- }
- QueryInterface.prototype.getForeignKeysForTables = function(tableNames) {
- var self = this
- return new Utils.CustomEventEmitter(function(emitter) {
- if (tableNames.length === 0) {
- emitter.emit('success', {})
- } else {
- var chainer = new Utils.QueryChainer()
- tableNames.forEach(function(tableName) {
- var sql = self.QueryGenerator.getForeignKeysQuery(tableName, self.sequelize.config.database)
- chainer.add(self.sequelize, 'query', [sql])
- })
- chainer.runSerially().proxy(emitter, {
- skipEvents: ['success']
- }).success(function(results) {
- var result = {}
- tableNames.forEach(function(tableName, i) {
- result[tableName] = Utils._.compact(results[i]).map(function(r) { return r.constraint_name })
- })
- emitter.emit('success', result)
- })
- }
- }).run()
- }
- QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes) {
- var sql = this.QueryGenerator.removeIndexQuery(tableName, indexNameOrAttributes)
- return queryAndEmit.call(this, sql, "removeIndex")
- }
- QueryInterface.prototype.insert = function(dao, tableName, values, options) {
- var sql = this.QueryGenerator.insertQuery(tableName, values, dao.daoFactory.rawAttributes)
- return queryAndEmit.call(this, [sql, dao, options], 'insert', {
- success: function(obj) { obj.isNewRecord = false }
- })
- }
- QueryInterface.prototype.bulkInsert = function(tableName, records, options) {
- var sql = this.QueryGenerator.bulkInsertQuery(tableName, records, options)
- return queryAndEmit.call(this, [sql, null, options], 'bulkInsert')
- }
- QueryInterface.prototype.update = function(dao, tableName, values, identifier, options) {
- var self = this
- , restrict = false
- , sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options, dao.daoFactory.rawAttributes)
- // Check for a restrict field
- if (!!dao.daoFactory && !!dao.daoFactory.associations) {
- var keys = Object.keys(dao.daoFactory.associations)
- , length = keys.length
- for (var i = 0; i < length; i++) {
- if (dao.daoFactory.associations[keys[i]].options && dao.daoFactory.associations[keys[i]].options.onUpdate && dao.daoFactory.associations[keys[i]].options.onUpdate === "restrict") {
- restrict = true
- }
- }
- }
- return new Utils.CustomEventEmitter(function(emitter) {
- var chainer = new Utils.QueryChainer()
- chainer.add(self, 'queryAndEmit', [[sql, dao, options], 'delete'])
- chainer.runSerially()
- .success(function(results){
- emitter.query = { sql: sql }
- emitter.emit('success', results[0])
- emitter.emit('sql', sql)
- })
- .error(function(err) {
- emitter.query = { sql: sql }
- emitter.emit('error', err)
- emitter.emit('sql', sql)
- })
- .on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }).run()
- }
- QueryInterface.prototype.bulkUpdate = function(tableName, values, identifier, options) {
- var self = this
- , sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options)
- return new Utils.CustomEventEmitter(function(emitter) {
- var chainer = new Utils.QueryChainer()
- chainer.add(self, 'queryAndEmit', [[sql, null, options], 'bulkUpdate'])
- return chainer.runSerially()
- .success(function(results){
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('success', results[0])
- })
- .error(function(err) {
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('error', err)
- })
- }).run()
- }
- QueryInterface.prototype.delete = function(dao, tableName, identifier, options) {
- var self = this
- , restrict = false
- , cascades = []
- , sql = self.QueryGenerator.deleteQuery(tableName, identifier, null, dao.daoFactory)
- // Check for a restrict field
- if (!!dao.daoFactory && !!dao.daoFactory.associations) {
- var keys = Object.keys(dao.daoFactory.associations)
- , length = keys.length
- for (var i = 0; i < length; i++) {
- if (dao.daoFactory.associations[keys[i]].options && dao.daoFactory.associations[keys[i]].options.onDelete) {
- if (dao.daoFactory.associations[keys[i]].options.onDelete === "restrict") {
- restrict = true
- }
- else if (dao.daoFactory.associations[keys[i]].options.onDelete === "cascade" && dao.daoFactory.associations[keys[i]].options.useHooks === true) {
- cascades[cascades.length] = dao.daoFactory.associations[keys[i]].accessors.get
- }
- }
- }
- }
- return new Utils.CustomEventEmitter(function(emitter) {
- var tick = 0
- var iterate = function(err, i) {
- if (!!err || i >= cascades.length) {
- return run(err)
- }
- dao[cascades[i]]().success(function(tasks) {
- if (tasks === null || tasks.length < 1) {
- return run()
- }
- tasks = Array.isArray(tasks) ? tasks : [tasks]
- var ii = 0
- var next = function(err, ii) {
- if (!!err || ii >= tasks.length) {
- return iterate(err)
- }
- tasks[ii].destroy().error(function(err) {
- return iterate(err)
- })
- .success(function() {
- ii++
- if (ii >= tasks.length) {
- tick++
- return iterate(null, tick)
- }
- next(null, ii)
- })
- }
- next(null, ii)
- })
- }
- var run = function(err) {
- if (!!err) {
- return emitter.emit('error', err)
- }
- var chainer = new Utils.QueryChainer()
- chainer.add(self, 'queryAndEmit', [[sql, dao, options], 'delete'])
- chainer.runSerially()
- .success(function(results){
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('success', results[1])
- })
- .error(function(err) {
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('error', err)
- })
- }
- if (cascades.length > 0) {
- iterate(null, tick)
- } else {
- run()
- }
- }).run()
- }
- QueryInterface.prototype.bulkDelete = function(tableName, identifier, options) {
- var self = this
- var sql = self.QueryGenerator.deleteQuery(tableName, identifier, Utils._.defaults(options || {}, {limit: null}))
- return new Utils.CustomEventEmitter(function(emitter) {
- var chainer = new Utils.QueryChainer()
- chainer.add(self, 'queryAndEmit', [[sql, null, options], 'bulkDelete', options])
- chainer.runSerially()
- .success(function(results){
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('success', results[0])
- })
- .error(function(err) {
- emitter.query = { sql: sql }
- emitter.emit('sql', sql)
- emitter.emit('error', err)
- })
- }).run()
- }
- QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) {
- options = options || {}
- // See if we need to merge options and factory.scopeObj
- // we're doing this on the QueryInterface level because it's a bridge between
- // sequelize and the databases
- if (Object.keys(factory.scopeObj).length > 0) {
- if (!!options) {
- Utils.injectScope.call(factory, options, true)
- }
- var scopeObj = buildScope.call(factory)
- Object.keys(scopeObj).forEach(function(method) {
- if (typeof scopeObj[method] === "number" || !Utils._.isEmpty(scopeObj[method])) {
- options[method] = scopeObj[method]
- }
- })
- }
- var sql = this.QueryGenerator.selectQuery(tableName, options, factory)
- queryOptions = Utils._.extend({}, queryOptions, {
- include: options.include,
- includeNames: options.includeNames,
- includeMap: options.includeMap,
- hasSingleAssociation: options.hasSingleAssociation,
- hasMultiAssociation: options.hasMultiAssociation
- })
- return queryAndEmit.call(this, [sql, factory, queryOptions], 'select')
- }
- QueryInterface.prototype.increment = function(dao, tableName, values, identifier, options) {
- var sql = this.QueryGenerator.incrementQuery(tableName, values, identifier, options.attributes)
- return queryAndEmit.call(this, [sql, dao, options], 'increment')
- }
- QueryInterface.prototype.rawSelect = function(tableName, options, attributeSelector) {
- var self = this
- if (attributeSelector === undefined) {
- throw new Error('Please pass an attribute selector!')
- }
- return new Utils.CustomEventEmitter(function(emitter) {
- var sql = self.QueryGenerator.selectQuery(tableName, options)
- , queryOptions = Utils._.extend({ transaction: options.transaction }, { plain: true, raw: true, type: QueryTypes.SELECT })
- , query = self.sequelize.query(sql, null, queryOptions)
- query
- .success(function(data) {
- var result = data ? data[attributeSelector] : null
- if (options && options.dataType) {
- var dataType = options.dataType;
- if (dataType instanceof DataTypes.DECIMAL || dataType instanceof DataTypes.FLOAT) {
- result = parseFloat(result);
- } else if (dataType === DataTypes.INTEGER || dataType instanceof DataTypes.BIGINT) {
- result = parseInt(result, 10);
- } else if (dataType === DataTypes.DATE) {
- result = new Date(result + 'Z');
- } else if (dataType === DataTypes.STRING) {
- // Nothing to do, result is already a string.
- }
- }
- self.emit('rawSelect', null)
- emitter.emit('success', result)
- })
- .error(function(err) {
- self.emit('rawSelect', err)
- emitter.emit('error', err)
- })
- .on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }).run()
- }
- QueryInterface.prototype.createTrigger = function(tableName, triggerName, timingType, fireOnArray,
- functionName, functionParams, optionsArray) {
- var sql = this.QueryGenerator.createTrigger(tableName, triggerName, timingType, fireOnArray, functionName
- , functionParams, optionsArray)
- if (sql){
- return queryAndEmit.call(this, sql, 'createTrigger')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('createTrigger', null)
- emitter.emit('success')
- }).run()
- }
- }
- QueryInterface.prototype.dropTrigger = function(tableName, triggerName) {
- var sql = this.QueryGenerator.dropTrigger(tableName, triggerName)
- if (sql){
- return queryAndEmit.call(this, sql, 'dropTrigger')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('dropTrigger', null)
- emitter.emit('success')
- }).run()
- }
- }
- QueryInterface.prototype.renameTrigger = function(tableName, oldTriggerName, newTriggerName) {
- var sql = this.QueryGenerator.renameTrigger(tableName, oldTriggerName, newTriggerName)
- if (sql){
- return queryAndEmit.call(this, sql, 'renameTrigger')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('renameTrigger', null)
- emitter.emit('success')
- }).run()
- }
- }
- QueryInterface.prototype.createFunction = function(functionName, params, returnType, language, body, options) {
- var sql = this.QueryGenerator.createFunction(functionName, params, returnType, language, body, options)
- if (sql){
- return queryAndEmit.call(this, sql, 'createFunction')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('createFunction', null)
- emitter.emit('success')
- }).run()
- }
- }
- QueryInterface.prototype.dropFunction = function(functionName, params) {
- var sql = this.QueryGenerator.dropFunction(functionName, params)
- if (sql){
- return queryAndEmit.call(this, sql, 'dropFunction')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('dropFunction', null)
- emitter.emit('success')
- }).run()
- }
- }
- QueryInterface.prototype.renameFunction = function(oldFunctionName, params, newFunctionName) {
- var sql = this.QueryGenerator.renameFunction(oldFunctionName, params, newFunctionName)
- if (sql){
- return queryAndEmit.call(this, sql, 'renameFunction')
- } else {
- return new Utils.CustomEventEmitter(function(emitter) {
- this.emit('renameFunction', null)
- emitter.emit('success')
- }).run()
- }
- }
- // Helper methods useful for querying
- /**
- * Escape an identifier (e.g. a table or attribute name). If force is true,
- * the identifier will be quoted even if the `quoteIdentifiers` option is
- * false.
- */
- QueryInterface.prototype.quoteIdentifier = function(identifier, force) {
- return this.QueryGenerator.quoteIdentifier(identifier, force)
- }
- /**
- * Split an identifier into .-separated tokens and quote each part.
- * If force is true, the identifier will be quoted even if the
- * `quoteIdentifiers` option is false.
- */
- QueryInterface.prototype.quoteIdentifiers = function(identifiers, force) {
- return this.QueryGenerator.quoteIdentifiers(identifiers, force)
- }
- /**
- * Escape a value (e.g. a string, number or date)
- */
- QueryInterface.prototype.escape = function(value) {
- return this.QueryGenerator.escape(value)
- }
- QueryInterface.prototype.setAutocommit = function(transaction, value) {
- if (!transaction || !(transaction instanceof Transaction)) {
- throw new Error('Unable to set autocommit for a transaction without transaction object!')
- }
- var sql = this.QueryGenerator.setAutocommitQuery(value)
- return this.queryAndEmit([sql, null, { transaction: transaction }], 'setAutocommit')
- }
- QueryInterface.prototype.setIsolationLevel = function(transaction, value) {
- if (!transaction || !(transaction instanceof Transaction)) {
- throw new Error('Unable to set isolation level for a transaction without transaction object!')
- }
- var sql = this.QueryGenerator.setIsolationLevelQuery(value)
- return this.queryAndEmit([sql, null, { transaction: transaction }], 'setIsolationLevel')
- }
- QueryInterface.prototype.startTransaction = function(transaction, options) {
- if (!transaction || !(transaction instanceof Transaction)) {
- throw new Error('Unable to start a transaction without transaction object!')
- }
- options = Utils._.extend({
- transaction: transaction
- }, options || {})
- var sql = this.QueryGenerator.startTransactionQuery(options)
- return this.queryAndEmit([sql, null, options], 'startTransaction')
- }
- QueryInterface.prototype.commitTransaction = function(transaction, options) {
- if (!transaction || !(transaction instanceof Transaction)) {
- throw new Error('Unable to commit a transaction without transaction object!')
- }
- options = Utils._.extend({
- transaction: transaction
- }, options || {})
- var sql = this.QueryGenerator.commitTransactionQuery(options)
- return this.queryAndEmit([sql, null, options], 'commitTransaction')
- }
- QueryInterface.prototype.rollbackTransaction = function(transaction, options) {
- if (!transaction || !(transaction instanceof Transaction)) {
- throw new Error('Unable to rollback a transaction without transaction object!')
- }
- options = Utils._.extend({
- transaction: transaction
- }, options || {})
- var sql = this.QueryGenerator.rollbackTransactionQuery(options)
- return this.queryAndEmit([sql, null, options], 'rollbackTransaction')
- }
- // private
- var buildScope = function() {
- var smart
- // Use smartWhere to convert several {where} objects into a single where object
- smart = Utils.smartWhere(this.scopeObj.where || [], this.daoFactoryManager.sequelize.options.dialect)
- smart = Utils.compileSmartWhere.call(this, smart, this.daoFactoryManager.sequelize.options.dialect)
- return {limit: this.scopeObj.limit || null, offset: this.scopeObj.offset || null, where: smart, order: (this.scopeObj.order || []).join(', ')}
- }
- var queryAndEmit = QueryInterface.prototype.queryAndEmit = function(sqlOrQueryParams, methodName, options, emitter) {
- options = Utils._.extend({
- success: function(){},
- error: function(){},
- transaction: null,
- logging: this.sequelize.options.logging
- }, options || {})
- var execQuery = function(emitter) {
- if (Array.isArray(sqlOrQueryParams)) {
- if (sqlOrQueryParams.length === 1) {
- sqlOrQueryParams.push(null)
- }
- if (sqlOrQueryParams.length === 2) {
- sqlOrQueryParams.push(typeof options === "object" ? options : {})
- }
- emitter.query = this.sequelize.query.apply(this.sequelize, sqlOrQueryParams)
- } else {
- emitter.query = this.sequelize.query(sqlOrQueryParams, null, options)
- }
- emitter
- .query
- .success(function(obj) {
- if (options.success) {
- options.success(obj)
- }
- this.emit(methodName, null)
- emitter.emit('success', obj)
- }.bind(this))
- .error(function(err) {
- if (options.error) {
- options.error(err)
- }
- this.emit(methodName, err)
- emitter.emit('error', err)
- }.bind(this))
- .on('sql', function(sql) {
- emitter.emit('sql', sql)
- })
- }.bind(this)
- if (!!emitter) {
- execQuery(emitter)
- } else {
- return new Utils.CustomEventEmitter(execQuery).run()
- }
- }
- return QueryInterface
- })()
|