template and back

This commit is contained in:
romantarkin committed 2025-01-29 15:09:27 +05:00
commit 07ef7e9b8f
3773 files changed
+422508

No files matched your search

@@ -0,0 +1,78 @@
"use strict";
const fs = require("fs");
const path = require("path");
const AbstractConnectionManager = require("../abstract/connection-manager");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("connection:sqlite");
const dataTypes = require("../../data-types").sqlite;
const sequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("sqlite");
const { promisify } = require("util");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
super(dialect, sequelize);
if (this.sequelize.options.host === "localhost") {
delete this.sequelize.options.host;
}
this.connections = {};
this.lib = this._loadDialectModule("sqlite3");
this.refreshTypeParser(dataTypes);
}
async _onProcessExit() {
await Promise.all(Object.getOwnPropertyNames(this.connections).map((connection) => promisify((callback) => this.connections[connection].close(callback))()));
return super._onProcessExit.call(this);
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async getConnection(options) {
options = options || {};
options.uuid = options.uuid || "default";
if (!!this.sequelize.options.storage !== null && this.sequelize.options.storage !== void 0) {
options.storage = this.sequelize.options.storage;
} else {
options.storage = this.sequelize.options.host || ":memory:";
}
options.inMemory = options.storage === ":memory:" ? 1 : 0;
const dialectOptions = this.sequelize.options.dialectOptions;
const defaultReadWriteMode = this.lib.OPEN_READWRITE | this.lib.OPEN_CREATE;
options.readWriteMode = dialectOptions && dialectOptions.mode || defaultReadWriteMode;
if (this.connections[options.inMemory || options.uuid]) {
return this.connections[options.inMemory || options.uuid];
}
if (!options.inMemory && (options.readWriteMode & this.lib.OPEN_CREATE) !== 0) {
fs.mkdirSync(path.dirname(options.storage), { recursive: true });
}
const connection = await new Promise((resolve, reject) => {
this.connections[options.inMemory || options.uuid] = new this.lib.Database(options.storage, options.readWriteMode, (err) => {
if (err)
return reject(new sequelizeErrors.ConnectionError(err));
debug(`connection acquired ${options.uuid}`);
resolve(this.connections[options.inMemory || options.uuid]);
});
});
if (this.sequelize.config.password) {
connection.run(`PRAGMA KEY=${this.sequelize.escape(this.sequelize.config.password)}`);
}
if (this.sequelize.options.foreignKeys !== false) {
connection.run("PRAGMA FOREIGN_KEYS=ON");
}
return connection;
}
releaseConnection(connection, force) {
if (connection.filename === ":memory:" && force !== true)
return;
if (connection.uuid) {
connection.close();
debug(`connection released ${connection.uuid}`);
delete this.connections[connection.uuid];
}
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/connection-manager.js"],
"sourcesContent": ["'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst AbstractConnectionManager = require('../abstract/connection-manager');\nconst { logger } = require('../../utils/logger');\nconst debug = logger.debugContext('connection:sqlite');\nconst dataTypes = require('../../data-types').sqlite;\nconst sequelizeErrors = require('../../errors');\nconst parserStore = require('../parserStore')('sqlite');\nconst { promisify } = require('util');\n\nclass ConnectionManager extends AbstractConnectionManager {\n constructor(dialect, sequelize) {\n super(dialect, sequelize);\n\n // We attempt to parse file location from a connection uri\n // but we shouldn't match sequelize default host.\n if (this.sequelize.options.host === 'localhost') {\n delete this.sequelize.options.host;\n }\n\n this.connections = {};\n this.lib = this._loadDialectModule('sqlite3');\n this.refreshTypeParser(dataTypes);\n }\n\n async _onProcessExit() {\n await Promise.all(\n Object.getOwnPropertyNames(this.connections)\n .map(connection => promisify(callback => this.connections[connection].close(callback))())\n );\n return super._onProcessExit.call(this);\n }\n\n // Expose this as a method so that the parsing may be updated when the user has added additional, custom types\n _refreshTypeParser(dataType) {\n parserStore.refresh(dataType);\n }\n\n _clearTypeParser() {\n parserStore.clear();\n }\n\n async getConnection(options) {\n options = options || {};\n options.uuid = options.uuid || 'default';\n\n if (!!this.sequelize.options.storage !== null && this.sequelize.options.storage !== undefined) {\n // Check explicitely for the storage option to not be set since an empty string signals\n // SQLite will create a temporary disk-based database in that case.\n options.storage = this.sequelize.options.storage;\n } else {\n options.storage = this.sequelize.options.host || ':memory:';\n }\n\n options.inMemory = options.storage === ':memory:' ? 1 : 0;\n\n const dialectOptions = this.sequelize.options.dialectOptions;\n const defaultReadWriteMode = this.lib.OPEN_READWRITE | this.lib.OPEN_CREATE;\n\n options.readWriteMode = dialectOptions && dialectOptions.mode || defaultReadWriteMode;\n\n if (this.connections[options.inMemory || options.uuid]) {\n return this.connections[options.inMemory || options.uuid];\n }\n\n if (!options.inMemory && (options.readWriteMode & this.lib.OPEN_CREATE) !== 0) {\n // automatic path provision for `options.storage`\n fs.mkdirSync(path.dirname(options.storage), { recursive: true });\n }\n\n const connection = await new Promise((resolve, reject) => {\n this.connections[options.inMemory || options.uuid] = new this.lib.Database(\n options.storage,\n options.readWriteMode,\n err => {\n if (err) return reject(new sequelizeErrors.ConnectionError(err));\n debug(`connection acquired ${options.uuid}`);\n resolve(this.connections[options.inMemory || options.uuid]);\n }\n );\n });\n\n if (this.sequelize.config.password) {\n // Make it possible to define and use password for sqlite encryption plugin like sqlcipher\n connection.run(`PRAGMA KEY=${this.sequelize.escape(this.sequelize.config.password)}`);\n }\n if (this.sequelize.options.foreignKeys !== false) {\n // Make it possible to define and use foreign key constraints unless\n // explicitly disallowed. It's still opt-in per relation\n connection.run('PRAGMA FOREIGN_KEYS=ON');\n }\n\n return connection;\n }\n\n releaseConnection(connection, force) {\n if (connection.filename === ':memory:' && force !== true) return;\n\n if (connection.uuid) {\n connection.close();\n debug(`connection released ${connection.uuid}`);\n delete this.connections[connection.uuid];\n }\n }\n}\n\nmodule.exports = ConnectionManager;\nmodule.exports.ConnectionManager = ConnectionManager;\nmodule.exports.default = ConnectionManager;\n"],
"mappings": ";AAEA,MAAM,KAAK,QAAQ;AACnB,MAAM,OAAO,QAAQ;AACrB,MAAM,4BAA4B,QAAQ;AAC1C,MAAM,EAAE,WAAW,QAAQ;AAC3B,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,kBAAkB,QAAQ;AAChC,MAAM,cAAc,QAAQ,kBAAkB;AAC9C,MAAM,EAAE,cAAc,QAAQ;AAE9B,gCAAgC,0BAA0B;AAAA,EACxD,YAAY,SAAS,WAAW;AAC9B,UAAM,SAAS;AAIf,QAAI,KAAK,UAAU,QAAQ,SAAS,aAAa;AAC/C,aAAO,KAAK,UAAU,QAAQ;AAAA;AAGhC,SAAK,cAAc;AACnB,SAAK,MAAM,KAAK,mBAAmB;AACnC,SAAK,kBAAkB;AAAA;AAAA,QAGnB,iBAAiB;AACrB,UAAM,QAAQ,IACZ,OAAO,oBAAoB,KAAK,aAC7B,IAAI,gBAAc,UAAU,cAAY,KAAK,YAAY,YAAY,MAAM;AAEhF,WAAO,MAAM,eAAe,KAAK;AAAA;AAAA,EAInC,mBAAmB,UAAU;AAC3B,gBAAY,QAAQ;AAAA;AAAA,EAGtB,mBAAmB;AACjB,gBAAY;AAAA;AAAA,QAGR,cAAc,SAAS;AAC3B,cAAU,WAAW;AACrB,YAAQ,OAAO,QAAQ,QAAQ;AAE/B,QAAI,CAAC,CAAC,KAAK,UAAU,QAAQ,YAAY,QAAQ,KAAK,UAAU,QAAQ,YAAY,QAAW;AAG7F,cAAQ,UAAU,KAAK,UAAU,QAAQ;AAAA,WACpC;AACL,cAAQ,UAAU,KAAK,UAAU,QAAQ,QAAQ;AAAA;AAGnD,YAAQ,WAAW,QAAQ,YAAY,aAAa,IAAI;AAExD,UAAM,iBAAiB,KAAK,UAAU,QAAQ;AAC9C,UAAM,uBAAuB,KAAK,IAAI,iBAAiB,KAAK,IAAI;AAEhE,YAAQ,gBAAgB,kBAAkB,eAAe,QAAQ;AAEjE,QAAI,KAAK,YAAY,QAAQ,YAAY,QAAQ,OAAO;AACtD,aAAO,KAAK,YAAY,QAAQ,YAAY,QAAQ;AAAA;AAGtD,QAAI,CAAC,QAAQ,YAAa,SAAQ,gBAAgB,KAAK,IAAI,iBAAiB,GAAG;AAE7E,SAAG,UAAU,KAAK,QAAQ,QAAQ,UAAU,EAAE,WAAW;AAAA;AAG3D,UAAM,aAAa,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACxD,WAAK,YAAY,QAAQ,YAAY,QAAQ,QAAQ,IAAI,KAAK,IAAI,SAChE,QAAQ,SACR,QAAQ,eACR,SAAO;AACL,YAAI;AAAK,iBAAO,OAAO,IAAI,gBAAgB,gBAAgB;AAC3D,cAAM,uBAAuB,QAAQ;AACrC,gBAAQ,KAAK,YAAY,QAAQ,YAAY,QAAQ;AAAA;AAAA;AAK3D,QAAI,KAAK,UAAU,OAAO,UAAU;AAElC,iBAAW,IAAI,cAAc,KAAK,UAAU,OAAO,KAAK,UAAU,OAAO;AAAA;AAE3E,QAAI,KAAK,UAAU,QAAQ,gBAAgB,OAAO;AAGhD,iBAAW,IAAI;AAAA;AAGjB,WAAO;AAAA;AAAA,EAGT,kBAAkB,YAAY,OAAO;AACnC,QAAI,WAAW,aAAa,cAAc,UAAU;AAAM;AAE1D,QAAI,WAAW,MAAM;AACnB,iBAAW;AACX,YAAM,uBAAuB,WAAW;AACxC,aAAO,KAAK,YAAY,WAAW;AAAA;AAAA;AAAA;AAKzC,OAAO,UAAU;AACjB,OAAO,QAAQ,oBAAoB;AACnC,OAAO,QAAQ,UAAU;",
"names": []
}
+180
View File
@@ -0,0 +1,180 @@
"use strict";
module.exports = (BaseTypes) => {
const warn = BaseTypes.ABSTRACT.warn.bind(void 0, "https://www.sqlite.org/datatype3.html");
function removeUnsupportedIntegerOptions(dataType) {
if (dataType._zerofill || dataType._unsigned) {
warn(`SQLite does not support '${dataType.key}' with UNSIGNED or ZEROFILL. Plain '${dataType.key}' will be used instead.`);
dataType._unsigned = void 0;
dataType._zerofill = void 0;
}
}
BaseTypes.DATE.types.sqlite = ["DATETIME"];
BaseTypes.STRING.types.sqlite = ["VARCHAR", "VARCHAR BINARY"];
BaseTypes.CHAR.types.sqlite = ["CHAR", "CHAR BINARY"];
BaseTypes.TEXT.types.sqlite = ["TEXT"];
BaseTypes.TINYINT.types.sqlite = ["TINYINT"];
BaseTypes.SMALLINT.types.sqlite = ["SMALLINT"];
BaseTypes.MEDIUMINT.types.sqlite = ["MEDIUMINT"];
BaseTypes.INTEGER.types.sqlite = ["INTEGER"];
BaseTypes.BIGINT.types.sqlite = ["BIGINT"];
BaseTypes.FLOAT.types.sqlite = ["FLOAT"];
BaseTypes.TIME.types.sqlite = ["TIME"];
BaseTypes.DATEONLY.types.sqlite = ["DATE"];
BaseTypes.BOOLEAN.types.sqlite = ["TINYINT"];
BaseTypes.BLOB.types.sqlite = ["TINYBLOB", "BLOB", "LONGBLOB"];
BaseTypes.DECIMAL.types.sqlite = ["DECIMAL"];
BaseTypes.UUID.types.sqlite = ["UUID"];
BaseTypes.ENUM.types.sqlite = false;
BaseTypes.REAL.types.sqlite = ["REAL"];
BaseTypes.DOUBLE.types.sqlite = ["DOUBLE PRECISION"];
BaseTypes.GEOMETRY.types.sqlite = false;
BaseTypes.JSON.types.sqlite = ["JSON", "JSONB"];
class JSONTYPE extends BaseTypes.JSON {
static parse(data) {
return JSON.parse(data);
}
}
class DATE extends BaseTypes.DATE {
static parse(date, options) {
if (!date.includes("+")) {
return new Date(date + options.timezone);
}
return new Date(date);
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(date) {
return date;
}
}
class STRING extends BaseTypes.STRING {
toSql() {
if (this._binary) {
return `VARCHAR BINARY(${this._length})`;
}
return super.toSql(this);
}
}
class TEXT extends BaseTypes.TEXT {
toSql() {
if (this._length) {
warn("SQLite does not support TEXT with options. Plain `TEXT` will be used instead.");
this._length = void 0;
}
return "TEXT";
}
}
class CITEXT extends BaseTypes.CITEXT {
toSql() {
return "TEXT COLLATE NOCASE";
}
}
class CHAR extends BaseTypes.CHAR {
toSql() {
if (this._binary) {
return `CHAR BINARY(${this._length})`;
}
return super.toSql();
}
}
class NUMBER extends BaseTypes.NUMBER {
toSql() {
let result = this.key;
if (this._unsigned) {
result += " UNSIGNED";
}
if (this._zerofill) {
result += " ZEROFILL";
}
if (this._length) {
result += `(${this._length}`;
if (typeof this._decimals === "number") {
result += `,${this._decimals}`;
}
result += ")";
}
return result;
}
}
class TINYINT extends BaseTypes.TINYINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class SMALLINT extends BaseTypes.SMALLINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class MEDIUMINT extends BaseTypes.MEDIUMINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class INTEGER extends BaseTypes.INTEGER {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class FLOAT extends BaseTypes.FLOAT {
}
class DOUBLE extends BaseTypes.DOUBLE {
}
class REAL extends BaseTypes.REAL {
}
function parseFloating(value) {
if (typeof value !== "string") {
return value;
}
if (value === "NaN") {
return NaN;
}
if (value === "Infinity") {
return Infinity;
}
if (value === "-Infinity") {
return -Infinity;
}
}
for (const floating of [FLOAT, DOUBLE, REAL]) {
floating.parse = parseFloating;
}
for (const num of [FLOAT, DOUBLE, REAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT]) {
num.prototype.toSql = NUMBER.prototype.toSql;
}
class ENUM extends BaseTypes.ENUM {
toSql() {
return "TEXT";
}
}
return {
DATE,
DATEONLY,
STRING,
CHAR,
NUMBER,
FLOAT,
REAL,
"DOUBLE PRECISION": DOUBLE,
TINYINT,
SMALLINT,
MEDIUMINT,
INTEGER,
BIGINT,
TEXT,
ENUM,
JSON: JSONTYPE,
CITEXT
};
};
//# sourceMappingURL=data-types.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/data-types.js"],
"sourcesContent": ["'use strict';\n\nmodule.exports = BaseTypes => {\n const warn = BaseTypes.ABSTRACT.warn.bind(undefined, 'https://www.sqlite.org/datatype3.html');\n\n /**\n * Removes unsupported SQLite options, i.e., UNSIGNED and ZEROFILL, for the integer data types.\n *\n * @param {object} dataType The base integer data type.\n * @private\n */\n function removeUnsupportedIntegerOptions(dataType) {\n if (dataType._zerofill || dataType._unsigned) {\n warn(`SQLite does not support '${dataType.key}' with UNSIGNED or ZEROFILL. Plain '${dataType.key}' will be used instead.`);\n dataType._unsigned = undefined;\n dataType._zerofill = undefined;\n }\n }\n\n /**\n * @see https://sqlite.org/datatype3.html\n */\n\n BaseTypes.DATE.types.sqlite = ['DATETIME'];\n BaseTypes.STRING.types.sqlite = ['VARCHAR', 'VARCHAR BINARY'];\n BaseTypes.CHAR.types.sqlite = ['CHAR', 'CHAR BINARY'];\n BaseTypes.TEXT.types.sqlite = ['TEXT'];\n BaseTypes.TINYINT.types.sqlite = ['TINYINT'];\n BaseTypes.SMALLINT.types.sqlite = ['SMALLINT'];\n BaseTypes.MEDIUMINT.types.sqlite = ['MEDIUMINT'];\n BaseTypes.INTEGER.types.sqlite = ['INTEGER'];\n BaseTypes.BIGINT.types.sqlite = ['BIGINT'];\n BaseTypes.FLOAT.types.sqlite = ['FLOAT'];\n BaseTypes.TIME.types.sqlite = ['TIME'];\n BaseTypes.DATEONLY.types.sqlite = ['DATE'];\n BaseTypes.BOOLEAN.types.sqlite = ['TINYINT'];\n BaseTypes.BLOB.types.sqlite = ['TINYBLOB', 'BLOB', 'LONGBLOB'];\n BaseTypes.DECIMAL.types.sqlite = ['DECIMAL'];\n BaseTypes.UUID.types.sqlite = ['UUID'];\n BaseTypes.ENUM.types.sqlite = false;\n BaseTypes.REAL.types.sqlite = ['REAL'];\n BaseTypes.DOUBLE.types.sqlite = ['DOUBLE PRECISION'];\n BaseTypes.GEOMETRY.types.sqlite = false;\n BaseTypes.JSON.types.sqlite = ['JSON', 'JSONB'];\n\n class JSONTYPE extends BaseTypes.JSON {\n static parse(data) {\n return JSON.parse(data);\n }\n }\n\n class DATE extends BaseTypes.DATE {\n static parse(date, options) {\n if (!date.includes('+')) {\n // For backwards compat. Dates inserted by sequelize < 2.0dev12 will not have a timestamp set\n return new Date(date + options.timezone);\n }\n return new Date(date); // We already have a timezone stored in the string\n }\n }\n\n class DATEONLY extends BaseTypes.DATEONLY {\n static parse(date) {\n return date;\n }\n }\n\n class STRING extends BaseTypes.STRING {\n toSql() {\n if (this._binary) {\n return `VARCHAR BINARY(${this._length})`;\n }\n return super.toSql(this);\n }\n }\n\n class TEXT extends BaseTypes.TEXT {\n toSql() {\n if (this._length) {\n warn('SQLite does not support TEXT with options. Plain `TEXT` will be used instead.');\n this._length = undefined;\n }\n return 'TEXT';\n }\n }\n\n class CITEXT extends BaseTypes.CITEXT {\n toSql() {\n return 'TEXT COLLATE NOCASE';\n }\n }\n\n class CHAR extends BaseTypes.CHAR {\n toSql() {\n if (this._binary) {\n return `CHAR BINARY(${this._length})`;\n }\n return super.toSql();\n }\n }\n\n class NUMBER extends BaseTypes.NUMBER {\n toSql() {\n let result = this.key;\n if (this._unsigned) {\n result += ' UNSIGNED';\n }\n if (this._zerofill) {\n result += ' ZEROFILL';\n }\n if (this._length) {\n result += `(${this._length}`;\n if (typeof this._decimals === 'number') {\n result += `,${this._decimals}`;\n }\n result += ')';\n }\n return result;\n }\n }\n\n class TINYINT extends BaseTypes.TINYINT {\n constructor(length) {\n super(length);\n removeUnsupportedIntegerOptions(this);\n }\n }\n\n class SMALLINT extends BaseTypes.SMALLINT {\n constructor(length) {\n super(length);\n removeUnsupportedIntegerOptions(this);\n }\n }\n\n class MEDIUMINT extends BaseTypes.MEDIUMINT {\n constructor(length) {\n super(length);\n removeUnsupportedIntegerOptions(this);\n }\n }\n\n class INTEGER extends BaseTypes.INTEGER {\n constructor(length) {\n super(length);\n removeUnsupportedIntegerOptions(this);\n }\n }\n\n class BIGINT extends BaseTypes.BIGINT {\n constructor(length) {\n super(length);\n removeUnsupportedIntegerOptions(this);\n }\n }\n\n class FLOAT extends BaseTypes.FLOAT {\n }\n\n class DOUBLE extends BaseTypes.DOUBLE {\n }\n\n class REAL extends BaseTypes.REAL { }\n\n function parseFloating(value) {\n if (typeof value !== 'string') {\n return value;\n }\n if (value === 'NaN') {\n return NaN;\n }\n if (value === 'Infinity') {\n return Infinity;\n }\n if (value === '-Infinity') {\n return -Infinity;\n }\n }\n for (const floating of [FLOAT, DOUBLE, REAL]) {\n floating.parse = parseFloating;\n }\n\n\n for (const num of [FLOAT, DOUBLE, REAL, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT]) {\n numLine truncated
"mappings": "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",
"names": []
}
+57
View File
@@ -0,0 +1,57 @@
"use strict";
const _ = require("lodash");
const AbstractDialect = require("../abstract");
const ConnectionManager = require("./connection-manager");
const Query = require("./query");
const QueryGenerator = require("./query-generator");
const DataTypes = require("../../data-types").sqlite;
const { SQLiteQueryInterface } = require("./query-interface");
class SqliteDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new SQLiteQueryInterface(sequelize, this.queryGenerator);
}
}
SqliteDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
DEFAULT: false,
"DEFAULT VALUES": true,
"UNION ALL": false,
"RIGHT JOIN": false,
inserts: {
ignoreDuplicates: " OR IGNORE",
updateOnDuplicate: " ON CONFLICT DO UPDATE SET",
conflictFields: true,
onConflictWhere: true
},
index: {
using: false,
where: true,
functionBased: true
},
transactionOptions: {
type: true
},
constraints: {
addConstraint: false,
dropConstraint: false
},
groupedLimit: false,
JSON: true
});
SqliteDialect.prototype.defaultVersion = "3.8.0";
SqliteDialect.prototype.Query = Query;
SqliteDialect.prototype.DataTypes = DataTypes;
SqliteDialect.prototype.name = "sqlite";
SqliteDialect.prototype.TICK_CHAR = "`";
SqliteDialect.prototype.TICK_CHAR_LEFT = SqliteDialect.prototype.TICK_CHAR;
SqliteDialect.prototype.TICK_CHAR_RIGHT = SqliteDialect.prototype.TICK_CHAR;
module.exports = SqliteDialect;
module.exports.SqliteDialect = SqliteDialect;
module.exports.default = SqliteDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/index.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst AbstractDialect = require('../abstract');\nconst ConnectionManager = require('./connection-manager');\nconst Query = require('./query');\nconst QueryGenerator = require('./query-generator');\nconst DataTypes = require('../../data-types').sqlite;\nconst { SQLiteQueryInterface } = require('./query-interface');\n\nclass SqliteDialect extends AbstractDialect {\n constructor(sequelize) {\n super();\n this.sequelize = sequelize;\n this.connectionManager = new ConnectionManager(this, sequelize);\n this.queryGenerator = new QueryGenerator({\n _dialect: this,\n sequelize\n });\n\n this.queryInterface = new SQLiteQueryInterface(\n sequelize,\n this.queryGenerator\n );\n }\n}\n\nSqliteDialect.prototype.supports = _.merge(\n _.cloneDeep(AbstractDialect.prototype.supports),\n {\n DEFAULT: false,\n 'DEFAULT VALUES': true,\n 'UNION ALL': false,\n 'RIGHT JOIN': false,\n inserts: {\n ignoreDuplicates: ' OR IGNORE',\n updateOnDuplicate: ' ON CONFLICT DO UPDATE SET',\n conflictFields: true,\n onConflictWhere: true\n },\n index: {\n using: false,\n where: true,\n functionBased: true\n },\n transactionOptions: {\n type: true\n },\n constraints: {\n addConstraint: false,\n dropConstraint: false\n },\n groupedLimit: false,\n JSON: true\n }\n);\n\nSqliteDialect.prototype.defaultVersion = '3.8.0'; // minimum supported version\nSqliteDialect.prototype.Query = Query;\nSqliteDialect.prototype.DataTypes = DataTypes;\nSqliteDialect.prototype.name = 'sqlite';\nSqliteDialect.prototype.TICK_CHAR = '`';\nSqliteDialect.prototype.TICK_CHAR_LEFT = SqliteDialect.prototype.TICK_CHAR;\nSqliteDialect.prototype.TICK_CHAR_RIGHT = SqliteDialect.prototype.TICK_CHAR;\n\nmodule.exports = SqliteDialect;\nmodule.exports.SqliteDialect = SqliteDialect;\nmodule.exports.default = SqliteDialect;\n"],
"mappings": ";AAEA,MAAM,IAAI,QAAQ;AAClB,MAAM,kBAAkB,QAAQ;AAChC,MAAM,oBAAoB,QAAQ;AAClC,MAAM,QAAQ,QAAQ;AACtB,MAAM,iBAAiB,QAAQ;AAC/B,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,EAAE,yBAAyB,QAAQ;AAEzC,4BAA4B,gBAAgB;AAAA,EAC1C,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAGF,SAAK,iBAAiB,IAAI,qBACxB,WACA,KAAK;AAAA;AAAA;AAKX,cAAc,UAAU,WAAW,EAAE,MACnC,EAAE,UAAU,gBAAgB,UAAU,WACtC;AAAA,EACE,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,IACP,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA;AAAA,EAEnB,OAAO;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,eAAe;AAAA;AAAA,EAEjB,oBAAoB;AAAA,IAClB,MAAM;AAAA;AAAA,EAER,aAAa;AAAA,IACX,eAAe;AAAA,IACf,gBAAgB;AAAA;AAAA,EAElB,cAAc;AAAA,EACd,MAAM;AAAA;AAIV,cAAc,UAAU,iBAAiB;AACzC,cAAc,UAAU,QAAQ;AAChC,cAAc,UAAU,YAAY;AACpC,cAAc,UAAU,OAAO;AAC/B,cAAc,UAAU,YAAY;AACpC,cAAc,UAAU,iBAAiB,cAAc,UAAU;AACjE,cAAc,UAAU,kBAAkB,cAAc,UAAU;AAElE,OAAO,UAAU;AACjB,OAAO,QAAQ,gBAAgB;AAC/B,OAAO,QAAQ,UAAU;",
"names": []
}
+362
View File
@@ -0,0 +1,362 @@
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const Utils = require("../../utils");
const Transaction = require("../../transaction");
const _ = require("lodash");
const MySqlQueryGenerator = require("../mysql/query-generator");
const AbstractQueryGenerator = require("../abstract/query-generator");
class SQLiteQueryGenerator extends MySqlQueryGenerator {
createSchema() {
return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
}
showSchemasQuery() {
return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
}
versionQuery() {
return "SELECT sqlite_version() as `version`";
}
createTableQuery(tableName, attributes, options) {
options = options || {};
const primaryKeys = [];
const needsMultiplePrimaryKeys = Object.values(attributes).filter((definition) => definition.includes("PRIMARY KEY")).length > 1;
const attrArray = [];
for (const attr in attributes) {
if (Object.prototype.hasOwnProperty.call(attributes, attr)) {
const dataType = attributes[attr];
const containsAutoIncrement = dataType.includes("AUTOINCREMENT");
let dataTypeString = dataType;
if (dataType.includes("PRIMARY KEY")) {
if (dataType.includes("INT")) {
dataTypeString = containsAutoIncrement ? "INTEGER PRIMARY KEY AUTOINCREMENT" : "INTEGER PRIMARY KEY";
if (dataType.includes(" REFERENCES")) {
dataTypeString += dataType.substr(dataType.indexOf(" REFERENCES"));
}
}
if (needsMultiplePrimaryKeys) {
primaryKeys.push(attr);
if (dataType.includes("NOT NULL")) {
dataTypeString = dataType.replace(" PRIMARY KEY", "");
} else {
dataTypeString = dataType.replace("PRIMARY KEY", "NOT NULL");
}
}
}
attrArray.push(`${this.quoteIdentifier(attr)} ${dataTypeString}`);
}
}
const table = this.quoteTable(tableName);
let attrStr = attrArray.join(", ");
const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
if (options.uniqueKeys) {
_.each(options.uniqueKeys, (columns) => {
if (columns.customIndex) {
attrStr += `, UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
});
}
if (pkString.length > 0) {
attrStr += `, PRIMARY KEY (${pkString})`;
}
const sql = `CREATE TABLE IF NOT EXISTS ${table} (${attrStr});`;
return this.replaceBooleanDefaults(sql);
}
booleanValue(value) {
return value ? 1 : 0;
}
_checkValidJsonStatement(stmt) {
if (typeof stmt !== "string") {
return false;
}
const jsonFunctionRegex = /^\s*(json(?:_[a-z]+){0,2})\([^)]*\)/i;
const tokenCaptureRegex = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i;
let currentIndex = 0;
let openingBrackets = 0;
let closingBrackets = 0;
let hasJsonFunction = false;
let hasInvalidToken = false;
while (currentIndex < stmt.length) {
const string = stmt.substr(currentIndex);
const functionMatches = jsonFunctionRegex.exec(string);
if (functionMatches) {
currentIndex += functionMatches[0].indexOf("(");
hasJsonFunction = true;
continue;
}
const tokenMatches = tokenCaptureRegex.exec(string);
if (tokenMatches) {
const capturedToken = tokenMatches[1];
if (capturedToken === "(") {
openingBrackets++;
} else if (capturedToken === ")") {
closingBrackets++;
} else if (capturedToken === ";") {
hasInvalidToken = true;
break;
}
currentIndex += tokenMatches[0].length;
continue;
}
break;
}
hasInvalidToken |= openingBrackets !== closingBrackets;
if (hasJsonFunction && hasInvalidToken) {
throw new Error(`Invalid json statement: ${stmt}`);
}
return hasJsonFunction;
}
_toJSONValue(value) {
if (value instanceof Date) {
return value.toISOString();
}
if (Array.isArray(value) && value[0] instanceof Date) {
return value.map((val) => val.toISOString());
}
return value;
}
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
if (smth instanceof Utils.Json) {
return super.handleSequelizeMethod(smth, tableName, factory, options, prepend);
}
if (smth instanceof Utils.Cast) {
if (/timestamp/i.test(smth.type)) {
smth.type = "datetime";
}
}
return AbstractQueryGenerator.prototype.handleSequelizeMethod.call(this, smth, tableName, factory, options, prepend);
}
addColumnQuery(table, key, dataType) {
const attributes = {};
attributes[key] = dataType;
const fields = this.attributesToSQL(attributes, { context: "addColumn" });
const attribute = `${this.quoteIdentifier(key)} ${fields[key]}`;
const sql = `ALTER TABLE ${this.quoteTable(table)} ADD ${attribute};`;
return this.replaceBooleanDefaults(sql);
}
showTablesQuery() {
return "SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';";
}
updateQuery(tableName, attrValueHash, where, options, attributes) {
options = options || {};
_.defaults(options, this.options);
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, options.omitNull, options);
const modelAttributeMap = {};
const values = [];
const bind = [];
const bindParam = options.bindParam || this.bindParam(bind);
if (attributes) {
_.each(attributes, (attribute, key) => {
modelAttributeMap[key] = attribute;
if (attribute.field) {
modelAttributeMap[attribute.field] = attribute;
}
});
}
for (const key in attrValueHash) {
const value = attrValueHash[key];
if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {
values.push(`${this.quoteIdentifier(key)}=${this.escape(value, modelAttributeMap && modelAttributeMap[key] || void 0, { context: "UPDATE" })}`);
} else {
values.push(`${this.quoteIdentifier(key)}=${this.format(value, modelAttributeMap && modelAttributeMap[key] || void 0, { context: "UPDATE" }, bindParam)}`);
}
}
let query;
const whereOptions = __spreadProps(__spreadValues({}, options), { bindParam });
if (options.limit) {
query = `UPDATE ${this.quoteTable(tableName)} SET ${values.join(",")} WHERE rowid IN (SELECT rowid FROM ${this.quoteTable(tableName)} ${this.whereQuery(where, whereOptions)} LIMIT ${this.escape(options.limit)})`;
} else {
query = `UPDATE ${this.quoteTable(tableName)} SET ${values.join(",")} ${this.whereQuery(where, whereOptions)}`;
}
return { query, bind };
}
truncateTableQuery(tableName, options = {}) {
return [
`DELETE FROM ${this.quoteTable(tableName)}`,
options.restartIdentity ? `; DELETE FROM ${this.quoteTable("sqlite_sequence")} WHERE ${this.quoteIdentifier("name")} = ${Utils.addTicks(Utils.removeTicks(this.quoteTable(tableName), "`"), "'")};` : ""
].join("");
}
deleteQuery(tableName, where, options = {}, model) {
_.defaults(options, this.options);
let whereClause = this.getWhereConditions(where, null, model, options);
if (whereClause) {
whereClause = `WHERE ${whereClause}`;
}
if (options.limit) {
whereClause = `WHERE rowid IN (SELECT rowid FROM ${this.quoteTable(tableName)} ${whereClause} LIMIT ${this.escape(options.limit)})`;
}
return `DELETE FROM ${this.quoteTable(tableName)} ${whereClause}`;
}
attributesToSQL(attributes) {
const result = {};
for (const name in attributes) {
const dataType = attributes[name];
const fieldName = dataType.field || name;
if (_.isObject(dataType)) {
let sql = dataType.type.toString();
if (Object.prototype.hasOwnProperty.call(dataType, "allowNull") && !dataType.allowNull) {
sql += " NOT NULL";
}
if (Utils.defaultValueSchemable(dataType.defaultValue)) {
sql += ` DEFAULT ${this.escape(dataType.defaultValue, dataType)}`;
}
if (dataType.unique === true) {
sql += " UNIQUE";
}
if (dataType.primaryKey) {
sql += " PRIMARY KEY";
if (dataType.autoIncrement) {
sql += " AUTOINCREMENT";
}
}
if (dataType.references) {
const referencesTable = this.quoteTable(dataType.references.model);
let referencesKey;
if (dataType.references.key) {
referencesKey = this.quoteIdentifier(dataType.references.key);
} else {
referencesKey = this.quoteIdentifier("id");
}
sql += ` REFERENCES ${referencesTable} (${referencesKey})`;
if (dataType.onDelete) {
sql += ` ON DELETE ${dataType.onDelete.toUpperCase()}`;
}
if (dataType.onUpdate) {
sql += ` ON UPDATE ${dataType.onUpdate.toUpperCase()}`;
}
}
result[fieldName] = sql;
} else {
result[fieldName] = dataType;
}
}
return result;
}
showIndexesQuery(tableName) {
return `PRAGMA INDEX_LIST(${this.quoteTable(tableName)})`;
}
showConstraintsQuery(tableName, constraintName) {
let sql = `SELECT sql FROM sqlite_master WHERE tbl_name='${tableName}'`;
if (constraintName) {
sql += ` AND sql LIKE '%${constraintName}%'`;
}
return `${sql};`;
}
removeIndexQuery(tableName, indexNameOrAttributes) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return `DROP INDEX IF EXISTS ${this.quoteIdentifier(indexName)}`;
}
describeTableQuery(tableName, schema, schemaDelimiter) {
const table = {
_schema: schema,
_schemaDelimiter: schemaDelimiter,
tableName
};
return `PRAGMA TABLE_INFO(${this.quoteTable(this.addSchema(table))});`;
}
describeCreateTableQuery(tableName) {
return `SELECT sql FROM sqlite_master WHERE tbl_name='${tableName}';`;
}
removeColumnQuery(tableName, attributes) {
attributes = this.attributesToSQL(attributes);
let backupTableName;
if (typeof tableName === "object") {
backupTableName = {
tableName: `${tableName.tableName}_backup`,
schema: tableName.schema
};
} else {
backupTableName = `${tableName}_backup`;
}
const quotedTableName = this.quoteTable(tableName);
const quotedBackupTableName = this.quoteTable(backupTableName);
const attributeNames = Object.keys(attributes).map((attr) => this.quoteIdentifier(attr)).join(", ");
return `${this.createTableQuery(backupTableName, attributes)}INSERT INTO ${quotedBackupTableName} SELECT ${attributeNames} FROM ${quotedTableName};DROP TABLE ${quotedTableName};${this.createTableQuery(tableName, attributes)}INSERT INTO ${quotedTableName} SELECT ${attributeNames} FROM ${quotedBackupTableName};DROP TABLE ${quotedBackupTableName};`;
}
_alterConstraintQuery(tableName, attributes, createTableSql) {
let backupTableName;
attributes = this.attributesToSQL(attributes);
if (typeof tableName === "object") {
backupTableName = {
tableName: `${tableName.tableName}_backup`,
schema: tableName.schema
};
} else {
backupTableName = `${tableName}_backup`;
}
const quotedTableName = this.quoteTable(tableName);
const quotedBackupTableName = this.quoteTable(backupTableName);
const attributeNames = Object.keys(attributes).map((attr) => this.quoteIdentifier(attr)).join(", ");
return `${createTableSql.replace(`CREATE TABLE ${quotedTableName}`, `CREATE TABLE ${quotedBackupTableName}`).replace(`CREATE TABLE ${quotedTableName.replace(/`/g, '"')}`, `CREATE TABLE ${quotedBackupTableName}`)}INSERT INTO ${quotedBackupTableName} SELECT ${attributeNames} FROM ${quotedTableName};DROP TABLE ${quotedTableName};ALTER TABLE ${quotedBackupTableName} RENAME TO ${quotedTableName};`;
}
renameColumnQuery(tableName, attrNameBefore, attrNameAfter, attributes) {
let backupTableName;
attributes = this.attributesToSQL(attributes);
if (typeof tableName === "object") {
backupTableName = {
tableName: `${tableName.tableName}_backup`,
schema: tableName.schema
};
} else {
backupTableName = `${tableName}_backup`;
}
const quotedTableName = this.quoteTable(tableName);
const quotedBackupTableName = this.quoteTable(backupTableName);
const attributeNamesImport = Object.keys(attributes).map((attr) => attrNameAfter === attr ? `${this.quoteIdentifier(attrNameBefore)} AS ${this.quoteIdentifier(attr)}` : this.quoteIdentifier(attr)).join(", ");
const attributeNamesExport = Object.keys(attributes).map((attr) => this.quoteIdentifier(attr)).join(", ");
return `${this.createTableQuery(backupTableName, attributes)}INSERT INTO ${quotedBackupTableName} SELECT ${attributeNamesImport} FROM ${quotedTableName};DROP TABLE ${quotedTableName};${this.createTableQuery(tableName, attributes)}INSERT INTO ${quotedTableName} SELECT ${attributeNamesExport} FROM ${quotedBackupTableName};DROP TABLE ${quotedBackupTableName};`;
}
startTransactionQuery(transaction) {
if (transaction.parent) {
return `SAVEPOINT ${this.quoteIdentifier(transaction.name)};`;
}
return `BEGIN ${transaction.options.type} TRANSACTION;`;
}
setIsolationLevelQuery(value) {
switch (value) {
case Transaction.ISOLATION_LEVELS.REPEATABLE_READ:
return "-- SQLite is not able to choose the isolation level REPEATABLE READ.";
case Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED:
return "PRAGMA read_uncommitted = ON;";
case Transaction.ISOLATION_LEVELS.READ_COMMITTED:
return "PRAGMA read_uncommitted = OFF;";
case Transaction.ISOLATION_LEVELS.SERIALIZABLE:
return "-- SQLite's default isolation level is SERIALIZABLE. Nothing to do.";
default:
throw new Error(`Unknown isolation level: ${value}`);
}
}
replaceBooleanDefaults(sql) {
return sql.replace(/DEFAULT '?false'?/g, "DEFAULT 0").replace(/DEFAULT '?true'?/g, "DEFAULT 1");
}
getForeignKeysQuery(tableName) {
return `PRAGMA foreign_key_list(${this.quoteTable(this.addSchema(tableName))})`;
}
tableExistsQuery(tableName) {
return `SELECT name FROM sqlite_master WHERE type='table' AND name=${this.escape(this.addSchema(tableName))};`;
}
quoteIdentifier(identifier, force) {
return Utils.addTicks(Utils.removeTicks(identifier, "`"), "`");
}
}
module.exports = SQLiteQueryGenerator;
//# sourceMappingURL=query-generator.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/query-generator.js"],
"sourcesContent": ["'use strict';\n\nconst Utils = require('../../utils');\nconst Transaction = require('../../transaction');\nconst _ = require('lodash');\nconst MySqlQueryGenerator = require('../mysql/query-generator');\nconst AbstractQueryGenerator = require('../abstract/query-generator');\n\nclass SQLiteQueryGenerator extends MySqlQueryGenerator {\n createSchema() {\n return \"SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';\";\n }\n\n showSchemasQuery() {\n return \"SELECT name FROM `sqlite_master` WHERE type='table' and name!='sqlite_sequence';\";\n }\n\n versionQuery() {\n return 'SELECT sqlite_version() as `version`';\n }\n\n createTableQuery(tableName, attributes, options) {\n options = options || {};\n\n const primaryKeys = [];\n const needsMultiplePrimaryKeys = Object.values(attributes).filter(definition => definition.includes('PRIMARY KEY')).length > 1;\n const attrArray = [];\n\n for (const attr in attributes) {\n if (Object.prototype.hasOwnProperty.call(attributes, attr)) {\n const dataType = attributes[attr];\n const containsAutoIncrement = dataType.includes('AUTOINCREMENT');\n\n let dataTypeString = dataType;\n if (dataType.includes('PRIMARY KEY')) {\n if (dataType.includes('INT')) {\n // Only INTEGER is allowed for primary key, see https://github.com/sequelize/sequelize/issues/969 (no lenght, unsigned etc)\n dataTypeString = containsAutoIncrement ? 'INTEGER PRIMARY KEY AUTOINCREMENT' : 'INTEGER PRIMARY KEY';\n\n if (dataType.includes(' REFERENCES')) {\n dataTypeString += dataType.substr(dataType.indexOf(' REFERENCES'));\n }\n }\n\n if (needsMultiplePrimaryKeys) {\n primaryKeys.push(attr);\n if (dataType.includes('NOT NULL')) {\n dataTypeString = dataType.replace(' PRIMARY KEY', '');\n } else {\n dataTypeString = dataType.replace('PRIMARY KEY', 'NOT NULL');\n }\n }\n }\n attrArray.push(`${this.quoteIdentifier(attr)} ${dataTypeString}`);\n }\n }\n\n const table = this.quoteTable(tableName);\n let attrStr = attrArray.join(', ');\n const pkString = primaryKeys.map(pk => this.quoteIdentifier(pk)).join(', ');\n\n if (options.uniqueKeys) {\n _.each(options.uniqueKeys, columns => {\n if (columns.customIndex) {\n attrStr += `, UNIQUE (${columns.fields.map(field => this.quoteIdentifier(field)).join(', ')})`;\n }\n });\n }\n\n if (pkString.length > 0) {\n attrStr += `, PRIMARY KEY (${pkString})`;\n }\n\n const sql = `CREATE TABLE IF NOT EXISTS ${table} (${attrStr});`;\n return this.replaceBooleanDefaults(sql);\n }\n\n booleanValue(value) {\n return value ? 1 : 0;\n }\n\n /**\n * Check whether the statmement is json function or simple path\n *\n * @param {string} stmt The statement to validate\n * @returns {boolean} true if the given statement is json function\n * @throws {Error} throw if the statement looks like json function but has invalid token\n */\n _checkValidJsonStatement(stmt) {\n if (typeof stmt !== 'string') {\n return false;\n }\n\n // https://sqlite.org/json1.html\n const jsonFunctionRegex = /^\\s*(json(?:_[a-z]+){0,2})\\([^)]*\\)/i;\n const tokenCaptureRegex = /^\\s*((?:([`\"'])(?:(?!\\2).|\\2{2})*\\2)|[\\w\\d\\s]+|[().,;+-])/i;\n\n let currentIndex = 0;\n let openingBrackets = 0;\n let closingBrackets = 0;\n let hasJsonFunction = false;\n let hasInvalidToken = false;\n\n while (currentIndex < stmt.length) {\n const string = stmt.substr(currentIndex);\n const functionMatches = jsonFunctionRegex.exec(string);\n if (functionMatches) {\n currentIndex += functionMatches[0].indexOf('(');\n hasJsonFunction = true;\n continue;\n }\n\n const tokenMatches = tokenCaptureRegex.exec(string);\n if (tokenMatches) {\n const capturedToken = tokenMatches[1];\n if (capturedToken === '(') {\n openingBrackets++;\n } else if (capturedToken === ')') {\n closingBrackets++;\n } else if (capturedToken === ';') {\n hasInvalidToken = true;\n break;\n }\n currentIndex += tokenMatches[0].length;\n continue;\n }\n\n break;\n }\n\n // Check invalid json statement\n hasInvalidToken |= openingBrackets !== closingBrackets;\n if (hasJsonFunction && hasInvalidToken) {\n throw new Error(`Invalid json statement: ${stmt}`);\n }\n\n // return true if the statement has valid json function\n return hasJsonFunction;\n }\n\n //sqlite can't cast to datetime so we need to convert date values to their ISO strings\n _toJSONValue(value) {\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (Array.isArray(value) && vLine truncated
"mappings": "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 truncated
"names": []
}
+175
View File
@@ -0,0 +1,175 @@
"use strict";
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
const sequelizeErrors = require("../../errors");
const QueryTypes = require("../../query-types");
const { QueryInterface } = require("../abstract/query-interface");
const { cloneDeep } = require("../../utils");
const _ = require("lodash");
class SQLiteQueryInterface extends QueryInterface {
async removeColumn(tableName, attributeName, options) {
options = options || {};
const fields = await this.describeTable(tableName, options);
delete fields[attributeName];
const sql = this.queryGenerator.removeColumnQuery(tableName, fields);
const subQueries = sql.split(";").filter((q) => q !== "");
for (const subQuery of subQueries)
await this.sequelize.query(`${subQuery};`, __spreadValues({ raw: true }, options));
}
async changeColumn(tableName, attributeName, dataTypeOrOptions, options) {
options = options || {};
const fields = await this.describeTable(tableName, options);
Object.assign(fields[attributeName], this.normalizeAttribute(dataTypeOrOptions));
const sql = this.queryGenerator.removeColumnQuery(tableName, fields);
const subQueries = sql.split(";").filter((q) => q !== "");
for (const subQuery of subQueries)
await this.sequelize.query(`${subQuery};`, __spreadValues({ raw: true }, options));
}
async renameColumn(tableName, attrNameBefore, attrNameAfter, options) {
options = options || {};
const fields = await this.assertTableHasColumn(tableName, attrNameBefore, options);
fields[attrNameAfter] = __spreadValues({}, fields[attrNameBefore]);
delete fields[attrNameBefore];
const sql = this.queryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields);
const subQueries = sql.split(";").filter((q) => q !== "");
for (const subQuery of subQueries)
await this.sequelize.query(`${subQuery};`, __spreadValues({ raw: true }, options));
}
async removeConstraint(tableName, constraintName, options) {
let createTableSql;
const constraints = await this.showConstraint(tableName, constraintName);
const constraint = constraints.find((constaint) => constaint.constraintName === constraintName);
if (!constraint) {
throw new sequelizeErrors.UnknownConstraintError({
message: `Constraint ${constraintName} on table ${tableName} does not exist`,
constraint: constraintName,
table: tableName
});
}
createTableSql = constraint.sql;
constraint.constraintName = this.queryGenerator.quoteIdentifier(constraint.constraintName);
let constraintSnippet = `, CONSTRAINT ${constraint.constraintName} ${constraint.constraintType} ${constraint.constraintCondition}`;
if (constraint.constraintType === "FOREIGN KEY") {
const referenceTableName = this.queryGenerator.quoteTable(constraint.referenceTableName);
constraint.referenceTableKeys = constraint.referenceTableKeys.map((columnName) => this.queryGenerator.quoteIdentifier(columnName));
const referenceTableKeys = constraint.referenceTableKeys.join(", ");
constraintSnippet += ` REFERENCES ${referenceTableName} (${referenceTableKeys})`;
constraintSnippet += ` ON UPDATE ${constraint.updateAction}`;
constraintSnippet += ` ON DELETE ${constraint.deleteAction}`;
}
createTableSql = createTableSql.replace(constraintSnippet, "");
createTableSql += ";";
const fields = await this.describeTable(tableName, options);
const sql = this.queryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const subQueries = sql.split(";").filter((q) => q !== "");
for (const subQuery of subQueries)
await this.sequelize.query(`${subQuery};`, __spreadValues({ raw: true }, options));
}
async addConstraint(tableName, options) {
if (!options.fields) {
throw new Error("Fields must be specified through options.fields");
}
if (!options.type) {
throw new Error("Constraint type must be specified through options.type");
}
options = cloneDeep(options);
const constraintSnippet = this.queryGenerator.getConstraintSnippet(tableName, options);
const describeCreateTableSql = this.queryGenerator.describeCreateTableQuery(tableName);
const constraints = await this.sequelize.query(describeCreateTableSql, __spreadProps(__spreadValues({}, options), { type: QueryTypes.SELECT, raw: true }));
let sql = constraints[0].sql;
const index = sql.length - 1;
const createTableSql = `${sql.substr(0, index)}, ${constraintSnippet})${sql.substr(index + 1)};`;
const fields = await this.describeTable(tableName, options);
sql = this.queryGenerator._alterConstraintQuery(tableName, fields, createTableSql);
const subQueries = sql.split(";").filter((q) => q !== "");
for (const subQuery of subQueries)
await this.sequelize.query(`${subQuery};`, __spreadValues({ raw: true }, options));
}
async getForeignKeyReferencesForTable(tableName, options) {
const database = this.sequelize.config.database;
const query = this.queryGenerator.getForeignKeysQuery(tableName, database);
const result = await this.sequelize.query(query, options);
return result.map((row) => ({
tableName,
columnName: row.from,
referencedTableName: row.table,
referencedColumnName: row.to,
tableCatalog: database,
referencedTableCatalog: database
}));
}
async dropAllTables(options) {
options = options || {};
const skip = options.skip || [];
const tableNames = await this.showAllTables(options);
await this.sequelize.query("PRAGMA foreign_keys = OFF", options);
await this._dropAllTables(tableNames, skip, options);
await this.sequelize.query("PRAGMA foreign_keys = ON", options);
}
async describeTable(tableName, options) {
let schema = null;
let schemaDelimiter = null;
if (typeof options === "string") {
schema = options;
} else if (typeof options === "object" && options !== null) {
schema = options.schema || null;
schemaDelimiter = options.schemaDelimiter || null;
}
if (typeof tableName === "object" && tableName !== null) {
schema = tableName.schema;
tableName = tableName.tableName;
}
const sql = this.queryGenerator.describeTableQuery(tableName, schema, schemaDelimiter);
options = __spreadProps(__spreadValues({}, options), { type: QueryTypes.DESCRIBE });
const sqlIndexes = this.queryGenerator.showIndexesQuery(tableName);
try {
const data = await this.sequelize.query(sql, options);
if (_.isEmpty(data)) {
throw new Error(`No description found for "${tableName}" table. Check the table name and schema; remember, they _are_ case sensitive.`);
}
const indexes = await this.sequelize.query(sqlIndexes, options);
for (const prop in data) {
data[prop].unique = false;
}
for (const index of indexes) {
for (const field of index.fields) {
if (index.unique !== void 0) {
data[field.attribute].unique = index.unique;
}
}
}
const foreignKeys = await this.getForeignKeyReferencesForTable(tableName, options);
for (const foreignKey of foreignKeys) {
data[foreignKey.columnName].references = {
model: foreignKey.referencedTableName,
key: foreignKey.referencedColumnName
};
}
return data;
} catch (e) {
if (e.original && e.original.code === "ER_NO_SUCH_TABLE") {
throw new Error(`No description found for "${tableName}" table. Check the table name and schema; remember, they _are_ case sensitive.`);
}
throw e;
}
}
}
exports.SQLiteQueryInterface = SQLiteQueryInterface;
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"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 Line truncated
"mappings": "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",
"names": []
}
+364
View File
@@ -0,0 +1,364 @@
"use strict";
const _ = require("lodash");
const Utils = require("../../utils");
const AbstractQuery = require("../abstract/query");
const QueryTypes = require("../../query-types");
const sequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("sqlite");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("sql:sqlite");
function stringifyIfBigint(value) {
if (typeof value === "bigint") {
return value.toString();
}
return value;
}
class Query extends AbstractQuery {
getInsertIdField() {
return "lastID";
}
static formatBindParameters(sql, values, dialect) {
let bindParam;
if (Array.isArray(values)) {
bindParam = {};
values.forEach((v, i) => {
bindParam[`$${i + 1}`] = v;
});
sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
} else {
bindParam = {};
if (typeof values === "object") {
for (const k of Object.keys(values)) {
bindParam[`$${k}`] = values[k];
}
}
sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
}
return [sql, bindParam];
}
_collectModels(include, prefix) {
const ret = {};
if (include) {
for (const _include of include) {
let key;
if (!prefix) {
key = _include.as;
} else {
key = `${prefix}.${_include.as}`;
}
ret[key] = _include.model;
if (_include.include) {
_.merge(ret, this._collectModels(_include.include, key));
}
}
}
return ret;
}
_handleQueryResponse(metaData, columnTypes, err, results, errStack) {
if (err) {
err.sql = this.sql;
throw this.formatError(err, errStack);
}
let result = this.instance;
if (this.isInsertQuery(results, metaData) || this.isUpsertQuery()) {
this.handleInsertQuery(results, metaData);
if (!this.instance) {
if (metaData.constructor.name === "Statement" && this.model && this.model.autoIncrementAttribute && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute && this.model.rawAttributes[this.model.primaryKeyAttribute]) {
const startId = metaData[this.getInsertIdField()] - metaData.changes + 1;
result = [];
for (let i = startId; i < startId + metaData.changes; i++) {
result.push({ [this.model.rawAttributes[this.model.primaryKeyAttribute].field]: i });
}
} else {
result = metaData[this.getInsertIdField()];
}
}
}
if (this.isShowTablesQuery()) {
return results.map((row) => row.name);
}
if (this.isShowConstraintsQuery()) {
result = results;
if (results && results[0] && results[0].sql) {
result = this.parseConstraintsFromSql(results[0].sql);
}
return result;
}
if (this.isSelectQuery()) {
if (this.options.raw) {
return this.handleSelectQuery(results);
}
const prefixes = this._collectModels(this.options.include);
results = results.map((result2) => {
return _.mapValues(result2, (value, name) => {
let model;
if (name.includes(".")) {
const lastind = name.lastIndexOf(".");
model = prefixes[name.substr(0, lastind)];
name = name.substr(lastind + 1);
} else {
model = this.options.model;
}
const tableName = model.getTableName().toString().replace(/`/g, "");
const tableTypes = columnTypes[tableName] || {};
if (tableTypes && !(name in tableTypes)) {
_.forOwn(model.rawAttributes, (attribute, key) => {
if (name === key && attribute.field) {
name = attribute.field;
return false;
}
});
}
return Object.prototype.hasOwnProperty.call(tableTypes, name) ? this.applyParsers(tableTypes[name], value) : value;
});
});
return this.handleSelectQuery(results);
}
if (this.isShowOrDescribeQuery()) {
return results;
}
if (this.sql.includes("PRAGMA INDEX_LIST")) {
return this.handleShowIndexesQuery(results);
}
if (this.sql.includes("PRAGMA INDEX_INFO")) {
return results;
}
if (this.sql.includes("PRAGMA TABLE_INFO")) {
result = {};
let defaultValue;
for (const _result of results) {
if (_result.dflt_value === null) {
defaultValue = void 0;
} else if (_result.dflt_value === "NULL") {
defaultValue = null;
} else {
defaultValue = _result.dflt_value;
}
result[_result.name] = {
type: _result.type,
allowNull: _result.notnull === 0,
defaultValue,
primaryKey: _result.pk !== 0
};
if (result[_result.name].type === "TINYINT(1)") {
result[_result.name].defaultValue = { "0": false, "1": true }[result[_result.name].defaultValue];
}
if (typeof result[_result.name].defaultValue === "string") {
result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, "");
}
}
return result;
}
if (this.sql.includes("PRAGMA foreign_keys;")) {
return results[0];
}
if (this.sql.includes("PRAGMA foreign_keys")) {
return results;
}
if (this.sql.includes("PRAGMA foreign_key_list")) {
return results;
}
if ([QueryTypes.BULKUPDATE, QueryTypes.BULKDELETE].includes(this.options.type)) {
return metaData.changes;
}
if (this.options.type === QueryTypes.VERSION) {
return results[0].version;
}
if (this.options.type === QueryTypes.RAW) {
return [results, metaData];
}
if (this.isUpsertQuery()) {
return [result, null];
}
if (this.isUpdateQuery() || this.isInsertQuery()) {
return [result, metaData.changes];
}
return result;
}
async run(sql, parameters) {
const conn = this.connection;
this.sql = sql;
const method = this.getDatabaseMethod();
const complete = this._logQuery(sql, debug, parameters);
return new Promise((resolve, reject) => conn.serialize(async () => {
const columnTypes = {};
const errForStack = new Error();
const executeSql = () => {
if (sql.startsWith("-- ")) {
return resolve();
}
const query = this;
function afterExecute(executionError, results) {
try {
complete();
resolve(query._handleQueryResponse(this, columnTypes, executionError, results, errForStack.stack));
return;
} catch (error) {
reject(error);
}
}
if (!parameters)
parameters = [];
if (_.isPlainObject(parameters)) {
const newParameters = Object.create(null);
for (const key of Object.keys(parameters)) {
newParameters[`${key}`] = stringifyIfBigint(parameters[key]);
}
parameters = newParameters;
} else {
parameters = parameters.map(stringifyIfBigint);
}
conn[method](sql, parameters, afterExecute);
return null;
};
if (this.getDatabaseMethod() === "all") {
let tableNames = [];
if (this.options && this.options.tableNames) {
tableNames = this.options.tableNames;
} else if (/FROM `(.*?)`/i.exec(this.sql)) {
tableNames.push(/FROM `(.*?)`/i.exec(this.sql)[1]);
}
tableNames = tableNames.filter((tableName) => !(tableName in columnTypes) && tableName !== "sqlite_master");
if (!tableNames.length) {
return executeSql();
}
await Promise.all(tableNames.map((tableName) => new Promise((resolve2) => {
tableName = tableName.replace(/`/g, "");
columnTypes[tableName] = {};
conn.all(`PRAGMA table_info(\`${tableName}\`)`, (err, results) => {
if (!err) {
for (const result of results) {
columnTypes[tableName][result.name] = result.type;
}
}
resolve2();
});
})));
}
return executeSql();
}));
}
parseConstraintsFromSql(sql) {
let constraints = sql.split("CONSTRAINT ");
let referenceTableName, referenceTableKeys, updateAction, deleteAction;
constraints.splice(0, 1);
constraints = constraints.map((constraintSql) => {
if (constraintSql.includes("REFERENCES")) {
updateAction = constraintSql.match(/ON UPDATE (CASCADE|SET NULL|RESTRICT|NO ACTION|SET DEFAULT){1}/);
deleteAction = constraintSql.match(/ON DELETE (CASCADE|SET NULL|RESTRICT|NO ACTION|SET DEFAULT){1}/);
if (updateAction) {
updateAction = updateAction[1];
}
if (deleteAction) {
deleteAction = deleteAction[1];
}
const referencesRegex = /REFERENCES.+\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/;
const referenceConditions = constraintSql.match(referencesRegex)[0].split(" ");
referenceTableName = Utils.removeTicks(referenceConditions[1]);
let columnNames = referenceConditions[2];
columnNames = columnNames.replace(/\(|\)/g, "").split(", ");
referenceTableKeys = columnNames.map((column) => Utils.removeTicks(column));
}
const constraintCondition = constraintSql.match(/\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/)[0];
constraintSql = constraintSql.replace(/\(.+\)/, "");
const constraint = constraintSql.split(" ");
if (["PRIMARY", "FOREIGN"].includes(constraint[1])) {
constraint[1] += " KEY";
}
return {
constraintName: Utils.removeTicks(constraint[0]),
constraintType: constraint[1],
updateAction,
deleteAction,
sql: sql.replace(/"/g, "`"),
constraintCondition,
referenceTableName,
referenceTableKeys
};
});
return constraints;
}
applyParsers(type, value) {
if (type.includes("(")) {
type = type.substr(0, type.indexOf("("));
}
type = type.replace("UNSIGNED", "").replace("ZEROFILL", "");
type = type.trim().toUpperCase();
const parse = parserStore.get(type);
if (value !== null && parse) {
return parse(value, { timezone: this.sequelize.options.timezone });
}
return value;
}
formatError(err, errStack) {
switch (err.code) {
case "SQLITE_CONSTRAINT_UNIQUE":
case "SQLITE_CONSTRAINT_PRIMARYKEY":
case "SQLITE_CONSTRAINT_TRIGGER":
case "SQLITE_CONSTRAINT_FOREIGNKEY":
case "SQLITE_CONSTRAINT": {
if (err.message.includes("FOREIGN KEY constraint failed")) {
return new sequelizeErrors.ForeignKeyConstraintError({
parent: err,
stack: errStack
});
}
let fields = [];
let match = err.message.match(/columns (.*?) are/);
if (match !== null && match.length >= 2) {
fields = match[1].split(", ");
} else {
match = err.message.match(/UNIQUE constraint failed: (.*)/);
if (match !== null && match.length >= 2) {
fields = match[1].split(", ").map((columnWithTable) => columnWithTable.split(".")[1]);
}
}
const errors = [];
let message = "Validation error";
for (const field of fields) {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, this.instance && this.instance[field], this.instance, "not_unique"));
}
if (this.model) {
_.forOwn(this.model.uniqueKeys, (constraint) => {
if (_.isEqual(constraint.fields, fields) && !!constraint.msg) {
message = constraint.msg;
return false;
}
});
}
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
case "SQLITE_BUSY":
return new sequelizeErrors.TimeoutError(err, { stack: errStack });
default:
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
}
async handleShowIndexesQuery(data) {
return Promise.all(data.reverse().map(async (item) => {
item.fields = [];
item.primary = false;
item.unique = !!item.unique;
item.constraintName = item.name;
const columns = await this.run(`PRAGMA INDEX_INFO(\`${item.name}\`)`);
for (const column of columns) {
item.fields[column.seqno] = {
attribute: column.name,
length: void 0,
order: void 0
};
}
return item;
}));
}
getDatabaseMethod() {
if (this.isInsertQuery() || this.isUpdateQuery() || this.isUpsertQuery() || this.isBulkUpdateQuery() || this.sql.toLowerCase().includes("CREATE TEMPORARY TABLE".toLowerCase()) || this.options.type === QueryTypes.BULKDELETE) {
return "run";
}
return "all";
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/query.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst Utils = require('../../utils');\nconst AbstractQuery = require('../abstract/query');\nconst QueryTypes = require('../../query-types');\nconst sequelizeErrors = require('../../errors');\nconst parserStore = require('../parserStore')('sqlite');\nconst { logger } = require('../../utils/logger');\n\nconst debug = logger.debugContext('sql:sqlite');\n\n// sqlite3 currently ignores bigint values, so we have to translate to string for now\n// There's a WIP here: https://github.com/TryGhost/node-sqlite3/pull/1501\nfunction stringifyIfBigint(value) {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n return value;\n}\n\nclass Query extends AbstractQuery {\n getInsertIdField() {\n return 'lastID';\n }\n\n /**\n * rewrite query with parameters.\n *\n * @param {string} sql\n * @param {Array|object} values\n * @param {string} dialect\n * @private\n */\n static formatBindParameters(sql, values, dialect) {\n let bindParam;\n if (Array.isArray(values)) {\n bindParam = {};\n values.forEach((v, i) => {\n bindParam[`$${i + 1}`] = v;\n });\n sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];\n } else {\n bindParam = {};\n if (typeof values === 'object') {\n for (const k of Object.keys(values)) {\n bindParam[`$${k}`] = values[k];\n }\n }\n sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];\n }\n return [sql, bindParam];\n }\n\n _collectModels(include, prefix) {\n const ret = {};\n\n if (include) {\n for (const _include of include) {\n let key;\n if (!prefix) {\n key = _include.as;\n } else {\n key = `${prefix}.${_include.as}`;\n }\n ret[key] = _include.model;\n\n if (_include.include) {\n _.merge(ret, this._collectModels(_include.include, key));\n }\n }\n }\n\n return ret;\n }\n\n _handleQueryResponse(metaData, columnTypes, err, results, errStack) {\n if (err) {\n err.sql = this.sql;\n throw this.formatError(err, errStack);\n }\n let result = this.instance;\n\n // add the inserted row id to the instance\n if (this.isInsertQuery(results, metaData) || this.isUpsertQuery()) {\n this.handleInsertQuery(results, metaData);\n if (!this.instance) {\n // handle bulkCreate AI primary key\n if (\n metaData.constructor.name === 'Statement'\n && this.model\n && this.model.autoIncrementAttribute\n && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute\n && this.model.rawAttributes[this.model.primaryKeyAttribute]\n ) {\n const startId = metaData[this.getInsertIdField()] - metaData.changes + 1;\n result = [];\n for (let i = startId; i < startId + metaData.changes; i++) {\n result.push({ [this.model.rawAttributes[this.model.primaryKeyAttribute].field]: i });\n }\n } else {\n result = metaData[this.getInsertIdField()];\n }\n }\n }\n\n if (this.isShowTablesQuery()) {\n return results.map(row => row.name);\n }\n if (this.isShowConstraintsQuery()) {\n result = results;\n if (results && results[0] && results[0].sql) {\n result = this.parseConstraintsFromSql(results[0].sql);\n }\n return result;\n }\n if (this.isSelectQuery()) {\n if (this.options.raw) {\n return this.handleSelectQuery(results);\n }\n // This is a map of prefix strings to models, e.g. user.projects -> Project model\n const prefixes = this._collectModels(this.options.include);\n\n results = results.map(result => {\n return _.mapValues(result, (value, name) => {\n let model;\n if (name.includes('.')) {\n const lastind = name.lastIndexOf('.');\n\n model = prefixes[name.substr(0, lastind)];\n\n name = name.substr(lastind + 1);\n } else {\n model = this.options.model;\n }\n\n const tableName = model.getTableName().toString().replace(/`/g, '');\n const tableTypes = columnTypes[tableName] || {};\n\n if (tableTypes && !(name in tableTypes)) {\n // The column is aliased\n _.forOwn(model.rawAttributes, (attribute, key) => {\n if (name === key && attribute.field) {\n name = attribute.field;\n return false;\n }\n });\n }\n\n return Object.prototype.hasOwnProperty.call(tableTypes, name)\n ? this.applyParsers(tableTypes[name], value)\n : value;\n });\n });\n\n return this.handleSelectQuery(results);\n }\n if (this.isShowOrDescribeQuery()) {\n return results;\n }\n if Line truncated
"mappings": "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 truncated
"names": []
}
+19
View File
@@ -0,0 +1,19 @@
var __defProp = Object.defineProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
__export(exports, {
withSqliteForeignKeysOff: () => withSqliteForeignKeysOff
});
async function withSqliteForeignKeysOff(sequelize, options, cb) {
try {
await sequelize.query("PRAGMA foreign_keys = OFF", options);
return await cb();
} finally {
await sequelize.query("PRAGMA foreign_keys = ON", options);
}
}
//# sourceMappingURL=sqlite-utils.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/sqlite/sqlite-utils.ts"],
"sourcesContent": ["import type { Sequelize } from '../../sequelize.js';\nimport type { QueryOptions } from '../abstract/query-interface.js';\n\nexport async function withSqliteForeignKeysOff<T>(sequelize: Sequelize, options: QueryOptions, cb: () => Promise<T>): Promise<T> {\n try {\n await sequelize.query('PRAGMA foreign_keys = OFF', options);\n\n return await cb();\n } finally {\n await sequelize.query('PRAGMA foreign_keys = ON', options);\n }\n}\n"],
"mappings": ";;;;;;;AAAA;AAAA;AAAA;AAGA,wCAAkD,WAAsB,SAAuB,IAAkC;AAC/H,MAAI;AACF,UAAM,UAAU,MAAM,6BAA6B;AAEnD,WAAO,MAAM;AAAA,YACb;AACA,UAAM,UAAU,MAAM,4BAA4B;AAAA;AAAA;",
"names": []
}