{ "version": 3, "sources": ["../../../src/dialects/sqlite/query-interface.js"], "sourcesContent": ["'use strict';\n\nconst sequelizeErrors = require('../../errors');\nconst QueryTypes = require('../../query-types');\nconst { QueryInterface } = require('../abstract/query-interface');\nconst { cloneDeep } = require('../../utils');\nconst _ = require('lodash');\n\n/**\n * The interface that Sequelize uses to talk with SQLite database\n */\nclass SQLiteQueryInterface extends QueryInterface {\n /**\n * A wrapper that fixes SQLite's inability to remove columns from existing tables.\n * It will create a backup of the table, drop the table afterwards and create a\n * new table with the same name but without the obsolete column.\n *\n * @override\n */\n async removeColumn(tableName, attributeName, options) {\n options = options || {};\n\n const fields = await this.describeTable(tableName, options);\n delete fields[attributeName];\n\n const sql = this.queryGenerator.removeColumnQuery(tableName, fields);\n const subQueries = sql.split(';').filter(q => q !== '');\n\n for (const subQuery of subQueries) await this.sequelize.query(`${subQuery};`, { raw: true, ...options });\n }\n\n /**\n * A wrapper that fixes SQLite's inability to change columns from existing tables.\n * It will create a backup of the table, drop the table afterwards and create a\n * new table with the same name but with a modified version of the respective column.\n *\n * @override\n */\n async changeColumn(tableName, attributeName, dataTypeOrOptions, options) {\n options = options || {};\n\n const fields = await this.describeTable(tableName, options);\n Object.assign(fields[attributeName], this.normalizeAttribute(dataTypeOrOptions));\n\n const sql = this.queryGenerator.removeColumnQuery(tableName, fields);\n const subQueries = sql.split(';').filter(q => q !== '');\n\n for (const subQuery of subQueries) await this.sequelize.query(`${subQuery};`, { raw: true, ...options });\n }\n\n /**\n * A wrapper that fixes SQLite's inability to rename columns from existing tables.\n * It will create a backup of the table, drop the table afterwards and create a\n * new table with the same name but with a renamed version of the respective column.\n *\n * @override\n */\n async renameColumn(tableName, attrNameBefore, attrNameAfter, options) {\n options = options || {};\n const fields = await this.assertTableHasColumn(tableName, attrNameBefore, options);\n\n fields[attrNameAfter] = { ...fields[attrNameBefore] };\n delete fields[attrNameBefore];\n\n const sql = this.queryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields);\n const subQueries = sql.split(';').filter(q => q !== '');\n\n for (const subQuery of subQueries) await this.sequelize.query(`${subQuery};`, { raw: true, ...options });\n }\n\n /**\n * @override\n */\n async removeConstraint(tableName, constraintName, options) {\n let createTableSql;\n\n const constraints = await this.showConstraint(tableName, constraintName);\n // sqlite can't show only one constraint, so we find here the one to remove\n const constraint = constraints.find(constaint => constaint.constraintName === constraintName);\n\n if (!constraint) {\n throw new sequelizeErrors.UnknownConstraintError({\n message: `Constraint ${constraintName} on table ${tableName} does not exist`,\n constraint: constraintName,\n table: tableName\n });\n }\n createTableSql = constraint.sql;\n constraint.constraintName = this.queryGenerator.quoteIdentifier(constraint.constraintName);\n let constraintSnippet = `, CONSTRAINT ${constraint.constraintName} ${constraint.constraintType} ${constraint.constraintCondition}`;\n\n if (constraint.constraintType === 'FOREIGN KEY') {\n const referenceTableName = this.queryGenerator.quoteTable(constraint.referenceTableName);\n constraint.referenceTableKeys = constraint.referenceTableKeys.map(columnName => this.queryGenerator.quoteIdentifier(columnName));\n const referenceTableKeys = constraint.referenceTableKeys.join(', ');\n constraintSnippet += ` REFERENCES ${referenceTableName} (${referenceTableKeys})`;\n constraintSnippet += ` ON UPDATE ${constraint.updateAction}`;\n constraintSnippet += ` ON DELETE ${constraint.deleteAction}`;\n }\n\n createTableSql = createTableSql.replace(constraintSnippet, '');\n createTableSql += ';';\n\n const fields = await this.describeTable(tableName, options);\n\n const sql = this.queryGenerator._alterConstraintQuery(tableName, fields, createTableSql);\n const subQueries = sql.split(';').filter(q => q !== '');\n\n for (const subQuery of subQueries) await this.sequelize.query(`${subQuery};`, { raw: true, ...options });\n }\n\n /**\n * @override\n */\n async addConstraint(tableName, options) {\n if (!options.fields) {\n throw new Error('Fields must be specified through options.fields');\n }\n\n if (!options.type) {\n throw new Error('Constraint type must be specified through options.type');\n }\n\n options = cloneDeep(options);\n\n const constraintSnippet = this.queryGenerator.getConstraintSnippet(tableName, options);\n const describeCreateTableSql = this.queryGenerator.describeCreateTableQuery(tableName);\n\n const constraints = await this.sequelize.query(describeCreateTableSql, { ...options, type: QueryTypes.SELECT, raw: true });\n let sql = constraints[0].sql;\n const index = sql.length - 1;\n //Replace ending ')' with constraint snippet - Simulates String.replaceAt\n //http://stackoverflow.com/questions/1431094\n const createTableSql = `${sql.substr(0, index)}, ${constraintSnippet})${sql.substr(index + 1)};`;\n\n const fields = await this.describeTable(tableName, options);\n sql = this.queryGenerator._alterConstraintQuery(tableName, fields, createTableSql);\n const subQueries = sql.split(';').filter(q => q !== '');\n\n for (const subQuery of subQueries) await this.sequelize.query(`${subQuery};`, { raw: true, ...options });\n }\n\n /**\n * @override\n */\n async getForeignKeyReferencesForTable(tableName, options) {\n const database = this.sequelize.config.database;\n const query = this.queryGenerator.getForeignKeysQuery(tableName, database);\n const result = await this.sequelize.query(query, options);\n return result.map(row => ({\n tableName,\n columnName: row.from,\n referencedTableName: row.table,\n referencedColumnName: row.to,\n tableCatalog: database,\n referencedTableCatalog: database\n }));\n }\n\n /**\n * @override\n */\n async dropAllTables(options) {\n options = options || {};\n const skip = options.skip || [];\n\n const tableNames = await this.showAllTables(options);\n await this.sequelize.query('PRAGMA foreign_keys = OFF', options);\n await this._dropAllTables(tableNames, skip, options);\n await this.sequelize.query('PRAGMA foreign_keys = ON', options);\n }\n\n /**\n * @override\n */\n async describeTable(tableName, options) {\n let schema = null;\n let schemaDelimiter = null;\n\n if (typeof options === 'string') {\n schema = options;\n } else if (typeof options === 'object' && options !== null) {\n schema = options.schema || null;\n schemaDelimiter = options.schemaDelimiter || null;\n }\n\n if (typeof tableName === 'object' && tableName !== null) {\n schema = tableName.schema;\n tableName = tableName.tableName;\n }\n\n const sql = this.queryGenerator.describeTableQuery(tableName, schema, schemaDelimiter);\n options = { ...options, type: QueryTypes.DESCRIBE };\n const sqlIndexes = this.queryGenerator.showIndexesQuery(tableName);\n\n try {\n const data = await this.sequelize.query(sql, options);\n /*\n * If no data is returned from the query, then the table name may be wrong.\n * Query generators that use information_schema for retrieving table info will just return an empty result set,\n * it will not throw an error like built-ins do (e.g. DESCRIBE on MySql).\n */\n if (_.isEmpty(data)) {\n throw new Error(`No description found for \"${tableName}\" table. Check the table name and schema; remember, they _are_ case sensitive.`);\n }\n\n const indexes = await this.sequelize.query(sqlIndexes, options);\n for (const prop in data) {\n data[prop].unique = false;\n }\n for (const index of indexes) {\n for (const field of index.fields) {\n if (index.unique !== undefined) {\n data[field.attribute].unique = index.unique;\n }\n }\n }\n\n const foreignKeys = await this.getForeignKeyReferencesForTable(tableName, options);\n for (const foreignKey of foreignKeys) {\n data[foreignKey.columnName].references = {\n model: foreignKey.referencedTableName,\n key: foreignKey.referencedColumnName\n };\n }\n\n return data;\n } catch (e) {\n if (e.original && e.original.code === 'ER_NO_SUCH_TABLE') {\n throw new Error(`No description found for \"${tableName}\" table. Check the table name and schema; remember, they _are_ case sensitive.`);\n }\n\n throw e;\n }\n }\n}\n\nexports.SQLiteQueryInterface = SQLiteQueryInterface;\n"], "mappings": "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", "names": [] }