feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2014-present Sequelize contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+83
View File
@@ -0,0 +1,83 @@
<p align="center">
<img src="logo.svg" width="100" alt="Sequelize logo" />
<h1 align="center"><a href="https://sequelize.org">Sequelize</a></h1>
</p>
[![npm version](https://badgen.net/npm/v/sequelize)](https://www.npmjs.com/package/sequelize)
[![Build Status](https://github.com/sequelize/sequelize/workflows/CI/badge.svg)](https://github.com/sequelize/sequelize/actions?query=workflow%3ACI)
[![npm downloads](https://badgen.net/npm/dm/sequelize)](https://www.npmjs.com/package/sequelize)
[![contributors](https://img.shields.io/github/contributors/sequelize/sequelize)](https://github.com/sequelize/sequelize/graphs/contributors)
[![Open Collective](https://img.shields.io/opencollective/backers/sequelize)](https://opencollective.com/sequelize#section-contributors)
[![sponsor](https://img.shields.io/opencollective/all/sequelize?label=sponsors)](https://opencollective.com/sequelize)
[![Merged PRs](https://badgen.net/github/merged-prs/sequelize/sequelize)](https://github.com/sequelize/sequelize)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
Sequelize is an easy-to-use and promise-based [Node.js](https://nodejs.org/en/about/) [ORM tool](https://en.wikipedia.org/wiki/Object-relational_mapping) for [Postgres](https://en.wikipedia.org/wiki/PostgreSQL), [MySQL](https://en.wikipedia.org/wiki/MySQL), [MariaDB](https://en.wikipedia.org/wiki/MariaDB), [SQLite](https://en.wikipedia.org/wiki/SQLite), [DB2](https://en.wikipedia.org/wiki/IBM_Db2_Family), [Microsoft SQL Server](https://en.wikipedia.org/wiki/Microsoft_SQL_Server), and [Snowflake](https://www.snowflake.com/). It features solid transaction support, relations, eager and lazy loading, read replication and more.
Would you like to contribute? Read [our contribution guidelines](https://github.com/sequelize/sequelize/blob/main/CONTRIBUTING.md) to know more. There are many ways to help! 😃
## 🚀 Seeking New Maintainers for Sequelize! 🚀
We're looking for new maintainers to help finalize and release the next major version of Sequelize! If you're passionate about open-source and database ORMs, we'd love to have you onboard.
### 💰 Funding Available
We distribute **$2,500 per quarter** among maintainers and have additional funds for full-time contributions.
### 🛠️ What Youll Work On
- Finalizing and releasing Sequelizes next major version
- Improving TypeScript support and database integrations
- Fixing critical issues and shaping the ORMs future
### 🤝 How to Get Involved
Interested? Join our Slack and reach out to **@WikiRik** or **@sdepold**:
➡️ **[sequelize.org/slack](https://sequelize.org/slack)**
Wed love to have you on board! 🚀
## :computer: Getting Started
Ready to start using Sequelize? Head to [sequelize.org](https://sequelize.org) to begin!
- [Our Getting Started guide for Sequelize 6 (stable)](https://sequelize.org/docs/v6/getting-started)
## :money_with_wings: Supporting the project
Do you like Sequelize and would like to give back to the engineering team behind it?
We have recently created an [OpenCollective based money pool](https://opencollective.com/sequelize) which is shared amongst all core maintainers based on their contributions. Every support is wholeheartedly welcome. ❤️
## :pencil: Major version changelog
Please find upgrade information to major versions here:
- [Upgrade from v5 to v6](https://sequelize.org/docs/v6/other-topics/upgrade-to-v6)
## :book: Resources
- [Documentation](https://sequelize.org)
- [Databases Compatibility Table](https://sequelize.org/releases/)
- [Changelog](https://github.com/sequelize/sequelize/releases)
- [Discussions](https://github.com/sequelize/sequelize/discussions)
- [Slack](https://sequelize.org/slack)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/sequelize.js)
### :wrench: Tools
- [CLI](https://github.com/sequelize/cli)
- [With TypeScript](https://sequelize.org/docs/v6/other-topics/typescript)
- [Enhanced TypeScript with decorators](https://github.com/RobinBuschmann/sequelize-typescript)
- [For GraphQL](https://github.com/mickhansen/graphql-sequelize)
- [For CockroachDB](https://github.com/cockroachdb/sequelize-cockroachdb)
- [Awesome Sequelize](https://sequelize.org/docs/v6/other-topics/resources/)
- [For YugabyteDB](https://github.com/yugabyte/sequelize-yugabytedb)
### :speech_balloon: Translations
- [English](https://sequelize.org) (Official)
- [中文文档](https://github.com/demopark/sequelize-docs-Zh-CN) (Unofficial)
## :warning: Responsible disclosure
If you have security issues to report, please refer to our
[Responsible Disclosure Policy](https://github.com/sequelize/sequelize/blob/main/SECURITY.md) for more details.
+12
View File
@@ -0,0 +1,12 @@
'use strict';
// TODO [>=7]: remove me. I've been moved to 'exports' in package.json
/**
* A Sequelize module that contains the sequelize entry point.
*
* @module sequelize
*/
/** Exports the sequelize entry point. */
module.exports = require('./lib');
+33
View File
@@ -0,0 +1,33 @@
"use strict";
const { AssociationError } = require("./../errors");
class Association {
constructor(source, target, options = {}) {
this.source = source;
this.target = target;
this.options = options;
this.scope = options.scope;
this.isSelfAssociation = this.source === this.target;
this.as = options.as;
this.associationType = "";
if (source.hasAlias(options.as)) {
throw new AssociationError(`You have used the alias ${options.as} in two separate associations. Aliased associations must have unique aliases.`);
}
}
toInstanceArray(input) {
if (!Array.isArray(input)) {
input = [input];
}
return input.map((element) => {
if (element instanceof this.target)
return element;
const tmpInstance = {};
tmpInstance[this.target.primaryKeyAttribute] = element;
return this.target.build(tmpInstance, { isNewRecord: false });
});
}
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.as;
}
}
module.exports = Association;
//# sourceMappingURL=base.js.map
File diff suppressed because one or more lines are too long
+566
View File
@@ -0,0 +1,566 @@
"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 Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const BelongsTo = require("./belongs-to");
const HasMany = require("./has-many");
const HasOne = require("./has-one");
const AssociationError = require("../errors").AssociationError;
const EmptyResultError = require("../errors").EmptyResultError;
const Op = require("../operators");
class BelongsToMany extends Association {
constructor(source, target, options) {
super(source, target, options);
if (this.options.through === void 0 || this.options.through === true || this.options.through === null) {
throw new AssociationError(`${source.name}.belongsToMany(${target.name}) requires through option, pass either a string or a model`);
}
if (!this.options.through.model) {
this.options.through = {
model: options.through
};
}
this.associationType = "BelongsToMany";
this.targetAssociation = null;
this.sequelize = source.sequelize;
this.through = __spreadValues({}, this.options.through);
this.isMultiAssociation = true;
this.doubleLinked = false;
if (!this.as && this.isSelfAssociation) {
throw new AssociationError("'as' must be defined for many-to-many self-associations");
}
if (this.as) {
this.isAliased = true;
if (_.isPlainObject(this.as)) {
this.options.name = this.as;
this.as = this.as.plural;
} else {
this.options.name = {
plural: this.as,
singular: Utils.singularize(this.as)
};
}
} else {
this.as = this.target.options.name.plural;
this.options.name = this.target.options.name;
}
this.combinedTableName = Utils.combineTableNames(this.source.tableName, this.isSelfAssociation ? this.as || this.target.tableName : this.target.tableName);
if (this.isSelfAssociation) {
this.targetAssociation = this;
}
_.each(this.target.associations, (association) => {
if (association.associationType !== "BelongsToMany")
return;
if (association.target !== this.source)
return;
if (this.options.through.model === association.options.through.model) {
this.paired = association;
association.paired = this;
}
});
this.sourceKey = this.options.sourceKey || this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
if (this.options.targetKey) {
this.targetKey = this.options.targetKey;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
} else {
this.targetKeyDefault = true;
this.targetKey = this.target.primaryKeyAttribute;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
}
this._createForeignAndOtherKeys();
if (typeof this.through.model === "string") {
if (!this.sequelize.isDefined(this.through.model)) {
this.through.model = this.sequelize.define(this.through.model, {}, Object.assign(this.options, {
tableName: this.through.model,
indexes: [],
paranoid: this.through.paranoid ? this.through.paranoid : false,
validate: {}
}));
} else {
this.through.model = this.sequelize.model(this.through.model);
}
}
Object.assign(this.options, _.pick(this.through.model.options, [
"timestamps",
"createdAt",
"updatedAt",
"deletedAt",
"paranoid"
]));
if (this.paired) {
let needInjectPaired = false;
if (this.targetKeyDefault) {
this.targetKey = this.paired.sourceKey;
this.targetKeyField = this.paired.sourceKeyField;
this._createForeignAndOtherKeys();
}
if (this.paired.targetKeyDefault) {
if (this.paired.targetKey !== this.sourceKey) {
delete this.through.model.rawAttributes[this.paired.otherKey];
this.paired.targetKey = this.sourceKey;
this.paired.targetKeyField = this.sourceKeyField;
this.paired._createForeignAndOtherKeys();
needInjectPaired = true;
}
}
if (this.otherKeyDefault) {
this.otherKey = this.paired.foreignKey;
}
if (this.paired.otherKeyDefault) {
if (this.paired.otherKey !== this.foreignKey) {
delete this.through.model.rawAttributes[this.paired.otherKey];
this.paired.otherKey = this.foreignKey;
needInjectPaired = true;
}
}
if (needInjectPaired) {
this.paired._injectAttributes();
}
}
if (this.through) {
this.throughModel = this.through.model;
}
this.options.tableName = this.combinedName = this.through.model === Object(this.through.model) ? this.through.model.tableName : this.through.model;
this.associationAccessor = this.as;
const plural = _.upperFirst(this.options.name.plural);
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${plural}`,
set: `set${plural}`,
addMultiple: `add${plural}`,
add: `add${singular}`,
create: `create${singular}`,
remove: `remove${singular}`,
removeMultiple: `remove${plural}`,
hasSingle: `has${singular}`,
hasAll: `has${plural}`,
count: `count${plural}`
};
}
_createForeignAndOtherKeys() {
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else {
this.foreignKeyAttribute = {};
this.foreignKey = this.options.foreignKey || Utils.camelize([
this.source.options.name.singular,
this.sourceKey
].join("_"));
}
if (_.isObject(this.options.otherKey)) {
this.otherKeyAttribute = this.options.otherKey;
this.otherKey = this.otherKeyAttribute.name || this.otherKeyAttribute.fieldName;
} else {
if (!this.options.otherKey) {
this.otherKeyDefault = true;
}
this.otherKeyAttribute = {};
this.otherKey = this.options.otherKey || Utils.camelize([
this.isSelfAssociation ? Utils.singularize(this.as) : this.target.options.name.singular,
this.targetKey
].join("_"));
}
}
_injectAttributes() {
this.identifier = this.foreignKey;
this.foreignIdentifier = this.otherKey;
_.each(this.through.model.rawAttributes, (attribute, attributeName) => {
if (attribute.primaryKey === true && attribute._autoGenerated === true) {
if ([this.foreignKey, this.otherKey].includes(attributeName)) {
attribute.primaryKey = false;
} else {
delete this.through.model.rawAttributes[attributeName];
}
this.primaryKeyDeleted = true;
}
});
const sourceKey = this.source.rawAttributes[this.sourceKey];
const sourceKeyType = sourceKey.type;
const sourceKeyField = this.sourceKeyField;
const targetKey = this.target.rawAttributes[this.targetKey];
const targetKeyType = targetKey.type;
const targetKeyField = this.targetKeyField;
const sourceAttribute = __spreadValues({ type: sourceKeyType }, this.foreignKeyAttribute);
const targetAttribute = __spreadValues({ type: targetKeyType }, this.otherKeyAttribute);
if (this.primaryKeyDeleted === true) {
targetAttribute.primaryKey = sourceAttribute.primaryKey = true;
} else if (this.through.unique !== false) {
let uniqueKey;
if (typeof this.options.uniqueKey === "string" && this.options.uniqueKey !== "") {
uniqueKey = this.options.uniqueKey;
} else {
uniqueKey = [this.through.model.tableName, this.foreignKey, this.otherKey, "unique"].join("_");
}
targetAttribute.unique = sourceAttribute.unique = uniqueKey;
}
if (!this.through.model.rawAttributes[this.foreignKey]) {
this.through.model.rawAttributes[this.foreignKey] = {
_autoGenerated: true
};
}
if (!this.through.model.rawAttributes[this.otherKey]) {
this.through.model.rawAttributes[this.otherKey] = {
_autoGenerated: true
};
}
if (this.options.constraints !== false) {
sourceAttribute.references = {
model: this.source.getTableName(),
key: sourceKeyField
};
sourceAttribute.onDelete = this.options.onDelete || this.through.model.rawAttributes[this.foreignKey].onDelete;
sourceAttribute.onUpdate = this.options.onUpdate || this.through.model.rawAttributes[this.foreignKey].onUpdate;
if (!sourceAttribute.onDelete)
sourceAttribute.onDelete = "CASCADE";
if (!sourceAttribute.onUpdate)
sourceAttribute.onUpdate = "CASCADE";
targetAttribute.references = {
model: this.target.getTableName(),
key: targetKeyField
};
targetAttribute.onDelete = this.through.model.rawAttributes[this.otherKey].onDelete || this.options.onDelete;
targetAttribute.onUpdate = this.through.model.rawAttributes[this.otherKey].onUpdate || this.options.onUpdate;
if (!targetAttribute.onDelete)
targetAttribute.onDelete = "CASCADE";
if (!targetAttribute.onUpdate)
targetAttribute.onUpdate = "CASCADE";
}
Object.assign(this.through.model.rawAttributes[this.foreignKey], sourceAttribute);
Object.assign(this.through.model.rawAttributes[this.otherKey], targetAttribute);
this.through.model.refreshAttributes();
this.identifierField = this.through.model.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignIdentifierField = this.through.model.rawAttributes[this.otherKey].field || this.otherKey;
if (this.options.sequelize.options.dialect === "db2" && this.source.rawAttributes[this.sourceKey].primaryKey !== true) {
this.source.rawAttributes[this.sourceKey].unique = true;
}
if (this.paired && !this.paired.foreignIdentifierField) {
this.paired.foreignIdentifierField = this.through.model.rawAttributes[this.paired.otherKey].field || this.paired.otherKey;
}
this.toSource = new BelongsTo(this.through.model, this.source, {
foreignKey: this.foreignKey
});
this.manyFromSource = new HasMany(this.source, this.through.model, {
foreignKey: this.foreignKey
});
this.oneFromSource = new HasOne(this.source, this.through.model, {
foreignKey: this.foreignKey,
sourceKey: this.sourceKey,
as: this.through.model.name
});
this.toTarget = new BelongsTo(this.through.model, this.target, {
foreignKey: this.otherKey
});
this.manyFromTarget = new HasMany(this.target, this.through.model, {
foreignKey: this.otherKey
});
this.oneFromTarget = new HasOne(this.target, this.through.model, {
foreignKey: this.otherKey,
sourceKey: this.targetKey,
as: this.through.model.name
});
if (this.paired && this.paired.otherKeyDefault) {
this.paired.toTarget = new BelongsTo(this.paired.through.model, this.paired.target, {
foreignKey: this.paired.otherKey
});
this.paired.oneFromTarget = new HasOne(this.paired.target, this.paired.through.model, {
foreignKey: this.paired.otherKey,
sourceKey: this.paired.targetKey,
as: this.paired.through.model.name
});
}
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "count", "hasSingle", "hasAll", "set", "add", "addMultiple", "remove", "removeMultiple", "create"];
const aliases = {
hasSingle: "has",
hasAll: "has",
addMultiple: "add",
removeMultiple: "remove"
};
Helpers.mixinMethods(this, obj, methods, aliases);
}
async get(instance, options) {
options = Utils.cloneDeep(options) || {};
const through = this.through;
let scopeWhere;
let throughWhere;
if (this.scope) {
scopeWhere = __spreadValues({}, this.scope);
}
options.where = {
[Op.and]: [
scopeWhere,
options.where
]
};
if (Object(through.model) === through.model) {
throughWhere = {};
throughWhere[this.foreignKey] = instance.get(this.sourceKey);
if (through.scope) {
Object.assign(throughWhere, through.scope);
}
if (options.through && options.through.where) {
throughWhere = {
[Op.and]: [throughWhere, options.through.where]
};
}
options.include = options.include || [];
options.include.push({
association: this.oneFromTarget,
attributes: options.joinTableAttributes,
required: true,
paranoid: _.get(options.through, "paranoid", true),
where: throughWhere
});
}
let model = this.target;
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
model = model.schema(options.schema, options.schemaDelimiter);
}
return model.findAll(options);
}
async count(instance, options) {
const sequelize = this.target.sequelize;
options = Utils.cloneDeep(options);
options.attributes = [
[sequelize.fn("COUNT", sequelize.col([this.target.name, this.targetKeyField].join("."))), "count"]
];
options.joinTableAttributes = [];
options.raw = true;
options.plain = true;
const result = await this.get(instance, options);
return parseInt(result.count, 10);
}
async has(sourceInstance, instances, options) {
if (!Array.isArray(instances)) {
instances = [instances];
}
options = __spreadProps(__spreadValues({
raw: true
}, options), {
scope: false,
attributes: [this.targetKey],
joinTableAttributes: []
});
const instancePrimaryKeys = instances.map((instance) => {
if (instance instanceof this.target) {
return instance.where();
}
return {
[this.targetKey]: instance
};
});
options.where = {
[Op.and]: [
{ [Op.or]: instancePrimaryKeys },
options.where
]
};
const associatedObjects = await this.get(sourceInstance, options);
return _.differenceWith(instancePrimaryKeys, associatedObjects, (a, b) => _.isEqual(a[this.targetKey], b[this.targetKey])).length === 0;
}
async set(sourceInstance, newAssociatedObjects, options) {
options = options || {};
const sourceKey = this.sourceKey;
const targetKey = this.targetKey;
const identifier = this.identifier;
const foreignIdentifier = this.foreignIdentifier;
if (newAssociatedObjects === null) {
newAssociatedObjects = [];
} else {
newAssociatedObjects = this.toInstanceArray(newAssociatedObjects);
}
const where = __spreadValues({
[identifier]: sourceInstance.get(sourceKey)
}, this.through.scope);
const updateAssociations = (currentRows) => {
const obsoleteAssociations = [];
const promises = [];
const defaultAttributes = options.through || {};
const unassociatedObjects = newAssociatedObjects.filter((obj) => !currentRows.some((currentRow) => currentRow[foreignIdentifier] === obj.get(targetKey)));
for (const currentRow of currentRows) {
const newObj = newAssociatedObjects.find((obj) => currentRow[foreignIdentifier] === obj.get(targetKey));
if (!newObj) {
obsoleteAssociations.push(currentRow);
} else {
let throughAttributes = newObj[this.through.model.name];
if (throughAttributes instanceof this.through.model) {
throughAttributes = {};
}
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (Object.keys(attributes).length) {
promises.push(this.through.model.update(attributes, Object.assign(options, {
where: {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: newObj.get(targetKey)
}
})));
}
}
}
if (obsoleteAssociations.length > 0) {
promises.push(this.through.model.destroy(__spreadProps(__spreadValues({}, options), {
where: __spreadValues({
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: obsoleteAssociations.map((obsoleteAssociation) => obsoleteAssociation[foreignIdentifier])
}, this.through.scope)
})));
}
if (unassociatedObjects.length > 0) {
const bulk = unassociatedObjects.map((unassociatedObject) => {
return __spreadValues(__spreadProps(__spreadValues(__spreadValues({}, defaultAttributes), unassociatedObject[this.through.model.name]), {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: unassociatedObject.get(targetKey)
}), this.through.scope);
});
promises.push(this.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
}
return Promise.all(promises);
};
try {
const currentRows = await this.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
return await updateAssociations(currentRows);
} catch (error) {
if (error instanceof EmptyResultError)
return updateAssociations([]);
throw error;
}
}
async add(sourceInstance, newInstances, options) {
if (!newInstances)
return Promise.resolve();
options = __spreadValues({}, options);
const association = this;
const sourceKey = association.sourceKey;
const targetKey = association.targetKey;
const identifier = association.identifier;
const foreignIdentifier = association.foreignIdentifier;
const defaultAttributes = options.through || {};
newInstances = association.toInstanceArray(newInstances);
const where = __spreadValues({
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: newInstances.map((newInstance) => newInstance.get(targetKey))
}, association.through.scope);
const updateAssociations = (currentRows) => {
const promises = [];
const unassociatedObjects = [];
const changedAssociations = [];
for (const obj of newInstances) {
const existingAssociation = currentRows && currentRows.find((current) => current[foreignIdentifier] === obj.get(targetKey));
if (!existingAssociation) {
unassociatedObjects.push(obj);
} else {
const throughAttributes = obj[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (Object.keys(attributes).some((attribute) => attributes[attribute] !== existingAssociation[attribute])) {
changedAssociations.push(obj);
}
}
}
if (unassociatedObjects.length > 0) {
const bulk = unassociatedObjects.map((unassociatedObject) => {
const throughAttributes = unassociatedObject[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
attributes[identifier] = sourceInstance.get(sourceKey);
attributes[foreignIdentifier] = unassociatedObject.get(targetKey);
Object.assign(attributes, association.through.scope);
return attributes;
});
promises.push(association.through.model.bulkCreate(bulk, __spreadValues({ validate: true }, options)));
}
for (const assoc of changedAssociations) {
let throughAttributes = assoc[association.through.model.name];
const attributes = __spreadValues(__spreadValues({}, defaultAttributes), throughAttributes);
if (throughAttributes instanceof association.through.model) {
throughAttributes = {};
}
promises.push(association.through.model.update(attributes, Object.assign(options, { where: {
[identifier]: sourceInstance.get(sourceKey),
[foreignIdentifier]: assoc.get(targetKey)
} })));
}
return Promise.all(promises);
};
try {
const currentRows = await association.through.model.findAll(__spreadProps(__spreadValues({}, options), { where, raw: true }));
const [associations] = await updateAssociations(currentRows);
return associations;
} catch (error) {
if (error instanceof EmptyResultError)
return updateAssociations();
throw error;
}
}
remove(sourceInstance, oldAssociatedObjects, options) {
const association = this;
options = options || {};
oldAssociatedObjects = association.toInstanceArray(oldAssociatedObjects);
const where = {
[association.identifier]: sourceInstance.get(association.sourceKey),
[association.foreignIdentifier]: oldAssociatedObjects.map((newInstance) => newInstance.get(association.targetKey))
};
return association.through.model.destroy(__spreadProps(__spreadValues({}, options), { where }));
}
async create(sourceInstance, values, options) {
const association = this;
options = options || {};
values = values || {};
if (Array.isArray(options)) {
options = {
fields: options
};
}
if (association.scope) {
Object.assign(values, association.scope);
if (options.fields) {
options.fields = options.fields.concat(Object.keys(association.scope));
}
}
const newAssociatedObject = await association.target.create(values, options);
await sourceInstance[association.accessors.add](newAssociatedObject, _.omit(options, ["fields"]));
return newAssociatedObject;
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
}
module.exports = BelongsToMany;
module.exports.BelongsToMany = BelongsToMany;
module.exports.default = BelongsToMany;
//# sourceMappingURL=belongs-to-many.js.map
File diff suppressed because one or more lines are too long
+172
View File
@@ -0,0 +1,172 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const Utils = require("./../utils");
const Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class BelongsTo extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "BelongsTo";
this.isSingleAssociation = true;
this.foreignKeyAttribute = {};
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
this.as,
this.target.primaryKeyAttribute
].join("_"));
}
this.identifier = this.foreignKey;
if (this.source.rawAttributes[this.identifier]) {
this.identifierField = this.source.rawAttributes[this.identifier].field || this.identifier;
}
if (this.options.targetKey && !this.target.rawAttributes[this.options.targetKey]) {
throw new Error(`Unknown attribute "${this.options.targetKey}" passed as targetKey, define this attribute on model "${this.target.name}" first`);
}
this.targetKey = this.options.targetKey || this.target.primaryKeyAttribute;
this.targetKeyField = this.target.rawAttributes[this.targetKey].field || this.targetKey;
this.targetKeyIsPrimary = this.targetKey === this.target.primaryKeyAttribute;
this.targetIdentifier = this.targetKey;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${singular}`,
set: `set${singular}`,
create: `create${singular}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.target.rawAttributes[this.targetKey].type,
allowNull: true
}, this.foreignKeyAttribute)
};
if (this.options.constraints !== false) {
const source = this.source.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (source.allowNull ? "SET NULL" : "NO ACTION");
this.options.onUpdate = this.options.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.target, this.source, this.options, this.targetKeyField);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
this.source.refreshAttributes();
this.identifierField = this.source.rawAttributes[this.foreignKey].field || this.foreignKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "set", "create"];
Helpers.mixinMethods(this, obj, methods);
}
async get(instances, options) {
const where = {};
let Target = this.target;
let instance;
options = Utils.cloneDeep(options);
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Target = Target.unscoped();
} else {
Target = Target.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Target = Target.schema(options.schema, options.schemaDelimiter);
}
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
if (instances) {
where[this.targetKey] = {
[Op.in]: instances.map((_instance) => _instance.get(this.foreignKey))
};
} else {
if (this.targetKeyIsPrimary && !options.where) {
return Target.findByPk(instance.get(this.foreignKey), options);
}
where[this.targetKey] = instance.get(this.foreignKey);
options.limit = null;
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (instances) {
const results = await Target.findAll(options);
const result = {};
for (const _instance of instances) {
result[_instance.get(this.foreignKey, { raw: true })] = null;
}
for (const _instance of results) {
result[_instance.get(this.targetKey, { raw: true })] = _instance;
}
return result;
}
return Target.findOne(options);
}
async set(sourceInstance, associatedInstance, options = {}) {
let value = associatedInstance;
if (associatedInstance instanceof this.target) {
value = associatedInstance[this.targetKey];
}
sourceInstance.set(this.foreignKey, value);
if (options.save === false)
return;
options = __spreadValues({
fields: [this.foreignKey],
allowNull: [this.foreignKey],
association: true
}, options);
return await sourceInstance.save(options);
}
async create(sourceInstance, values, options) {
values = values || {};
options = options || {};
const newAssociatedObject = await this.target.create(values, options);
await sourceInstance[this.accessors.set](newAssociatedObject, options);
return newAssociatedObject;
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
}
module.exports = BelongsTo;
module.exports.BelongsTo = BelongsTo;
module.exports.default = BelongsTo;
//# sourceMappingURL=belongs-to.js.map
File diff suppressed because one or more lines are too long
+316
View File
@@ -0,0 +1,316 @@
"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 Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class HasMany extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "HasMany";
this.targetAssociation = null;
this.sequelize = source.sequelize;
this.isMultiAssociation = true;
this.foreignKeyAttribute = {};
if (this.options.through) {
throw new Error("N:M associations are not supported with hasMany. Use belongsToMany instead");
}
if (this.isSelfAssociation) {
this.targetAssociation = this;
}
if (this.as) {
this.isAliased = true;
if (_.isPlainObject(this.as)) {
this.options.name = this.as;
this.as = this.as.plural;
} else {
this.options.name = {
plural: this.as,
singular: Utils.singularize(this.as)
};
}
} else {
this.as = this.target.options.name.plural;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
this.source.options.name.singular,
this.source.primaryKeyAttribute
].join("_"));
}
if (this.target.rawAttributes[this.foreignKey]) {
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignKeyField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
}
this.sourceKey = this.options.sourceKey || this.source.primaryKeyAttribute;
if (this.source.rawAttributes[this.sourceKey]) {
this.sourceKeyAttribute = this.sourceKey;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
} else {
this.sourceKeyAttribute = this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.primaryKeyField;
}
const plural = _.upperFirst(this.options.name.plural);
const singular = _.upperFirst(this.options.name.singular);
this.associationAccessor = this.as;
this.accessors = {
get: `get${plural}`,
set: `set${plural}`,
addMultiple: `add${plural}`,
add: `add${singular}`,
create: `create${singular}`,
remove: `remove${singular}`,
removeMultiple: `remove${plural}`,
hasSingle: `has${singular}`,
hasAll: `has${plural}`,
count: `count${plural}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.source.rawAttributes[this.sourceKeyAttribute].type,
allowNull: true
}, this.foreignKeyAttribute)
};
const constraintOptions = __spreadValues({}, this.options);
if (this.options.constraints !== false) {
const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
constraintOptions.onDelete = constraintOptions.onDelete || (target.allowNull ? "SET NULL" : "CASCADE");
constraintOptions.onUpdate = constraintOptions.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.source, this.target, constraintOptions, this.sourceKeyField);
Utils.mergeDefaults(this.target.rawAttributes, newAttributes);
this.target.refreshAttributes();
this.source.refreshAttributes();
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.foreignKeyField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "count", "hasSingle", "hasAll", "set", "add", "addMultiple", "remove", "removeMultiple", "create"];
const aliases = {
hasSingle: "has",
hasAll: "has",
addMultiple: "add",
removeMultiple: "remove"
};
Helpers.mixinMethods(this, obj, methods, aliases);
}
async get(instances, options = {}) {
const where = {};
let Model = this.target;
let instance;
let values;
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
options = __spreadValues({}, options);
if (this.scope) {
Object.assign(where, this.scope);
}
if (instances) {
values = instances.map((_instance) => _instance.get(this.sourceKey, { raw: true }));
if (options.limit && instances.length > 1) {
options.groupedLimit = {
limit: options.limit,
on: this,
values
};
delete options.limit;
} else {
where[this.foreignKey] = {
[Op.in]: values
};
delete options.groupedLimit;
}
} else {
where[this.foreignKey] = instance.get(this.sourceKey, { raw: true });
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Model = Model.unscoped();
} else {
Model = Model.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Model = Model.schema(options.schema, options.schemaDelimiter);
}
const results = await Model.findAll(options);
if (instance)
return results;
const result = {};
for (const _instance of instances) {
result[_instance.get(this.sourceKey, { raw: true })] = [];
}
for (const _instance of results) {
result[_instance.get(this.foreignKey, { raw: true })].push(_instance);
}
return result;
}
async count(instance, options) {
options = Utils.cloneDeep(options);
options.attributes = [
[
this.sequelize.fn("COUNT", this.sequelize.col(`${this.target.name}.${this.target.primaryKeyField}`)),
"count"
]
];
options.raw = true;
options.plain = true;
const result = await this.get(instance, options);
return parseInt(result.count, 10);
}
async has(sourceInstance, targetInstances, options) {
const where = {};
if (!Array.isArray(targetInstances)) {
targetInstances = [targetInstances];
}
options = __spreadProps(__spreadValues({}, options), {
scope: false,
attributes: [this.target.primaryKeyAttribute],
raw: true
});
where[Op.or] = targetInstances.map((instance) => {
if (instance instanceof this.target) {
return instance.where();
}
return {
[this.target.primaryKeyAttribute]: instance
};
});
options.where = {
[Op.and]: [
where,
options.where
]
};
const associatedObjects = await this.get(sourceInstance, options);
return associatedObjects.length === targetInstances.length;
}
async set(sourceInstance, targetInstances, options) {
if (targetInstances === null) {
targetInstances = [];
} else {
targetInstances = this.toInstanceArray(targetInstances);
}
const oldAssociations = await this.get(sourceInstance, __spreadProps(__spreadValues({}, options), { scope: false, raw: true }));
const promises = [];
const obsoleteAssociations = oldAssociations.filter((old) => !targetInstances.find((obj) => obj[this.target.primaryKeyAttribute] === old[this.target.primaryKeyAttribute]));
const unassociatedObjects = targetInstances.filter((obj) => !oldAssociations.find((old) => obj[this.target.primaryKeyAttribute] === old[this.target.primaryKeyAttribute]));
let updateWhere;
let update;
if (obsoleteAssociations.length > 0) {
update = {};
update[this.foreignKey] = null;
updateWhere = {
[this.target.primaryKeyAttribute]: obsoleteAssociations.map((associatedObject) => associatedObject[this.target.primaryKeyAttribute])
};
promises.push(this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), {
where: updateWhere
})));
}
if (unassociatedObjects.length > 0) {
updateWhere = {};
update = {};
update[this.foreignKey] = sourceInstance.get(this.sourceKey);
Object.assign(update, this.scope);
updateWhere[this.target.primaryKeyAttribute] = unassociatedObjects.map((unassociatedObject) => unassociatedObject[this.target.primaryKeyAttribute]);
promises.push(this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), {
where: updateWhere
})));
}
await Promise.all(promises);
return sourceInstance;
}
async add(sourceInstance, targetInstances, options = {}) {
if (!targetInstances)
return Promise.resolve();
targetInstances = this.toInstanceArray(targetInstances);
const update = __spreadValues({
[this.foreignKey]: sourceInstance.get(this.sourceKey)
}, this.scope);
const where = {
[this.target.primaryKeyAttribute]: targetInstances.map((unassociatedObject) => unassociatedObject.get(this.target.primaryKeyAttribute))
};
await this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), { where }));
return sourceInstance;
}
async remove(sourceInstance, targetInstances, options = {}) {
const update = {
[this.foreignKey]: null
};
targetInstances = this.toInstanceArray(targetInstances);
const where = {
[this.foreignKey]: sourceInstance.get(this.sourceKey),
[this.target.primaryKeyAttribute]: targetInstances.map((targetInstance) => targetInstance.get(this.target.primaryKeyAttribute))
};
await this.target.unscoped().update(update, __spreadProps(__spreadValues({}, options), { where }));
return this;
}
async create(sourceInstance, values, options = {}) {
if (Array.isArray(options)) {
options = {
fields: options
};
}
if (values === void 0) {
values = {};
}
if (this.scope) {
for (const attribute of Object.keys(this.scope)) {
values[attribute] = this.scope[attribute];
if (options.fields)
options.fields.push(attribute);
}
}
values[this.foreignKey] = sourceInstance.get(this.sourceKey);
if (options.fields)
options.fields.push(this.foreignKey);
return await this.target.create(values, options);
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.plural) {
return this.as === alias.plural;
}
return !this.isAliased;
}
}
module.exports = HasMany;
module.exports.HasMany = HasMany;
module.exports.default = HasMany;
//# sourceMappingURL=has-many.js.map
File diff suppressed because one or more lines are too long
+191
View File
@@ -0,0 +1,191 @@
"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 Helpers = require("./helpers");
const _ = require("lodash");
const Association = require("./base");
const Op = require("../operators");
class HasOne extends Association {
constructor(source, target, options) {
super(source, target, options);
this.associationType = "HasOne";
this.isSingleAssociation = true;
this.foreignKeyAttribute = {};
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
if (_.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else if (this.options.foreignKey) {
this.foreignKey = this.options.foreignKey;
}
if (!this.foreignKey) {
this.foreignKey = Utils.camelize([
Utils.singularize(this.options.as || this.source.name),
this.source.primaryKeyAttribute
].join("_"));
}
if (this.options.sourceKey && !this.source.rawAttributes[this.options.sourceKey]) {
throw new Error(`Unknown attribute "${this.options.sourceKey}" passed as sourceKey, define this attribute on model "${this.source.name}" first`);
}
this.sourceKey = this.sourceKeyAttribute = this.options.sourceKey || this.source.primaryKeyAttribute;
this.sourceKeyField = this.source.rawAttributes[this.sourceKey].field || this.sourceKey;
this.sourceKeyIsPrimary = this.sourceKey === this.source.primaryKeyAttribute;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
if (this.target.rawAttributes[this.foreignKey]) {
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
}
const singular = _.upperFirst(this.options.name.singular);
this.accessors = {
get: `get${singular}`,
set: `set${singular}`,
create: `create${singular}`
};
}
_injectAttributes() {
const newAttributes = {
[this.foreignKey]: __spreadValues({
type: this.options.keyType || this.source.rawAttributes[this.sourceKey].type,
allowNull: true
}, this.foreignKeyAttribute)
};
if (this.options.constraints !== false) {
const target = this.target.rawAttributes[this.foreignKey] || newAttributes[this.foreignKey];
this.options.onDelete = this.options.onDelete || (target.allowNull ? "SET NULL" : "CASCADE");
this.options.onUpdate = this.options.onUpdate || "CASCADE";
}
Helpers.addForeignKeyConstraints(newAttributes[this.foreignKey], this.source, this.target, this.options, this.sourceKeyField);
Utils.mergeDefaults(this.target.rawAttributes, newAttributes);
this.target.refreshAttributes();
this.identifierField = this.target.rawAttributes[this.foreignKey].field || this.foreignKey;
Helpers.checkNamingCollision(this);
return this;
}
mixin(obj) {
const methods = ["get", "set", "create"];
Helpers.mixinMethods(this, obj, methods);
}
async get(instances, options) {
const where = {};
let Target = this.target;
let instance;
options = Utils.cloneDeep(options);
if (Object.prototype.hasOwnProperty.call(options, "scope")) {
if (!options.scope) {
Target = Target.unscoped();
} else {
Target = Target.scope(options.scope);
}
}
if (Object.prototype.hasOwnProperty.call(options, "schema")) {
Target = Target.schema(options.schema, options.schemaDelimiter);
}
if (!Array.isArray(instances)) {
instance = instances;
instances = void 0;
}
if (instances) {
where[this.foreignKey] = {
[Op.in]: instances.map((_instance) => _instance.get(this.sourceKey))
};
} else {
where[this.foreignKey] = instance.get(this.sourceKey);
}
if (this.scope) {
Object.assign(where, this.scope);
}
options.where = options.where ? { [Op.and]: [where, options.where] } : where;
if (instances) {
const results = await Target.findAll(options);
const result = {};
for (const _instance of instances) {
result[_instance.get(this.sourceKey, { raw: true })] = null;
}
for (const _instance of results) {
result[_instance.get(this.foreignKey, { raw: true })] = _instance;
}
return result;
}
return Target.findOne(options);
}
async set(sourceInstance, associatedInstance, options) {
options = __spreadProps(__spreadValues({}, options), { scope: false });
const oldInstance = await sourceInstance[this.accessors.get](options);
const alreadyAssociated = oldInstance && associatedInstance && this.target.primaryKeyAttributes.every((attribute) => oldInstance.get(attribute, { raw: true }) === (associatedInstance.get ? associatedInstance.get(attribute, { raw: true }) : associatedInstance));
if (oldInstance && !alreadyAssociated) {
oldInstance[this.foreignKey] = null;
await oldInstance.save(__spreadProps(__spreadValues({}, options), {
fields: [this.foreignKey],
allowNull: [this.foreignKey],
association: true
}));
}
if (associatedInstance && !alreadyAssociated) {
if (!(associatedInstance instanceof this.target)) {
const tmpInstance = {};
tmpInstance[this.target.primaryKeyAttribute] = associatedInstance;
associatedInstance = this.target.build(tmpInstance, {
isNewRecord: false
});
}
Object.assign(associatedInstance, this.scope);
associatedInstance.set(this.foreignKey, sourceInstance.get(this.sourceKeyAttribute));
return associatedInstance.save(options);
}
return null;
}
async create(sourceInstance, values, options) {
values = values || {};
options = options || {};
if (this.scope) {
for (const attribute of Object.keys(this.scope)) {
values[attribute] = this.scope[attribute];
if (options.fields) {
options.fields.push(attribute);
}
}
}
values[this.foreignKey] = sourceInstance.get(this.sourceKeyAttribute);
if (options.fields) {
options.fields.push(this.foreignKey);
}
return await this.target.create(values, options);
}
verifyAssociationAlias(alias) {
if (typeof alias === "string") {
return this.as === alias;
}
if (alias && alias.singular) {
return this.as === alias.singular;
}
return !this.isAliased;
}
}
module.exports = HasOne;
//# sourceMappingURL=has-one.js.map
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
"use strict";
function checkNamingCollision(association) {
if (Object.prototype.hasOwnProperty.call(association.source.rawAttributes, association.as)) {
throw new Error(`Naming collision between attribute '${association.as}' and association '${association.as}' on model ${association.source.name}. To remedy this, change either foreignKey or as in your association definition`);
}
}
exports.checkNamingCollision = checkNamingCollision;
function addForeignKeyConstraints(newAttribute, source, target, options, key) {
if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
const primaryKeys = Object.keys(source.primaryKeys).map((primaryKeyAttribute) => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);
if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {
newAttribute.references = {
model: source.getTableName(),
key: key || primaryKeys[0]
};
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
}
}
}
exports.addForeignKeyConstraints = addForeignKeyConstraints;
function mixinMethods(association, obj, methods, aliases) {
aliases = aliases || {};
for (const method of methods) {
if (!Object.prototype.hasOwnProperty.call(obj, association.accessors[method])) {
const realMethod = aliases[method] || method;
obj[association.accessors[method]] = function() {
return association[realMethod](this, ...Array.from(arguments));
};
}
}
}
exports.mixinMethods = mixinMethods;
//# sourceMappingURL=helpers.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/helpers.js"],
"sourcesContent": ["'use strict';\n\nfunction checkNamingCollision(association) {\n if (Object.prototype.hasOwnProperty.call(association.source.rawAttributes, association.as)) {\n throw new Error(\n `Naming collision between attribute '${association.as}'` +\n ` and association '${association.as}' on model ${association.source.name}` +\n '. To remedy this, change either foreignKey or as in your association definition'\n );\n }\n}\nexports.checkNamingCollision = checkNamingCollision;\n\nfunction addForeignKeyConstraints(newAttribute, source, target, options, key) {\n // FK constraints are opt-in: users must either set `foreignKeyConstraints`\n // on the association, or request an `onDelete` or `onUpdate` behavior\n\n if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {\n // Find primary keys: composite keys not supported with this approach\n const primaryKeys = Object.keys(source.primaryKeys)\n .map(primaryKeyAttribute => source.rawAttributes[primaryKeyAttribute].field || primaryKeyAttribute);\n\n if (primaryKeys.length === 1 || !primaryKeys.includes(key)) {\n newAttribute.references = {\n model: source.getTableName(),\n key: key || primaryKeys[0]\n };\n\n newAttribute.onDelete = options.onDelete;\n newAttribute.onUpdate = options.onUpdate;\n }\n }\n}\nexports.addForeignKeyConstraints = addForeignKeyConstraints;\n\n/**\n * Mixin (inject) association methods to model prototype\n *\n * @private\n *\n * @param {object} association instance\n * @param {object} obj Model prototype\n * @param {Array} methods Method names to inject\n * @param {object} aliases Mapping between model and association method names\n *\n */\nfunction mixinMethods(association, obj, methods, aliases) {\n aliases = aliases || {};\n\n for (const method of methods) {\n // don't override custom methods\n if (!Object.prototype.hasOwnProperty.call(obj, association.accessors[method])) {\n const realMethod = aliases[method] || method;\n\n obj[association.accessors[method]] = function() {\n return association[realMethod](this, ...Array.from(arguments));\n };\n }\n }\n}\nexports.mixinMethods = mixinMethods;\n"],
"mappings": ";AAEA,8BAA8B,aAAa;AACzC,MAAI,OAAO,UAAU,eAAe,KAAK,YAAY,OAAO,eAAe,YAAY,KAAK;AAC1F,UAAM,IAAI,MACR,uCAAuC,YAAY,wBAC9B,YAAY,gBAAgB,YAAY,OAAO;AAAA;AAAA;AAK1E,QAAQ,uBAAuB;AAE/B,kCAAkC,cAAc,QAAQ,QAAQ,SAAS,KAAK;AAI5E,MAAI,QAAQ,wBAAwB,QAAQ,YAAY,QAAQ,UAAU;AAExE,UAAM,cAAc,OAAO,KAAK,OAAO,aACpC,IAAI,yBAAuB,OAAO,cAAc,qBAAqB,SAAS;AAEjF,QAAI,YAAY,WAAW,KAAK,CAAC,YAAY,SAAS,MAAM;AAC1D,mBAAa,aAAa;AAAA,QACxB,OAAO,OAAO;AAAA,QACd,KAAK,OAAO,YAAY;AAAA;AAG1B,mBAAa,WAAW,QAAQ;AAChC,mBAAa,WAAW,QAAQ;AAAA;AAAA;AAAA;AAItC,QAAQ,2BAA2B;AAanC,sBAAsB,aAAa,KAAK,SAAS,SAAS;AACxD,YAAU,WAAW;AAErB,aAAW,UAAU,SAAS;AAE5B,QAAI,CAAC,OAAO,UAAU,eAAe,KAAK,KAAK,YAAY,UAAU,UAAU;AAC7E,YAAM,aAAa,QAAQ,WAAW;AAEtC,UAAI,YAAY,UAAU,WAAW,WAAW;AAC9C,eAAO,YAAY,YAAY,MAAM,GAAG,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAK3D,QAAQ,eAAe;",
"names": []
}
+10
View File
@@ -0,0 +1,10 @@
"use strict";
const Association = require("./base");
Association.BelongsTo = require("./belongs-to");
Association.HasOne = require("./has-one");
Association.HasMany = require("./has-many");
Association.BelongsToMany = require("./belongs-to-many");
module.exports = Association;
module.exports.default = Association;
module.exports.Association = Association;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/index.js"],
"sourcesContent": ["'use strict';\n\nconst Association = require('./base');\n\nAssociation.BelongsTo = require('./belongs-to');\nAssociation.HasOne = require('./has-one');\nAssociation.HasMany = require('./has-many');\nAssociation.BelongsToMany = require('./belongs-to-many');\n\nmodule.exports = Association;\nmodule.exports.default = Association;\nmodule.exports.Association = Association;\n"],
"mappings": ";AAEA,MAAM,cAAc,QAAQ;AAE5B,YAAY,YAAY,QAAQ;AAChC,YAAY,SAAS,QAAQ;AAC7B,YAAY,UAAU,QAAQ;AAC9B,YAAY,gBAAgB,QAAQ;AAEpC,OAAO,UAAU;AACjB,OAAO,QAAQ,UAAU;AACzB,OAAO,QAAQ,cAAc;",
"names": []
}
+85
View File
@@ -0,0 +1,85 @@
"use strict";
const _ = require("lodash");
const HasOne = require("./has-one");
const HasMany = require("./has-many");
const BelongsToMany = require("./belongs-to-many");
const BelongsTo = require("./belongs-to");
function isModel(model, sequelize) {
return model && model.prototype && model.prototype instanceof sequelize.Sequelize.Model;
}
const Mixin = {
hasMany(target, options = {}) {
if (!isModel(target, this.sequelize)) {
throw new Error(`${this.name}.hasMany called with something that's not a subclass of Sequelize.Model`);
}
const source = this;
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
Object.assign(options, _.omit(source.options, ["hooks"]));
if (options.useHooks) {
this.runHooks("beforeAssociate", { source, target, type: HasMany }, options);
}
const association = new HasMany(source, target, options);
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
this.runHooks("afterAssociate", { source, target, type: HasMany, association }, options);
}
return association;
},
belongsToMany(target, options = {}) {
if (!isModel(target, this.sequelize)) {
throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model`);
}
const source = this;
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
options.timestamps = options.timestamps === void 0 ? this.sequelize.options.timestamps : options.timestamps;
Object.assign(options, _.omit(source.options, ["hooks", "timestamps", "scopes", "defaultScope"]));
if (options.useHooks) {
this.runHooks("beforeAssociate", { source, target, type: BelongsToMany }, options);
}
const association = new BelongsToMany(source, target, options);
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
this.runHooks("afterAssociate", { source, target, type: BelongsToMany, association }, options);
}
return association;
},
getAssociations(target) {
return Object.values(this.associations).filter((association) => association.target.name === target.name);
},
getAssociationForAlias(target, alias) {
return this.getAssociations(target).find((association) => association.verifyAssociationAlias(alias)) || null;
}
};
function singleLinked(Type) {
return function(target, options = {}) {
const source = this;
if (!isModel(target, source.sequelize)) {
throw new Error(`${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);
}
options.hooks = options.hooks === void 0 ? false : Boolean(options.hooks);
options.useHooks = options.hooks;
if (options.useHooks) {
source.runHooks("beforeAssociate", { source, target, type: Type }, options);
}
const association = new Type(source, target, Object.assign(options, source.options));
source.associations[association.associationAccessor] = association;
association._injectAttributes();
association.mixin(source.prototype);
if (options.useHooks) {
source.runHooks("afterAssociate", { source, target, type: Type, association }, options);
}
return association;
};
}
Mixin.hasOne = singleLinked(HasOne);
Mixin.belongsTo = singleLinked(BelongsTo);
module.exports = Mixin;
module.exports.Mixin = Mixin;
module.exports.default = Mixin;
//# sourceMappingURL=mixin.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/associations/mixin.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst HasOne = require('./has-one');\nconst HasMany = require('./has-many');\nconst BelongsToMany = require('./belongs-to-many');\nconst BelongsTo = require('./belongs-to');\n\nfunction isModel(model, sequelize) {\n return model\n && model.prototype\n && model.prototype instanceof sequelize.Sequelize.Model;\n}\n\nconst Mixin = {\n hasMany(target, options = {}) {\n if (!isModel(target, this.sequelize)) {\n throw new Error(`${this.name}.hasMany called with something that's not a subclass of Sequelize.Model`);\n }\n\n const source = this;\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n\n Object.assign(options, _.omit(source.options, ['hooks']));\n\n if (options.useHooks) {\n this.runHooks('beforeAssociate', { source, target, type: HasMany }, options);\n }\n\n // the id is in the foreign table or in a connecting table\n const association = new HasMany(source, target, options);\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n this.runHooks('afterAssociate', { source, target, type: HasMany, association }, options);\n }\n\n return association;\n },\n\n belongsToMany(target, options = {}) {\n if (!isModel(target, this.sequelize)) {\n throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model`);\n }\n\n const source = this;\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n options.timestamps = options.timestamps === undefined ? this.sequelize.options.timestamps : options.timestamps;\n Object.assign(options, _.omit(source.options, ['hooks', 'timestamps', 'scopes', 'defaultScope']));\n\n if (options.useHooks) {\n this.runHooks('beforeAssociate', { source, target, type: BelongsToMany }, options);\n }\n // the id is in the foreign table or in a connecting table\n const association = new BelongsToMany(source, target, options);\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n this.runHooks('afterAssociate', { source, target, type: BelongsToMany, association }, options);\n }\n\n return association;\n },\n\n getAssociations(target) {\n return Object.values(this.associations).filter(association => association.target.name === target.name);\n },\n\n getAssociationForAlias(target, alias) {\n // Two associations cannot have the same alias, so we can use find instead of filter\n return this.getAssociations(target).find(association => association.verifyAssociationAlias(alias)) || null;\n }\n};\n\n// The logic for hasOne and belongsTo is exactly the same\nfunction singleLinked(Type) {\n return function(target, options = {}) {\n // eslint-disable-next-line no-invalid-this\n const source = this;\n if (!isModel(target, source.sequelize)) {\n throw new Error(`${source.name}.${_.lowerFirst(Type.name)} called with something that's not a subclass of Sequelize.Model`);\n }\n\n\n // Since this is a mixin, we'll need a unique letiable name for hooks (since Model will override our hooks option)\n options.hooks = options.hooks === undefined ? false : Boolean(options.hooks);\n options.useHooks = options.hooks;\n\n if (options.useHooks) {\n source.runHooks('beforeAssociate', { source, target, type: Type }, options);\n }\n // the id is in the foreign table\n const association = new Type(source, target, Object.assign(options, source.options));\n source.associations[association.associationAccessor] = association;\n\n association._injectAttributes();\n association.mixin(source.prototype);\n\n if (options.useHooks) {\n source.runHooks('afterAssociate', { source, target, type: Type, association }, options);\n }\n\n return association;\n };\n}\n\nMixin.hasOne = singleLinked(HasOne);\nMixin.belongsTo = singleLinked(BelongsTo);\n\nmodule.exports = Mixin;\nmodule.exports.Mixin = Mixin;\nmodule.exports.default = Mixin;\n"],
"mappings": ";AAEA,MAAM,IAAI,QAAQ;AAClB,MAAM,SAAS,QAAQ;AACvB,MAAM,UAAU,QAAQ;AACxB,MAAM,gBAAgB,QAAQ;AAC9B,MAAM,YAAY,QAAQ;AAE1B,iBAAiB,OAAO,WAAW;AACjC,SAAO,SACF,MAAM,aACN,MAAM,qBAAqB,UAAU,UAAU;AAAA;AAGtD,MAAM,QAAQ;AAAA,EACZ,QAAQ,QAAQ,UAAU,IAAI;AAC5B,QAAI,CAAC,QAAQ,QAAQ,KAAK,YAAY;AACpC,YAAM,IAAI,MAAM,GAAG,KAAK;AAAA;AAG1B,UAAM,SAAS;AAGf,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAE3B,WAAO,OAAO,SAAS,EAAE,KAAK,OAAO,SAAS,CAAC;AAE/C,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,WAAW;AAAA;AAItE,UAAM,cAAc,IAAI,QAAQ,QAAQ,QAAQ;AAChD,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,SAAS,eAAe;AAAA;AAGlF,WAAO;AAAA;AAAA,EAGT,cAAc,QAAQ,UAAU,IAAI;AAClC,QAAI,CAAC,QAAQ,QAAQ,KAAK,YAAY;AACpC,YAAM,IAAI,MAAM,GAAG,KAAK;AAAA;AAG1B,UAAM,SAAS;AAGf,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAC3B,YAAQ,aAAa,QAAQ,eAAe,SAAY,KAAK,UAAU,QAAQ,aAAa,QAAQ;AACpG,WAAO,OAAO,SAAS,EAAE,KAAK,OAAO,SAAS,CAAC,SAAS,cAAc,UAAU;AAEhF,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,iBAAiB;AAAA;AAG5E,UAAM,cAAc,IAAI,cAAc,QAAQ,QAAQ;AACtD,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,WAAK,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,eAAe,eAAe;AAAA;AAGxF,WAAO;AAAA;AAAA,EAGT,gBAAgB,QAAQ;AACtB,WAAO,OAAO,OAAO,KAAK,cAAc,OAAO,iBAAe,YAAY,OAAO,SAAS,OAAO;AAAA;AAAA,EAGnG,uBAAuB,QAAQ,OAAO;AAEpC,WAAO,KAAK,gBAAgB,QAAQ,KAAK,iBAAe,YAAY,uBAAuB,WAAW;AAAA;AAAA;AAK1G,sBAAsB,MAAM;AAC1B,SAAO,SAAS,QAAQ,UAAU,IAAI;AAEpC,UAAM,SAAS;AACf,QAAI,CAAC,QAAQ,QAAQ,OAAO,YAAY;AACtC,YAAM,IAAI,MAAM,GAAG,OAAO,QAAQ,EAAE,WAAW,KAAK;AAAA;AAKtD,YAAQ,QAAQ,QAAQ,UAAU,SAAY,QAAQ,QAAQ,QAAQ;AACtE,YAAQ,WAAW,QAAQ;AAE3B,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS,mBAAmB,EAAE,QAAQ,QAAQ,MAAM,QAAQ;AAAA;AAGrE,UAAM,cAAc,IAAI,KAAK,QAAQ,QAAQ,OAAO,OAAO,SAAS,OAAO;AAC3E,WAAO,aAAa,YAAY,uBAAuB;AAEvD,gBAAY;AACZ,gBAAY,MAAM,OAAO;AAEzB,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,MAAM,MAAM,eAAe;AAAA;AAGjF,WAAO;AAAA;AAAA;AAIX,MAAM,SAAS,aAAa;AAC5B,MAAM,YAAY,aAAa;AAE/B,OAAO,UAAU;AACjB,OAAO,QAAQ,QAAQ;AACvB,OAAO,QAAQ,UAAU;",
"names": []
}
+669
View File
@@ -0,0 +1,669 @@
"use strict";
const util = require("util");
const _ = require("lodash");
const wkx = require("wkx");
const sequelizeErrors = require("./errors");
const Validator = require("./utils/validator-extras").validator;
const momentTz = require("moment-timezone");
const moment = require("moment");
const { logger } = require("./utils/logger");
const warnings = {};
const { classToInvokable } = require("./utils/class-to-invokable");
const { joinSQLFragments } = require("./utils/join-sql-fragments");
class ABSTRACT {
toString(options) {
return this.toSql(options);
}
toSql() {
return this.key;
}
stringify(value, options) {
if (this._stringify) {
return this._stringify(value, options);
}
return value;
}
bindParam(value, options) {
if (this._bindParam) {
return this._bindParam(value, options);
}
return options.bindParam(this.stringify(value, options));
}
static toString() {
return this.name;
}
static warn(link, text) {
if (!warnings[text]) {
warnings[text] = true;
logger.warn(`${text}
>> Check: ${link}`);
}
}
static extend(oldType) {
return new this(oldType.options);
}
}
ABSTRACT.prototype.dialectTypes = "";
class STRING extends ABSTRACT {
constructor(length, binary) {
super();
const options = typeof length === "object" && length || { length, binary };
this.options = options;
this._binary = options.binary;
this._length = options.length || 255;
}
toSql() {
return joinSQLFragments([
`VARCHAR(${this._length})`,
this._binary && "BINARY"
]);
}
validate(value) {
if (Object.prototype.toString.call(value) !== "[object String]") {
if (this.options.binary && Buffer.isBuffer(value) || typeof value === "number") {
return true;
}
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid string", value));
}
return true;
}
get BINARY() {
this._binary = true;
this.options.binary = true;
return this;
}
static get BINARY() {
return new this().BINARY;
}
}
class CHAR extends STRING {
constructor(length, binary) {
super(typeof length === "object" && length || { length, binary });
}
toSql() {
return joinSQLFragments([
`CHAR(${this._length})`,
this._binary && "BINARY"
]);
}
}
class TEXT extends ABSTRACT {
constructor(length) {
super();
const options = typeof length === "object" && length || { length };
this.options = options;
this._length = options.length || "";
}
toSql() {
switch (this._length.toLowerCase()) {
case "tiny":
return "TINYTEXT";
case "medium":
return "MEDIUMTEXT";
case "long":
return "LONGTEXT";
default:
return this.key;
}
}
validate(value) {
if (typeof value !== "string") {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid string", value));
}
return true;
}
}
class CITEXT extends ABSTRACT {
toSql() {
return "CITEXT";
}
validate(value) {
if (typeof value !== "string") {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid string", value));
}
return true;
}
}
class NUMBER extends ABSTRACT {
constructor(options = {}) {
super();
if (typeof options === "number") {
options = {
length: options
};
}
this.options = options;
this._length = options.length;
this._zerofill = options.zerofill;
this._decimals = options.decimals;
this._precision = options.precision;
this._scale = options.scale;
this._unsigned = options.unsigned;
}
toSql() {
let result = this.key;
if (this._length) {
result += `(${this._length}`;
if (typeof this._decimals === "number") {
result += `,${this._decimals}`;
}
result += ")";
}
if (this._unsigned) {
result += " UNSIGNED";
}
if (this._zerofill) {
result += " ZEROFILL";
}
return result;
}
validate(value) {
if (!Validator.isFloat(String(value))) {
throw new sequelizeErrors.ValidationError(util.format(`%j is not a valid ${this.key.toLowerCase()}`, value));
}
return true;
}
_stringify(number) {
if (typeof number === "number" || typeof number === "bigint" || typeof number === "boolean" || number === null || number === void 0) {
return number;
}
if (typeof number.toString === "function") {
return number.toString();
}
return number;
}
get UNSIGNED() {
this._unsigned = true;
this.options.unsigned = true;
return this;
}
get ZEROFILL() {
this._zerofill = true;
this.options.zerofill = true;
return this;
}
static get UNSIGNED() {
return new this().UNSIGNED;
}
static get ZEROFILL() {
return new this().ZEROFILL;
}
}
class INTEGER extends NUMBER {
validate(value) {
if (!Validator.isInt(String(value))) {
throw new sequelizeErrors.ValidationError(util.format(`%j is not a valid ${this.key.toLowerCase()}`, value));
}
return true;
}
}
class TINYINT extends INTEGER {
}
class SMALLINT extends INTEGER {
}
class MEDIUMINT extends INTEGER {
}
class BIGINT extends INTEGER {
}
class FLOAT extends NUMBER {
constructor(length, decimals) {
super(typeof length === "object" && length || { length, decimals });
}
validate(value) {
if (!Validator.isFloat(String(value))) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid float", value));
}
return true;
}
}
class REAL extends NUMBER {
constructor(length, decimals) {
super(typeof length === "object" && length || { length, decimals });
}
}
class DOUBLE extends NUMBER {
constructor(length, decimals) {
super(typeof length === "object" && length || { length, decimals });
}
}
class DECIMAL extends NUMBER {
constructor(precision, scale) {
super(typeof precision === "object" && precision || { precision, scale });
}
toSql() {
if (this._precision || this._scale) {
return `DECIMAL(${[this._precision, this._scale].filter(_.identity).join(",")})`;
}
return "DECIMAL";
}
validate(value) {
if (!Validator.isDecimal(String(value))) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid decimal", value));
}
return true;
}
}
const protoExtensions = {
escape: false,
_value(value) {
if (isNaN(value)) {
return "NaN";
}
if (!isFinite(value)) {
const sign = value < 0 ? "-" : "";
return `${sign}Infinity`;
}
return value;
},
_stringify(value) {
return `'${this._value(value)}'`;
},
_bindParam(value, options) {
return options.bindParam(this._value(value));
}
};
for (const floating of [FLOAT, DOUBLE, REAL]) {
Object.assign(floating.prototype, protoExtensions);
}
class BOOLEAN extends ABSTRACT {
toSql() {
return "TINYINT(1)";
}
validate(value) {
if (!Validator.isBoolean(String(value))) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid boolean", value));
}
return true;
}
_sanitize(value) {
if (value !== null && value !== void 0) {
if (Buffer.isBuffer(value) && value.length === 1) {
value = value[0];
}
const type = typeof value;
if (type === "string") {
return value === "true" ? true : value === "false" ? false : value;
}
if (type === "number") {
return value === 1 ? true : value === 0 ? false : value;
}
}
return value;
}
}
BOOLEAN.parse = BOOLEAN.prototype._sanitize;
class TIME extends ABSTRACT {
toSql() {
return "TIME";
}
}
class DATE extends ABSTRACT {
constructor(length) {
super();
const options = typeof length === "object" && length || { length };
this.options = options;
this._length = options.length || "";
}
toSql() {
return "DATETIME";
}
validate(value) {
if (!Validator.isDate(String(value))) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid date", value));
}
return true;
}
_sanitize(value, options) {
if ((!options || options && !options.raw) && !(value instanceof Date) && !!value) {
return new Date(value);
}
return value;
}
_isChanged(value, originalValue) {
if (originalValue && !!value && (value === originalValue || value instanceof Date && originalValue instanceof Date && value.getTime() === originalValue.getTime())) {
return false;
}
if (!originalValue && !value && originalValue === value) {
return false;
}
return true;
}
_applyTimezone(date, options) {
if (options.timezone) {
if (momentTz.tz.zone(options.timezone)) {
return momentTz(date).tz(options.timezone);
}
return date = moment(date).utcOffset(options.timezone);
}
return momentTz(date);
}
_stringify(date, options) {
if (!moment.isMoment(date)) {
date = this._applyTimezone(date, options);
}
return date.format("YYYY-MM-DD HH:mm:ss.SSS Z");
}
}
class DATEONLY extends ABSTRACT {
toSql() {
return "DATE";
}
_stringify(date) {
return moment(date).format("YYYY-MM-DD");
}
_sanitize(value, options) {
if ((!options || options && !options.raw) && !!value) {
return moment(value).format("YYYY-MM-DD");
}
return value;
}
_isChanged(value, originalValue) {
if (originalValue && !!value && originalValue === value) {
return false;
}
if (!originalValue && !value && originalValue === value) {
return false;
}
return true;
}
}
class HSTORE extends ABSTRACT {
validate(value) {
if (!_.isPlainObject(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid hstore", value));
}
return true;
}
}
class JSONTYPE extends ABSTRACT {
validate() {
return true;
}
_stringify(value) {
return JSON.stringify(value);
}
}
class JSONB extends JSONTYPE {
}
class NOW extends ABSTRACT {
}
class BLOB extends ABSTRACT {
constructor(length) {
super();
const options = typeof length === "object" && length || { length };
this.options = options;
this._length = options.length || "";
}
toSql() {
switch (this._length.toLowerCase()) {
case "tiny":
return "TINYBLOB";
case "medium":
return "MEDIUMBLOB";
case "long":
return "LONGBLOB";
default:
return this.key;
}
}
validate(value) {
if (typeof value !== "string" && !Buffer.isBuffer(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid blob", value));
}
return true;
}
_stringify(value) {
if (!Buffer.isBuffer(value)) {
if (Array.isArray(value)) {
value = Buffer.from(value);
} else {
value = Buffer.from(value.toString());
}
}
const hex = value.toString("hex");
return this._hexify(hex);
}
_hexify(hex) {
return `X'${hex}'`;
}
_bindParam(value, options) {
if (!Buffer.isBuffer(value)) {
if (Array.isArray(value)) {
value = Buffer.from(value);
} else {
value = Buffer.from(value.toString());
}
}
return options.bindParam(value);
}
}
BLOB.prototype.escape = false;
class RANGE extends ABSTRACT {
constructor(subtype) {
super();
const options = _.isPlainObject(subtype) ? subtype : { subtype };
if (!options.subtype)
options.subtype = new INTEGER();
if (typeof options.subtype === "function") {
options.subtype = new options.subtype();
}
this._subtype = options.subtype.key;
this.options = options;
}
validate(value) {
if (!Array.isArray(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid range", value));
}
if (value.length !== 2) {
throw new sequelizeErrors.ValidationError("A range must be an array with two elements");
}
return true;
}
}
class UUID extends ABSTRACT {
validate(value, options) {
if (typeof value !== "string" || !Validator.isUUID(value) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid uuid", value));
}
return true;
}
}
class UUIDV1 extends ABSTRACT {
validate(value, options) {
if (typeof value !== "string" || !Validator.isUUID(value) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid uuid", value));
}
return true;
}
}
class UUIDV4 extends ABSTRACT {
validate(value, options) {
if (typeof value !== "string" || !Validator.isUUID(value, 4) && (!options || !options.acceptStrings)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid uuidv4", value));
}
return true;
}
}
class VIRTUAL extends ABSTRACT {
constructor(ReturnType, fields) {
super();
if (typeof ReturnType === "function")
ReturnType = new ReturnType();
this.returnType = ReturnType;
this.fields = fields;
}
}
class ENUM extends ABSTRACT {
constructor(...args) {
super();
const value = args[0];
const options = typeof value === "object" && !Array.isArray(value) && value || {
values: args.reduce((result, element) => {
return result.concat(Array.isArray(element) ? element : [element]);
}, [])
};
this.values = options.values;
this.options = options;
}
validate(value) {
if (!this.values.includes(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid choice in %j", value, this.values));
}
return true;
}
}
class ARRAY extends ABSTRACT {
constructor(type) {
super();
const options = _.isPlainObject(type) ? type : { type };
this.options = options;
this.type = typeof options.type === "function" ? new options.type() : options.type;
}
toSql() {
return `${this.type.toSql()}[]`;
}
validate(value) {
if (!Array.isArray(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid array", value));
}
return true;
}
static is(obj, type) {
return obj instanceof ARRAY && obj.type instanceof type;
}
}
class GEOMETRY extends ABSTRACT {
constructor(type, srid) {
super();
const options = _.isPlainObject(type) ? type : { type, srid };
this.options = options;
this.type = options.type;
this.srid = options.srid;
}
_stringify(value, options) {
return `ST_GeomFromText(${options.escape(wkx.Geometry.parseGeoJSON(value).toWkt())})`;
}
_bindParam(value, options) {
return `ST_GeomFromText(${options.bindParam(wkx.Geometry.parseGeoJSON(value).toWkt())})`;
}
}
GEOMETRY.prototype.escape = false;
class GEOGRAPHY extends ABSTRACT {
constructor(type, srid) {
super();
const options = _.isPlainObject(type) ? type : { type, srid };
this.options = options;
this.type = options.type;
this.srid = options.srid;
}
_stringify(value, options) {
return `ST_GeomFromText(${options.escape(wkx.Geometry.parseGeoJSON(value).toWkt())})`;
}
_bindParam(value, options) {
return `ST_GeomFromText(${options.bindParam(wkx.Geometry.parseGeoJSON(value).toWkt())})`;
}
}
GEOGRAPHY.prototype.escape = false;
class CIDR extends ABSTRACT {
validate(value) {
if (typeof value !== "string" || !Validator.isIPRange(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid CIDR", value));
}
return true;
}
}
class INET extends ABSTRACT {
validate(value) {
if (typeof value !== "string" || !Validator.isIP(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid INET", value));
}
return true;
}
}
class MACADDR extends ABSTRACT {
validate(value) {
if (typeof value !== "string" || !Validator.isMACAddress(value)) {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid MACADDR", value));
}
return true;
}
}
class TSVECTOR extends ABSTRACT {
validate(value) {
if (typeof value !== "string") {
throw new sequelizeErrors.ValidationError(util.format("%j is not a valid string", value));
}
return true;
}
}
const DataTypes = module.exports = {
ABSTRACT,
STRING,
CHAR,
TEXT,
NUMBER,
TINYINT,
SMALLINT,
MEDIUMINT,
INTEGER,
BIGINT,
FLOAT,
TIME,
DATE,
DATEONLY,
BOOLEAN,
NOW,
BLOB,
DECIMAL,
NUMERIC: DECIMAL,
UUID,
UUIDV1,
UUIDV4,
HSTORE,
JSON: JSONTYPE,
JSONB,
VIRTUAL,
ARRAY,
ENUM,
RANGE,
REAL,
"DOUBLE PRECISION": DOUBLE,
DOUBLE,
GEOMETRY,
GEOGRAPHY,
CIDR,
INET,
MACADDR,
CITEXT,
TSVECTOR
};
_.each(DataTypes, (dataType, name) => {
if (!Object.prototype.hasOwnProperty.call(dataType, "key")) {
dataType.types = {};
dataType.key = dataType.prototype.key = name;
}
});
const dialectMap = {};
dialectMap.postgres = require("./dialects/postgres/data-types")(DataTypes);
dialectMap.mysql = require("./dialects/mysql/data-types")(DataTypes);
dialectMap.mariadb = require("./dialects/mariadb/data-types")(DataTypes);
dialectMap.sqlite = require("./dialects/sqlite/data-types")(DataTypes);
dialectMap.mssql = require("./dialects/mssql/data-types")(DataTypes);
dialectMap.db2 = require("./dialects/db2/data-types")(DataTypes);
dialectMap.snowflake = require("./dialects/snowflake/data-types")(DataTypes);
dialectMap.oracle = require("./dialects/oracle/data-types")(DataTypes);
const dialectList = Object.values(dialectMap);
for (const dataTypes of dialectList) {
_.each(dataTypes, (DataType, key) => {
if (!DataType.key) {
DataType.key = DataType.prototype.key = key;
}
});
}
for (const dataTypes of [DataTypes, ...dialectList]) {
_.each(dataTypes, (DataType, key) => {
dataTypes[key] = classToInvokable(DataType);
});
}
Object.assign(DataTypes, dialectMap);
//# sourceMappingURL=data-types.js.map
File diff suppressed because one or more lines are too long
+55
View File
@@ -0,0 +1,55 @@
"use strict";
const { classToInvokable } = require("./utils");
class ABSTRACT {
static toString(...args) {
return new this().toString(...args);
}
toString(...args) {
return this.toSql(...args);
}
toSql() {
throw new Error("toSql implementation missing");
}
}
class INITIALLY_DEFERRED extends ABSTRACT {
toSql() {
return "DEFERRABLE INITIALLY DEFERRED";
}
}
class INITIALLY_IMMEDIATE extends ABSTRACT {
toSql() {
return "DEFERRABLE INITIALLY IMMEDIATE";
}
}
class NOT extends ABSTRACT {
toSql() {
return "NOT DEFERRABLE";
}
}
class SET_DEFERRED extends ABSTRACT {
constructor(constraints) {
super();
this.constraints = constraints;
}
toSql(queryGenerator) {
return queryGenerator.setDeferredQuery(this.constraints);
}
}
class SET_IMMEDIATE extends ABSTRACT {
constructor(constraints) {
super();
this.constraints = constraints;
}
toSql(queryGenerator) {
return queryGenerator.setImmediateQuery(this.constraints);
}
}
const Deferrable = {
INITIALLY_DEFERRED: classToInvokable(INITIALLY_DEFERRED),
INITIALLY_IMMEDIATE: classToInvokable(INITIALLY_IMMEDIATE),
NOT: classToInvokable(NOT),
SET_DEFERRED: classToInvokable(SET_DEFERRED),
SET_IMMEDIATE: classToInvokable(SET_IMMEDIATE)
};
module.exports = Deferrable;
//# sourceMappingURL=deferrable.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/deferrable.js"],
"sourcesContent": ["'use strict';\n\nconst { classToInvokable } = require('./utils');\n\nclass ABSTRACT {\n static toString(...args) {\n return new this().toString(...args);\n }\n\n toString(...args) {\n return this.toSql(...args);\n }\n\n toSql() {\n throw new Error('toSql implementation missing');\n }\n}\n\nclass INITIALLY_DEFERRED extends ABSTRACT {\n toSql() {\n return 'DEFERRABLE INITIALLY DEFERRED';\n }\n}\n\nclass INITIALLY_IMMEDIATE extends ABSTRACT {\n toSql() {\n return 'DEFERRABLE INITIALLY IMMEDIATE';\n }\n}\n\nclass NOT extends ABSTRACT {\n toSql() {\n return 'NOT DEFERRABLE';\n }\n}\n\nclass SET_DEFERRED extends ABSTRACT {\n constructor(constraints) {\n super();\n this.constraints = constraints;\n }\n\n toSql(queryGenerator) {\n return queryGenerator.setDeferredQuery(this.constraints);\n }\n}\n\nclass SET_IMMEDIATE extends ABSTRACT {\n constructor(constraints) {\n super();\n this.constraints = constraints;\n }\n\n toSql(queryGenerator) {\n return queryGenerator.setImmediateQuery(this.constraints);\n }\n}\n\n/**\n * A collection of properties related to deferrable constraints. It can be used to\n * make foreign key constraints deferrable and to set the constraints within a\n * transaction. This is only supported in PostgreSQL.\n *\n * The foreign keys can be configured like this. It will create a foreign key\n * that will check the constraints immediately when the data was inserted.\n *\n * ```js\n * sequelize.define('Model', {\n * foreign_id: {\n * type: Sequelize.INTEGER,\n * references: {\n * model: OtherModel,\n * key: 'id',\n * deferrable: Sequelize.Deferrable.INITIALLY_IMMEDIATE\n * }\n * }\n * });\n * ```\n *\n * The constraints can be configured in a transaction like this. It will\n * trigger a query once the transaction has been started and set the constraints\n * to be checked at the very end of the transaction.\n *\n * ```js\n * sequelize.transaction({\n * deferrable: Sequelize.Deferrable.SET_DEFERRED\n * });\n * ```\n *\n * @property INITIALLY_DEFERRED Use when declaring a constraint. Allow and enable by default this constraint's checks to be deferred at the end of transactions.\n * @property INITIALLY_IMMEDIATE Use when declaring a constraint. Allow the constraint's checks to be deferred at the end of transactions.\n * @property NOT Use when declaring a constraint. Set the constraint to not deferred. This is the default in PostgreSQL and makes it impossible to dynamically defer the constraints within a transaction.\n * @property SET_DEFERRED Use when declaring a transaction. Defer the deferrable checks involved in this transaction at commit.\n * @property SET_IMMEDIATE Use when declaring a transaction. Execute the deferrable checks involved in this transaction immediately.\n */\n\nconst Deferrable = {\n INITIALLY_DEFERRED: classToInvokable(INITIALLY_DEFERRED),\n INITIALLY_IMMEDIATE: classToInvokable(INITIALLY_IMMEDIATE),\n NOT: classToInvokable(NOT),\n SET_DEFERRED: classToInvokable(SET_DEFERRED),\n SET_IMMEDIATE: classToInvokable(SET_IMMEDIATE)\n};\n\nmodule.exports = Deferrable;\n"],
"mappings": ";AAEA,MAAM,EAAE,qBAAqB,QAAQ;AAErC,eAAe;AAAA,SACN,YAAY,MAAM;AACvB,WAAO,IAAI,OAAO,SAAS,GAAG;AAAA;AAAA,EAGhC,YAAY,MAAM;AAChB,WAAO,KAAK,MAAM,GAAG;AAAA;AAAA,EAGvB,QAAQ;AACN,UAAM,IAAI,MAAM;AAAA;AAAA;AAIpB,iCAAiC,SAAS;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA;AAAA;AAIX,kCAAkC,SAAS;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA;AAAA;AAIX,kBAAkB,SAAS;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA;AAAA;AAIX,2BAA2B,SAAS;AAAA,EAClC,YAAY,aAAa;AACvB;AACA,SAAK,cAAc;AAAA;AAAA,EAGrB,MAAM,gBAAgB;AACpB,WAAO,eAAe,iBAAiB,KAAK;AAAA;AAAA;AAIhD,4BAA4B,SAAS;AAAA,EACnC,YAAY,aAAa;AACvB;AACA,SAAK,cAAc;AAAA;AAAA,EAGrB,MAAM,gBAAgB;AACpB,WAAO,eAAe,kBAAkB,KAAK;AAAA;AAAA;AA0CjD,MAAM,aAAa;AAAA,EACjB,oBAAoB,iBAAiB;AAAA,EACrC,qBAAqB,iBAAiB;AAAA,EACtC,KAAK,iBAAiB;AAAA,EACtB,cAAc,iBAAiB;AAAA,EAC/B,eAAe,iBAAiB;AAAA;AAGlC,OAAO,UAAU;",
"names": []
}
@@ -0,0 +1,241 @@
"use strict";
const { Pool, TimeoutError } = require("sequelize-pool");
const _ = require("lodash");
const semver = require("semver");
const errors = require("../../errors");
const { logger } = require("../../utils/logger");
const deprecations = require("../../utils/deprecations");
const debug = logger.debugContext("pool");
class ConnectionManager {
constructor(dialect, sequelize) {
const config = _.cloneDeep(sequelize.config);
this.sequelize = sequelize;
this.config = config;
this.dialect = dialect;
this.versionPromise = null;
this.dialectName = this.sequelize.options.dialect;
if (config.pool === false) {
throw new Error("Support for pool:false was removed in v4.0");
}
config.pool = _.defaults(config.pool || {}, {
max: 5,
min: 0,
idle: 1e4,
acquire: 6e4,
evict: 1e3,
validate: this._validate.bind(this)
});
this.initPools();
}
refreshTypeParser(dataTypes) {
_.each(dataTypes, (dataType) => {
if (Object.prototype.hasOwnProperty.call(dataType, "parse")) {
if (dataType.types[this.dialectName]) {
this._refreshTypeParser(dataType);
} else {
throw new Error(`Parse function not supported for type ${dataType.key} in dialect ${this.dialectName}`);
}
}
});
}
_loadDialectModule(moduleName) {
try {
if (this.sequelize.config.dialectModulePath) {
return require(this.sequelize.config.dialectModulePath);
}
if (this.sequelize.config.dialectModule) {
return this.sequelize.config.dialectModule;
}
return require(moduleName);
} catch (err) {
if (err.code === "MODULE_NOT_FOUND") {
if (this.sequelize.config.dialectModulePath) {
throw new Error(`Unable to find dialect at ${this.sequelize.config.dialectModulePath}`);
}
throw new Error(`Please install ${moduleName} package manually`);
}
throw err;
}
}
async _onProcessExit() {
if (!this.pool) {
return;
}
await this.pool.drain();
debug("connection drain due to process exit");
return await this.pool.destroyAllNow();
}
async close() {
this.getConnection = async function getConnection() {
throw new Error("ConnectionManager.getConnection was called after the connection manager was closed!");
};
return await this._onProcessExit();
}
initPools() {
const config = this.config;
if (!config.replication) {
this.pool = new Pool({
name: "sequelize",
create: () => this._connect(config),
destroy: async (connection) => {
const result = await this._disconnect(connection);
debug("connection destroy");
return result;
},
validate: config.pool.validate,
max: config.pool.max,
min: config.pool.min,
acquireTimeoutMillis: config.pool.acquire,
idleTimeoutMillis: config.pool.idle,
reapIntervalMillis: config.pool.evict,
maxUses: config.pool.maxUses
});
debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, no replication`);
return;
}
if (!Array.isArray(config.replication.read)) {
config.replication.read = [config.replication.read];
}
config.replication.write = _.defaults(config.replication.write, _.omit(config, "replication"));
config.replication.read = config.replication.read.map((readConfig) => _.defaults(readConfig, _.omit(this.config, "replication")));
let reads = 0;
this.pool = {
release: (client) => {
if (client.queryType === "read") {
this.pool.read.release(client);
} else {
this.pool.write.release(client);
}
},
acquire: (queryType, useMaster) => {
useMaster = useMaster === void 0 ? false : useMaster;
if (queryType === "SELECT" && !useMaster) {
return this.pool.read.acquire();
}
return this.pool.write.acquire();
},
destroy: (connection) => {
this.pool[connection.queryType].destroy(connection);
debug("connection destroy");
},
destroyAllNow: async () => {
await Promise.all([
this.pool.read.destroyAllNow(),
this.pool.write.destroyAllNow()
]);
debug("all connections destroyed");
},
drain: async () => Promise.all([
this.pool.write.drain(),
this.pool.read.drain()
]),
read: new Pool({
name: "sequelize:read",
create: async () => {
const nextRead = reads++ % config.replication.read.length;
const connection = await this._connect(config.replication.read[nextRead]);
connection.queryType = "read";
return connection;
},
destroy: (connection) => this._disconnect(connection),
validate: config.pool.validate,
max: config.pool.max,
min: config.pool.min,
acquireTimeoutMillis: config.pool.acquire,
idleTimeoutMillis: config.pool.idle,
reapIntervalMillis: config.pool.evict,
maxUses: config.pool.maxUses
}),
write: new Pool({
name: "sequelize:write",
create: async () => {
const connection = await this._connect(config.replication.write);
connection.queryType = "write";
return connection;
},
destroy: (connection) => this._disconnect(connection),
validate: config.pool.validate,
max: config.pool.max,
min: config.pool.min,
acquireTimeoutMillis: config.pool.acquire,
idleTimeoutMillis: config.pool.idle,
reapIntervalMillis: config.pool.evict,
maxUses: config.pool.maxUses
})
};
debug(`pool created with max/min: ${config.pool.max}/${config.pool.min}, with replication`);
}
async getConnection(options) {
options = options || {};
if (this.sequelize.options.databaseVersion === 0) {
if (!this.versionPromise) {
this.versionPromise = (async () => {
try {
const connection = await this._connect(this.config.replication.write || this.config);
const _options = {};
_options.transaction = { connection };
_options.logging = () => {
};
_options.logging.__testLoggingFn = true;
if (this.sequelize.options.databaseVersion === 0) {
const version = await this.sequelize.databaseVersion(_options);
const parsedVersion = _.get(semver.coerce(version), "version") || version;
this.sequelize.options.databaseVersion = semver.valid(parsedVersion) ? parsedVersion : this.dialect.defaultVersion;
}
if (semver.lt(this.sequelize.options.databaseVersion, this.dialect.defaultVersion)) {
deprecations.unsupportedEngine();
debug(`Unsupported database engine version ${this.sequelize.options.databaseVersion}`);
}
this.versionPromise = null;
return await this._disconnect(connection);
} catch (err) {
this.versionPromise = null;
throw err;
}
})();
}
await this.versionPromise;
}
let result;
try {
await this.sequelize.runHooks("beforePoolAcquire", options);
result = await this.pool.acquire(options.type, options.useMaster);
await this.sequelize.runHooks("afterPoolAcquire", result, options);
} catch (error) {
if (error instanceof TimeoutError)
throw new errors.ConnectionAcquireTimeoutError(error);
throw error;
}
debug("connection acquired");
return result;
}
releaseConnection(connection) {
this.pool.release(connection);
debug("connection released");
}
async destroyConnection(connection) {
await this.pool.destroy(connection);
debug(`connection ${connection.uuid} destroyed`);
}
async _connect(config) {
await this.sequelize.runHooks("beforeConnect", config);
const connection = await this.dialect.connectionManager.connect(config);
await this.sequelize.runHooks("afterConnect", connection, config);
return connection;
}
async _disconnect(connection) {
await this.sequelize.runHooks("beforeDisconnect", connection);
await this.dialect.connectionManager.disconnect(connection);
return this.sequelize.runHooks("afterDisconnect", connection);
}
_validate(connection) {
if (!this.dialect.connectionManager.validate) {
return true;
}
return this.dialect.connectionManager.validate(connection);
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
File diff suppressed because one or more lines are too long
+68
View File
@@ -0,0 +1,68 @@
"use strict";
class AbstractDialect {
canBackslashEscape() {
return false;
}
}
AbstractDialect.prototype.supports = {
"DEFAULT": true,
"DEFAULT VALUES": false,
"VALUES ()": false,
"LIMIT ON UPDATE": false,
"ON DUPLICATE KEY": true,
"ORDER NULLS": false,
"UNION": true,
"UNION ALL": true,
"RIGHT JOIN": true,
returnValues: false,
autoIncrement: {
identityInsert: false,
defaultValue: true,
update: true
},
bulkDefault: false,
schemas: false,
transactions: true,
settingIsolationLevelDuringTransaction: true,
transactionOptions: {
type: false
},
migrations: true,
upserts: true,
inserts: {
ignoreDuplicates: "",
updateOnDuplicate: false,
onConflictDoNothing: "",
onConflictWhere: false,
conflictFields: false
},
constraints: {
restrict: true,
addConstraint: true,
dropConstraint: true,
unique: true,
default: false,
check: true,
foreignKey: true,
primaryKey: true
},
index: {
collate: true,
length: false,
parser: false,
concurrently: false,
type: false,
using: true,
functionBased: false,
operator: false
},
groupedLimit: true,
indexViaAlter: false,
JSON: false,
deferrableConstraints: false,
escapeStringConstants: false
};
module.exports = AbstractDialect;
module.exports.AbstractDialect = AbstractDialect;
module.exports.default = AbstractDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/abstract/index.js"],
"sourcesContent": ["'use strict';\n\nclass AbstractDialect {\n /**\n * Whether this dialect can use \\ in strings to escape string delimiters.\n *\n * @returns {boolean}\n */\n canBackslashEscape() {\n return false;\n }\n}\n\nAbstractDialect.prototype.supports = {\n 'DEFAULT': true,\n 'DEFAULT VALUES': false,\n 'VALUES ()': false,\n 'LIMIT ON UPDATE': false,\n 'ON DUPLICATE KEY': true,\n 'ORDER NULLS': false,\n 'UNION': true,\n 'UNION ALL': true,\n 'RIGHT JOIN': true,\n\n /* does the dialect support returning values for inserted/updated fields */\n returnValues: false,\n\n /* features specific to autoIncrement values */\n autoIncrement: {\n /* does the dialect require modification of insert queries when inserting auto increment fields */\n identityInsert: false,\n\n /* does the dialect support inserting default/null values for autoincrement fields */\n defaultValue: true,\n\n /* does the dialect support updating autoincrement fields */\n update: true\n },\n /* Do we need to say DEFAULT for bulk insert */\n bulkDefault: false,\n schemas: false,\n transactions: true,\n settingIsolationLevelDuringTransaction: true,\n transactionOptions: {\n type: false\n },\n migrations: true,\n upserts: true,\n inserts: {\n ignoreDuplicates: '', /* dialect specific words for INSERT IGNORE or DO NOTHING */\n updateOnDuplicate: false, /* whether dialect supports ON DUPLICATE KEY UPDATE */\n onConflictDoNothing: '', /* dialect specific words for ON CONFLICT DO NOTHING */\n onConflictWhere: false, /* whether dialect supports ON CONFLICT WHERE */\n conflictFields: false /* whether the dialect supports specifying conflict fields or not */\n },\n constraints: {\n restrict: true,\n addConstraint: true,\n dropConstraint: true,\n unique: true,\n default: false,\n check: true,\n foreignKey: true,\n primaryKey: true\n },\n index: {\n collate: true,\n length: false,\n parser: false,\n concurrently: false,\n type: false,\n using: true,\n functionBased: false,\n operator: false\n },\n groupedLimit: true,\n indexViaAlter: false,\n JSON: false,\n /**\n * This dialect supports marking a column's constraints as deferrable.\n * e.g. 'DEFERRABLE' and 'INITIALLY DEFERRED'\n */\n deferrableConstraints: false,\n escapeStringConstants: false\n};\n\nmodule.exports = AbstractDialect;\nmodule.exports.AbstractDialect = AbstractDialect;\nmodule.exports.default = AbstractDialect;\n"],
"mappings": ";AAEA,sBAAsB;AAAA,EAMpB,qBAAqB;AACnB,WAAO;AAAA;AAAA;AAIX,gBAAgB,UAAU,WAAW;AAAA,EACnC,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,aAAa;AAAA,EACb,cAAc;AAAA,EAGd,cAAc;AAAA,EAGd,eAAe;AAAA,IAEb,gBAAgB;AAAA,IAGhB,cAAc;AAAA,IAGd,QAAQ;AAAA;AAAA,EAGV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,cAAc;AAAA,EACd,wCAAwC;AAAA,EACxC,oBAAoB;AAAA,IAClB,MAAM;AAAA;AAAA,EAER,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,SAAS;AAAA,IACP,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA;AAAA,EAElB,aAAa;AAAA,IACX,UAAU;AAAA,IACV,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA;AAAA,EAEd,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,MAAM;AAAA,IACN,OAAO;AAAA,IACP,eAAe;AAAA,IACf,UAAU;AAAA;AAAA,EAEZ,cAAc;AAAA,EACd,eAAe;AAAA,EACf,MAAM;AAAA,EAKN,uBAAuB;AAAA,EACvB,uBAAuB;AAAA;AAGzB,OAAO,UAAU;AACjB,OAAO,QAAQ,kBAAkB;AACjC,OAAO,QAAQ,UAAU;",
"names": []
}
+2173
View File
@@ -0,0 +1,2173 @@
"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 util = require("util");
const _ = require("lodash");
const uuidv4 = require("uuid").v4;
const Utils = require("../../utils");
const deprecations = require("../../utils/deprecations");
const SqlString = require("../../sql-string");
const DataTypes = require("../../data-types");
const Model = require("../../model");
const Association = require("../../associations/base");
const BelongsTo = require("../../associations/belongs-to");
const BelongsToMany = require("../../associations/belongs-to-many");
const HasMany = require("../../associations/has-many");
const Op = require("../../operators");
const sequelizeError = require("../../errors");
const IndexHints = require("../../index-hints");
const ALLOWED_CAST_TYPES = /* @__PURE__ */ new Set([
"integer",
"int",
"smallint",
"bigint",
"float",
"real",
"double precision",
"decimal",
"numeric",
"boolean",
"text",
"char",
"varchar",
"nvarchar",
"date",
"timestamp",
"timestamptz",
"datetime",
"json",
"jsonb",
"signed",
"unsigned"
]);
class QueryGenerator {
constructor(options) {
if (!options.sequelize)
throw new Error("QueryGenerator initialized without options.sequelize");
if (!options._dialect)
throw new Error("QueryGenerator initialized without options._dialect");
this.sequelize = options.sequelize;
this.options = options.sequelize.options;
this.dialect = options._dialect.name;
this._dialect = options._dialect;
this._initQuoteIdentifier();
}
extractTableDetails(tableName, options) {
options = options || {};
tableName = tableName || {};
return {
schema: tableName.schema || options.schema || this.options.schema || "public",
tableName: _.isPlainObject(tableName) ? tableName.tableName : tableName,
delimiter: tableName.delimiter || options.delimiter || "."
};
}
addSchema(param) {
if (!param._schema)
return param.tableName || param;
const self = this;
return {
tableName: param.tableName || param,
table: param.tableName || param,
name: param.name || param,
schema: param._schema,
delimiter: param._schemaDelimiter || ".",
toString() {
return self.quoteTable(this);
}
};
}
dropSchema(tableName, options) {
return this.dropTableQuery(tableName, options);
}
describeTableQuery(tableName, schema, schemaDelimiter) {
const table = this.quoteTable(this.addSchema({
tableName,
_schema: schema,
_schemaDelimiter: schemaDelimiter
}));
return `DESCRIBE ${table};`;
}
dropTableQuery(tableName) {
return `DROP TABLE IF EXISTS ${this.quoteTable(tableName)};`;
}
renameTableQuery(before, after) {
return `ALTER TABLE ${this.quoteTable(before)} RENAME TO ${this.quoteTable(after)};`;
}
populateInsertQueryReturnIntoBinds() {
}
insertQuery(table, valueHash, modelAttributes, options) {
options = options || {};
_.defaults(options, this.options);
const modelAttributeMap = {};
const bind = options.bind || [];
const fields = [];
const returningModelAttributes = [];
const returnTypes = [];
const values = [];
const quotedTable = this.quoteTable(table);
const bindParam = options.bindParam === void 0 ? this.bindParam(bind) : options.bindParam;
const returnAttributes = [];
let query;
let valueQuery = "";
let emptyQuery = "";
let outputFragment = "";
let returningFragment = "";
let identityWrapperRequired = false;
let tmpTable = "";
if (modelAttributes) {
_.each(modelAttributes, (attribute, key) => {
modelAttributeMap[key] = attribute;
if (attribute.field) {
modelAttributeMap[attribute.field] = attribute;
}
});
}
if (this._dialect.supports["DEFAULT VALUES"]) {
emptyQuery += " DEFAULT VALUES";
} else if (this._dialect.supports["VALUES ()"]) {
emptyQuery += " VALUES ()";
}
if ((this._dialect.supports.returnValues || this._dialect.supports.returnIntoValues) && options.returning) {
const returnValues = this.generateReturnValues(modelAttributes, options);
returningModelAttributes.push(...returnValues.returnFields);
if (this._dialect.supports.returnIntoValues) {
returnTypes.push(...returnValues.returnTypes);
}
returningFragment = returnValues.returningFragment;
tmpTable = returnValues.tmpTable || "";
outputFragment = returnValues.outputFragment || "";
}
if (_.get(this, ["sequelize", "options", "dialectOptions", "prependSearchPath"]) || options.searchPath) {
options.bindParam = false;
}
if (this._dialect.supports.EXCEPTION && options.exception) {
options.bindParam = false;
}
valueHash = Utils.removeNullValuesFromHash(valueHash, this.options.omitNull);
for (const key in valueHash) {
if (Object.prototype.hasOwnProperty.call(valueHash, key)) {
const value = valueHash[key];
fields.push(this.quoteIdentifier(key));
if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true && value == null) {
if (!this._dialect.supports.autoIncrement.defaultValue) {
fields.splice(-1, 1);
} else if (this._dialect.supports.DEFAULT) {
values.push("DEFAULT");
} else {
values.push(this.escape(null));
}
} else {
if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true) {
identityWrapperRequired = true;
}
if (value instanceof Utils.SequelizeMethod || options.bindParam === false) {
values.push(this.escape(value, modelAttributeMap && modelAttributeMap[key] || void 0, { context: "INSERT" }));
} else {
values.push(this.format(value, modelAttributeMap && modelAttributeMap[key] || void 0, { context: "INSERT" }, bindParam));
}
}
}
}
let onDuplicateKeyUpdate = "";
if (!_.isEmpty(options.conflictWhere) && !this._dialect.supports.inserts.onConflictWhere) {
throw new Error("missing dialect support for conflictWhere option");
}
if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {
if (this._dialect.supports.inserts.updateOnDuplicate == " ON CONFLICT DO UPDATE SET") {
const conflictKeys = options.upsertKeys.map((attr) => this.quoteIdentifier(attr));
const updateKeys = options.updateOnDuplicate.map((attr) => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);
const fragments = [
"ON CONFLICT",
"(",
conflictKeys.join(","),
")"
];
if (!_.isEmpty(options.conflictWhere)) {
fragments.push(this.whereQuery(options.conflictWhere, options));
}
if (_.isEmpty(updateKeys)) {
fragments.push("DO NOTHING");
} else {
fragments.push("DO UPDATE SET", updateKeys.join(","));
}
onDuplicateKeyUpdate = ` ${Utils.joinSQLFragments(fragments)}`;
} else {
const valueKeys = options.updateOnDuplicate.map((attr) => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);
if (_.isEmpty(valueKeys) && options.upsertKeys) {
valueKeys.push(...options.upsertKeys.map((attr) => `${this.quoteIdentifier(attr)}=${this.quoteIdentifier(attr)}`));
}
if (_.isEmpty(valueKeys)) {
throw new Error("No update values found for ON DUPLICATE KEY UPDATE clause, and no identifier fields could be found to use instead.");
}
onDuplicateKeyUpdate += `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(",")}`;
}
}
const replacements = {
ignoreDuplicates: options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : "",
onConflictDoNothing: options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : "",
attributes: fields.join(","),
output: outputFragment,
values: values.join(","),
tmpTable
};
valueQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable} (${replacements.attributes})${replacements.output} VALUES (${replacements.values})${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${valueQuery}`;
emptyQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable}${replacements.output}${onDuplicateKeyUpdate}${replacements.onConflictDoNothing}${emptyQuery}`;
if (this._dialect.supports.EXCEPTION && options.exception) {
const dropFunction = "DROP FUNCTION IF EXISTS pg_temp.testfunc()";
if (returningModelAttributes.length === 0) {
returningModelAttributes.push("*");
}
const delimiter = `$func_${uuidv4().replace(/-/g, "")}$`;
const selectQuery = `SELECT (testfunc.response).${returningModelAttributes.join(", (testfunc.response).")}, testfunc.sequelize_caught_exception FROM pg_temp.testfunc();`;
options.exception = "WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;";
valueQuery = `CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response ${quotedTable}, OUT sequelize_caught_exception text) RETURNS RECORD AS ${delimiter} BEGIN ${valueQuery} RETURNING * INTO response; EXCEPTION ${options.exception} END ${delimiter} LANGUAGE plpgsql; ${selectQuery} ${dropFunction}`;
} else {
valueQuery += returningFragment;
emptyQuery += returningFragment;
}
if (this._dialect.supports.returnIntoValues && options.returning) {
this.populateInsertQueryReturnIntoBinds(returningModelAttributes, returnTypes, bind.length, returnAttributes, options);
}
query = `${replacements.attributes.length ? valueQuery : emptyQuery}${returnAttributes.join(",")};`;
if (this._dialect.supports.finalTable) {
query = `SELECT * FROM FINAL TABLE(${replacements.attributes.length ? valueQuery : emptyQuery});`;
}
if (identityWrapperRequired && this._dialect.supports.autoIncrement.identityInsert) {
query = `SET IDENTITY_INSERT ${quotedTable} ON; ${query} SET IDENTITY_INSERT ${quotedTable} OFF;`;
}
const result = { query };
if (options.bindParam !== false) {
result.bind = bind;
}
return result;
}
bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes) {
options = options || {};
fieldMappedAttributes = fieldMappedAttributes || {};
const tuples = [];
const serials = {};
const allAttributes = [];
let onDuplicateKeyUpdate = "";
for (const fieldValueHash of fieldValueHashes) {
_.forOwn(fieldValueHash, (value, key) => {
if (!allAttributes.includes(key)) {
allAttributes.push(key);
}
if (fieldMappedAttributes[key] && fieldMappedAttributes[key].autoIncrement === true) {
serials[key] = true;
}
});
}
for (const fieldValueHash of fieldValueHashes) {
const values = allAttributes.map((key) => {
if (this._dialect.supports.bulkDefault && serials[key] === true) {
return fieldValueHash[key] != null ? fieldValueHash[key] : "DEFAULT";
}
return this.escape(fieldValueHash[key], fieldMappedAttributes[key], { context: "INSERT" });
});
tuples.push(`(${values.join(",")})`);
}
if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) {
if (this._dialect.supports.inserts.updateOnDuplicate == " ON CONFLICT DO UPDATE SET") {
const conflictKeys = options.upsertKeys.map((attr) => this.quoteIdentifier(attr));
const updateKeys = options.updateOnDuplicate.map((attr) => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`);
let whereClause = false;
if (options.conflictWhere) {
if (!this._dialect.supports.inserts.onConflictWhere) {
throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);
}
whereClause = this.whereQuery(options.conflictWhere, options);
}
onDuplicateKeyUpdate = [
"ON CONFLICT",
"(",
conflictKeys.join(","),
")",
whereClause,
"DO UPDATE SET",
updateKeys.join(",")
];
} else {
if (options.conflictWhere) {
throw new Error(`conflictWhere not supported for dialect ${this._dialect.name}`);
}
const valueKeys = options.updateOnDuplicate.map((attr) => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`);
onDuplicateKeyUpdate = `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(",")}`;
}
}
const ignoreDuplicates = options.ignoreDuplicates ? this._dialect.supports.inserts.ignoreDuplicates : "";
const attributes = allAttributes.map((attr) => this.quoteIdentifier(attr)).join(",");
const onConflictDoNothing = options.ignoreDuplicates ? this._dialect.supports.inserts.onConflictDoNothing : "";
let returning = "";
if (this._dialect.supports.returnValues && options.returning) {
const returnValues = this.generateReturnValues(fieldMappedAttributes, options);
returning += returnValues.returningFragment;
}
return Utils.joinSQLFragments([
"INSERT",
ignoreDuplicates,
"INTO",
this.quoteTable(tableName),
`(${attributes})`,
"VALUES",
tuples.join(","),
onDuplicateKeyUpdate,
onConflictDoNothing,
returning,
";"
]);
}
updateQuery(tableName, attrValueHash, where, options, attributes) {
options = options || {};
_.defaults(options, this.options);
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, options.omitNull, options);
const values = [];
const bind = [];
const modelAttributeMap = {};
let outputFragment = "";
let tmpTable = "";
let suffix = "";
if (_.get(this, ["sequelize", "options", "dialectOptions", "prependSearchPath"]) || options.searchPath) {
options.bindParam = false;
}
const bindParam = options.bindParam === void 0 ? this.bindParam(bind) : options.bindParam;
if (this._dialect.supports["LIMIT ON UPDATE"] && options.limit) {
if (!["mssql", "db2", "oracle"].includes(this.dialect)) {
suffix = ` LIMIT ${this.escape(options.limit)} `;
} else if (this.dialect === "oracle") {
if (where && (where.length && where.length > 0 || Object.keys(where).length > 0)) {
suffix += " AND ";
} else {
suffix += " WHERE ";
}
suffix += `rownum <= ${this.escape(options.limit)} `;
}
}
if (this._dialect.supports.returnValues && options.returning) {
const returnValues = this.generateReturnValues(attributes, options);
suffix += returnValues.returningFragment;
tmpTable = returnValues.tmpTable || "";
outputFragment = returnValues.outputFragment || "";
if (!this._dialect.supports.returnValues.output && options.returning) {
options.mapToModel = true;
}
}
if (attributes) {
_.each(attributes, (attribute, key) => {
modelAttributeMap[key] = attribute;
if (attribute.field) {
modelAttributeMap[attribute.field] = attribute;
}
});
}
for (const key in attrValueHash) {
if (modelAttributeMap && modelAttributeMap[key] && modelAttributeMap[key].autoIncrement === true && !this._dialect.supports.autoIncrement.update) {
continue;
}
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)}`);
}
}
const whereOptions = __spreadProps(__spreadValues({}, options), { bindParam });
if (values.length === 0) {
return "";
}
const query = `${tmpTable}UPDATE ${this.quoteTable(tableName)} SET ${values.join(",")}${outputFragment} ${this.whereQuery(where, whereOptions)}${suffix}`.trim();
const result = { query };
if (options.bindParam !== false) {
result.bind = bind;
}
return result;
}
arithmeticQuery(operator, tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options) {
options = options || {};
_.defaults(options, { returning: true });
extraAttributesToBeUpdated = Utils.removeNullValuesFromHash(extraAttributesToBeUpdated, this.options.omitNull);
let outputFragment = "";
let returningFragment = "";
if (this._dialect.supports.returnValues && options.returning) {
const returnValues = this.generateReturnValues(null, options);
outputFragment = returnValues.outputFragment;
returningFragment = returnValues.returningFragment;
}
const updateSetSqlFragments = [];
for (const field in incrementAmountsByField) {
const incrementAmount = incrementAmountsByField[field];
const quotedField = this.quoteIdentifier(field);
const escapedAmount = this.escape(incrementAmount);
updateSetSqlFragments.push(`${quotedField}=${quotedField}${operator} ${escapedAmount}`);
}
for (const field in extraAttributesToBeUpdated) {
const newValue = extraAttributesToBeUpdated[field];
const quotedField = this.quoteIdentifier(field);
const escapedValue = this.escape(newValue);
updateSetSqlFragments.push(`${quotedField}=${escapedValue}`);
}
return Utils.joinSQLFragments([
"UPDATE",
this.quoteTable(tableName),
"SET",
updateSetSqlFragments.join(","),
outputFragment,
this.whereQuery(where),
returningFragment
]);
}
addIndexQuery(tableName, attributes, options, rawTablename) {
options = options || {};
if (!Array.isArray(attributes)) {
options = attributes;
attributes = void 0;
} else {
options.fields = attributes;
}
options.prefix = options.prefix || rawTablename || tableName;
if (options.prefix && typeof options.prefix === "string") {
options.prefix = options.prefix.replace(/\./g, "_");
options.prefix = options.prefix.replace(/("|')/g, "");
}
const fieldsSql = options.fields.map((field) => {
if (field instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(field);
}
if (typeof field === "string") {
field = {
name: field
};
}
let result = "";
if (field.attribute) {
field.name = field.attribute;
}
if (!field.name) {
throw new Error(`The following index field has no name: ${util.inspect(field)}`);
}
result += this.quoteIdentifier(field.name);
if (this._dialect.supports.index.collate && field.collate) {
result += ` COLLATE ${this.quoteIdentifier(field.collate)}`;
}
if (this._dialect.supports.index.operator) {
const operator = field.operator || options.operator;
if (operator) {
result += ` ${operator}`;
}
}
if (this._dialect.supports.index.length && field.length) {
result += `(${field.length})`;
}
if (field.order) {
result += ` ${field.order}`;
}
return result;
});
if (!options.name) {
options = Utils.nameIndex(options, options.prefix);
}
options = Model._conformIndex(options);
if (!this._dialect.supports.index.type) {
delete options.type;
}
if (options.where) {
options.where = this.whereQuery(options.where);
}
if (typeof tableName === "string") {
tableName = this.quoteIdentifiers(tableName);
} else {
tableName = this.quoteTable(tableName);
}
const concurrently = this._dialect.supports.index.concurrently && options.concurrently ? "CONCURRENTLY" : void 0;
let ind;
if (this._dialect.supports.indexViaAlter) {
ind = [
"ALTER TABLE",
tableName,
concurrently,
"ADD"
];
} else {
ind = ["CREATE"];
}
ind = ind.concat(options.unique ? "UNIQUE" : "", options.type, "INDEX", !this._dialect.supports.indexViaAlter ? concurrently : void 0, this.quoteIdentifiers(options.name), this._dialect.supports.index.using === 1 && options.using ? `USING ${options.using}` : "", !this._dialect.supports.indexViaAlter ? `ON ${tableName}` : void 0, this._dialect.supports.index.using === 2 && options.using ? `USING ${options.using}` : "", `(${fieldsSql.join(", ")})`, this._dialect.supports.index.parser && options.parser ? `WITH PARSER ${options.parser}` : void 0, this._dialect.supports.index.where && options.where ? options.where : void 0);
return _.compact(ind).join(" ");
}
addConstraintQuery(tableName, options) {
if (typeof tableName === "string") {
tableName = this.quoteIdentifiers(tableName);
} else {
tableName = this.quoteTable(tableName);
}
return Utils.joinSQLFragments([
"ALTER TABLE",
tableName,
"ADD",
this.getConstraintSnippet(tableName, options || {}),
";"
]);
}
getConstraintSnippet(tableName, options) {
let constraintSnippet, constraintName;
const fieldsSql = options.fields.map((field) => {
if (typeof field === "string") {
return this.quoteIdentifier(field);
}
if (field instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(field);
}
if (field.attribute) {
field.name = field.attribute;
}
if (!field.name) {
throw new Error(`The following index field has no name: ${field}`);
}
return this.quoteIdentifier(field.name);
});
const fieldsSqlQuotedString = fieldsSql.join(", ");
const fieldsSqlString = fieldsSql.join("_");
switch (options.type.toUpperCase()) {
case "UNIQUE":
constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_uk`);
constraintSnippet = `CONSTRAINT ${constraintName} UNIQUE (${fieldsSqlQuotedString})`;
break;
case "CHECK":
options.where = this.whereItemsQuery(options.where);
constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_ck`);
constraintSnippet = `CONSTRAINT ${constraintName} CHECK (${options.where})`;
break;
case "DEFAULT":
if (options.defaultValue === void 0) {
throw new Error("Default value must be specified for DEFAULT CONSTRAINT");
}
if (this._dialect.name !== "mssql") {
throw new Error("Default constraints are supported only for MSSQL dialect.");
}
constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_df`);
constraintSnippet = `CONSTRAINT ${constraintName} DEFAULT (${this.escape(options.defaultValue)}) FOR ${fieldsSql[0]}`;
break;
case "PRIMARY KEY":
constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_pk`);
constraintSnippet = `CONSTRAINT ${constraintName} PRIMARY KEY (${fieldsSqlQuotedString})`;
break;
case "FOREIGN KEY":
const references = options.references;
if (!references || !references.table || !(references.field || references.fields)) {
throw new Error("references object with table and field must be specified");
}
constraintName = this.quoteIdentifier(options.name || `${tableName}_${fieldsSqlString}_${references.table}_fk`);
const quotedReferences = typeof references.field !== "undefined" ? this.quoteIdentifier(references.field) : references.fields.map((f) => this.quoteIdentifier(f)).join(", ");
const referencesSnippet = `${this.quoteTable(references.table)} (${quotedReferences})`;
constraintSnippet = `CONSTRAINT ${constraintName} `;
constraintSnippet += `FOREIGN KEY (${fieldsSqlQuotedString}) REFERENCES ${referencesSnippet}`;
if (options.onUpdate) {
constraintSnippet += ` ON UPDATE ${options.onUpdate.toUpperCase()}`;
}
if (options.onDelete) {
constraintSnippet += ` ON DELETE ${options.onDelete.toUpperCase()}`;
}
break;
default:
throw new Error(`${options.type} is invalid.`);
}
if (options.deferrable && ["UNIQUE", "PRIMARY KEY", "FOREIGN KEY"].includes(options.type.toUpperCase())) {
constraintSnippet += ` ${this.deferConstraintsQuery(options)}`;
}
return constraintSnippet;
}
removeConstraintQuery(tableName, constraintName) {
if (typeof tableName === "string") {
tableName = this.quoteIdentifiers(tableName);
} else {
tableName = this.quoteTable(tableName);
}
return Utils.joinSQLFragments([
"ALTER TABLE",
tableName,
"DROP CONSTRAINT",
this.quoteIdentifiers(constraintName)
]);
}
quote(collection, parent, connector) {
const validOrderOptions = [
"ASC",
"DESC",
"ASC NULLS LAST",
"DESC NULLS LAST",
"ASC NULLS FIRST",
"DESC NULLS FIRST",
"NULLS FIRST",
"NULLS LAST"
];
connector = connector || ".";
if (typeof collection === "string") {
return this.quoteIdentifiers(collection);
}
if (Array.isArray(collection)) {
collection.forEach((item2, index) => {
const previous = collection[index - 1];
let previousAssociation;
let previousModel;
if (!previous && parent !== void 0) {
previousModel = parent;
} else if (previous && previous instanceof Association) {
previousAssociation = previous;
previousModel = previous.target;
}
if (previousModel && previousModel.prototype instanceof Model) {
let model;
let as;
if (typeof item2 === "function" && item2.prototype instanceof Model) {
model = item2;
} else if (_.isPlainObject(item2) && item2.model && item2.model.prototype instanceof Model) {
model = item2.model;
as = item2.as;
}
if (model) {
if (!as && previousAssociation && previousAssociation instanceof Association && previousAssociation.through && previousAssociation.through.model === model) {
item2 = new Association(previousModel, model, {
as: model.name
});
} else {
item2 = previousModel.getAssociationForAlias(model, as);
if (!item2) {
item2 = previousModel.getAssociationForAlias(model, model.name);
}
}
if (!(item2 instanceof Association)) {
throw new Error(util.format("Unable to find a valid association for model, '%s'", model.name));
}
}
}
if (typeof item2 === "string") {
const orderIndex = validOrderOptions.indexOf(item2.toUpperCase());
if (index > 0 && orderIndex !== -1) {
item2 = this.sequelize.literal(` ${validOrderOptions[orderIndex]}`);
} else if (previousModel && previousModel.prototype instanceof Model) {
if (previousModel.associations !== void 0 && previousModel.associations[item2]) {
item2 = previousModel.associations[item2];
} else if (previousModel.rawAttributes !== void 0 && previousModel.rawAttributes[item2] && item2 !== previousModel.rawAttributes[item2].field) {
item2 = previousModel.rawAttributes[item2].field;
} else if (item2.includes(".") && previousModel.rawAttributes !== void 0) {
const itemSplit = item2.split(".");
if (previousModel.rawAttributes[itemSplit[0]].type instanceof DataTypes.JSON) {
const identifier = this.quoteIdentifiers(`${previousModel.name}.${previousModel.rawAttributes[itemSplit[0]].field}`);
const path = itemSplit.slice(1);
item2 = this.jsonPathExtractionQuery(identifier, path);
item2 = this.sequelize.literal(item2);
}
}
}
}
collection[index] = item2;
}, this);
const collectionLength = collection.length;
const tableNames = [];
let item;
let i = 0;
for (i = 0; i < collectionLength - 1; i++) {
item = collection[i];
if (typeof item === "string" || item._modelAttribute || item instanceof Utils.SequelizeMethod) {
break;
} else if (item instanceof Association) {
tableNames[i] = item.as;
}
}
let sql = "";
if (i > 0) {
sql += `${this.quoteIdentifier(tableNames.join(connector))}.`;
} else if (typeof collection[0] === "string" && parent) {
sql += `${this.quoteIdentifier(parent.name)}.`;
}
collection.slice(i).forEach((collectionItem) => {
sql += this.quote(collectionItem, parent, connector);
}, this);
return sql;
}
if (collection._modelAttribute) {
return `${this.quoteTable(collection.Model.name)}.${this.quoteIdentifier(collection.fieldName)}`;
}
if (collection instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(collection);
}
if (_.isPlainObject(collection) && collection.raw) {
throw new Error('The `{raw: "..."}` syntax is no longer supported. Use `sequelize.literal` instead.');
}
throw new Error(`Unknown structure passed to order / group: ${util.inspect(collection)}`);
}
_initQuoteIdentifier() {
this._quoteIdentifier = this.quoteIdentifier;
this.quoteIdentifier = function(identifier, force) {
if (identifier === "*")
return identifier;
return this._quoteIdentifier(identifier, force);
};
}
quoteIdentifier(identifier, force) {
throw new Error(`quoteIdentifier for Dialect "${this.dialect}" is not implemented`);
}
quoteIdentifiers(identifiers) {
if (identifiers.includes(".")) {
identifiers = identifiers.split(".");
const head = identifiers.slice(0, identifiers.length - 1).join("->");
const tail = identifiers[identifiers.length - 1];
return `${this.quoteIdentifier(head)}.${this.quoteIdentifier(tail)}`;
}
return this.quoteIdentifier(identifiers);
}
quoteAttribute(attribute, model) {
if (model && attribute in model.rawAttributes) {
return this.quoteIdentifier(attribute);
}
return this.quoteIdentifiers(attribute);
}
getAliasToken() {
return "AS";
}
quoteTable(param, alias) {
let table = "";
if (alias === true) {
alias = param.as || param.name || param;
}
if (_.isObject(param)) {
if (this._dialect.supports.schemas) {
if (param.schema) {
table += `${this.quoteIdentifier(param.schema)}.`;
}
table += this.quoteIdentifier(param.tableName);
} else {
if (param.schema) {
table += param.schema + (param.delimiter || ".");
}
table += param.tableName;
table = this.quoteIdentifier(table);
}
} else {
table = this.quoteIdentifier(param);
}
if (alias) {
table += ` ${this.getAliasToken()} ${this.quoteIdentifier(alias)}`;
}
return table;
}
escape(value, field, options) {
options = options || {};
if (value !== null && value !== void 0) {
if (value instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(value);
}
if (field && field.type) {
if (field.type instanceof DataTypes.STRING && ["mysql", "mariadb"].includes(this.dialect) && ["number", "boolean"].includes(typeof value)) {
value = String(Number(value));
}
this.validate(value, field, options);
if (field.type.stringify) {
const simpleEscape = (escVal) => SqlString.escape(escVal, this.options.timezone, this.dialect);
value = field.type.stringify(value, { escape: simpleEscape, field, timezone: this.options.timezone, operation: options.operation });
if (field.type.escape === false) {
return value;
}
}
}
}
return SqlString.escape(value, this.options.timezone, this.dialect);
}
bindParam(bind) {
return (value) => {
bind.push(value);
return `$${bind.length}`;
};
}
format(value, field, options, bindParam) {
options = options || {};
if (value !== null && value !== void 0) {
if (value instanceof Utils.SequelizeMethod) {
throw new Error("Cannot pass SequelizeMethod as a bind parameter - use escape instead");
}
if (field && field.type) {
this.validate(value, field, options);
if (field.type.bindParam) {
return field.type.bindParam(value, { escape: _.identity, field, timezone: this.options.timezone, operation: options.operation, bindParam });
}
}
}
return bindParam(value);
}
validate(value, field, options) {
if (this.typeValidation && field.type.validate && value) {
try {
if (options.isList && Array.isArray(value)) {
for (const item of value) {
field.type.validate(item, options);
}
} else {
field.type.validate(value, options);
}
} catch (error) {
if (error instanceof sequelizeError.ValidationError) {
error.errors.push(new sequelizeError.ValidationErrorItem(error.message, "Validation error", field.fieldName, value, null, `${field.type.key} validator`));
}
throw error;
}
}
}
isIdentifierQuoted(identifier) {
return /^\s*(?:([`"'])(?:(?!\1).|\1{2})*\1\.?)+\s*$/i.test(identifier);
}
jsonPathExtractionQuery(column, path, isJson) {
let paths = _.toPath(path);
let pathStr;
const quotedColumn = this.isIdentifierQuoted(column) ? column : this.quoteIdentifier(column);
switch (this.dialect) {
case "mysql":
case "mariadb":
case "sqlite":
if (this.dialect === "mysql") {
paths = paths.map((subPath) => {
return /\D/.test(subPath) ? Utils.addTicks(subPath, '"') : subPath;
});
}
pathStr = this.escape(["$"].concat(paths).join(".").replace(/\.(\d+)(?:(?=\.)|$)/g, (__, digit) => `[${digit}]`));
if (this.dialect === "sqlite") {
return `json_extract(${quotedColumn},${pathStr})`;
}
return `json_unquote(json_extract(${quotedColumn},${pathStr}))`;
case "postgres":
const join = isJson ? "#>" : "#>>";
pathStr = this.escape(`{${paths.join(",")}}`);
return `(${quotedColumn}${join}${pathStr})`;
default:
throw new Error(`Unsupported ${this.dialect} for JSON operations`);
}
}
selectQuery(tableName, options, model) {
options = options || {};
const limit = options.limit;
const mainQueryItems = [];
const subQueryItems = [];
const subQuery = options.subQuery === void 0 ? limit && options.hasMultiAssociation : options.subQuery;
const attributes = {
main: options.attributes && options.attributes.slice(),
subQuery: null
};
const mainTable = {
name: tableName,
quotedName: null,
as: null,
model
};
const topLevelInfo = {
names: mainTable,
options,
subQuery
};
let mainJoinQueries = [];
let subJoinQueries = [];
let query;
if (this.options.minifyAliases && !options.aliasesMapping) {
options.aliasesMapping = /* @__PURE__ */ new Map();
options.aliasesByTable = {};
options.includeAliases = /* @__PURE__ */ new Map();
}
if (options.tableAs) {
mainTable.as = this.quoteIdentifier(options.tableAs);
} else if (!Array.isArray(mainTable.name) && mainTable.model) {
mainTable.as = this.quoteIdentifier(mainTable.model.name);
}
mainTable.quotedName = !Array.isArray(mainTable.name) ? this.quoteTable(mainTable.name) : tableName.map((t) => {
return Array.isArray(t) ? this.quoteTable(t[0], t[1]) : this.quoteTable(t, true);
}).join(", ");
if (subQuery && attributes.main) {
for (const keyAtt of mainTable.model.primaryKeyAttributes) {
if (!attributes.main.some((attr) => keyAtt === attr || keyAtt === attr[0] || keyAtt === attr[1])) {
attributes.main.push(mainTable.model.rawAttributes[keyAtt].field ? [keyAtt, mainTable.model.rawAttributes[keyAtt].field] : keyAtt);
}
}
}
attributes.main = this.escapeAttributes(attributes.main, options, mainTable.as);
attributes.main = attributes.main || (options.include ? [`${mainTable.as}.*`] : ["*"]);
if (subQuery || options.groupedLimit) {
attributes.subQuery = attributes.main;
attributes.main = [`${mainTable.as || mainTable.quotedName}.*`];
}
if (options.include) {
for (const include of options.include) {
if (include.separate) {
continue;
}
const joinQueries = this.generateInclude(include, { externalAs: mainTable.as, internalAs: mainTable.as }, topLevelInfo);
subJoinQueries = subJoinQueries.concat(joinQueries.subQuery);
mainJoinQueries = mainJoinQueries.concat(joinQueries.mainQuery);
if (joinQueries.attributes.main.length > 0) {
attributes.main = _.uniq(attributes.main.concat(joinQueries.attributes.main));
}
if (joinQueries.attributes.subQuery.length > 0) {
attributes.subQuery = _.uniq(attributes.subQuery.concat(joinQueries.attributes.subQuery));
}
}
}
if (subQuery) {
subQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.subQuery, mainTable.quotedName, mainTable.as));
subQueryItems.push(subJoinQueries.join(""));
} else {
if (options.groupedLimit) {
if (!mainTable.as) {
mainTable.as = mainTable.quotedName;
}
const where = __spreadValues({}, options.where);
let groupedLimitOrder, whereKey, include, groupedTableName = mainTable.as;
if (typeof options.groupedLimit.on === "string") {
whereKey = options.groupedLimit.on;
} else if (options.groupedLimit.on instanceof HasMany) {
whereKey = options.groupedLimit.on.foreignKeyField;
}
if (options.groupedLimit.on instanceof BelongsToMany) {
groupedTableName = options.groupedLimit.on.manyFromSource.as;
const groupedLimitOptions = Model._validateIncludedElements({
include: [{
association: options.groupedLimit.on.manyFromSource,
duplicating: false,
required: true,
where: __spreadValues({
[Op.placeholder]: true
}, options.groupedLimit.through && options.groupedLimit.through.where)
}],
model
});
options.hasJoin = true;
options.hasMultiAssociation = true;
options.includeMap = Object.assign(groupedLimitOptions.includeMap, options.includeMap);
options.includeNames = groupedLimitOptions.includeNames.concat(options.includeNames || []);
include = groupedLimitOptions.include;
if (Array.isArray(options.order)) {
options.order.forEach((order, i) => {
if (Array.isArray(order)) {
order = order[0];
}
let alias = `subquery_order_${i}`;
options.attributes.push([order, alias]);
alias = this.sequelize.literal(this.quote(alias));
if (Array.isArray(options.order[i])) {
options.order[i][0] = alias;
} else {
options.order[i] = alias;
}
});
groupedLimitOrder = options.order;
}
} else {
groupedLimitOrder = options.order;
if (!this._dialect.supports.topLevelOrderByRequired) {
delete options.order;
}
where[Op.placeholder] = true;
}
const baseQuery = `SELECT * FROM (${this.selectQuery(tableName, {
attributes: options.attributes,
offset: options.offset,
limit: options.groupedLimit.limit,
order: groupedLimitOrder,
aliasesMapping: options.aliasesMapping,
aliasesByTable: options.aliasesByTable,
where,
include,
model
}, model).replace(/;$/, "")}) ${this.getAliasToken()} sub`;
const placeHolder = this.whereItemQuery(Op.placeholder, true, { model });
const splicePos = baseQuery.indexOf(placeHolder);
mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, `(${options.groupedLimit.values.map((value) => {
let groupWhere;
if (whereKey) {
groupWhere = {
[whereKey]: value
};
}
if (include) {
groupWhere = {
[options.groupedLimit.on.foreignIdentifierField]: value
};
}
return Utils.spliceStr(baseQuery, splicePos, placeHolder.length, this.getWhereConditions(groupWhere, groupedTableName));
}).join(this._dialect.supports["UNION ALL"] ? " UNION ALL " : " UNION ")})`, mainTable.as));
} else {
mainQueryItems.push(this.selectFromTableFragment(options, mainTable.model, attributes.main, mainTable.quotedName, mainTable.as));
}
mainQueryItems.push(mainJoinQueries.join(""));
}
if (Object.prototype.hasOwnProperty.call(options, "where") && !options.groupedLimit) {
options.where = this.getWhereConditions(options.where, mainTable.as || tableName, model, options);
if (options.where) {
if (subQuery) {
subQueryItems.push(` WHERE ${options.where}`);
} else {
mainQueryItems.push(` WHERE ${options.where}`);
mainQueryItems.forEach((value, key) => {
if (value.startsWith("SELECT")) {
mainQueryItems[key] = this.selectFromTableFragment(options, model, attributes.main, mainTable.quotedName, mainTable.as, options.where);
}
});
}
}
}
if (options.group) {
options.group = Array.isArray(options.group) ? options.group.map((t) => this.aliasGrouping(t, model, mainTable.as, options)).join(", ") : this.aliasGrouping(options.group, model, mainTable.as, options);
if (subQuery && options.group) {
subQueryItems.push(` GROUP BY ${options.group}`);
} else if (options.group) {
mainQueryItems.push(` GROUP BY ${options.group}`);
}
}
if (Object.prototype.hasOwnProperty.call(options, "having")) {
options.having = this.getWhereConditions(options.having, tableName, model, options, false);
if (options.having) {
if (subQuery) {
subQueryItems.push(` HAVING ${options.having}`);
} else {
mainQueryItems.push(` HAVING ${options.having}`);
}
}
}
if (options.order) {
const orders = this.getQueryOrders(options, model, subQuery);
if (orders.mainQueryOrder.length) {
mainQueryItems.push(` ORDER BY ${orders.mainQueryOrder.join(", ")}`);
}
if (orders.subQueryOrder.length) {
subQueryItems.push(` ORDER BY ${orders.subQueryOrder.join(", ")}`);
}
}
const limitOrder = this.addLimitAndOffset(options, mainTable.model);
if (limitOrder && !options.groupedLimit) {
if (subQuery) {
subQueryItems.push(limitOrder);
} else {
mainQueryItems.push(limitOrder);
}
}
if (subQuery) {
this._throwOnEmptyAttributes(attributes.main, { modelName: model && model.name, as: mainTable.as });
query = `SELECT ${attributes.main.join(", ")} FROM (${subQueryItems.join("")}) ${this.getAliasToken()} ${mainTable.as}${mainJoinQueries.join("")}${mainQueryItems.join("")}`;
} else {
query = mainQueryItems.join("");
}
if (options.lock && this._dialect.supports.lock) {
let lock = options.lock;
if (typeof options.lock === "object") {
lock = options.lock.level;
}
if (this._dialect.supports.lockKey && ["KEY SHARE", "NO KEY UPDATE"].includes(lock)) {
query += ` FOR ${lock}`;
} else if (lock === "SHARE") {
query += ` ${this._dialect.supports.forShare}`;
} else {
query += " FOR UPDATE";
}
if (this._dialect.supports.lockOf && options.lock.of && options.lock.of.prototype instanceof Model) {
query += ` OF ${this.quoteTable(options.lock.of.name)}`;
}
if (this._dialect.supports.skipLocked && options.skipLocked) {
query += " SKIP LOCKED";
}
}
return `${query};`;
}
aliasGrouping(field, model, tableName, options) {
const src = Array.isArray(field) ? field[0] : field;
return this.quote(this._getAliasForField(tableName, src, options) || src, model);
}
escapeAttributes(attributes, options, mainTableAs) {
return attributes && attributes.map((attr) => {
let addTable = true;
if (attr instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(attr);
}
if (Array.isArray(attr)) {
if (attr.length !== 2) {
throw new Error(`${JSON.stringify(attr)} is not a valid attribute definition. Please use the following format: ['attribute definition', 'alias']`);
}
attr = attr.slice();
if (attr[0] instanceof Utils.SequelizeMethod) {
attr[0] = this.handleSequelizeMethod(attr[0]);
addTable = false;
} else if (this.options.attributeBehavior === "escape" || !attr[0].includes("(") && !attr[0].includes(")")) {
attr[0] = this.quoteIdentifier(attr[0]);
} else if (this.options.attributeBehavior !== "unsafe-legacy") {
throw new Error(`Attributes cannot include parentheses in Sequelize 6:
In order to fix the vulnerability CVE-2023-22578, we had to remove support for treating attributes as raw SQL if they included parentheses.
Sequelize 7 escapes all attributes, even if they include parentheses.
For Sequelize 6, because we're introducing this change in a minor release, we've opted for throwing an error instead of silently escaping the attribute as a way to warn you about this change.
Here is what you can do to fix this error:
- Wrap the attribute in a literal() call. This will make Sequelize treat it as raw SQL.
- Set the "attributeBehavior" sequelize option to "escape" to make Sequelize escape the attribute, like in Sequelize v7. We highly recommend this option.
- Set the "attributeBehavior" sequelize option to "unsafe-legacy" to make Sequelize escape the attribute, like in Sequelize v5.
We sincerely apologize for the inconvenience this may cause you. You can find more information on the following threads:
https://github.com/sequelize/sequelize/security/advisories/GHSA-f598-mfpv-gmfx
https://github.com/sequelize/sequelize/discussions/15694`);
}
let alias = attr[1];
if (this.options.minifyAliases) {
alias = this._getMinifiedAlias(alias, mainTableAs, options);
}
attr = [attr[0], this.quoteIdentifier(alias)].join(" AS ");
} else {
attr = !attr.includes(Utils.TICK_CHAR) && !attr.includes('"') ? this.quoteAttribute(attr, options.model) : this.escape(attr);
}
if (!_.isEmpty(options.include) && (!attr.includes(".") || options.dotNotation) && addTable) {
attr = `${mainTableAs}.${attr}`;
}
return attr;
});
}
generateInclude(include, parentTableName, topLevelInfo) {
const joinQueries = {
mainQuery: [],
subQuery: []
};
const mainChildIncludes = [];
const subChildIncludes = [];
let requiredMismatch = false;
const includeAs = {
internalAs: include.as,
externalAs: include.as
};
const attributes = {
main: [],
subQuery: []
};
let joinQuery;
topLevelInfo.options.keysEscaped = true;
if (topLevelInfo.names.name !== parentTableName.externalAs && topLevelInfo.names.as !== parentTableName.externalAs) {
includeAs.internalAs = `${parentTableName.internalAs}->${include.as}`;
includeAs.externalAs = `${parentTableName.externalAs}.${include.as}`;
}
if (topLevelInfo.options.includeIgnoreAttributes !== false) {
include.model._expandAttributes(include);
Utils.mapFinderOptions(include, include.model);
const includeAttributes = include.attributes.map((attr) => {
let attrAs = attr;
let verbatim = false;
if (Array.isArray(attr) && attr.length === 2) {
if (attr[0] instanceof Utils.SequelizeMethod && (attr[0] instanceof Utils.Literal || attr[0] instanceof Utils.Cast || attr[0] instanceof Utils.Fn)) {
verbatim = true;
}
attr = attr.map((attr2) => attr2 instanceof Utils.SequelizeMethod ? this.handleSequelizeMethod(attr2) : attr2);
attrAs = attr[1];
attr = attr[0];
}
if (attr instanceof Utils.Literal) {
return attr.val;
}
if (attr instanceof Utils.Cast || attr instanceof Utils.Fn) {
throw new Error("Tried to select attributes using Sequelize.cast or Sequelize.fn without specifying an alias for the result, during eager loading. This means the attribute will not be added to the returned instance");
}
let prefix;
if (verbatim === true) {
prefix = attr;
} else if (/#>>|->>/.test(attr)) {
prefix = `(${this.quoteIdentifier(includeAs.internalAs)}.${attr.replace(/\(|\)/g, "")})`;
} else if (/json_extract\(/.test(attr)) {
prefix = attr.replace(/json_extract\(/i, `json_extract(${this.quoteIdentifier(includeAs.internalAs)}.`);
} else if (/json_value\(/.test(attr)) {
prefix = attr.replace(/json_value\(/i, `json_value(${this.quoteIdentifier(includeAs.internalAs)}.`);
} else {
prefix = `${this.quoteIdentifier(includeAs.internalAs)}.${this.quoteIdentifier(attr)}`;
}
let alias = `${includeAs.externalAs}.${attrAs}`;
if (this.options.minifyAliases) {
alias = this._getMinifiedAlias(alias, includeAs.internalAs, topLevelInfo.options);
}
return Utils.joinSQLFragments([
prefix,
"AS",
this.quoteIdentifier(alias, true)
]);
});
if (include.subQuery && topLevelInfo.subQuery) {
for (const attr of includeAttributes) {
attributes.subQuery.push(attr);
}
} else {
for (const attr of includeAttributes) {
attributes.main.push(attr);
}
}
}
if (include.through) {
joinQuery = this.generateThroughJoin(include, includeAs, parentTableName.internalAs, topLevelInfo);
} else {
this._generateSubQueryFilter(include, includeAs, topLevelInfo);
joinQuery = this.generateJoin(include, topLevelInfo);
}
if (joinQuery.attributes.main.length > 0) {
attributes.main = attributes.main.concat(joinQuery.attributes.main);
}
if (joinQuery.attributes.subQuery.length > 0) {
attributes.subQuery = attributes.subQuery.concat(joinQuery.attributes.subQuery);
}
if (include.include) {
for (const childInclude of include.include) {
if (childInclude.separate || childInclude._pseudo) {
continue;
}
const childJoinQueries = this.generateInclude(childInclude, includeAs, topLevelInfo);
if (include.required === false && childInclude.required === true) {
requiredMismatch = true;
}
if (childInclude.subQuery && topLevelInfo.subQuery) {
subChildIncludes.push(childJoinQueries.subQuery);
}
if (childJoinQueries.mainQuery) {
mainChildIncludes.push(childJoinQueries.mainQuery);
}
if (childJoinQueries.attributes.main.length > 0) {
attributes.main = attributes.main.concat(childJoinQueries.attributes.main);
}
if (childJoinQueries.attributes.subQuery.length > 0) {
attributes.subQuery = attributes.subQuery.concat(childJoinQueries.attributes.subQuery);
}
}
}
if (include.subQuery && topLevelInfo.subQuery) {
if (requiredMismatch && subChildIncludes.length > 0) {
joinQueries.subQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${subChildIncludes.join("")} ) ON ${joinQuery.condition}`);
} else {
joinQueries.subQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);
if (subChildIncludes.length > 0) {
joinQueries.subQuery.push(subChildIncludes.join(""));
}
}
joinQueries.mainQuery.push(mainChildIncludes.join(""));
} else {
if (requiredMismatch && mainChildIncludes.length > 0) {
joinQueries.mainQuery.push(` ${joinQuery.join} ( ${joinQuery.body}${mainChildIncludes.join("")} ) ON ${joinQuery.condition}`);
} else {
joinQueries.mainQuery.push(` ${joinQuery.join} ${joinQuery.body} ON ${joinQuery.condition}`);
if (mainChildIncludes.length > 0) {
joinQueries.mainQuery.push(mainChildIncludes.join(""));
}
}
joinQueries.subQuery.push(subChildIncludes.join(""));
}
return {
mainQuery: joinQueries.mainQuery.join(""),
subQuery: joinQueries.subQuery.join(""),
attributes
};
}
_getMinifiedAlias(alias, tableName, options) {
if (options.aliasesByTable[`${tableName}${alias}`]) {
return options.aliasesByTable[`${tableName}${alias}`];
}
if (alias.match(/subquery_order_[0-9]/)) {
return alias;
}
const minifiedAlias = `_${options.aliasesMapping.size}`;
options.aliasesMapping.set(minifiedAlias, alias);
options.aliasesByTable[`${tableName}${alias}`] = minifiedAlias;
return minifiedAlias;
}
_getAliasForField(tableName, field, options) {
if (this.options.minifyAliases) {
if (options.aliasesByTable[`${tableName}${field}`]) {
return options.aliasesByTable[`${tableName}${field}`];
}
}
return null;
}
generateJoin(include, topLevelInfo) {
const association = include.association;
const parent = include.parent;
const parentIsTop = !!parent && !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;
let $parent;
let joinWhere;
const left = association.source;
const attrLeft = association instanceof BelongsTo ? association.identifier : association.sourceKeyAttribute || left.primaryKeyAttribute;
const fieldLeft = association instanceof BelongsTo ? association.identifierField : left.rawAttributes[association.sourceKeyAttribute || left.primaryKeyAttribute].field;
let asLeft;
const right = include.model;
const tableRight = right.getTableName();
const fieldRight = association instanceof BelongsTo ? right.rawAttributes[association.targetIdentifier || right.primaryKeyAttribute].field : association.identifierField;
let asRight = include.as;
while (($parent = $parent && $parent.parent || include.parent) && $parent.association) {
if (asLeft) {
asLeft = `${$parent.as}->${asLeft}`;
} else {
asLeft = $parent.as;
}
}
if (!asLeft)
asLeft = parent.as || parent.model.name;
else
asRight = `${asLeft}->${asRight}`;
let joinOn = `${this.quoteTable(asLeft)}.${this.quoteIdentifier(fieldLeft)}`;
const subqueryAttributes = [];
if (topLevelInfo.options.groupedLimit && parentIsTop || topLevelInfo.subQuery && include.parent.subQuery && !include.subQuery) {
if (parentIsTop) {
const tableName = this.quoteTable(parent.as || parent.model.name);
joinOn = this._getAliasForField(tableName, attrLeft, topLevelInfo.options) || `${tableName}.${this.quoteIdentifier(attrLeft)}`;
if (topLevelInfo.subQuery) {
const dbIdentifier = `${tableName}.${this.quoteIdentifier(fieldLeft)}`;
subqueryAttributes.push(dbIdentifier !== joinOn ? `${dbIdentifier} AS ${this.quoteIdentifier(attrLeft)}` : dbIdentifier);
}
} else {
const joinSource = `${asLeft.replace(/->/g, ".")}.${attrLeft}`;
joinOn = this._getAliasForField(asLeft, joinSource, topLevelInfo.options) || this.quoteIdentifier(joinSource);
}
}
joinOn += ` = ${this.quoteIdentifier(asRight)}.${this.quoteIdentifier(fieldRight)}`;
if (include.on) {
joinOn = this.whereItemsQuery(include.on, {
prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),
model: include.model
});
}
if (include.where) {
joinWhere = this.whereItemsQuery(include.where, {
prefix: this.sequelize.literal(this.quoteIdentifier(asRight)),
model: include.model
});
if (joinWhere) {
if (include.or) {
joinOn += ` OR ${joinWhere}`;
} else {
joinOn += ` AND ${joinWhere}`;
}
}
}
this.aliasAs(asRight, topLevelInfo);
return {
join: include.required ? "INNER JOIN" : include.right && this._dialect.supports["RIGHT JOIN"] ? "RIGHT OUTER JOIN" : "LEFT OUTER JOIN",
body: this.quoteTable(tableRight, asRight),
condition: joinOn,
attributes: {
main: [],
subQuery: subqueryAttributes
}
};
}
generateReturnValues(modelAttributes, options) {
const returnFields = [];
const returnTypes = [];
let outputFragment = "";
let returningFragment = "";
let tmpTable = "";
if (Array.isArray(options.returning)) {
returnFields.push(...options.returning.map((field) => this.quoteIdentifier(field)));
} else if (modelAttributes) {
_.each(modelAttributes, (attribute) => {
if (!(attribute.type instanceof DataTypes.VIRTUAL)) {
returnFields.push(this.quoteIdentifier(attribute.field));
returnTypes.push(attribute.type);
}
});
}
if (_.isEmpty(returnFields)) {
returnFields.push("*");
}
if (this._dialect.supports.returnValues.returning) {
returningFragment = ` RETURNING ${returnFields.join(",")}`;
} else if (this._dialect.supports.returnIntoValues) {
returningFragment = ` RETURNING ${returnFields.join(",")} INTO `;
} else if (this._dialect.supports.returnValues.output) {
outputFragment = ` OUTPUT ${returnFields.map((field) => `INSERTED.${field}`).join(",")}`;
if (options.hasTrigger && this._dialect.supports.tmpTableTrigger) {
const tmpColumns = returnFields.map((field, i) => `${field} ${returnTypes[i].toSql()}`);
tmpTable = `DECLARE @tmp TABLE (${tmpColumns.join(",")}); `;
outputFragment += " INTO @tmp";
returningFragment = "; SELECT * FROM @tmp";
}
}
return { outputFragment, returnFields, returnTypes, returningFragment, tmpTable };
}
generateThroughJoin(include, includeAs, parentTableName, topLevelInfo) {
const through = include.through;
const throughTable = through.model.getTableName();
const throughAs = `${includeAs.internalAs}->${through.as}`;
const externalThroughAs = `${includeAs.externalAs}.${through.as}`;
const throughAttributes = through.attributes.map((attr) => {
let alias = `${externalThroughAs}.${Array.isArray(attr) ? attr[1] : attr}`;
if (this.options.minifyAliases) {
alias = this._getMinifiedAlias(alias, throughAs, topLevelInfo.options);
}
return Utils.joinSQLFragments([
`${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(Array.isArray(attr) ? attr[0] : attr)}`,
"AS",
this.quoteIdentifier(alias)
]);
});
const association = include.association;
const parentIsTop = !include.parent.association && include.parent.model.name === topLevelInfo.options.model.name;
const tableSource = parentTableName;
const identSource = association.identifierField;
const tableTarget = includeAs.internalAs;
const identTarget = association.foreignIdentifierField;
const attrTarget = association.targetKeyField;
const joinType = include.required ? "INNER JOIN" : include.right && this._dialect.supports["RIGHT JOIN"] ? "RIGHT OUTER JOIN" : "LEFT OUTER JOIN";
let joinBody;
let joinCondition;
const attributes = {
main: [],
subQuery: []
};
let attrSource = association.sourceKey;
let sourceJoinOn;
let targetJoinOn;
let throughWhere;
let targetWhere;
if (topLevelInfo.options.includeIgnoreAttributes !== false) {
for (const attr of throughAttributes) {
attributes.main.push(attr);
}
}
if (!topLevelInfo.subQuery) {
attrSource = association.sourceKeyField;
}
if (topLevelInfo.subQuery && !include.subQuery && !include.parent.subQuery && include.parent.model !== topLevelInfo.options.mainModel) {
attrSource = association.sourceKeyField;
}
if (topLevelInfo.subQuery && !include.subQuery && include.parent.subQuery && !parentIsTop) {
const joinSource = this._getAliasForField(tableSource, `${tableSource}.${attrSource}`, topLevelInfo.options) || `${tableSource}.${attrSource}`;
sourceJoinOn = `${this.quoteIdentifier(joinSource)} = `;
} else {
const aliasedSource = this._getAliasForField(tableSource, attrSource, topLevelInfo.options) || attrSource;
sourceJoinOn = `${this.quoteTable(tableSource)}.${this.quoteIdentifier(aliasedSource)} = `;
}
sourceJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identSource)}`;
targetJoinOn = `${this.quoteIdentifier(tableTarget)}.${this.quoteIdentifier(attrTarget)} = `;
targetJoinOn += `${this.quoteIdentifier(throughAs)}.${this.quoteIdentifier(identTarget)}`;
if (through.where) {
throughWhere = this.getWhereConditions(through.where, this.sequelize.literal(this.quoteIdentifier(throughAs)), through.model);
}
this.aliasAs(includeAs.internalAs, topLevelInfo);
joinBody = `( ${this.quoteTable(throughTable, throughAs)} INNER JOIN ${this.quoteTable(include.model.getTableName(), includeAs.internalAs)} ON ${targetJoinOn}`;
if (throughWhere) {
joinBody += ` AND ${throughWhere}`;
}
joinBody += ")";
joinCondition = sourceJoinOn;
if (include.where || include.through.where) {
if (include.where) {
targetWhere = this.getWhereConditions(include.where, this.sequelize.literal(this.quoteIdentifier(includeAs.internalAs)), include.model, topLevelInfo.options);
if (targetWhere) {
joinCondition += ` AND ${targetWhere}`;
}
}
}
this._generateSubQueryFilter(include, includeAs, topLevelInfo);
return {
join: joinType,
body: joinBody,
condition: joinCondition,
attributes
};
}
aliasAs(as, topLevelInfo) {
if (this.options.minifyAliases && as.length >= 64) {
const alias = `%${topLevelInfo.options.includeAliases.size}`;
topLevelInfo.options.includeAliases.set(alias, as);
}
}
_generateSubQueryFilter(include, includeAs, topLevelInfo) {
if (!topLevelInfo.subQuery || !include.subQueryFilter) {
return;
}
if (!topLevelInfo.options.where) {
topLevelInfo.options.where = {};
}
let parent = include;
let child = include;
let nestedIncludes = this._getRequiredClosure(include).include;
let query;
while (parent = parent.parent) {
if (parent.parent && !parent.required) {
return;
}
if (parent.subQueryFilter) {
return;
}
nestedIncludes = [__spreadProps(__spreadValues({}, child), { include: nestedIncludes, attributes: [] })];
child = parent;
}
const topInclude = nestedIncludes[0];
const topParent = topInclude.parent;
const topAssociation = topInclude.association;
topInclude.association = void 0;
if (topInclude.through && Object(topInclude.through.model) === topInclude.through.model) {
query = this.selectQuery(topInclude.through.model.getTableName(), {
attributes: [topInclude.through.model.primaryKeyField],
include: Model._validateIncludedElements({
model: topInclude.through.model,
include: [{
association: topAssociation.toTarget,
required: true,
where: topInclude.where,
include: topInclude.include
}]
}).include,
model: topInclude.through.model,
where: {
[Op.and]: [
this.sequelize.literal([
`${this.quoteTable(topParent.model.name)}.${this.quoteIdentifier(topParent.model.primaryKeyField)}`,
`${this.quoteIdentifier(topInclude.through.model.name)}.${this.quoteIdentifier(topAssociation.identifierField)}`
].join(" = ")),
topInclude.through.where
]
},
limit: 1,
includeIgnoreAttributes: false
}, topInclude.through.model);
} else {
const isBelongsTo = topAssociation.associationType === "BelongsTo";
const sourceField = isBelongsTo ? topAssociation.identifierField : topAssociation.sourceKeyField || topParent.model.primaryKeyField;
const targetField = isBelongsTo ? topAssociation.sourceKeyField || topInclude.model.primaryKeyField : topAssociation.identifierField;
const join = [
`${this.quoteIdentifier(topInclude.as)}.${this.quoteIdentifier(targetField)}`,
`${this.quoteTable(topParent.as || topParent.model.name)}.${this.quoteIdentifier(sourceField)}`
].join(" = ");
query = this.selectQuery(topInclude.model.getTableName(), {
attributes: [targetField],
include: Model._validateIncludedElements(topInclude).include,
model: topInclude.model,
where: {
[Op.and]: [
topInclude.where,
{ [Op.join]: this.sequelize.literal(join) }
]
},
limit: 1,
tableAs: topInclude.as,
includeIgnoreAttributes: false
}, topInclude.model);
}
if (!topLevelInfo.options.where[Op.and]) {
topLevelInfo.options.where[Op.and] = [];
}
topLevelInfo.options.where[`__${includeAs.internalAs}`] = this.sequelize.literal([
"(",
query.replace(/;$/, ""),
")",
"IS NOT NULL"
].join(" "));
}
_getRequiredClosure(include) {
const copy = __spreadProps(__spreadValues({}, include), { attributes: [], include: [] });
if (Array.isArray(include.include)) {
copy.include = include.include.filter((i) => i.required).map((inc) => this._getRequiredClosure(inc));
}
return copy;
}
getQueryOrders(options, model, subQuery) {
const mainQueryOrder = [];
const subQueryOrder = [];
if (Array.isArray(options.order)) {
for (let order of options.order) {
if (!Array.isArray(order)) {
order = [order];
}
if (subQuery && Array.isArray(order) && order[0] && !(order[0] instanceof Association) && !(typeof order[0] === "function" && order[0].prototype instanceof Model) && !(typeof order[0].model === "function" && order[0].model.prototype instanceof Model) && !(typeof order[0] === "string" && model && model.associations !== void 0 && model.associations[order[0]])) {
const field = model.rawAttributes[order[0]] ? model.rawAttributes[order[0]].field : order[0];
const subQueryAlias = this._getAliasForField(this.quoteIdentifier(model.name), field, options);
let parent = null;
let orderToQuote = [];
if (subQueryAlias === null) {
orderToQuote = order;
parent = model;
} else {
orderToQuote = [subQueryAlias, order.length > 1 ? order[1] : "ASC"];
parent = null;
}
subQueryOrder.push(this.quote(orderToQuote, parent, "->"));
}
if (options.attributes && model) {
const aliasedAttribute = options.attributes.find((attr) => Array.isArray(attr) && attr[1] && (attr[0] === order[0] || attr[1] === order[0]));
if (aliasedAttribute) {
const modelName = this.quoteIdentifier(model.name);
const alias = this._getAliasForField(modelName, aliasedAttribute[1], options);
order[0] = new Utils.Col(alias || aliasedAttribute[1]);
}
}
mainQueryOrder.push(this.quote(order, model, "->"));
}
} else if (options.order instanceof Utils.SequelizeMethod) {
const sql = this.quote(options.order, model, "->");
if (subQuery) {
subQueryOrder.push(sql);
}
mainQueryOrder.push(sql);
} else {
throw new Error("Order must be type of array or instance of a valid sequelize method.");
}
return { mainQueryOrder, subQueryOrder };
}
_throwOnEmptyAttributes(attributes, extraInfo = {}) {
if (attributes.length > 0)
return;
const asPart = extraInfo.as && `as ${extraInfo.as}` || "";
const namePart = extraInfo.modelName && `for model '${extraInfo.modelName}'` || "";
const message = `Attempted a SELECT query ${namePart} ${asPart} without selecting any columns`;
throw new sequelizeError.QueryError(message.replace(/ +/g, " "));
}
selectFromTableFragment(options, model, attributes, tables, mainTableAs) {
this._throwOnEmptyAttributes(attributes, { modelName: model && model.name, as: mainTableAs });
let fragment = `SELECT ${attributes.join(", ")} FROM ${tables}`;
if (mainTableAs) {
fragment += ` ${this.getAliasToken()} ${mainTableAs}`;
}
if (options.indexHints && this._dialect.supports.indexHints) {
for (const hint of options.indexHints) {
if (IndexHints[hint.type]) {
fragment += ` ${IndexHints[hint.type]} INDEX (${hint.values.map((indexName) => this.quoteIdentifiers(indexName)).join(",")})`;
}
}
}
return fragment;
}
addLimitAndOffset(options) {
let fragment = "";
if (options.offset != null && options.limit == null) {
fragment += " LIMIT " + this.escape(options.offset) + ", " + 1e13;
} else if (options.limit != null) {
if (options.offset != null) {
fragment += " LIMIT " + this.escape(options.offset) + ", " + this.escape(options.limit);
} else {
fragment += " LIMIT " + this.escape(options.limit);
}
}
return fragment;
}
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
let result;
if (Object.prototype.hasOwnProperty.call(this.OperatorMap, smth.comparator)) {
smth.comparator = this.OperatorMap[smth.comparator];
}
if (smth instanceof Utils.Where) {
let value = smth.logic;
let key;
if (smth.attribute instanceof Utils.SequelizeMethod) {
key = this.getWhereConditions(smth.attribute, tableName, factory, options, prepend);
} else {
key = `${this.quoteTable(smth.attribute.Model.name)}.${this.quoteIdentifier(smth.attribute.field || smth.attribute.fieldName)}`;
}
if (value && value instanceof Utils.SequelizeMethod) {
value = this.getWhereConditions(value, tableName, factory, options, prepend);
if (value === "NULL") {
if (smth.comparator === "=") {
smth.comparator = "IS";
}
if (smth.comparator === "!=") {
smth.comparator = "IS NOT";
}
}
return [key, value].join(` ${smth.comparator} `);
}
if (_.isPlainObject(value)) {
return this.whereItemQuery(smth.attribute, value, {
model: factory
});
}
if ([this.OperatorMap[Op.between], this.OperatorMap[Op.notBetween]].includes(smth.comparator)) {
value = `${this.escape(value[0])} AND ${this.escape(value[1])}`;
} else if (typeof value === "boolean") {
value = this.booleanValue(value);
} else {
value = this.escape(value);
}
if (value === "NULL") {
if (smth.comparator === "=") {
smth.comparator = "IS";
}
if (smth.comparator === "!=") {
smth.comparator = "IS NOT";
}
}
return [key, value].join(` ${smth.comparator} `);
}
if (smth instanceof Utils.Literal) {
return smth.val;
}
if (smth instanceof Utils.Cast) {
if (smth.val instanceof Utils.SequelizeMethod) {
result = this.handleSequelizeMethod(smth.val, tableName, factory, options, prepend);
} else if (_.isPlainObject(smth.val)) {
result = this.whereItemsQuery(smth.val);
} else {
result = this.escape(smth.val);
}
return `CAST(${result} AS ${smth.type.toUpperCase()})`;
}
if (smth instanceof Utils.Fn) {
return `${smth.fn}(${smth.args.map((arg) => {
if (arg instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(arg, tableName, factory, options, prepend);
}
if (_.isPlainObject(arg)) {
return this.whereItemsQuery(arg);
}
return this.escape(typeof arg === "string" ? arg.replace(/\$/g, "$$$") : arg);
}).join(", ")})`;
}
if (smth instanceof Utils.Col) {
if (Array.isArray(smth.col) && !factory) {
throw new Error("Cannot call Sequelize.col() with array outside of order / group clause");
}
if (smth.col.startsWith("*")) {
return "*";
}
return this.quote(smth.col, factory);
}
return smth.toString(this, factory);
}
whereQuery(where, options) {
const query = this.whereItemsQuery(where, options);
if (query && query.length) {
return `WHERE ${query}`;
}
return "";
}
whereItemsQuery(where, options, binding) {
if (where === null || where === void 0 || Utils.getComplexSize(where) === 0) {
return "";
}
if (typeof where === "string") {
throw new Error("Support for `{where: 'raw query'}` has been removed.");
}
const items = [];
binding = binding || "AND";
if (binding[0] !== " ")
binding = ` ${binding} `;
if (_.isPlainObject(where)) {
Utils.getComplexKeys(where).forEach((prop) => {
const item = where[prop];
items.push(this.whereItemQuery(prop, item, options));
});
} else {
items.push(this.whereItemQuery(void 0, where, options));
}
return items.length && items.filter((item) => item && item.length).join(binding) || "";
}
whereItemQuery(key, value, options = {}) {
if (value === void 0) {
throw new Error(`WHERE parameter "${key}" has invalid "undefined" value`);
}
if (typeof key === "string" && key.includes(".") && options.model) {
const keyParts = key.split(".");
if (options.model.rawAttributes[keyParts[0]] && options.model.rawAttributes[keyParts[0]].type instanceof DataTypes.JSON) {
const tmp = {};
const field2 = options.model.rawAttributes[keyParts[0]];
_.set(tmp, keyParts.slice(1), value);
return this.whereItemQuery(field2.field || keyParts[0], tmp, __spreadValues({ field: field2 }, options));
}
}
const field = this._findField(key, options);
const fieldType = field && field.type || options.type;
const isPlainObject = _.isPlainObject(value);
const isArray = !isPlainObject && Array.isArray(value);
key = this.OperatorsAliasMap && this.OperatorsAliasMap[key] || key;
if (isPlainObject) {
value = this._replaceAliases(value);
}
const valueKeys = isPlainObject && Utils.getComplexKeys(value);
if (key === void 0) {
if (typeof value === "string") {
return value;
}
if (isPlainObject && valueKeys.length === 1) {
return this.whereItemQuery(valueKeys[0], value[valueKeys[0]], options);
}
}
if (value === null) {
const opValue2 = options.bindParam ? "NULL" : this.escape(value, field);
return this._joinKeyValue(key, opValue2, this.OperatorMap[Op.is], options.prefix);
}
if (!value) {
const opValue2 = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue2, this.OperatorMap[Op.eq], options.prefix);
}
if (value instanceof Utils.SequelizeMethod && !(key !== void 0 && value instanceof Utils.Fn)) {
return this.handleSequelizeMethod(value);
}
if (key === void 0 && isArray) {
if (Utils.canTreatArrayAsAnd(value)) {
key = Op.and;
} else {
throw new Error("Support for literal replacements in the `where` object has been removed.");
}
}
if (key === Op.or || key === Op.and || key === Op.not) {
return this._whereGroupBind(key, value, options);
}
if (value[Op.or]) {
return this._whereBind(this.OperatorMap[Op.or], key, value[Op.or], options);
}
if (value[Op.and]) {
return this._whereBind(this.OperatorMap[Op.and], key, value[Op.and], options);
}
if (isArray && fieldType instanceof DataTypes.ARRAY) {
const opValue2 = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue2, this.OperatorMap[Op.eq], options.prefix);
}
if (isPlainObject && fieldType instanceof DataTypes.JSON && options.json !== false) {
return this._whereJSON(key, value, options);
}
if (isPlainObject && valueKeys.length > 1) {
return this._whereBind(this.OperatorMap[Op.and], key, value, options);
}
if (isArray) {
return this._whereParseSingleValueObject(key, field, Op.in, value, options);
}
if (isPlainObject) {
if (this.OperatorMap[valueKeys[0]]) {
return this._whereParseSingleValueObject(key, field, valueKeys[0], value[valueKeys[0]], options);
}
return this._whereParseSingleValueObject(key, field, this.OperatorMap[Op.eq], value, options);
}
if (key === Op.placeholder) {
const opValue2 = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(this.OperatorMap[key], opValue2, this.OperatorMap[Op.eq], options.prefix);
}
const opValue = options.bindParam ? this.format(value, field, options, options.bindParam) : this.escape(value, field);
return this._joinKeyValue(key, opValue, this.OperatorMap[Op.eq], options.prefix);
}
_findField(key, options) {
if (options.field) {
return options.field;
}
if (options.model && options.model.rawAttributes && options.model.rawAttributes[key]) {
return options.model.rawAttributes[key];
}
if (options.model && options.model.fieldRawAttributesMap && options.model.fieldRawAttributesMap[key]) {
return options.model.fieldRawAttributesMap[key];
}
}
_whereGroupBind(key, value, options) {
const binding = key === Op.or ? this.OperatorMap[Op.or] : this.OperatorMap[Op.and];
const outerBinding = key === Op.not ? "NOT " : "";
if (Array.isArray(value)) {
value = value.map((item) => {
let itemQuery = this.whereItemsQuery(item, options, this.OperatorMap[Op.and]);
if (itemQuery && itemQuery.length && (Array.isArray(item) || _.isPlainObject(item)) && Utils.getComplexSize(item) > 1) {
itemQuery = `(${itemQuery})`;
}
return itemQuery;
}).filter((item) => item && item.length);
value = value.length && value.join(binding);
} else {
value = this.whereItemsQuery(value, options, binding);
}
if ((key === Op.or || key === Op.not) && !value) {
return "0 = 1";
}
return value ? `${outerBinding}(${value})` : void 0;
}
_whereBind(binding, key, value, options) {
if (_.isPlainObject(value)) {
value = Utils.getComplexKeys(value).map((prop) => {
const item = value[prop];
return this.whereItemQuery(key, { [prop]: item }, options);
});
} else {
value = value.map((item) => this.whereItemQuery(key, item, options));
}
value = value.filter((item) => item && item.length);
return value.length ? `(${value.join(binding)})` : void 0;
}
_whereJSON(key, value, options) {
const items = [];
let baseKey = this.quoteIdentifier(key);
if (options.prefix) {
if (options.prefix instanceof Utils.Literal) {
baseKey = `${this.handleSequelizeMethod(options.prefix)}.${baseKey}`;
} else {
baseKey = `${this.quoteTable(options.prefix)}.${baseKey}`;
}
}
Utils.getOperators(value).forEach((op) => {
const where = {
[op]: value[op]
};
items.push(this.whereItemQuery(key, where, __spreadProps(__spreadValues({}, options), { json: false })));
});
_.forOwn(value, (item, prop) => {
this._traverseJSON(items, baseKey, prop, item, [prop]);
});
const result = items.join(this.OperatorMap[Op.and]);
return items.length > 1 ? `(${result})` : result;
}
_traverseJSON(items, baseKey, prop, item, path) {
let cast;
if (path[path.length - 1].includes("::")) {
const tmp = path[path.length - 1].split("::");
cast = tmp[1];
path[path.length - 1] = tmp[0];
this._validateCastType(cast);
}
let pathKey = this.jsonPathExtractionQuery(baseKey, path);
if (_.isPlainObject(item)) {
Utils.getOperators(item).forEach((op) => {
const value = this._toJSONValue(item[op]);
let isJson = false;
if (typeof value === "string" && op === Op.contains) {
try {
JSON.stringify(value);
isJson = true;
} catch (e) {
}
}
pathKey = this.jsonPathExtractionQuery(baseKey, path, isJson);
items.push(this.whereItemQuery(this._castKey(pathKey, value, cast), { [op]: value }));
});
_.forOwn(item, (value, itemProp) => {
this._traverseJSON(items, baseKey, itemProp, value, path.concat([itemProp]));
});
return;
}
item = this._toJSONValue(item);
items.push(this.whereItemQuery(this._castKey(pathKey, item, cast), { [Op.eq]: item }));
}
_toJSONValue(value) {
return value;
}
_castKey(key, value, cast, json) {
cast = cast || this._getJsonCast(Array.isArray(value) ? value[0] : value);
if (cast) {
return new Utils.Literal(this.handleSequelizeMethod(new Utils.Cast(new Utils.Literal(key), cast, json)));
}
return new Utils.Literal(key);
}
_getJsonCast(value) {
if (typeof value === "number") {
return "double precision";
}
if (value instanceof Date) {
return "timestamptz";
}
if (typeof value === "boolean") {
return "boolean";
}
return;
}
_validateCastType(cast) {
if (!ALLOWED_CAST_TYPES.has(cast.toLowerCase())) {
throw new Error(`Invalid cast type: ${cast}`);
}
}
_joinKeyValue(key, value, comparator, prefix) {
if (!key) {
return value;
}
if (comparator === void 0) {
throw new Error(`${key} and ${value} has no comparator`);
}
key = this._getSafeKey(key, prefix);
return [key, value].join(` ${comparator} `);
}
_getSafeKey(key, prefix) {
if (key instanceof Utils.SequelizeMethod) {
key = this.handleSequelizeMethod(key);
return this._prefixKey(this.handleSequelizeMethod(key), prefix);
}
if (Utils.isColString(key)) {
key = key.substr(1, key.length - 2).split(".");
if (key.length > 2) {
key = [
key.slice(0, -1).join("->"),
key[key.length - 1]
];
}
return key.map((identifier) => this.quoteIdentifier(identifier)).join(".");
}
return this._prefixKey(this.quoteIdentifier(key), prefix);
}
_prefixKey(key, prefix) {
if (prefix) {
if (prefix instanceof Utils.Literal) {
return [this.handleSequelizeMethod(prefix), key].join(".");
}
return [this.quoteTable(prefix), key].join(".");
}
return key;
}
_whereParseSingleValueObject(key, field, prop, value, options) {
if (prop === Op.not) {
if (Array.isArray(value)) {
prop = Op.notIn;
} else if (value !== null && value !== true && value !== false) {
prop = Op.ne;
}
}
let comparator = this.OperatorMap[prop] || this.OperatorMap[Op.eq];
switch (prop) {
case Op.in:
case Op.notIn:
if (value instanceof Utils.Literal) {
return this._joinKeyValue(key, value.val, comparator, options.prefix);
}
if (value.length) {
return this._joinKeyValue(key, `(${value.map((item) => this.escape(item, field)).join(", ")})`, comparator, options.prefix);
}
if (comparator === this.OperatorMap[Op.in]) {
return this._joinKeyValue(key, "(NULL)", comparator, options.prefix);
}
return "";
case Op.any:
case Op.all:
comparator = `${this.OperatorMap[Op.eq]} ${comparator}`;
if (value[Op.values]) {
return this._joinKeyValue(key, `(VALUES ${value[Op.values].map((item) => `(${this.escape(item)})`).join(", ")})`, comparator, options.prefix);
}
return this._joinKeyValue(key, `(${this.escape(value, field)})`, comparator, options.prefix);
case Op.between:
case Op.notBetween:
return this._joinKeyValue(key, `${this.escape(value[0], field)} AND ${this.escape(value[1], field)}`, comparator, options.prefix);
case Op.raw:
throw new Error("The `$raw` where property is no longer supported. Use `sequelize.literal` instead.");
case Op.col:
comparator = this.OperatorMap[Op.eq];
value = value.split(".");
if (value.length > 2) {
value = [
value.slice(0, -1).join("->"),
value[value.length - 1]
];
}
return this._joinKeyValue(key, value.map((identifier) => this.quoteIdentifier(identifier)).join("."), comparator, options.prefix);
case Op.startsWith:
case Op.endsWith:
case Op.substring:
comparator = this.OperatorMap[Op.like];
if (value instanceof Utils.Literal) {
value = value.val;
}
let pattern = `${value}%`;
if (prop === Op.endsWith)
pattern = `%${value}`;
if (prop === Op.substring)
pattern = `%${value}%`;
return this._joinKeyValue(key, this.escape(pattern), comparator, options.prefix);
}
const escapeOptions = {
acceptStrings: comparator.includes(this.OperatorMap[Op.like])
};
if (_.isPlainObject(value)) {
if (value[Op.col]) {
return this._joinKeyValue(key, this.whereItemQuery(null, value), comparator, options.prefix);
}
if (value[Op.any]) {
escapeOptions.isList = true;
return this._joinKeyValue(key, `(${this.escape(value[Op.any], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.any]}`, options.prefix);
}
if (value[Op.all]) {
escapeOptions.isList = true;
return this._joinKeyValue(key, `(${this.escape(value[Op.all], field, escapeOptions)})`, `${comparator} ${this.OperatorMap[Op.all]}`, options.prefix);
}
}
if (value === null && comparator === this.OperatorMap[Op.eq]) {
return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.is], options.prefix);
}
if (value === null && comparator === this.OperatorMap[Op.ne]) {
return this._joinKeyValue(key, this.escape(value, field, escapeOptions), this.OperatorMap[Op.not], options.prefix);
}
return this._joinKeyValue(key, this.escape(value, field, escapeOptions), comparator, options.prefix);
}
getWhereConditions(smth, tableName, factory, options, prepend) {
const where = {};
if (Array.isArray(tableName)) {
tableName = tableName[0];
if (Array.isArray(tableName)) {
tableName = tableName[1];
}
}
options = options || {};
if (prepend === void 0) {
prepend = true;
}
if (smth && smth instanceof Utils.SequelizeMethod) {
return this.handleSequelizeMethod(smth, tableName, factory, options, prepend);
}
if (_.isPlainObject(smth)) {
return this.whereItemsQuery(smth, {
model: factory,
prefix: prepend && tableName,
type: options.type
});
}
if (typeof smth === "number" || typeof smth === "bigint") {
let primaryKeys = factory ? Object.keys(factory.primaryKeys) : [];
if (primaryKeys.length > 0) {
primaryKeys = primaryKeys[0];
} else {
primaryKeys = "id";
}
where[primaryKeys] = smth;
return this.whereItemsQuery(where, {
model: factory,
prefix: prepend && tableName
});
}
if (typeof smth === "string") {
return this.whereItemsQuery(smth, {
model: factory,
prefix: prepend && tableName
});
}
if (Buffer.isBuffer(smth)) {
return this.escape(smth);
}
if (Array.isArray(smth)) {
if (smth.length === 0 || smth.length > 0 && smth[0].length === 0)
return "1=1";
if (Utils.canTreatArrayAsAnd(smth)) {
const _smth = { [Op.and]: smth };
return this.getWhereConditions(_smth, tableName, factory, options, prepend);
}
throw new Error("Support for literal replacements in the `where` object has been removed.");
}
if (smth == null) {
return this.whereItemsQuery(smth, {
model: factory,
prefix: prepend && tableName
});
}
throw new Error(`Unsupported where option value: ${util.inspect(smth)}. Please refer to the Sequelize documentation to learn more about which values are accepted as part of the where option.`);
}
parseConditionObject(conditions, path) {
path = path || [];
return _.reduce(conditions, (result, value, key) => {
if (_.isObject(value)) {
return result.concat(this.parseConditionObject(value, path.concat(key)));
}
result.push({ path: path.concat(key), value });
return result;
}, []);
}
booleanValue(value) {
return value;
}
authTestQuery() {
return "SELECT 1+1 AS result";
}
}
Object.assign(QueryGenerator.prototype, require("./query-generator/operators"));
Object.assign(QueryGenerator.prototype, require("./query-generator/transaction"));
module.exports = QueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,94 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const _ = require("lodash");
const Op = require("../../../operators");
const Utils = require("../../../utils");
const OperatorHelpers = {
OperatorMap: {
[Op.eq]: "=",
[Op.ne]: "!=",
[Op.gte]: ">=",
[Op.gt]: ">",
[Op.lte]: "<=",
[Op.lt]: "<",
[Op.not]: "IS NOT",
[Op.is]: "IS",
[Op.in]: "IN",
[Op.notIn]: "NOT IN",
[Op.like]: "LIKE",
[Op.notLike]: "NOT LIKE",
[Op.iLike]: "ILIKE",
[Op.notILike]: "NOT ILIKE",
[Op.startsWith]: "LIKE",
[Op.endsWith]: "LIKE",
[Op.substring]: "LIKE",
[Op.regexp]: "~",
[Op.notRegexp]: "!~",
[Op.iRegexp]: "~*",
[Op.notIRegexp]: "!~*",
[Op.between]: "BETWEEN",
[Op.notBetween]: "NOT BETWEEN",
[Op.overlap]: "&&",
[Op.contains]: "@>",
[Op.contained]: "<@",
[Op.adjacent]: "-|-",
[Op.strictLeft]: "<<",
[Op.strictRight]: ">>",
[Op.noExtendRight]: "&<",
[Op.noExtendLeft]: "&>",
[Op.any]: "ANY",
[Op.all]: "ALL",
[Op.and]: " AND ",
[Op.or]: " OR ",
[Op.col]: "COL",
[Op.placeholder]: "$$PLACEHOLDER$$",
[Op.match]: "@@"
},
OperatorsAliasMap: {},
setOperatorsAliases(aliases) {
if (!aliases || _.isEmpty(aliases)) {
this.OperatorsAliasMap = false;
} else {
this.OperatorsAliasMap = __spreadValues({}, aliases);
}
},
_replaceAliases(orig) {
const obj = {};
if (!this.OperatorsAliasMap) {
return orig;
}
Utils.getOperators(orig).forEach((op) => {
const item = orig[op];
if (_.isPlainObject(item)) {
obj[op] = this._replaceAliases(item);
} else {
obj[op] = item;
}
});
_.forOwn(orig, (item, prop) => {
prop = this.OperatorsAliasMap[prop] || prop;
if (_.isPlainObject(item)) {
item = this._replaceAliases(item);
}
obj[prop] = item;
});
return obj;
}
};
module.exports = OperatorHelpers;
//# sourceMappingURL=operators.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../../src/dialects/abstract/query-generator/operators.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst Op = require('../../../operators');\nconst Utils = require('../../../utils');\n\nconst OperatorHelpers = {\n OperatorMap: {\n [Op.eq]: '=',\n [Op.ne]: '!=',\n [Op.gte]: '>=',\n [Op.gt]: '>',\n [Op.lte]: '<=',\n [Op.lt]: '<',\n [Op.not]: 'IS NOT',\n [Op.is]: 'IS',\n [Op.in]: 'IN',\n [Op.notIn]: 'NOT IN',\n [Op.like]: 'LIKE',\n [Op.notLike]: 'NOT LIKE',\n [Op.iLike]: 'ILIKE',\n [Op.notILike]: 'NOT ILIKE',\n [Op.startsWith]: 'LIKE',\n [Op.endsWith]: 'LIKE',\n [Op.substring]: 'LIKE',\n [Op.regexp]: '~',\n [Op.notRegexp]: '!~',\n [Op.iRegexp]: '~*',\n [Op.notIRegexp]: '!~*',\n [Op.between]: 'BETWEEN',\n [Op.notBetween]: 'NOT BETWEEN',\n [Op.overlap]: '&&',\n [Op.contains]: '@>',\n [Op.contained]: '<@',\n [Op.adjacent]: '-|-',\n [Op.strictLeft]: '<<',\n [Op.strictRight]: '>>',\n [Op.noExtendRight]: '&<',\n [Op.noExtendLeft]: '&>',\n [Op.any]: 'ANY',\n [Op.all]: 'ALL',\n [Op.and]: ' AND ',\n [Op.or]: ' OR ',\n [Op.col]: 'COL',\n [Op.placeholder]: '$$PLACEHOLDER$$',\n [Op.match]: '@@'\n },\n\n OperatorsAliasMap: {},\n\n setOperatorsAliases(aliases) {\n if (!aliases || _.isEmpty(aliases)) {\n this.OperatorsAliasMap = false;\n } else {\n this.OperatorsAliasMap = { ...aliases };\n }\n },\n\n _replaceAliases(orig) {\n const obj = {};\n if (!this.OperatorsAliasMap) {\n return orig;\n }\n\n Utils.getOperators(orig).forEach(op => {\n const item = orig[op];\n if (_.isPlainObject(item)) {\n obj[op] = this._replaceAliases(item);\n } else {\n obj[op] = item;\n }\n });\n\n _.forOwn(orig, (item, prop) => {\n prop = this.OperatorsAliasMap[prop] || prop;\n if (_.isPlainObject(item)) {\n item = this._replaceAliases(item);\n }\n obj[prop] = item;\n });\n return obj;\n }\n};\n\nmodule.exports = OperatorHelpers;\n"],
"mappings": ";;;;;;;;;;;;;;;;;AAEA,MAAM,IAAI,QAAQ;AAClB,MAAM,KAAK,QAAQ;AACnB,MAAM,QAAQ,QAAQ;AAEtB,MAAM,kBAAkB;AAAA,EACtB,aAAa;AAAA,KACV,GAAG,KAAK;AAAA,KACR,GAAG,KAAK;AAAA,KACR,GAAG,MAAM;AAAA,KACT,GAAG,KAAK;AAAA,KACR,GAAG,MAAM;AAAA,KACT,GAAG,KAAK;AAAA,KACR,GAAG,MAAM;AAAA,KACT,GAAG,KAAK;AAAA,KACR,GAAG,KAAK;AAAA,KACR,GAAG,QAAQ;AAAA,KACX,GAAG,OAAO;AAAA,KACV,GAAG,UAAU;AAAA,KACb,GAAG,QAAQ;AAAA,KACX,GAAG,WAAW;AAAA,KACd,GAAG,aAAa;AAAA,KAChB,GAAG,WAAW;AAAA,KACd,GAAG,YAAY;AAAA,KACf,GAAG,SAAS;AAAA,KACZ,GAAG,YAAY;AAAA,KACf,GAAG,UAAU;AAAA,KACb,GAAG,aAAa;AAAA,KAChB,GAAG,UAAU;AAAA,KACb,GAAG,aAAa;AAAA,KAChB,GAAG,UAAU;AAAA,KACb,GAAG,WAAW;AAAA,KACd,GAAG,YAAY;AAAA,KACf,GAAG,WAAW;AAAA,KACd,GAAG,aAAa;AAAA,KAChB,GAAG,cAAc;AAAA,KACjB,GAAG,gBAAgB;AAAA,KACnB,GAAG,eAAe;AAAA,KAClB,GAAG,MAAM;AAAA,KACT,GAAG,MAAM;AAAA,KACT,GAAG,MAAM;AAAA,KACT,GAAG,KAAK;AAAA,KACR,GAAG,MAAM;AAAA,KACT,GAAG,cAAc;AAAA,KACjB,GAAG,QAAQ;AAAA;AAAA,EAGd,mBAAmB;AAAA,EAEnB,oBAAoB,SAAS;AAC3B,QAAI,CAAC,WAAW,EAAE,QAAQ,UAAU;AAClC,WAAK,oBAAoB;AAAA,WACpB;AACL,WAAK,oBAAoB,mBAAK;AAAA;AAAA;AAAA,EAIlC,gBAAgB,MAAM;AACpB,UAAM,MAAM;AACZ,QAAI,CAAC,KAAK,mBAAmB;AAC3B,aAAO;AAAA;AAGT,UAAM,aAAa,MAAM,QAAQ,QAAM;AACrC,YAAM,OAAO,KAAK;AAClB,UAAI,EAAE,cAAc,OAAO;AACzB,YAAI,MAAM,KAAK,gBAAgB;AAAA,aAC1B;AACL,YAAI,MAAM;AAAA;AAAA;AAId,MAAE,OAAO,MAAM,CAAC,MAAM,SAAS;AAC7B,aAAO,KAAK,kBAAkB,SAAS;AACvC,UAAI,EAAE,cAAc,OAAO;AACzB,eAAO,KAAK,gBAAgB;AAAA;AAE9B,UAAI,QAAQ;AAAA;AAEd,WAAO;AAAA;AAAA;AAIX,OAAO,UAAU;",
"names": []
}
@@ -0,0 +1,41 @@
"use strict";
const uuidv4 = require("uuid").v4;
const TransactionQueries = {
setIsolationLevelQuery(value, options) {
if (options.parent) {
return;
}
return `SET TRANSACTION ISOLATION LEVEL ${value};`;
},
generateTransactionId() {
return uuidv4();
},
startTransactionQuery(transaction) {
if (transaction.parent) {
return `SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;
}
return "START TRANSACTION;";
},
deferConstraintsQuery() {
},
setConstraintQuery() {
},
setDeferredQuery() {
},
setImmediateQuery() {
},
commitTransactionQuery(transaction) {
if (transaction.parent) {
return;
}
return "COMMIT;";
},
rollbackTransactionQuery(transaction) {
if (transaction.parent) {
return `ROLLBACK TO SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;
}
return "ROLLBACK;";
}
};
module.exports = TransactionQueries;
//# sourceMappingURL=transaction.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../../src/dialects/abstract/query-generator/transaction.js"],
"sourcesContent": ["'use strict';\n\nconst uuidv4 = require('uuid').v4;\n\nconst TransactionQueries = {\n /**\n * Returns a query that sets the transaction isolation level.\n *\n * @param {string} value The isolation level.\n * @param {object} options An object with options.\n * @returns {string} The generated sql query.\n * @private\n */\n setIsolationLevelQuery(value, options) {\n if (options.parent) {\n return;\n }\n\n return `SET TRANSACTION ISOLATION LEVEL ${value};`;\n },\n\n generateTransactionId() {\n return uuidv4();\n },\n\n /**\n * Returns a query that starts a transaction.\n *\n * @param {Transaction} transaction\n * @returns {string} The generated sql query.\n * @private\n */\n startTransactionQuery(transaction) {\n if (transaction.parent) {\n // force quoting of savepoint identifiers for postgres\n return `SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;\n }\n\n return 'START TRANSACTION;';\n },\n\n deferConstraintsQuery() {},\n\n setConstraintQuery() {},\n setDeferredQuery() {},\n setImmediateQuery() {},\n\n /**\n * Returns a query that commits a transaction.\n *\n * @param {Transaction} transaction An object with options.\n * @returns {string} The generated sql query.\n * @private\n */\n commitTransactionQuery(transaction) {\n if (transaction.parent) {\n return;\n }\n\n return 'COMMIT;';\n },\n\n /**\n * Returns a query that rollbacks a transaction.\n *\n * @param {Transaction} transaction\n * @returns {string} The generated sql query.\n * @private\n */\n rollbackTransactionQuery(transaction) {\n if (transaction.parent) {\n // force quoting of savepoint identifiers for postgres\n return `ROLLBACK TO SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;\n }\n\n return 'ROLLBACK;';\n }\n};\n\nmodule.exports = TransactionQueries;\n"],
"mappings": ";AAEA,MAAM,SAAS,QAAQ,QAAQ;AAE/B,MAAM,qBAAqB;AAAA,EASzB,uBAAuB,OAAO,SAAS;AACrC,QAAI,QAAQ,QAAQ;AAClB;AAAA;AAGF,WAAO,mCAAmC;AAAA;AAAA,EAG5C,wBAAwB;AACtB,WAAO;AAAA;AAAA,EAUT,sBAAsB,aAAa;AACjC,QAAI,YAAY,QAAQ;AAEtB,aAAO,aAAa,KAAK,gBAAgB,YAAY,MAAM;AAAA;AAG7D,WAAO;AAAA;AAAA,EAGT,wBAAwB;AAAA;AAAA,EAExB,qBAAqB;AAAA;AAAA,EACrB,mBAAmB;AAAA;AAAA,EACnB,oBAAoB;AAAA;AAAA,EASpB,uBAAuB,aAAa;AAClC,QAAI,YAAY,QAAQ;AACtB;AAAA;AAGF,WAAO;AAAA;AAAA,EAUT,yBAAyB,aAAa;AACpC,QAAI,YAAY,QAAQ;AAEtB,aAAO,yBAAyB,KAAK,gBAAgB,YAAY,MAAM;AAAA;AAGzE,WAAO;AAAA;AAAA;AAIX,OAAO,UAAU;",
"names": []
}
+569
View File
@@ -0,0 +1,569 @@
"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 _ = require("lodash");
const Utils = require("../../utils");
const DataTypes = require("../../data-types");
const Transaction = require("../../transaction");
const QueryTypes = require("../../query-types");
class QueryInterface {
constructor(sequelize, queryGenerator) {
this.sequelize = sequelize;
this.queryGenerator = queryGenerator;
}
async createDatabase(database, options) {
options = options || {};
const sql = this.queryGenerator.createDatabaseQuery(database, options);
return await this.sequelize.query(sql, options);
}
async dropDatabase(database, options) {
options = options || {};
const sql = this.queryGenerator.dropDatabaseQuery(database);
return await this.sequelize.query(sql, options);
}
async createSchema(schema, options) {
options = options || {};
const sql = this.queryGenerator.createSchema(schema);
return await this.sequelize.query(sql, options);
}
async dropSchema(schema, options) {
options = options || {};
const sql = this.queryGenerator.dropSchema(schema);
return await this.sequelize.query(sql, options);
}
async dropAllSchemas(options) {
options = options || {};
if (!this.queryGenerator._dialect.supports.schemas) {
return this.sequelize.drop(options);
}
const schemas = await this.showAllSchemas(options);
return Promise.all(schemas.map((schemaName) => this.dropSchema(schemaName, options)));
}
async showAllSchemas(options) {
options = __spreadProps(__spreadValues({}, options), {
raw: true,
type: this.sequelize.QueryTypes.SELECT
});
const showSchemasSql = this.queryGenerator.showSchemasQuery(options);
const schemaNames = await this.sequelize.query(showSchemasSql, options);
return _.flatten(schemaNames.map((value) => value.schema_name ? value.schema_name : value));
}
async databaseVersion(options) {
return await this.sequelize.query(this.queryGenerator.versionQuery(), __spreadProps(__spreadValues({}, options), { type: QueryTypes.VERSION }));
}
async createTable(tableName, attributes, options, model) {
let sql = "";
options = __spreadValues({}, options);
if (options && options.uniqueKeys) {
_.forOwn(options.uniqueKeys, (uniqueKey) => {
if (uniqueKey.customIndex === void 0) {
uniqueKey.customIndex = true;
}
});
}
if (model) {
options.uniqueKeys = options.uniqueKeys || model.uniqueKeys;
}
attributes = _.mapValues(attributes, (attribute) => this.sequelize.normalizeAttribute(attribute));
await this.ensureEnums(tableName, attributes, options, model);
if (!tableName.schema && (options.schema || !!model && model._schema)) {
tableName = this.queryGenerator.addSchema({
tableName,
_schema: !!model && model._schema || options.schema
});
}
attributes = this.queryGenerator.attributesToSQL(attributes, {
table: tableName,
context: "createTable",
withoutForeignKeyConstraints: options.withoutForeignKeyConstraints
});
sql = this.queryGenerator.createTableQuery(tableName, attributes, options);
return await this.sequelize.query(sql, options);
}
async tableExists(tableName, options) {
const sql = this.queryGenerator.tableExistsQuery(tableName);
const out = await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), {
type: QueryTypes.SHOWTABLES
}));
return out.length === 1;
}
async dropTable(tableName, options) {
options = __spreadValues({}, options);
options.cascade = options.cascade || options.force || false;
const sql = this.queryGenerator.dropTableQuery(tableName, options);
await this.sequelize.query(sql, options);
}
async _dropAllTables(tableNames, skip, options) {
for (const tableName of tableNames) {
if (!skip.includes(tableName.tableName || tableName)) {
await this.dropTable(tableName, __spreadProps(__spreadValues({}, options), { cascade: true }));
}
}
}
async dropAllTables(options) {
options = options || {};
const skip = options.skip || [];
const tableNames = await this.showAllTables(options);
const foreignKeys = await this.getForeignKeysForTables(tableNames, options);
for (const tableName of tableNames) {
let normalizedTableName = tableName;
if (_.isObject(tableName)) {
normalizedTableName = `${tableName.schema}.${tableName.tableName}`;
}
for (const foreignKey of foreignKeys[normalizedTableName]) {
await this.sequelize.query(this.queryGenerator.dropForeignKeyQuery(tableName, foreignKey));
}
}
await this._dropAllTables(tableNames, skip, options);
}
async renameTable(before, after, options) {
options = options || {};
const sql = this.queryGenerator.renameTableQuery(before, after);
return await this.sequelize.query(sql, options);
}
async showAllTables(options) {
options = __spreadProps(__spreadValues({}, options), {
raw: true,
type: QueryTypes.SHOWTABLES
});
const showTablesSql = this.queryGenerator.showTablesQuery(this.sequelize.config.database);
const tableNames = await this.sequelize.query(showTablesSql, options);
return _.flatten(tableNames);
}
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 });
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.`);
}
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;
}
}
async addColumn(table, key, attribute, options) {
if (!table || !key || !attribute) {
throw new Error("addColumn takes at least 3 arguments (table, attribute name, attribute definition)");
}
options = options || {};
attribute = this.sequelize.normalizeAttribute(attribute);
return await this.sequelize.query(this.queryGenerator.addColumnQuery(table, key, attribute), options);
}
async removeColumn(tableName, attributeName, options) {
return this.sequelize.query(this.queryGenerator.removeColumnQuery(tableName, attributeName), options);
}
normalizeAttribute(dataTypeOrOptions) {
let attribute;
if (Object.values(DataTypes).includes(dataTypeOrOptions)) {
attribute = { type: dataTypeOrOptions, allowNull: true };
} else {
attribute = dataTypeOrOptions;
}
return this.sequelize.normalizeAttribute(attribute);
}
quoteIdentifier(identifier2, force) {
return this.queryGenerator.quoteIdentifier(identifier2, force);
}
quoteIdentifiers(identifiers) {
return this.queryGenerator.quoteIdentifiers(identifiers);
}
async changeColumn(tableName, attributeName, dataTypeOrOptions, options) {
options = options || {};
const query = this.queryGenerator.attributesToSQL({
[attributeName]: this.normalizeAttribute(dataTypeOrOptions)
}, {
context: "changeColumn",
table: tableName
});
const sql = this.queryGenerator.changeColumnQuery(tableName, query);
return this.sequelize.query(sql, options);
}
async assertTableHasColumn(tableName, columnName, options) {
const description = await this.describeTable(tableName, options);
if (description[columnName]) {
return description;
}
throw new Error(`Table ${tableName} doesn't have the column ${columnName}`);
}
async renameColumn(tableName, attrNameBefore, attrNameAfter, options) {
options = options || {};
const data = (await this.assertTableHasColumn(tableName, attrNameBefore, options))[attrNameBefore];
const _options = {};
_options[attrNameAfter] = {
attribute: attrNameAfter,
type: data.type,
allowNull: data.allowNull,
defaultValue: data.defaultValue
};
if (data.defaultValue === null && !data.allowNull) {
delete _options[attrNameAfter].defaultValue;
}
const sql = this.queryGenerator.renameColumnQuery(tableName, attrNameBefore, this.queryGenerator.attributesToSQL(_options));
return await this.sequelize.query(sql, options);
}
async addIndex(tableName, attributes, options, rawTablename) {
if (!Array.isArray(attributes)) {
rawTablename = options;
options = attributes;
attributes = options.fields;
}
if (!rawTablename) {
rawTablename = tableName;
}
options = Utils.cloneDeep(options);
options.fields = attributes;
const sql = this.queryGenerator.addIndexQuery(tableName, options, rawTablename);
return await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { supportsSearchPath: false }));
}
async showIndex(tableName, options) {
const sql = this.queryGenerator.showIndexesQuery(tableName, options);
return await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { type: QueryTypes.SHOWINDEXES }));
}
async getForeignKeysForTables(tableNames, options) {
if (tableNames.length === 0) {
return {};
}
options = __spreadProps(__spreadValues({}, options), { type: QueryTypes.FOREIGNKEYS });
const results = await Promise.all(tableNames.map((tableName) => this.sequelize.query(this.queryGenerator.getForeignKeysQuery(tableName, this.sequelize.config.database), options)));
const result = {};
tableNames.forEach((tableName, i) => {
if (_.isObject(tableName)) {
tableName = `${tableName.schema}.${tableName.tableName}`;
}
result[tableName] = Array.isArray(results[i]) ? results[i].map((r) => r.constraint_name) : [results[i] && results[i].constraint_name];
result[tableName] = result[tableName].filter(_.identity);
});
return result;
}
async getForeignKeyReferencesForTable(tableName, options) {
const queryOptions = __spreadProps(__spreadValues({}, options), {
type: QueryTypes.FOREIGNKEYS
});
const query = this.queryGenerator.getForeignKeysQuery(tableName, this.sequelize.config.database);
return this.sequelize.query(query, queryOptions);
}
async removeIndex(tableName, indexNameOrAttributes, options) {
options = options || {};
const sql = this.queryGenerator.removeIndexQuery(tableName, indexNameOrAttributes, options);
return await this.sequelize.query(sql, 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 = Utils.cloneDeep(options);
const sql = this.queryGenerator.addConstraintQuery(tableName, options);
return await this.sequelize.query(sql, options);
}
async showConstraint(tableName, constraintName, options) {
const sql = this.queryGenerator.showConstraintsQuery(tableName, constraintName);
return await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { type: QueryTypes.SHOWCONSTRAINTS }));
}
async removeConstraint(tableName, constraintName, options) {
return this.sequelize.query(this.queryGenerator.removeConstraintQuery(tableName, constraintName), options);
}
async insert(instance, tableName, values, options) {
options = Utils.cloneDeep(options);
options.hasTrigger = instance && instance.constructor.options.hasTrigger;
const sql = this.queryGenerator.insertQuery(tableName, values, instance && instance.constructor.rawAttributes, options);
options.type = QueryTypes.INSERT;
options.instance = instance;
const results = await this.sequelize.query(sql, options);
if (instance)
results[0].isNewRecord = false;
return results;
}
async upsert(tableName, insertValues, updateValues, where, options) {
options = __spreadValues({}, options);
const model = options.model;
options.type = QueryTypes.UPSERT;
options.updateOnDuplicate = Object.keys(updateValues);
options.upsertKeys = options.conflictFields || [];
if (options.upsertKeys.length === 0) {
const primaryKeys = Object.values(model.primaryKeys).map((item) => item.field);
const uniqueKeys = Object.values(model.uniqueKeys).filter((c) => c.fields.length > 0).map((c) => c.fields);
const indexKeys = Object.values(model._indexes).filter((c) => c.unique && c.fields.length > 0).map((c) => c.fields);
for (const field of options.updateOnDuplicate) {
const uniqueKey = uniqueKeys.find((fields) => fields.includes(field));
if (uniqueKey) {
options.upsertKeys = uniqueKey;
break;
}
const indexKey = indexKeys.find((fields) => fields.includes(field));
if (indexKey) {
options.upsertKeys = indexKey;
break;
}
}
if (options.upsertKeys.length === 0 || _.intersection(options.updateOnDuplicate, primaryKeys).length) {
options.upsertKeys = primaryKeys;
}
options.upsertKeys = _.uniq(options.upsertKeys);
}
const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);
return await this.sequelize.query(sql, options);
}
async bulkInsert(tableName, records, options, attributes) {
options = __spreadValues({}, options);
options.type = QueryTypes.INSERT;
const results = await this.sequelize.query(this.queryGenerator.bulkInsertQuery(tableName, records, options, attributes), options);
return results[0];
}
async update(instance, tableName, values, identifier2, options) {
options = __spreadValues({}, options);
options.hasTrigger = instance && instance.constructor.options.hasTrigger;
const sql = this.queryGenerator.updateQuery(tableName, values, identifier2, options, instance.constructor.rawAttributes);
options.type = QueryTypes.UPDATE;
options.instance = instance;
return await this.sequelize.query(sql, options);
}
async bulkUpdate(tableName, values, identifier2, options, attributes) {
options = Utils.cloneDeep(options);
if (typeof identifier2 === "object")
identifier2 = Utils.cloneDeep(identifier2);
const sql = this.queryGenerator.updateQuery(tableName, values, identifier2, options, attributes);
const table = _.isObject(tableName) ? tableName : { tableName };
const model = options.model ? options.model : _.find(this.sequelize.modelManager.models, { tableName: table.tableName });
options.type = QueryTypes.BULKUPDATE;
options.model = model;
return await this.sequelize.query(sql, options);
}
async delete(instance, tableName, identifier2, options) {
const cascades = [];
const sql = this.queryGenerator.deleteQuery(tableName, identifier2, {}, instance.constructor);
options = __spreadValues({}, options);
if (!!instance.constructor && !!instance.constructor.associations) {
const keys = Object.keys(instance.constructor.associations);
const length = keys.length;
let association;
for (let i = 0; i < length; i++) {
association = instance.constructor.associations[keys[i]];
if (association.options && association.options.onDelete && association.options.onDelete.toLowerCase() === "cascade" && association.options.useHooks === true) {
cascades.push(association.accessors.get);
}
}
}
for (const cascade of cascades) {
let instances = await instance[cascade](options);
if (!instances)
continue;
if (!Array.isArray(instances))
instances = [instances];
for (const _instance of instances)
await _instance.destroy(options);
}
options.instance = instance;
return await this.sequelize.query(sql, options);
}
async bulkDelete(tableName, where, options, model) {
options = Utils.cloneDeep(options);
options = _.defaults(options, { limit: null });
if (options.truncate === true) {
return this.sequelize.query(this.queryGenerator.truncateTableQuery(tableName, options), options);
}
if (typeof identifier === "object")
where = Utils.cloneDeep(where);
return await this.sequelize.query(this.queryGenerator.deleteQuery(tableName, where, options, model), options);
}
async select(model, tableName, optionsArg) {
const options = __spreadProps(__spreadValues({}, optionsArg), { type: QueryTypes.SELECT, model });
return await this.sequelize.query(this.queryGenerator.selectQuery(tableName, options, model), options);
}
async increment(model, tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options) {
options = Utils.cloneDeep(options);
const sql = this.queryGenerator.arithmeticQuery("+", tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options);
options.type = QueryTypes.UPDATE;
options.model = model;
return await this.sequelize.query(sql, options);
}
async decrement(model, tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options) {
options = Utils.cloneDeep(options);
const sql = this.queryGenerator.arithmeticQuery("-", tableName, where, incrementAmountsByField, extraAttributesToBeUpdated, options);
options.type = QueryTypes.UPDATE;
options.model = model;
return await this.sequelize.query(sql, options);
}
async rawSelect(tableName, options, attributeSelector, Model) {
options = Utils.cloneDeep(options);
options = _.defaults(options, {
raw: true,
plain: true,
type: QueryTypes.SELECT
});
const sql = this.queryGenerator.selectQuery(tableName, options, Model);
if (attributeSelector === void 0) {
throw new Error("Please pass an attribute selector!");
}
const data = await this.sequelize.query(sql, options);
if (!options.plain) {
return data;
}
const result = data ? data[attributeSelector] : null;
if (!options || !options.dataType) {
return result;
}
const dataType = options.dataType;
if (dataType instanceof DataTypes.DECIMAL || dataType instanceof DataTypes.FLOAT) {
if (result !== null) {
return parseFloat(result);
}
}
if (dataType instanceof DataTypes.INTEGER || dataType instanceof DataTypes.BIGINT) {
if (result !== null) {
return parseInt(result, 10);
}
}
if (dataType instanceof DataTypes.DATE) {
if (result !== null && !(result instanceof Date)) {
return new Date(result);
}
}
return result;
}
async createTrigger(tableName, triggerName, timingType, fireOnArray, functionName, functionParams, optionsArray, options) {
const sql = this.queryGenerator.createTrigger(tableName, triggerName, timingType, fireOnArray, functionName, functionParams, optionsArray);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async dropTrigger(tableName, triggerName, options) {
const sql = this.queryGenerator.dropTrigger(tableName, triggerName);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async renameTrigger(tableName, oldTriggerName, newTriggerName, options) {
const sql = this.queryGenerator.renameTrigger(tableName, oldTriggerName, newTriggerName);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async createFunction(functionName, params, returnType, language, body, optionsArray, options) {
const sql = this.queryGenerator.createFunction(functionName, params, returnType, language, body, optionsArray, options);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async dropFunction(functionName, params, options) {
const sql = this.queryGenerator.dropFunction(functionName, params);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async renameFunction(oldFunctionName, params, newFunctionName, options) {
const sql = this.queryGenerator.renameFunction(oldFunctionName, params, newFunctionName);
options = options || {};
if (sql) {
return await this.sequelize.query(sql, options);
}
}
ensureEnums() {
}
async setIsolationLevel(transaction, value, options) {
if (!transaction || !(transaction instanceof Transaction)) {
throw new Error("Unable to set isolation level for a transaction without transaction object!");
}
if (transaction.parent || !value) {
return;
}
options = __spreadProps(__spreadValues({}, options), { transaction: transaction.parent || transaction });
const sql = this.queryGenerator.setIsolationLevelQuery(value, {
parent: transaction.parent
});
if (!sql)
return;
return await this.sequelize.query(sql, options);
}
async startTransaction(transaction, options) {
if (!transaction || !(transaction instanceof Transaction)) {
throw new Error("Unable to start a transaction without transaction object!");
}
options = __spreadProps(__spreadValues({}, options), { transaction: transaction.parent || transaction });
options.transaction.name = transaction.parent ? transaction.name : void 0;
const sql = this.queryGenerator.startTransactionQuery(transaction);
return await this.sequelize.query(sql, options);
}
async deferConstraints(transaction, options) {
options = __spreadProps(__spreadValues({}, options), { transaction: transaction.parent || transaction });
const sql = this.queryGenerator.deferConstraintsQuery(options);
if (sql) {
return await this.sequelize.query(sql, options);
}
}
async commitTransaction(transaction, options) {
if (!transaction || !(transaction instanceof Transaction)) {
throw new Error("Unable to commit a transaction without transaction object!");
}
if (transaction.parent) {
return;
}
options = __spreadProps(__spreadValues({}, options), {
transaction: transaction.parent || transaction,
supportsSearchPath: false,
completesTransaction: true
});
const sql = this.queryGenerator.commitTransactionQuery(transaction);
const promise = this.sequelize.query(sql, options);
transaction.finished = "commit";
return await promise;
}
async rollbackTransaction(transaction, options) {
if (!transaction || !(transaction instanceof Transaction)) {
throw new Error("Unable to rollback a transaction without transaction object!");
}
options = __spreadProps(__spreadValues({}, options), {
transaction: transaction.parent || transaction,
supportsSearchPath: false,
completesTransaction: true
});
options.transaction.name = transaction.parent ? transaction.name : void 0;
const sql = this.queryGenerator.rollbackTransactionQuery(transaction);
const promise = this.sequelize.query(sql, options);
transaction.finished = "rollback";
return await promise;
}
}
exports.QueryInterface = QueryInterface;
//# sourceMappingURL=query-interface.js.map
File diff suppressed because one or more lines are too long
+546
View File
@@ -0,0 +1,546 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const _ = require("lodash");
const SqlString = require("../../sql-string");
const QueryTypes = require("../../query-types");
const Dot = require("dottie");
const deprecations = require("../../utils/deprecations");
const uuid = require("uuid").v4;
const { safeStringifyJson } = require("../../utils.js");
class AbstractQuery {
constructor(connection, sequelize, options) {
this.uuid = uuid();
this.connection = connection;
this.instance = options.instance;
this.model = options.model;
this.sequelize = sequelize;
this.options = __spreadValues({
plain: false,
raw: false,
logging: console.log
}, options);
this.checkLoggingOption();
if (options.rawErrors) {
this.formatError = AbstractQuery.prototype.formatError;
}
}
static formatBindParameters(sql, values, dialect, replacementFunc, options) {
if (!values) {
return [sql, []];
}
options = options || {};
if (typeof replacementFunc !== "function") {
options = replacementFunc || {};
replacementFunc = void 0;
}
if (!replacementFunc) {
if (options.skipValueReplace) {
replacementFunc = (match, key, values2) => {
if (values2[key] !== void 0) {
return match;
}
return void 0;
};
} else {
replacementFunc = (match, key, values2, timeZone2, dialect2) => {
if (values2[key] !== void 0) {
return SqlString.escape(values2[key], timeZone2, dialect2);
}
return void 0;
};
}
} else if (options.skipValueReplace) {
const origReplacementFunc = replacementFunc;
replacementFunc = (match, key, values2, timeZone2, dialect2, options2) => {
if (origReplacementFunc(match, key, values2, timeZone2, dialect2, options2) !== void 0) {
return match;
}
return void 0;
};
}
const timeZone = null;
const list = Array.isArray(values);
sql = sql.replace(/\B\$(\$|\w+)/g, (match, key) => {
if (key === "$") {
return options.skipUnescape ? match : key;
}
let replVal;
if (list) {
if (key.match(/^[1-9]\d*$/)) {
key = key - 1;
replVal = replacementFunc(match, key, values, timeZone, dialect, options);
}
} else if (!key.match(/^\d*$/)) {
replVal = replacementFunc(match, key, values, timeZone, dialect, options);
}
if (replVal === void 0) {
throw new Error(`Named bind parameter "${match}" has no value in the given object.`);
}
return replVal;
});
return [sql, []];
}
formatError(error, errStack) {
error.stack = errStack;
return error;
}
run() {
throw new Error("The run method wasn't overwritten!");
}
checkLoggingOption() {
if (this.options.logging === true) {
deprecations.noTrueLogging();
this.options.logging = console.log;
}
}
getInsertIdField() {
return "insertId";
}
getUniqueConstraintErrorMessage(field) {
let message = field ? `${field} must be unique` : "Must be unique";
if (field && this.model) {
for (const key of Object.keys(this.model.uniqueKeys)) {
if (this.model.uniqueKeys[key].fields.includes(field.replace(/"/g, ""))) {
if (this.model.uniqueKeys[key].msg) {
message = this.model.uniqueKeys[key].msg;
}
}
}
}
return message;
}
isRawQuery() {
return this.options.type === QueryTypes.RAW;
}
isVersionQuery() {
return this.options.type === QueryTypes.VERSION;
}
isUpsertQuery() {
return this.options.type === QueryTypes.UPSERT;
}
isInsertQuery(results, metaData) {
let result = true;
if (this.options.type === QueryTypes.INSERT) {
return true;
}
result = result && this.sql.toLowerCase().startsWith("insert into");
result = result && (!results || Object.prototype.hasOwnProperty.call(results, this.getInsertIdField()));
result = result && (!metaData || Object.prototype.hasOwnProperty.call(metaData, this.getInsertIdField()));
return result;
}
handleInsertQuery(results, metaData) {
if (this.instance) {
const autoIncrementAttribute = this.model.autoIncrementAttribute;
let id = null;
id = id || results && results[this.getInsertIdField()];
id = id || metaData && metaData[this.getInsertIdField()];
this.instance[autoIncrementAttribute] = id;
}
}
isShowTablesQuery() {
return this.options.type === QueryTypes.SHOWTABLES;
}
handleShowTablesQuery(results) {
return _.flatten(results.map((resultSet) => Object.values(resultSet)));
}
isShowIndexesQuery() {
return this.options.type === QueryTypes.SHOWINDEXES;
}
isShowConstraintsQuery() {
return this.options.type === QueryTypes.SHOWCONSTRAINTS;
}
isDescribeQuery() {
return this.options.type === QueryTypes.DESCRIBE;
}
isSelectQuery() {
return this.options.type === QueryTypes.SELECT;
}
isBulkUpdateQuery() {
return this.options.type === QueryTypes.BULKUPDATE;
}
isBulkDeleteQuery() {
return this.options.type === QueryTypes.BULKDELETE;
}
isForeignKeysQuery() {
return this.options.type === QueryTypes.FOREIGNKEYS;
}
isUpdateQuery() {
return this.options.type === QueryTypes.UPDATE;
}
handleSelectQuery(results) {
let result = null;
if (this.options.fieldMap) {
const fieldMap = this.options.fieldMap;
results = results.map((result2) => _.reduce(fieldMap, (result3, name, field) => {
if (result3[field] !== void 0 && name !== field) {
result3[name] = result3[field];
delete result3[field];
}
return result3;
}, result2));
}
if (this.options.raw) {
result = results.map((result2) => {
let o = {};
for (const key in result2) {
if (Object.prototype.hasOwnProperty.call(result2, key)) {
o[key] = result2[key];
}
}
if (this.options.nest) {
o = Dot.transform(o);
}
return o;
});
} else if (this.options.hasJoin === true) {
results = AbstractQuery._groupJoinData(results, {
model: this.model,
includeMap: this.options.includeMap,
includeNames: this.options.includeNames
}, {
checkExisting: this.options.hasMultiAssociation
});
result = this.model.bulkBuild(results, {
isNewRecord: false,
include: this.options.include,
includeNames: this.options.includeNames,
includeMap: this.options.includeMap,
includeValidated: true,
attributes: this.options.originalAttributes || this.options.attributes,
raw: true
});
} else {
result = this.model.bulkBuild(results, {
isNewRecord: false,
raw: true,
attributes: this.options.originalAttributes || this.options.attributes
});
}
if (this.options.plain) {
result = result.length === 0 ? null : result[0];
}
return result;
}
isShowOrDescribeQuery() {
let result = false;
result = result || this.sql.toLowerCase().startsWith("show");
result = result || this.sql.toLowerCase().startsWith("describe");
return result;
}
isCallQuery() {
return this.sql.toLowerCase().startsWith("call");
}
_logQuery(sql, debugContext, parameters) {
const { connection, options } = this;
const benchmark = this.sequelize.options.benchmark || options.benchmark;
const logQueryParameters = this.sequelize.options.logQueryParameters || options.logQueryParameters;
const startTime = Date.now();
let logParameter = "";
if (logQueryParameters && parameters) {
const delimiter = sql.endsWith(";") ? "" : ";";
let paramStr;
if (Array.isArray(parameters)) {
paramStr = parameters.map((p) => safeStringifyJson(p)).join(", ");
} else {
paramStr = safeStringifyJson(parameters);
}
logParameter = `${delimiter} ${paramStr}`;
}
const fmt = `(${connection.uuid || "default"}): ${sql}${logParameter}`;
const msg = `Executing ${fmt}`;
debugContext(msg);
if (!benchmark) {
this.sequelize.log(`Executing ${fmt}`, options);
}
return () => {
const afterMsg = `Executed ${fmt}`;
debugContext(afterMsg);
if (benchmark) {
this.sequelize.log(afterMsg, Date.now() - startTime, options);
}
};
}
static _groupJoinData(rows, includeOptions, options) {
if (!rows.length) {
return [];
}
let i;
let length;
let $i;
let $length;
let rowsI;
let row;
const rowsLength = rows.length;
let keys;
let key;
let keyI;
let keyLength;
let prevKey;
let values;
let topValues;
let topExists;
const checkExisting = options.checkExisting;
let itemHash;
let parentHash;
let topHash;
const results = checkExisting ? [] : new Array(rowsLength);
const resultMap = {};
const includeMap = {};
let $keyPrefix;
let $keyPrefixString;
let $prevKeyPrefixString;
let $prevKeyPrefix;
let $lastKeyPrefix;
let $current;
let $parent;
let previousPiece;
const buildIncludeMap = (piece) => {
if (Object.prototype.hasOwnProperty.call($current.includeMap, piece)) {
includeMap[key] = $current = $current.includeMap[piece];
if (previousPiece) {
previousPiece = `${previousPiece}.${piece}`;
} else {
previousPiece = piece;
}
includeMap[previousPiece] = $current;
}
};
const keyPrefixStringMemo = {};
const keyPrefixString = (key2, memo) => {
if (!Object.prototype.hasOwnProperty.call(memo, key2)) {
memo[key2] = key2.substr(0, key2.lastIndexOf("."));
}
return memo[key2];
};
const removeKeyPrefixMemo = {};
const removeKeyPrefix = (key2) => {
if (!Object.prototype.hasOwnProperty.call(removeKeyPrefixMemo, key2)) {
const index = key2.lastIndexOf(".");
removeKeyPrefixMemo[key2] = key2.substr(index === -1 ? 0 : index + 1);
}
return removeKeyPrefixMemo[key2];
};
const keyPrefixMemo = {};
const keyPrefix = (key2) => {
if (!Object.prototype.hasOwnProperty.call(keyPrefixMemo, key2)) {
const prefixString = keyPrefixString(key2, keyPrefixStringMemo);
if (!Object.prototype.hasOwnProperty.call(keyPrefixMemo, prefixString)) {
keyPrefixMemo[prefixString] = prefixString ? prefixString.split(".") : [];
}
keyPrefixMemo[key2] = keyPrefixMemo[prefixString];
}
return keyPrefixMemo[key2];
};
const lastKeyPrefixMemo = {};
const lastKeyPrefix = (key2) => {
if (!Object.prototype.hasOwnProperty.call(lastKeyPrefixMemo, key2)) {
const prefix2 = keyPrefix(key2);
const length2 = prefix2.length;
lastKeyPrefixMemo[key2] = !length2 ? "" : prefix2[length2 - 1];
}
return lastKeyPrefixMemo[key2];
};
const getUniqueKeyAttributes = (model) => {
let uniqueKeyAttributes2 = _.chain(model.uniqueKeys);
uniqueKeyAttributes2 = uniqueKeyAttributes2.result(`${uniqueKeyAttributes2.findKey()}.fields`).map((field) => _.findKey(model.attributes, (chr) => chr.field === field)).value();
return uniqueKeyAttributes2;
};
const stringify = (obj) => obj instanceof Buffer ? obj.toString("hex") : obj;
let primaryKeyAttributes;
let uniqueKeyAttributes;
let prefix;
for (rowsI = 0; rowsI < rowsLength; rowsI++) {
row = rows[rowsI];
if (rowsI === 0) {
keys = _.sortBy(Object.keys(row), (item) => [item.split(".").length]);
keyLength = keys.length;
}
if (checkExisting) {
topExists = false;
$length = includeOptions.model.primaryKeyAttributes.length;
topHash = "";
if ($length === 1) {
topHash = stringify(row[includeOptions.model.primaryKeyAttributes[0]]);
} else if ($length > 1) {
for ($i = 0; $i < $length; $i++) {
topHash += stringify(row[includeOptions.model.primaryKeyAttributes[$i]]);
}
} else if (!_.isEmpty(includeOptions.model.uniqueKeys)) {
uniqueKeyAttributes = getUniqueKeyAttributes(includeOptions.model);
for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
topHash += row[uniqueKeyAttributes[$i]];
}
}
}
topValues = values = {};
$prevKeyPrefix = void 0;
for (keyI = 0; keyI < keyLength; keyI++) {
key = keys[keyI];
$keyPrefixString = keyPrefixString(key, keyPrefixStringMemo);
$keyPrefix = keyPrefix(key);
if (rowsI === 0 && !Object.prototype.hasOwnProperty.call(includeMap, key)) {
if (!$keyPrefix.length) {
includeMap[key] = includeMap[""] = includeOptions;
} else {
$current = includeOptions;
previousPiece = void 0;
$keyPrefix.forEach(buildIncludeMap);
}
}
if ($prevKeyPrefix !== void 0 && $prevKeyPrefix !== $keyPrefix) {
if (checkExisting) {
length = $prevKeyPrefix.length;
$parent = null;
parentHash = null;
if (length) {
for (i = 0; i < length; i++) {
prefix = $parent ? `${$parent}.${$prevKeyPrefix[i]}` : $prevKeyPrefix[i];
primaryKeyAttributes = includeMap[prefix].model.primaryKeyAttributes;
$length = primaryKeyAttributes.length;
itemHash = prefix;
if ($length === 1) {
itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[0]}`]);
} else if ($length > 1) {
for ($i = 0; $i < $length; $i++) {
itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[$i]}`]);
}
} else if (!_.isEmpty(includeMap[prefix].model.uniqueKeys)) {
uniqueKeyAttributes = getUniqueKeyAttributes(includeMap[prefix].model);
for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
itemHash += row[`${prefix}.${uniqueKeyAttributes[$i]}`];
}
}
if (!parentHash) {
parentHash = topHash;
}
itemHash = parentHash + itemHash;
$parent = prefix;
if (i < length - 1) {
parentHash = itemHash;
}
}
} else {
itemHash = topHash;
}
if (itemHash === topHash) {
if (!resultMap[itemHash]) {
resultMap[itemHash] = values;
} else {
topExists = true;
}
} else if (!resultMap[itemHash]) {
$parent = resultMap[parentHash];
$lastKeyPrefix = lastKeyPrefix(prevKey);
if (includeMap[prevKey].association.isSingleAssociation) {
if ($parent) {
$parent[$lastKeyPrefix] = resultMap[itemHash] = values;
}
} else {
if (!$parent[$lastKeyPrefix]) {
$parent[$lastKeyPrefix] = [];
}
$parent[$lastKeyPrefix].push(resultMap[itemHash] = values);
}
}
values = {};
} else {
$current = topValues;
length = $keyPrefix.length;
if (length) {
for (i = 0; i < length; i++) {
if (i === length - 1) {
values = $current[$keyPrefix[i]] = {};
}
$current = $current[$keyPrefix[i]] || {};
}
}
}
}
values[removeKeyPrefix(key)] = row[key];
prevKey = key;
$prevKeyPrefix = $keyPrefix;
$prevKeyPrefixString = $keyPrefixString;
}
if (checkExisting) {
length = $prevKeyPrefix.length;
$parent = null;
parentHash = null;
if (length) {
for (i = 0; i < length; i++) {
prefix = $parent ? `${$parent}.${$prevKeyPrefix[i]}` : $prevKeyPrefix[i];
primaryKeyAttributes = includeMap[prefix].model.primaryKeyAttributes;
$length = primaryKeyAttributes.length;
itemHash = prefix;
if ($length === 1) {
itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[0]}`]);
} else if ($length > 0) {
for ($i = 0; $i < $length; $i++) {
itemHash += stringify(row[`${prefix}.${primaryKeyAttributes[$i]}`]);
}
} else if (!_.isEmpty(includeMap[prefix].model.uniqueKeys)) {
uniqueKeyAttributes = getUniqueKeyAttributes(includeMap[prefix].model);
for ($i = 0; $i < uniqueKeyAttributes.length; $i++) {
itemHash += row[`${prefix}.${uniqueKeyAttributes[$i]}`];
}
}
if (!parentHash) {
parentHash = topHash;
}
itemHash = parentHash + itemHash;
$parent = prefix;
if (i < length - 1) {
parentHash = itemHash;
}
}
} else {
itemHash = topHash;
}
if (itemHash === topHash) {
if (!resultMap[itemHash]) {
resultMap[itemHash] = values;
} else {
topExists = true;
}
} else if (!resultMap[itemHash]) {
$parent = resultMap[parentHash];
$lastKeyPrefix = lastKeyPrefix(prevKey);
if (includeMap[prevKey].association.isSingleAssociation) {
if ($parent) {
$parent[$lastKeyPrefix] = resultMap[itemHash] = values;
}
} else {
if (!$parent[$lastKeyPrefix]) {
$parent[$lastKeyPrefix] = [];
}
$parent[$lastKeyPrefix].push(resultMap[itemHash] = values);
}
}
if (!topExists) {
results.push(topValues);
}
} else {
results[rowsI] = topValues;
}
}
return results;
}
}
module.exports = AbstractQuery;
module.exports.AbstractQuery = AbstractQuery;
module.exports.default = AbstractQuery;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
+87
View File
@@ -0,0 +1,87 @@
"use strict";
const AbstractConnectionManager = require("../abstract/connection-manager");
const sequelizeErrors = require("../../errors");
const { logger } = require("../../utils/logger");
const DataTypes = require("../../data-types").db2;
const debug = logger.debugContext("connection:db2");
const parserStore = require("../parserStore")("db2");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 3306;
super(dialect, sequelize);
this.lib = this._loadDialectModule("ibm_db");
this.refreshTypeParser(DataTypes);
}
static _typecast(field, next) {
if (parserStore.get(field.type)) {
return parserStore.get(field.type)(field, this.sequelize.options, next);
}
return next();
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async connect(config) {
const connectionConfig = {
database: config.database,
hostname: config.host,
port: config.port,
uid: config.username,
pwd: config.password
};
if (config.ssl) {
connectionConfig["security"] = config.ssl;
}
if (config.sslcertificate) {
connectionConfig["SSLServerCertificate"] = config.sslcertificate;
}
if (config.dialectOptions) {
for (const key of Object.keys(config.dialectOptions)) {
connectionConfig[key] = config.dialectOptions[key];
}
}
try {
const connection = await new Promise((resolve, reject) => {
const connection2 = new this.lib.Database();
connection2.lib = this.lib;
connection2.open(connectionConfig, (error) => {
if (error) {
if (error.message && error.message.includes("SQL30081N")) {
return reject(new sequelizeErrors.ConnectionRefusedError(error));
}
return reject(new sequelizeErrors.ConnectionError(error));
}
return resolve(connection2);
});
});
return connection;
} catch (err) {
throw new sequelizeErrors.ConnectionError(err);
}
}
disconnect(connection) {
if (connection.connected) {
connection.close((error) => {
if (error) {
debug(error);
} else {
debug("connection closed");
}
});
}
return Promise.resolve();
}
validate(connection) {
return connection && connection.connected;
}
_disconnect(connection) {
return this.dialect.connectionManager.disconnect(connection);
}
}
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/db2/connection-manager.js"],
"sourcesContent": ["'use strict';\n\nconst AbstractConnectionManager = require('../abstract/connection-manager');\nconst sequelizeErrors = require('../../errors');\nconst { logger } = require('../../utils/logger');\nconst DataTypes = require('../../data-types').db2;\nconst debug = logger.debugContext('connection:db2');\nconst parserStore = require('../parserStore')('db2');\n\n/**\n * DB2 Connection Manager\n *\n * Get connections, validate and disconnect them.\n * AbstractConnectionManager pooling use it to handle DB2 specific connections\n * Use https://github.com/ibmdb/node-ibm_db to connect with DB2 server\n *\n * @private\n */\nclass ConnectionManager extends AbstractConnectionManager {\n constructor(dialect, sequelize) {\n sequelize.config.port = sequelize.config.port || 3306;\n super(dialect, sequelize);\n this.lib = this._loadDialectModule('ibm_db');\n this.refreshTypeParser(DataTypes);\n }\n\n static _typecast(field, next) {\n if (parserStore.get(field.type)) {\n return parserStore.get(field.type)(field, this.sequelize.options, next);\n }\n return next();\n }\n\n _refreshTypeParser(dataType) {\n parserStore.refresh(dataType);\n }\n\n _clearTypeParser() {\n parserStore.clear();\n }\n\n /**\n * Connect with DB2 database based on config, Handle any errors in connection\n * Set the pool handlers on connection.error\n * Also set proper timezone once connection is connected.\n *\n * @param {object} config\n * @returns {Promise<Connection>}\n * @private\n */\n async connect(config) {\n const connectionConfig = {\n database: config.database,\n hostname: config.host,\n port: config.port,\n uid: config.username,\n pwd: config.password\n };\n\n if (config.ssl) {\n connectionConfig['security'] = config.ssl;\n }\n if (config.sslcertificate) {\n connectionConfig['SSLServerCertificate'] = config.sslcertificate;\n }\n if (config.dialectOptions) {\n for (const key of Object.keys(config.dialectOptions)) {\n connectionConfig[key] = config.dialectOptions[key];\n }\n }\n\n try {\n const connection = await new Promise((resolve, reject) => {\n const connection = new this.lib.Database();\n connection.lib = this.lib;\n connection.open(connectionConfig, error => {\n if (error) {\n if (error.message && error.message.includes('SQL30081N')) {\n return reject(new sequelizeErrors.ConnectionRefusedError(error));\n }\n return reject(new sequelizeErrors.ConnectionError(error));\n }\n return resolve(connection);\n });\n });\n return connection;\n } catch (err) {\n throw new sequelizeErrors.ConnectionError(err);\n }\n }\n\n disconnect(connection) {\n // Don't disconnect a connection that is already disconnected\n if (connection.connected) {\n connection.close(error => {\n if (error) { debug(error); }\n else { debug('connection closed'); }\n });\n }\n return Promise.resolve();\n }\n\n validate(connection) {\n return connection && connection.connected;\n }\n\n /**\n * Call dialect library to disconnect a connection\n *\n * @param {Connection} connection\n * @private\n * @returns {Promise}\n */\n _disconnect(connection) {\n return this.dialect.connectionManager.disconnect(connection);\n }\n}\n\nmodule.exports = ConnectionManager;\nmodule.exports.ConnectionManager = ConnectionManager;\nmodule.exports.default = ConnectionManager;\n"],
"mappings": ";AAEA,MAAM,4BAA4B,QAAQ;AAC1C,MAAM,kBAAkB,QAAQ;AAChC,MAAM,EAAE,WAAW,QAAQ;AAC3B,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAM,cAAc,QAAQ,kBAAkB;AAW9C,gCAAgC,0BAA0B;AAAA,EACxD,YAAY,SAAS,WAAW;AAC9B,cAAU,OAAO,OAAO,UAAU,OAAO,QAAQ;AACjD,UAAM,SAAS;AACf,SAAK,MAAM,KAAK,mBAAmB;AACnC,SAAK,kBAAkB;AAAA;AAAA,SAGlB,UAAU,OAAO,MAAM;AAC5B,QAAI,YAAY,IAAI,MAAM,OAAO;AAC/B,aAAO,YAAY,IAAI,MAAM,MAAM,OAAO,KAAK,UAAU,SAAS;AAAA;AAEpE,WAAO;AAAA;AAAA,EAGT,mBAAmB,UAAU;AAC3B,gBAAY,QAAQ;AAAA;AAAA,EAGtB,mBAAmB;AACjB,gBAAY;AAAA;AAAA,QAYR,QAAQ,QAAQ;AACpB,UAAM,mBAAmB;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,MACb,KAAK,OAAO;AAAA,MACZ,KAAK,OAAO;AAAA;AAGd,QAAI,OAAO,KAAK;AACd,uBAAiB,cAAc,OAAO;AAAA;AAExC,QAAI,OAAO,gBAAgB;AACzB,uBAAiB,0BAA0B,OAAO;AAAA;AAEpD,QAAI,OAAO,gBAAgB;AACzB,iBAAW,OAAO,OAAO,KAAK,OAAO,iBAAiB;AACpD,yBAAiB,OAAO,OAAO,eAAe;AAAA;AAAA;AAIlD,QAAI;AACF,YAAM,aAAa,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACxD,cAAM,cAAa,IAAI,KAAK,IAAI;AAChC,oBAAW,MAAM,KAAK;AACtB,oBAAW,KAAK,kBAAkB,WAAS;AACzC,cAAI,OAAO;AACT,gBAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,cAAc;AACxD,qBAAO,OAAO,IAAI,gBAAgB,uBAAuB;AAAA;AAE3D,mBAAO,OAAO,IAAI,gBAAgB,gBAAgB;AAAA;AAEpD,iBAAO,QAAQ;AAAA;AAAA;AAGnB,aAAO;AAAA,aACA,KAAP;AACA,YAAM,IAAI,gBAAgB,gBAAgB;AAAA;AAAA;AAAA,EAI9C,WAAW,YAAY;AAErB,QAAI,WAAW,WAAW;AACxB,iBAAW,MAAM,WAAS;AACxB,YAAI,OAAO;AAAE,gBAAM;AAAA,eACd;AAAE,gBAAM;AAAA;AAAA;AAAA;AAGjB,WAAO,QAAQ;AAAA;AAAA,EAGjB,SAAS,YAAY;AACnB,WAAO,cAAc,WAAW;AAAA;AAAA,EAUlC,YAAY,YAAY;AACtB,WAAO,KAAK,QAAQ,kBAAkB,WAAW;AAAA;AAAA;AAIrD,OAAO,UAAU;AACjB,OAAO,QAAQ,oBAAoB;AACnC,OAAO,QAAQ,UAAU;",
"names": []
}
+294
View File
@@ -0,0 +1,294 @@
"use strict";
const momentTz = require("moment-timezone");
const moment = require("moment");
module.exports = (BaseTypes) => {
const warn = BaseTypes.ABSTRACT.warn.bind(void 0, "https://www.ibm.com/support/knowledgecenter/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0008478.html");
function removeUnsupportedIntegerOptions(dataType) {
if (dataType._length || dataType.options.length || dataType._unsigned || dataType._zerofill) {
warn(`Db2 does not support '${dataType.key}' with options. Plain '${dataType.key}' will be used instead.`);
dataType._length = void 0;
dataType.options.length = void 0;
dataType._unsigned = void 0;
dataType._zerofill = void 0;
}
}
BaseTypes.DATE.types.db2 = ["TIMESTAMP"];
BaseTypes.STRING.types.db2 = ["VARCHAR"];
BaseTypes.CHAR.types.db2 = ["CHAR"];
BaseTypes.TEXT.types.db2 = ["VARCHAR", "CLOB"];
BaseTypes.TINYINT.types.db2 = ["SMALLINT"];
BaseTypes.SMALLINT.types.db2 = ["SMALLINT"];
BaseTypes.MEDIUMINT.types.db2 = ["INTEGER"];
BaseTypes.INTEGER.types.db2 = ["INTEGER"];
BaseTypes.BIGINT.types.db2 = ["BIGINT"];
BaseTypes.FLOAT.types.db2 = ["DOUBLE", "REAL", "FLOAT"];
BaseTypes.TIME.types.db2 = ["TIME"];
BaseTypes.DATEONLY.types.db2 = ["DATE"];
BaseTypes.BOOLEAN.types.db2 = ["BOOLEAN", "BOOL", "SMALLINT", "BIT"];
BaseTypes.BLOB.types.db2 = ["BLOB"];
BaseTypes.DECIMAL.types.db2 = ["DECIMAL"];
BaseTypes.UUID.types.db2 = ["CHAR () FOR BIT DATA"];
BaseTypes.ENUM.types.db2 = ["VARCHAR"];
BaseTypes.REAL.types.db2 = ["REAL"];
BaseTypes.DOUBLE.types.db2 = ["DOUBLE"];
BaseTypes.GEOMETRY.types.db2 = false;
class BLOB extends BaseTypes.BLOB {
toSql() {
if (this._length) {
if (this._length.toLowerCase() === "tiny") {
return "BLOB(255)";
}
if (this._length.toLowerCase() === "medium") {
return "BLOB(16M)";
}
if (this._length.toLowerCase() === "long") {
return "BLOB(2G)";
}
return `BLOB(${this._length})`;
}
return "BLOB";
}
escape(blob) {
return `BLOB('${blob.toString().replace(/'/g, "''")}')`;
}
_stringify(value) {
if (Buffer.isBuffer(value)) {
return `BLOB('${value.toString().replace(/'/g, "''")}')`;
}
if (Array.isArray(value)) {
value = Buffer.from(value);
} else {
value = Buffer.from(value.toString());
}
const hex = value.toString("hex");
return this._hexify(hex);
}
_hexify(hex) {
return `x'${hex}'`;
}
}
class STRING extends BaseTypes.STRING {
toSql() {
if (!this._binary) {
if (this._length <= 4e3) {
return `VARCHAR(${this._length})`;
}
return `CLOB(${this._length})`;
}
if (this._length < 255) {
return `CHAR(${this._length}) FOR BIT DATA`;
}
if (this._length <= 4e3) {
return `VARCHAR(${this._length}) FOR BIT DATA`;
}
return `BLOB(${this._length})`;
}
_stringify(value, options) {
if (this._binary) {
return BLOB.prototype._hexify(value.toString("hex"));
}
return options.escape(value);
}
_bindParam(value, options) {
return options.bindParam(this._binary ? Buffer.from(value) : value);
}
}
STRING.prototype.escape = false;
class TEXT extends BaseTypes.TEXT {
toSql() {
let len = 0;
if (this._length) {
switch (this._length.toLowerCase()) {
case "tiny":
len = 256;
break;
case "medium":
len = 8192;
break;
case "long":
len = 65536;
break;
}
if (isNaN(this._length)) {
this._length = 32672;
}
if (len > 0) {
this._length = len;
}
} else {
this._length = 32672;
}
if (this._length > 32672) {
len = `CLOB(${this._length})`;
} else {
len = `VARCHAR(${this._length})`;
}
warn(`Db2 does not support TEXT datatype. ${len} will be used instead.`);
return len;
}
}
class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return "BOOLEAN";
}
_sanitize(value) {
if (value !== null && value !== void 0) {
if (Buffer.isBuffer(value) && value.length === 1) {
value = value[0];
}
if (typeof value === "string") {
value = value === "true" ? true : value === "false" ? false : value;
value = value === "" ? true : value === "\0" ? false : value;
} else if (typeof value === "number") {
value = value === 1 ? true : value === 0 ? false : value;
}
}
return value;
}
}
BOOLEAN.parse = BOOLEAN.prototype._sanitize;
class UUID extends BaseTypes.UUID {
toSql() {
return "CHAR(36) FOR BIT DATA";
}
}
class NOW extends BaseTypes.NOW {
toSql() {
return "CURRENT TIME";
}
}
class DATE extends BaseTypes.DATE {
toSql() {
if (this._length < 0) {
this._length = 0;
}
if (this._length > 6) {
this._length = 6;
}
return `TIMESTAMP${this._length ? `(${this._length})` : ""}`;
}
_stringify(date, options) {
if (!moment.isMoment(date)) {
date = this._applyTimezone(date, options);
}
if (this._length > 0) {
let msec = ".";
for (let i = 0; i < this._length && i < 6; i++) {
msec += "S";
}
return date.format(`YYYY-MM-DD HH:mm:ss${msec}`);
}
return date.format("YYYY-MM-DD HH:mm:ss");
}
static parse(value) {
if (typeof value !== "string") {
value = value.string();
}
if (value === null) {
return value;
}
value = new Date(momentTz.utc(value));
return value;
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return momentTz(value).format("YYYY-MM-DD");
}
}
class INTEGER extends BaseTypes.INTEGER {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class TINYINT extends BaseTypes.TINYINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class SMALLINT extends BaseTypes.SMALLINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class REAL extends BaseTypes.REAL {
constructor(length, decimals) {
super(length, decimals);
if (this._length || this.options.length || this._unsigned || this._zerofill) {
warn("Db2 does not support REAL with options. Plain `REAL` will be used instead.");
this._length = void 0;
this.options.length = void 0;
this._unsigned = void 0;
this._zerofill = void 0;
}
}
}
class FLOAT extends BaseTypes.FLOAT {
constructor(length, decimals) {
super(length, decimals);
if (this._decimals) {
warn("Db2 does not support Float with decimals. Plain `FLOAT` will be used instead.");
this._length = void 0;
this.options.length = void 0;
}
if (this._unsigned) {
warn("Db2 does not support Float unsigned. `UNSIGNED` was removed.");
this._unsigned = void 0;
}
if (this._zerofill) {
warn("Db2 does not support Float zerofill. `ZEROFILL` was removed.");
this._zerofill = void 0;
}
}
}
class ENUM extends BaseTypes.ENUM {
toSql() {
return "VARCHAR(255)";
}
}
class DOUBLE extends BaseTypes.DOUBLE {
constructor(length, decimals) {
super(length, decimals);
if (this._length || this.options.length || this._unsigned || this._zerofill) {
warn("db2 does not support DOUBLE with options. Plain DOUBLE will be used instead.");
this._length = void 0;
this.options.length = void 0;
this._unsigned = void 0;
this._zerofill = void 0;
}
}
toSql() {
return "DOUBLE";
}
}
DOUBLE.prototype.key = DOUBLE.key = "DOUBLE";
return {
BLOB,
BOOLEAN,
ENUM,
STRING,
UUID,
DATE,
DATEONLY,
NOW,
TINYINT,
SMALLINT,
INTEGER,
DOUBLE,
"DOUBLE PRECISION": DOUBLE,
BIGINT,
REAL,
FLOAT,
TEXT
};
};
//# sourceMappingURL=data-types.js.map
File diff suppressed because one or more lines are too long
+61
View File
@@ -0,0 +1,61 @@
"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").db2;
const { Db2QueryInterface } = require("./query-interface");
class Db2Dialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new Db2QueryInterface(sequelize, this.queryGenerator);
}
}
Db2Dialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"DEFAULT": true,
"DEFAULT VALUES": false,
"VALUES ()": false,
"LIMIT ON UPDATE": false,
"ORDER NULLS": false,
lock: false,
transactions: true,
migrations: false,
returnValues: false,
schemas: true,
finalTable: true,
autoIncrement: {
identityInsert: false,
defaultValue: false,
update: true
},
constraints: {
restrict: true,
default: false
},
index: {
collate: false,
length: false,
parser: false,
type: false,
using: false,
where: true
},
NUMERIC: true,
tmpTableTrigger: true
});
Db2Dialect.prototype.defaultVersion = "1.0.0";
Db2Dialect.prototype.Query = Query;
Db2Dialect.prototype.name = "db2";
Db2Dialect.prototype.TICK_CHAR = '"';
Db2Dialect.prototype.TICK_CHAR_LEFT = '"';
Db2Dialect.prototype.TICK_CHAR_RIGHT = '"';
Db2Dialect.prototype.DataTypes = DataTypes;
module.exports = Db2Dialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/db2/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').db2;\nconst { Db2QueryInterface } = require('./query-interface');\n\nclass Db2Dialect 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 this.queryInterface = new Db2QueryInterface(sequelize, this.queryGenerator);\n }\n}\n\nDb2Dialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {\n 'DEFAULT': true,\n 'DEFAULT VALUES': false,\n 'VALUES ()': false,\n 'LIMIT ON UPDATE': false,\n 'ORDER NULLS': false,\n lock: false,\n transactions: true,\n migrations: false,\n returnValues: false,\n schemas: true,\n finalTable: true,\n autoIncrement: {\n identityInsert: false,\n defaultValue: false,\n update: true\n },\n constraints: {\n restrict: true,\n default: false\n },\n index: {\n collate: false,\n length: false,\n parser: false,\n type: false,\n using: false,\n where: true\n },\n NUMERIC: true,\n tmpTableTrigger: true\n});\n\nDb2Dialect.prototype.defaultVersion = '1.0.0'; // Db2 supported version comes here\nDb2Dialect.prototype.Query = Query;\nDb2Dialect.prototype.name = 'db2';\nDb2Dialect.prototype.TICK_CHAR = '\"';\nDb2Dialect.prototype.TICK_CHAR_LEFT = '\"';\nDb2Dialect.prototype.TICK_CHAR_RIGHT = '\"';\nDb2Dialect.prototype.DataTypes = DataTypes;\n\nmodule.exports = Db2Dialect;\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,sBAAsB,QAAQ;AAEtC,yBAAyB,gBAAgB;AAAA,EACvC,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,kBAAkB,WAAW,KAAK;AAAA;AAAA;AAIhE,WAAW,UAAU,WAAW,EAAE,MAAM,EAAE,UAAU,gBAAgB,UAAU,WAAW;AAAA,EACvF,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,MAAM;AAAA,EACN,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,eAAe;AAAA,IACb,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,QAAQ;AAAA;AAAA,EAEV,aAAa;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,EAEX,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAET,SAAS;AAAA,EACT,iBAAiB;AAAA;AAGnB,WAAW,UAAU,iBAAiB;AACtC,WAAW,UAAU,QAAQ;AAC7B,WAAW,UAAU,OAAO;AAC5B,WAAW,UAAU,YAAY;AACjC,WAAW,UAAU,iBAAiB;AACtC,WAAW,UAAU,kBAAkB;AACvC,WAAW,UAAU,YAAY;AAEjC,OAAO,UAAU;",
"names": []
}
+710
View File
@@ -0,0 +1,710 @@
"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 _ = require("lodash");
const Utils = require("../../utils");
const DataTypes = require("../../data-types");
const AbstractQueryGenerator = require("../abstract/query-generator");
const randomBytes = require("crypto").randomBytes;
const Op = require("../../operators");
const throwMethodUndefined = function(methodName) {
throw new Error(`The method "${methodName}" is not defined! Please add it to your sql dialect.`);
};
class Db2QueryGenerator extends AbstractQueryGenerator {
constructor(options) {
super(options);
this.OperatorMap = __spreadProps(__spreadValues({}, this.OperatorMap), {
[Op.regexp]: "REGEXP_LIKE",
[Op.notRegexp]: "NOT REGEXP_LIKE"
});
this.autoGenValue = 1;
}
createSchema(schema) {
return [
"CREATE SCHEMA",
this.quoteIdentifier(schema),
";"
].join(" ");
}
dropSchema(schema) {
const query = `CALL SYSPROC.ADMIN_DROP_SCHEMA(${wrapSingleQuote(schema.trim())}, NULL, ? , ?)`;
const sql = { query };
sql.bind = [
{ ParamType: "INOUT", Data: "ERRORSCHEMA" },
{ ParamType: "INOUT", Data: "ERRORTABLE" }
];
return sql;
}
showSchemasQuery() {
return `SELECT SCHEMANAME AS "schema_name" FROM SYSCAT.SCHEMATA WHERE (SCHEMANAME NOT LIKE 'SYS%') AND SCHEMANAME NOT IN ('NULLID', 'SQLJ', 'ERRORSCHEMA')`;
}
versionQuery() {
return "select service_level as VERSION from TABLE (sysproc.env_get_inst_info()) as A";
}
createTableQuery(tableName, attributes, options) {
const query = "CREATE TABLE <%= table %> (<%= attributes %>)", primaryKeys = [], foreignKeys = {}, attrStr = [], commentTemplate = " -- <%= comment %>, TableName = <%= table %>, ColumnName = <%= column %>;";
let commentStr = "";
for (const attr in attributes) {
if (Object.prototype.hasOwnProperty.call(attributes, attr)) {
let dataType = attributes[attr];
let match;
if (dataType.includes("COMMENT ")) {
const commentMatch = dataType.match(/^(.+) (COMMENT.*)$/);
if (commentMatch && commentMatch.length > 2) {
const commentText = commentMatch[2].replace(/COMMENT/, "").trim();
commentStr += _.template(commentTemplate, this._templateSettings)({
table: this.quoteIdentifier(tableName),
comment: this.escape(commentText),
column: this.quoteIdentifier(attr)
});
dataType = commentMatch[1];
}
}
if (_.includes(dataType, "PRIMARY KEY")) {
primaryKeys.push(attr);
if (_.includes(dataType, "REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1].replace(/PRIMARY KEY/, "")}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType.replace(/PRIMARY KEY/, "")}`);
}
} else if (_.includes(dataType, "REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1]}`);
foreignKeys[attr] = match[2];
} else {
if (options && options.uniqueKeys) {
for (const ukey in options.uniqueKeys) {
if (options.uniqueKeys[ukey].fields.includes(attr) && !_.includes(dataType, "NOT NULL")) {
dataType += " NOT NULL";
break;
}
}
}
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType}`);
}
}
}
const values = {
table: this.quoteTable(tableName),
attributes: attrStr.join(", ")
}, pkString = primaryKeys.map((pk) => {
return this.quoteIdentifier(pk);
}).join(", ");
if (options && options.uniqueKeys) {
_.each(options.uniqueKeys, (columns, indexName) => {
if (columns.customIndex) {
if (!_.isString(indexName)) {
indexName = `uniq_${tableName}_${columns.fields.join("_")}`;
}
values.attributes += `, CONSTRAINT ${this.quoteIdentifier(indexName)} UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
});
}
if (pkString.length > 0) {
values.attributes += `, PRIMARY KEY (${pkString})`;
}
for (const fkey in foreignKeys) {
if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) {
values.attributes += `, FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`;
}
}
return `${_.template(query, this._templateSettings)(values).trim()};${commentStr}`;
}
describeTableQuery(tableName, schema) {
let sql = [
'SELECT NAME AS "Name", TBNAME AS "Table", TBCREATOR AS "Schema",',
'TRIM(COLTYPE) AS "Type", LENGTH AS "Length", SCALE AS "Scale",',
'NULLS AS "IsNull", DEFAULT AS "Default", COLNO AS "Colno",',
'IDENTITY AS "IsIdentity", KEYSEQ AS "KeySeq", REMARKS AS "Comment"',
"FROM",
"SYSIBM.SYSCOLUMNS",
"WHERE TBNAME =",
wrapSingleQuote(tableName)
].join(" ");
if (schema) {
sql += ` AND TBCREATOR =${wrapSingleQuote(schema)}`;
} else {
sql += " AND TBCREATOR = USER";
}
return `${sql};`;
}
renameTableQuery(before, after) {
const query = "RENAME TABLE <%= before %> TO <%= after %>;";
return _.template(query, this._templateSettings)({
before: this.quoteTable(before),
after: this.quoteTable(after)
});
}
showTablesQuery() {
return `SELECT TABNAME AS "tableName", TRIM(TABSCHEMA) AS "tableSchema" FROM SYSCAT.TABLES WHERE TABSCHEMA = USER AND TYPE = 'T' ORDER BY TABSCHEMA, TABNAME`;
}
tableExistsQuery(table) {
const tableName = table.tableName || table;
const schemaName = table.schema || this.sequelize.config.username.toUpperCase();
return `SELECT name FROM sysibm.systables WHERE NAME = ${wrapSingleQuote(tableName)} AND CREATOR = ${wrapSingleQuote(schemaName)}`;
}
dropTableQuery(tableName) {
const query = "DROP TABLE <%= table %>";
const values = {
table: this.quoteTable(tableName)
};
return `${_.template(query, this._templateSettings)(values).trim()};`;
}
addColumnQuery(table, key, dataType) {
dataType.field = key;
const query = "ALTER TABLE <%= table %> ADD <%= attribute %>;", attribute = _.template("<%= key %> <%= definition %>", this._templateSettings)({
key: this.quoteIdentifier(key),
definition: this.attributeToSQL(dataType, {
context: "addColumn"
})
});
return _.template(query, this._templateSettings)({
table: this.quoteTable(table),
attribute
});
}
removeColumnQuery(tableName, attributeName) {
const query = "ALTER TABLE <%= tableName %> DROP COLUMN <%= attributeName %>;";
return _.template(query, this._templateSettings)({
tableName: this.quoteTable(tableName),
attributeName: this.quoteIdentifier(attributeName)
});
}
changeColumnQuery(tableName, attributes) {
const query = "ALTER TABLE <%= tableName %> <%= query %>;";
const attrString = [], constraintString = [];
for (const attributeName in attributes) {
const attrValue = attributes[attributeName];
let defs = [attrValue];
if (Array.isArray(attrValue)) {
defs = attrValue;
}
for (let i = 0; i < defs.length; i++) {
const definition = defs[i];
if (definition.match(/REFERENCES/)) {
constraintString.push(_.template("<%= fkName %> FOREIGN KEY (<%= attrName %>) <%= definition %>", this._templateSettings)({
fkName: this.quoteIdentifier(`${attributeName}_foreign_idx`),
attrName: this.quoteIdentifier(attributeName),
definition: definition.replace(/.+?(?=REFERENCES)/, "")
}));
} else if (_.startsWith(definition, "DROP ")) {
attrString.push(_.template("<%= attrName %> <%= definition %>", this._templateSettings)({
attrName: this.quoteIdentifier(attributeName),
definition
}));
} else {
attrString.push(_.template("<%= attrName %> SET <%= definition %>", this._templateSettings)({
attrName: this.quoteIdentifier(attributeName),
definition
}));
}
}
}
let finalQuery = "";
if (attrString.length) {
finalQuery += `ALTER COLUMN ${attrString.join(" ALTER COLUMN ")}`;
finalQuery += constraintString.length ? " " : "";
}
if (constraintString.length) {
finalQuery += `ADD CONSTRAINT ${constraintString.join(" ADD CONSTRAINT ")}`;
}
return _.template(query, this._templateSettings)({
tableName: this.quoteTable(tableName),
query: finalQuery
});
}
renameColumnQuery(tableName, attrBefore, attributes) {
const query = "ALTER TABLE <%= tableName %> RENAME COLUMN <%= before %> TO <%= after %>;", newName = Object.keys(attributes)[0];
return _.template(query, this._templateSettings)({
tableName: this.quoteTable(tableName),
before: this.quoteIdentifier(attrBefore),
after: this.quoteIdentifier(newName)
});
}
addConstraintQuery(tableName, options) {
options = options || {};
if (options.onUpdate && options.onUpdate.toUpperCase() === "CASCADE") {
delete options.onUpdate;
}
const constraintSnippet = this.getConstraintSnippet(tableName, options);
if (typeof tableName === "string") {
tableName = this.quoteIdentifiers(tableName);
} else {
tableName = this.quoteTable(tableName);
}
return `ALTER TABLE ${tableName} ADD ${constraintSnippet};`;
}
bulkInsertQuery(tableName, attrValueHashes, options, attributes) {
options = options || {};
attributes = attributes || {};
let query = "INSERT INTO <%= table %> (<%= attributes %>)<%= output %> VALUES <%= tuples %>;";
if (options.returning) {
query = "SELECT * FROM FINAL TABLE( INSERT INTO <%= table %> (<%= attributes %>)<%= output %> VALUES <%= tuples %>);";
}
const emptyQuery = "INSERT INTO <%= table %>", tuples = [], allAttributes = [], allQueries = [];
let outputFragment;
const valuesForEmptyQuery = [];
if (options.returning) {
outputFragment = "";
}
_.forEach(attrValueHashes, (attrValueHash) => {
const fields = Object.keys(attrValueHash);
const firstAttr = attributes[fields[0]];
if (fields.length === 1 && firstAttr && firstAttr.autoIncrement && attrValueHash[fields[0]] === null) {
valuesForEmptyQuery.push(`(${this.autoGenValue++})`);
return;
}
_.forOwn(attrValueHash, (value, key) => {
if (allAttributes.indexOf(key) === -1) {
if (value === null && attributes[key] && attributes[key].autoIncrement)
return;
allAttributes.push(key);
}
});
});
if (valuesForEmptyQuery.length > 0) {
allQueries.push(`${emptyQuery} VALUES ${valuesForEmptyQuery.join(",")}`);
}
if (allAttributes.length > 0) {
_.forEach(attrValueHashes, (attrValueHash) => {
tuples.push(`(${allAttributes.map((key) => this.escape(attrValueHash[key]), void 0, { context: "INSERT" }).join(",")})`);
});
allQueries.push(query);
}
const replacements = {
table: this.quoteTable(tableName),
attributes: allAttributes.map((attr) => this.quoteIdentifier(attr)).join(","),
tuples,
output: outputFragment
};
const generatedQuery = _.template(allQueries.join(";"), this._templateSettings)(replacements);
return generatedQuery;
}
updateQuery(tableName, attrValueHash, where, options, attributes) {
const sql = super.updateQuery(tableName, attrValueHash, where, options, attributes);
options = options || {};
_.defaults(options, this.options);
if (!options.limit) {
sql.query = `SELECT * FROM FINAL TABLE (${sql.query});`;
return sql;
}
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 = _.defaults({ bindParam }, options);
query = `UPDATE (SELECT * FROM ${this.quoteTable(tableName)} ${this.whereQuery(where, whereOptions)} FETCH NEXT ${this.escape(options.limit)} ROWS ONLY) SET ${values.join(",")}`;
query = `SELECT * FROM FINAL TABLE (${query});`;
return { query, bind };
}
upsertQuery(tableName, insertValues, updateValues, where, model) {
const targetTableAlias = this.quoteTable(`${tableName}_target`);
const sourceTableAlias = this.quoteTable(`${tableName}_source`);
const primaryKeysAttrs = [];
const identityAttrs = [];
const uniqueAttrs = [];
const tableNameQuoted = this.quoteTable(tableName);
for (const key in model.rawAttributes) {
if (model.rawAttributes[key].primaryKey) {
primaryKeysAttrs.push(model.rawAttributes[key].field || key);
}
if (model.rawAttributes[key].unique) {
uniqueAttrs.push(model.rawAttributes[key].field || key);
}
if (model.rawAttributes[key].autoIncrement) {
identityAttrs.push(model.rawAttributes[key].field || key);
}
}
for (const index of model._indexes) {
if (index.unique && index.fields) {
for (const field of index.fields) {
const fieldName = typeof field === "string" ? field : field.name || field.attribute;
if (uniqueAttrs.indexOf(fieldName) === -1 && model.rawAttributes[fieldName]) {
uniqueAttrs.push(fieldName);
}
}
}
}
const updateKeys = Object.keys(updateValues);
const insertKeys = Object.keys(insertValues);
const insertKeysQuoted = insertKeys.map((key) => this.quoteIdentifier(key)).join(", ");
const insertValuesEscaped = insertKeys.map((key) => this.escape(insertValues[key])).join(", ");
const sourceTableQuery = `VALUES(${insertValuesEscaped})`;
let joinCondition;
const clauses = where[Op.or].filter((clause) => {
let valid = true;
for (const key in clause) {
if (!clause[key]) {
valid = false;
break;
}
}
return valid;
});
const getJoinSnippet = (array) => {
return array.map((key) => {
key = this.quoteIdentifier(key);
return `${targetTableAlias}.${key} = ${sourceTableAlias}.${key}`;
});
};
if (clauses.length === 0) {
throw new Error("Primary Key or Unique key should be passed to upsert query");
} else {
for (const key in clauses) {
const keys = Object.keys(clauses[key]);
if (primaryKeysAttrs.indexOf(keys[0]) !== -1) {
joinCondition = getJoinSnippet(primaryKeysAttrs).join(" AND ");
break;
}
}
if (!joinCondition) {
joinCondition = getJoinSnippet(uniqueAttrs).join(" AND ");
}
}
const filteredUpdateClauses = updateKeys.filter((key) => {
if (identityAttrs.indexOf(key) === -1) {
return true;
}
return false;
}).map((key) => {
const value = this.escape(updateValues[key]);
key = this.quoteIdentifier(key);
return `${targetTableAlias}.${key} = ${value}`;
}).join(", ");
const updateSnippet = filteredUpdateClauses.length > 0 ? `WHEN MATCHED THEN UPDATE SET ${filteredUpdateClauses}` : "";
const insertSnippet = `(${insertKeysQuoted}) VALUES(${insertValuesEscaped})`;
let query = `MERGE INTO ${tableNameQuoted} AS ${targetTableAlias} USING (${sourceTableQuery}) AS ${sourceTableAlias}(${insertKeysQuoted}) ON ${joinCondition}`;
query += ` ${updateSnippet} WHEN NOT MATCHED THEN INSERT ${insertSnippet};`;
return query;
}
truncateTableQuery(tableName) {
return `TRUNCATE TABLE ${this.quoteTable(tableName)} IMMEDIATE`;
}
deleteQuery(tableName, where, options = {}, model) {
const table = this.quoteTable(tableName);
const query = "DELETE FROM <%= table %><%= where %><%= limit %>";
where = this.getWhereConditions(where, null, model, options);
let limit = "";
if (options.offset > 0) {
limit = ` OFFSET ${this.escape(options.offset)} ROWS`;
}
if (options.limit) {
limit += ` FETCH NEXT ${this.escape(options.limit)} ROWS ONLY`;
}
const replacements = {
limit,
table,
where
};
if (replacements.where) {
replacements.where = ` WHERE ${replacements.where}`;
}
return _.template(query, this._templateSettings)(replacements);
}
showIndexesQuery(tableName) {
let sql = 'SELECT NAME AS "name", TBNAME AS "tableName", UNIQUERULE AS "keyType", COLNAMES, INDEXTYPE AS "type" FROM SYSIBM.SYSINDEXES WHERE TBNAME = <%= tableName %>';
let schema = void 0;
if (_.isObject(tableName)) {
schema = tableName.schema;
tableName = tableName.tableName;
}
if (schema) {
sql = `${sql} AND TBCREATOR = <%= schemaName %>`;
}
sql = `${sql} ORDER BY NAME;`;
return _.template(sql, this._templateSettings)({
tableName: wrapSingleQuote(tableName),
schemaName: wrapSingleQuote(schema)
});
}
showConstraintsQuery(tableName, constraintName) {
let sql = `SELECT CONSTNAME AS "constraintName", TRIM(TABSCHEMA) AS "schemaName", TABNAME AS "tableName" FROM SYSCAT.TABCONST WHERE TABNAME = '${tableName}'`;
if (constraintName) {
sql += ` AND CONSTNAME LIKE '%${constraintName}%'`;
}
return `${sql} ORDER BY CONSTNAME;`;
}
removeIndexQuery(tableName, indexNameOrAttributes) {
const sql = "DROP INDEX <%= indexName %>";
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
const values = {
tableName: this.quoteIdentifiers(tableName),
indexName: this.quoteIdentifiers(indexName)
};
return _.template(sql, this._templateSettings)(values);
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
let template;
let changeNull = 1;
if (attribute.type instanceof DataTypes.ENUM) {
if (attribute.type.values && !attribute.values)
attribute.values = attribute.type.values;
template = attribute.type.toSql();
template += ` CHECK (${this.quoteIdentifier(attribute.field)} IN(${attribute.values.map((value) => {
return this.escape(value);
}).join(", ")}))`;
} else {
template = attribute.type.toString();
}
if (options && options.context === "changeColumn" && attribute.type) {
template = `DATA TYPE ${template}`;
} else if (attribute.allowNull === false || attribute.primaryKey === true || attribute.unique) {
template += " NOT NULL";
changeNull = 0;
}
if (attribute.autoIncrement) {
let initialValue = 1;
if (attribute.initialAutoIncrement) {
initialValue = attribute.initialAutoIncrement;
}
template += ` GENERATED BY DEFAULT AS IDENTITY(START WITH ${initialValue}, INCREMENT BY 1)`;
}
if (attribute.type !== "TEXT" && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (attribute.unique === true) {
template += " UNIQUE";
}
if (attribute.primaryKey) {
template += " PRIMARY KEY";
}
if ((!options || !options.withoutForeignKeyConstraints) && attribute.references) {
if (options && options.context === "addColumn" && options.foreignKey) {
const attrName = this.quoteIdentifier(options.foreignKey);
const fkName = `${options.tableName}_${attrName}_fidx`;
template += `, CONSTRAINT ${fkName} FOREIGN KEY (${attrName})`;
}
template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
if (attribute.references.key) {
template += ` (${this.quoteIdentifier(attribute.references.key)})`;
} else {
template += ` (${this.quoteIdentifier("id")})`;
}
if (attribute.onDelete) {
template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
if (attribute.onUpdate && attribute.onUpdate.toUpperCase() != "CASCADE") {
template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
}
}
if (options && options.context === "changeColumn" && changeNull === 1 && attribute.allowNull !== void 0) {
template = [template];
if (attribute.allowNull) {
template.push("DROP NOT NULL");
} else {
template.push("NOT NULL");
}
}
if (attribute.comment && typeof attribute.comment === "string") {
template += ` COMMENT ${attribute.comment}`;
}
return template;
}
attributesToSQL(attributes, options) {
const result = {}, existingConstraints = [];
let key, attribute;
for (key in attributes) {
attribute = attributes[key];
if (attribute.references) {
if (existingConstraints.indexOf(attribute.references.model.toString()) !== -1) {
attribute.onDelete = "";
attribute.onUpdate = "";
} else if (attribute.unique && attribute.unique === true) {
attribute.onDelete = "";
attribute.onUpdate = "";
} else {
existingConstraints.push(attribute.references.model.toString());
}
}
if (key && !attribute.field && typeof attribute === "object")
attribute.field = key;
result[attribute.field || key] = this.attributeToSQL(attribute, options);
}
return result;
}
createTrigger() {
throwMethodUndefined("createTrigger");
}
dropTrigger() {
throwMethodUndefined("dropTrigger");
}
renameTrigger() {
throwMethodUndefined("renameTrigger");
}
createFunction() {
throwMethodUndefined("createFunction");
}
dropFunction() {
throwMethodUndefined("dropFunction");
}
renameFunction() {
throwMethodUndefined("renameFunction");
}
_getForeignKeysQuerySQL(condition) {
return `SELECT R.CONSTNAME AS "constraintName", TRIM(R.TABSCHEMA) AS "constraintSchema", R.TABNAME AS "tableName", TRIM(R.TABSCHEMA) AS "tableSchema", LISTAGG(C.COLNAME,', ') WITHIN GROUP (ORDER BY C.COLNAME) AS "columnName", TRIM(R.REFTABSCHEMA) AS "referencedTableSchema", R.REFTABNAME AS "referencedTableName", TRIM(R.PK_COLNAMES) AS "referencedColumnName" FROM SYSCAT.REFERENCES R, SYSCAT.KEYCOLUSE C WHERE R.CONSTNAME = C.CONSTNAME AND R.TABSCHEMA = C.TABSCHEMA AND R.TABNAME = C.TABNAME${condition} GROUP BY R.REFTABSCHEMA, R.REFTABNAME, R.TABSCHEMA, R.TABNAME, R.CONSTNAME, R.PK_COLNAMES`;
}
getForeignKeysQuery(table, schemaName) {
const tableName = table.tableName || table;
schemaName = table.schema || schemaName;
let sql = "";
if (tableName) {
sql = ` AND R.TABNAME = ${wrapSingleQuote(tableName)}`;
}
if (schemaName) {
sql += ` AND R.TABSCHEMA = ${wrapSingleQuote(schemaName)}`;
}
return this._getForeignKeysQuerySQL(sql);
}
getForeignKeyQuery(table, columnName) {
const tableName = table.tableName || table;
const schemaName = table.schema;
let sql = "";
if (tableName) {
sql = ` AND R.TABNAME = ${wrapSingleQuote(tableName)}`;
}
if (schemaName) {
sql += ` AND R.TABSCHEMA = ${wrapSingleQuote(schemaName)}`;
}
if (columnName) {
sql += ` AND C.COLNAME = ${wrapSingleQuote(columnName)}`;
}
return this._getForeignKeysQuerySQL(sql);
}
getPrimaryKeyConstraintQuery(table, attributeName) {
const tableName = wrapSingleQuote(table.tableName || table);
return [
'SELECT TABNAME AS "tableName",',
'COLNAME AS "columnName",',
'CONSTNAME AS "constraintName"',
"FROM SYSCAT.KEYCOLUSE WHERE CONSTNAME LIKE 'PK_%'",
`AND COLNAME = ${wrapSingleQuote(attributeName)}`,
`AND TABNAME = ${tableName};`
].join(" ");
}
dropForeignKeyQuery(tableName, foreignKey) {
return _.template("ALTER TABLE <%= table %> DROP <%= key %>", this._templateSettings)({
table: this.quoteTable(tableName),
key: this.quoteIdentifier(foreignKey)
});
}
dropConstraintQuery(tableName, constraintName) {
const sql = "ALTER TABLE <%= table %> DROP CONSTRAINT <%= constraint %>;";
return _.template(sql, this._templateSettings)({
table: this.quoteTable(tableName),
constraint: this.quoteIdentifier(constraintName)
});
}
setAutocommitQuery() {
return "";
}
setIsolationLevelQuery() {
}
generateTransactionId() {
return randomBytes(10).toString("hex");
}
startTransactionQuery(transaction) {
if (transaction.parent) {
return `SAVE TRANSACTION ${this.quoteIdentifier(transaction.name)};`;
}
return "BEGIN TRANSACTION;";
}
commitTransactionQuery(transaction) {
if (transaction.parent) {
return;
}
return "COMMIT TRANSACTION;";
}
rollbackTransactionQuery(transaction) {
if (transaction.parent) {
return `ROLLBACK TRANSACTION ${this.quoteIdentifier(transaction.name)};`;
}
return "ROLLBACK TRANSACTION;";
}
addLimitAndOffset(options) {
const offset = options.offset || 0;
let fragment = "";
if (offset > 0) {
fragment += ` OFFSET ${this.escape(offset)} ROWS`;
}
if (options.limit) {
fragment += ` FETCH NEXT ${this.escape(options.limit)} ROWS ONLY`;
}
return fragment;
}
booleanValue(value) {
return value ? 1 : 0;
}
addUniqueFields(dataValues, rawAttributes, uniqno) {
uniqno = uniqno === void 0 ? 1 : uniqno;
for (const key in rawAttributes) {
if (rawAttributes[key].unique && dataValues[key] === void 0) {
if (rawAttributes[key].type instanceof DataTypes.DATE) {
dataValues[key] = Utils.now("db2");
} else if (rawAttributes[key].type instanceof DataTypes.STRING) {
dataValues[key] = `unique${uniqno++}`;
} else if (rawAttributes[key].type instanceof DataTypes.INTEGER) {
dataValues[key] = uniqno++;
} else if (rawAttributes[key].type instanceof DataTypes.BOOLEAN) {
dataValues[key] = new DataTypes.BOOLEAN(false);
}
}
}
return uniqno;
}
quoteIdentifier(identifier, force) {
return Utils.addTicks(Utils.removeTicks(identifier, '"'), '"');
}
}
function wrapSingleQuote(identifier) {
if (identifier) {
return `'${identifier}'`;
}
return "";
}
module.exports = Db2QueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
+131
View File
@@ -0,0 +1,131 @@
"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 _ = require("lodash");
const Utils = require("../../utils");
const Op = require("../../operators");
const { QueryInterface } = require("../abstract/query-interface");
const QueryTypes = require("../../query-types");
class Db2QueryInterface extends QueryInterface {
async getForeignKeyReferencesForTable(tableName, options) {
const queryOptions = __spreadProps(__spreadValues({}, options), {
type: QueryTypes.FOREIGNKEYS
});
const query = this.queryGenerator.getForeignKeysQuery(tableName, this.sequelize.config.username.toUpperCase());
return this.sequelize.query(query, queryOptions);
}
async upsert(tableName, insertValues, updateValues, where, options) {
options = __spreadValues({}, options);
const model = options.model;
const wheres = [];
const attributes = Object.keys(insertValues);
let indexes = [];
let indexFields;
options = _.clone(options);
if (!Utils.isWhereEmpty(where)) {
wheres.push(where);
}
indexes = _.map(model.uniqueKeys, (value) => {
return value.fields;
});
model._indexes.forEach((value) => {
if (value.unique) {
indexFields = value.fields.map((field) => {
if (_.isPlainObject(field)) {
return field.attribute;
}
return field;
});
indexes.push(indexFields);
}
});
for (const index of indexes) {
if (_.intersection(attributes, index).length === index.length) {
where = {};
for (const field of index) {
where[field] = insertValues[field];
}
wheres.push(where);
}
}
where = { [Op.or]: wheres };
options.type = QueryTypes.UPSERT;
options.raw = true;
const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);
const result = await this.sequelize.query(sql, options);
return [result, void 0];
}
async createTable(tableName, attributes, options, model) {
let sql = "";
options = __spreadValues({}, options);
if (options && options.uniqueKeys) {
_.forOwn(options.uniqueKeys, (uniqueKey) => {
if (uniqueKey.customIndex === void 0) {
uniqueKey.customIndex = true;
}
});
}
if (model) {
options.uniqueKeys = options.uniqueKeys || model.uniqueKeys;
}
attributes = _.mapValues(attributes, (attribute) => this.sequelize.normalizeAttribute(attribute));
if (options.indexes) {
options.indexes.forEach((fields) => {
const fieldArr = fields.fields;
if (fieldArr.length === 1) {
fieldArr.forEach((field) => {
for (const property in attributes) {
if (field === attributes[property].field) {
attributes[property].unique = true;
}
}
});
}
});
}
if (options.alter) {
if (options.indexes) {
options.indexes.forEach((fields) => {
const fieldArr = fields.fields;
if (fieldArr.length === 1) {
fieldArr.forEach((field) => {
for (const property in attributes) {
if (field === attributes[property].field && attributes[property].unique) {
attributes[property].unique = false;
}
}
});
}
});
}
}
if (!tableName.schema && (options.schema || !!model && model._schema)) {
tableName = this.queryGenerator.addSchema({
tableName,
_schema: !!model && model._schema || options.schema
});
}
attributes = this.queryGenerator.attributesToSQL(attributes, { table: tableName, context: "createTable", withoutForeignKeyConstraints: options.withoutForeignKeyConstraints });
sql = this.queryGenerator.createTableQuery(tableName, attributes, options);
return await this.sequelize.query(sql, options);
}
}
exports.Db2QueryInterface = Db2QueryInterface;
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/db2/query-interface.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\nconst Utils = require('../../utils');\nconst Op = require('../../operators');\nconst { QueryInterface } = require('../abstract/query-interface');\nconst QueryTypes = require('../../query-types');\n\n/**\n * The interface that Sequelize uses to talk with Db2 database\n */\nclass Db2QueryInterface extends QueryInterface {\n async getForeignKeyReferencesForTable(tableName, options) {\n const queryOptions = {\n ...options,\n type: QueryTypes.FOREIGNKEYS\n };\n const query = this.queryGenerator.getForeignKeysQuery(tableName, this.sequelize.config.username.toUpperCase());\n return this.sequelize.query(query, queryOptions);\n }\n\n async upsert(tableName, insertValues, updateValues, where, options) {\n options = { ...options };\n\n const model = options.model;\n const wheres = [];\n const attributes = Object.keys(insertValues);\n let indexes = [];\n let indexFields;\n\n options = _.clone(options);\n\n if (!Utils.isWhereEmpty(where)) {\n wheres.push(where);\n }\n\n // Lets combine unique keys and indexes into one\n indexes = _.map(model.uniqueKeys, value => {\n return value.fields;\n });\n\n model._indexes.forEach(value => {\n if (value.unique) {\n // fields in the index may both the strings or objects with an attribute property - lets sanitize that\n indexFields = value.fields.map(field => {\n if (_.isPlainObject(field)) {\n return field.attribute;\n }\n return field;\n });\n indexes.push(indexFields);\n }\n });\n\n for (const index of indexes) {\n if (_.intersection(attributes, index).length === index.length) {\n where = {};\n for (const field of index) {\n where[field] = insertValues[field];\n }\n wheres.push(where);\n }\n }\n\n where = { [Op.or]: wheres };\n\n options.type = QueryTypes.UPSERT;\n options.raw = true;\n\n const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);\n const result = await this.sequelize.query(sql, options);\n return [result, undefined];\n }\n\n async createTable(tableName, attributes, options, model) {\n let sql = '';\n\n options = { ...options };\n\n if (options && options.uniqueKeys) {\n _.forOwn(options.uniqueKeys, uniqueKey => {\n if (uniqueKey.customIndex === undefined) {\n uniqueKey.customIndex = true;\n }\n });\n }\n\n if (model) {\n options.uniqueKeys = options.uniqueKeys || model.uniqueKeys;\n }\n attributes = _.mapValues(\n attributes,\n attribute => this.sequelize.normalizeAttribute(attribute)\n ); \n if (options.indexes) {\n options.indexes.forEach(fields=>{\n const fieldArr = fields.fields;\n if (fieldArr.length === 1) {\n fieldArr.forEach(field=>{ \n for (const property in attributes) {\n if (field === attributes[property].field) {\n attributes[property].unique = true;\n }\n }\n });\n }\n });\n }\n if (options.alter) {\n if (options.indexes) {\n options.indexes.forEach(fields=>{\n const fieldArr = fields.fields;\n if (fieldArr.length === 1) {\n fieldArr.forEach(field=>{ \n for (const property in attributes) {\n if (field === attributes[property].field && attributes[property].unique) {\n attributes[property].unique = false;\n }\n }\n });\n }\n });\n }\n }\n\n if (\n !tableName.schema &&\n (options.schema || !!model && model._schema)\n ) {\n tableName = this.queryGenerator.addSchema({\n tableName,\n _schema: !!model && model._schema || options.schema\n });\n }\n\n attributes = this.queryGenerator.attributesToSQL(attributes, { table: tableName, context: 'createTable', withoutForeignKeyConstraints: options.withoutForeignKeyConstraints });\n sql = this.queryGenerator.createTableQuery(tableName, attributes, options);\n\n return await this.sequelize.query(sql, options);\n }\n\n}\n\nexports.Db2QueryInterface = Db2QueryInterface;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAEA,MAAM,IAAI,QAAQ;AAClB,MAAM,QAAQ,QAAQ;AACtB,MAAM,KAAK,QAAQ;AACnB,MAAM,EAAE,mBAAmB,QAAQ;AACnC,MAAM,aAAa,QAAQ;AAK3B,gCAAgC,eAAe;AAAA,QACvC,gCAAgC,WAAW,SAAS;AACxD,UAAM,eAAe,iCAChB,UADgB;AAAA,MAEnB,MAAM,WAAW;AAAA;AAEnB,UAAM,QAAQ,KAAK,eAAe,oBAAoB,WAAW,KAAK,UAAU,OAAO,SAAS;AAChG,WAAO,KAAK,UAAU,MAAM,OAAO;AAAA;AAAA,QAG/B,OAAO,WAAW,cAAc,cAAc,OAAO,SAAS;AAClE,cAAU,mBAAK;AAEf,UAAM,QAAQ,QAAQ;AACtB,UAAM,SAAS;AACf,UAAM,aAAa,OAAO,KAAK;AAC/B,QAAI,UAAU;AACd,QAAI;AAEJ,cAAU,EAAE,MAAM;AAElB,QAAI,CAAC,MAAM,aAAa,QAAQ;AAC9B,aAAO,KAAK;AAAA;AAId,cAAU,EAAE,IAAI,MAAM,YAAY,WAAS;AACzC,aAAO,MAAM;AAAA;AAGf,UAAM,SAAS,QAAQ,WAAS;AAC9B,UAAI,MAAM,QAAQ;AAEhB,sBAAc,MAAM,OAAO,IAAI,WAAS;AACtC,cAAI,EAAE,cAAc,QAAQ;AAC1B,mBAAO,MAAM;AAAA;AAEf,iBAAO;AAAA;AAET,gBAAQ,KAAK;AAAA;AAAA;AAIjB,eAAW,SAAS,SAAS;AAC3B,UAAI,EAAE,aAAa,YAAY,OAAO,WAAW,MAAM,QAAQ;AAC7D,gBAAQ;AACR,mBAAW,SAAS,OAAO;AACzB,gBAAM,SAAS,aAAa;AAAA;AAE9B,eAAO,KAAK;AAAA;AAAA;AAIhB,YAAQ,GAAG,GAAG,KAAK;AAEnB,YAAQ,OAAO,WAAW;AAC1B,YAAQ,MAAM;AAEd,UAAM,MAAM,KAAK,eAAe,YAAY,WAAW,cAAc,cAAc,OAAO,OAAO;AACjG,UAAM,SAAS,MAAM,KAAK,UAAU,MAAM,KAAK;AAC/C,WAAO,CAAC,QAAQ;AAAA;AAAA,QAGZ,YAAY,WAAW,YAAY,SAAS,OAAO;AACvD,QAAI,MAAM;AAEV,cAAU,mBAAK;AAEf,QAAI,WAAW,QAAQ,YAAY;AACjC,QAAE,OAAO,QAAQ,YAAY,eAAa;AACxC,YAAI,UAAU,gBAAgB,QAAW;AACvC,oBAAU,cAAc;AAAA;AAAA;AAAA;AAK9B,QAAI,OAAO;AACT,cAAQ,aAAa,QAAQ,cAAc,MAAM;AAAA;AAEnD,iBAAa,EAAE,UACb,YACA,eAAa,KAAK,UAAU,mBAAmB;AAEjD,QAAI,QAAQ,SAAS;AACnB,cAAQ,QAAQ,QAAQ,YAAQ;AAC9B,cAAM,WAAW,OAAO;AACxB,YAAI,SAAS,WAAW,GAAG;AACzB,mBAAS,QAAQ,WAAO;AACtB,uBAAW,YAAY,YAAY;AACjC,kBAAI,UAAU,WAAW,UAAU,OAAO;AACxC,2BAAW,UAAU,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO1C,QAAI,QAAQ,OAAO;AACjB,UAAI,QAAQ,SAAS;AACnB,gBAAQ,QAAQ,QAAQ,YAAQ;AAC9B,gBAAM,WAAW,OAAO;AACxB,cAAI,SAAS,WAAW,GAAG;AACzB,qBAAS,QAAQ,WAAO;AACtB,yBAAW,YAAY,YAAY;AACjC,oBAAI,UAAU,WAAW,UAAU,SAAS,WAAW,UAAU,QAAQ;AACvE,6BAAW,UAAU,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS5C,QACE,CAAC,UAAU,UACV,SAAQ,UAAU,CAAC,CAAC,SAAS,MAAM,UACpC;AACA,kBAAY,KAAK,eAAe,UAAU;AAAA,QACxC;AAAA,QACA,SAAS,CAAC,CAAC,SAAS,MAAM,WAAW,QAAQ;AAAA;AAAA;AAIjD,iBAAa,KAAK,eAAe,gBAAgB,YAAY,EAAE,OAAO,WAAW,SAAS,eAAe,8BAA8B,QAAQ;AAC/I,UAAM,KAAK,eAAe,iBAAiB,WAAW,YAAY;AAElE,WAAO,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA;AAAA;AAK3C,QAAQ,oBAAoB;",
"names": []
}
+429
View File
@@ -0,0 +1,429 @@
"use strict";
const util = require("util");
const AbstractQuery = require("../abstract/query");
const sequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("db2");
const _ = require("lodash");
const { logger } = require("../../utils/logger");
const moment = require("moment");
const debug = logger.debugContext("sql:db2");
class Query extends AbstractQuery {
getInsertIdField() {
return "id";
}
getSQLTypeFromJsType(value) {
if (Buffer.isBuffer(value)) {
return { ParamType: "INPUT", DataType: "BLOB", Data: value };
}
if (typeof value === "bigint") {
return value.toString();
}
return value;
}
async _run(connection, sql, parameters) {
this.sql = sql;
const benchmark = this.sequelize.options.benchmark || this.options.benchmark;
let queryBegin;
if (benchmark) {
queryBegin = Date.now();
} else {
this.sequelize.log(`Executing (${this.connection.uuid || "default"}): ${this.sql}`, this.options);
}
const errStack = new Error().stack;
return new Promise((resolve, reject) => {
if (_.startsWith(this.sql, "BEGIN TRANSACTION")) {
connection.beginTransaction((err) => {
if (err) {
reject(this.formatError(err, errStack));
} else {
resolve(this.formatResults());
}
});
} else if (_.startsWith(this.sql, "COMMIT TRANSACTION")) {
connection.commitTransaction((err) => {
if (err) {
reject(this.formatError(err, errStack));
} else {
resolve(this.formatResults());
}
});
} else if (_.startsWith(this.sql, "ROLLBACK TRANSACTION")) {
connection.rollbackTransaction((err) => {
if (err) {
reject(this.formatError(err, errStack));
} else {
resolve(this.formatResults());
}
});
} else if (_.startsWith(this.sql, "SAVE TRANSACTION")) {
connection.commitTransaction((err) => {
if (err) {
reject(this.formatError(err, errStack));
} else {
connection.beginTransaction((err2) => {
if (err2) {
reject(this.formatError(err2, errStack));
} else {
resolve(this.formatResults());
}
});
}
}, this.options.transaction.name);
} else {
const params = [];
if (parameters) {
_.forOwn(parameters, (value, key) => {
const param = this.getSQLTypeFromJsType(value, key);
params.push(param);
});
}
const SQL = this.sql.toUpperCase();
let newSql = this.sql;
if ((this.isSelectQuery() || _.startsWith(SQL, "SELECT ")) && SQL.indexOf(" FROM ", 8) === -1) {
if (this.sql.charAt(this.sql.length - 1) === ";") {
newSql = this.sql.slice(0, this.sql.length - 1);
}
newSql += " FROM SYSIBM.SYSDUMMY1;";
}
connection.prepare(newSql, (err, stmt) => {
if (err) {
reject(this.formatError(err, errStack));
}
stmt.execute(params, (err2, result, outparams) => {
debug(`executed(${this.connection.uuid || "default"}):${newSql} ${parameters ? util.inspect(parameters, { compact: true, breakLength: Infinity }) : ""}`);
if (benchmark) {
this.sequelize.log(`Executed (${this.connection.uuid || "default"}): ${newSql} ${parameters ? util.inspect(parameters, { compact: true, breakLength: Infinity }) : ""}`, Date.now() - queryBegin, this.options);
}
if (err2 && err2.message) {
err2 = this.filterSQLError(err2, this.sql, connection);
if (err2 === null) {
stmt.closeSync();
resolve(this.formatResults([], 0));
}
}
if (err2) {
err2.sql = sql;
stmt.closeSync();
reject(this.formatError(err2, errStack, connection, parameters));
} else {
let data = [];
let metadata = [];
let affectedRows = 0;
if (typeof result === "object") {
if (_.startsWith(this.sql, "DELETE FROM ")) {
affectedRows = result.getAffectedRowsSync();
} else {
data = result.fetchAllSync();
metadata = result.getColumnMetadataSync();
}
result.closeSync();
}
stmt.closeSync();
const datalen = data.length;
if (datalen > 0) {
const coltypes = {};
for (let i = 0; i < metadata.length; i++) {
coltypes[metadata[i].SQL_DESC_NAME] = metadata[i].SQL_DESC_TYPE_NAME;
}
for (let i = 0; i < datalen; i++) {
for (const column in data[i]) {
const parse = parserStore.get(coltypes[column]);
const value = data[i][column];
if (value !== null) {
if (parse) {
data[i][column] = parse(value);
} else if (coltypes[column] === "TIMESTAMP") {
data[i][column] = new Date(moment.utc(value));
} else if (coltypes[column] === "BLOB") {
data[i][column] = new Buffer.from(value);
} else if (coltypes[column].indexOf("FOR BIT DATA") > 0) {
data[i][column] = new Buffer.from(value, "hex");
}
}
}
}
if (outparams && outparams.length) {
data.unshift(outparams);
}
resolve(this.formatResults(data, datalen, metadata, connection));
} else {
resolve(this.formatResults(data, affectedRows));
}
}
});
});
}
});
}
async run(sql, parameters) {
return await this._run(this.connection, sql, parameters);
}
static formatBindParameters(sql, values, dialect) {
let bindParam = {};
const replacementFunc = (match, key, values2) => {
if (values2[key] !== void 0) {
bindParam[key] = values2[key];
return "?";
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
if (Array.isArray(values) && typeof values[0] === "object") {
bindParam = values;
}
return [sql, bindParam];
}
filterSQLError(err, sql, connection) {
if (err.message.search("SQL0204N") != -1 && _.startsWith(sql, "DROP ")) {
err = null;
} else if (err.message.search("SQL0443N") != -1) {
if (this.isDropSchemaQuery()) {
connection.querySync("DROP TABLE ERRORSCHEMA.ERRORTABLE;");
connection.querySync(this.sql);
}
err = null;
} else if (err.message.search("SQL0601N") != -1) {
const match = err.message.match(/SQL0601N {2}The name of the object to be created is identical to the existing name "(.*)" of type "(.*)"./);
if (match && match.length > 1 && match[2] === "TABLE") {
let table;
const mtarray = match[1].split(".");
if (mtarray[1]) {
table = `"${mtarray[0]}"."${mtarray[1]}"`;
} else {
table = `"${mtarray[0]}"`;
}
if (connection.dropTable !== false) {
connection.querySync(`DROP TABLE ${table}`);
err = connection.querySync(sql);
} else {
err = null;
}
} else {
err = null;
}
} else if (err.message.search("SQL0911N") != -1) {
if (err.message.search('Reason code "2"') != -1) {
err = null;
}
} else if (err.message.search("SQL0605W") != -1) {
err = null;
} else if (err.message.search("SQL0668N") != -1 && _.startsWith(sql, "ALTER TABLE ")) {
connection.querySync(`CALL SYSPROC.ADMIN_CMD('REORG TABLE ${sql.substring(12).split(" ")[0]}')`);
err = connection.querySync(sql);
}
if (err && err.length === 0) {
err = null;
}
return err;
}
formatResults(data, rowCount, metadata, conn) {
let result = this.instance;
if (this.isInsertQuery(data, metadata)) {
this.handleInsertQuery(data, metadata);
if (!this.instance) {
if (this.options.plain) {
const record = data[0];
result = record[Object.keys(record)[0]];
} else {
result = data;
}
}
}
if (this.isShowTablesQuery()) {
result = data;
} else if (this.isDescribeQuery()) {
result = {};
for (const _result of data) {
if (_result.Default) {
_result.Default = _result.Default.replace("('", "").replace("')", "").replace(/'/g, "");
}
result[_result.Name] = {
type: _result.Type.toUpperCase(),
allowNull: _result.IsNull === "Y" ? true : false,
defaultValue: _result.Default,
primaryKey: _result.KeySeq > 0,
autoIncrement: _result.IsIdentity === "Y" ? true : false,
comment: _result.Comment
};
}
} else if (this.isShowIndexesQuery()) {
result = this.handleShowIndexesQuery(data);
} else if (this.isSelectQuery()) {
result = this.handleSelectQuery(data);
} else if (this.isUpsertQuery()) {
result = data;
} else if (this.isDropSchemaQuery()) {
result = data[0];
if (conn) {
const query = "DROP TABLE ERRORSCHEMA.ERRORTABLE";
conn.querySync(query);
}
} else if (this.isCallQuery()) {
result = data;
} else if (this.isBulkUpdateQuery()) {
result = data.length;
} else if (this.isBulkDeleteQuery()) {
result = rowCount;
} else if (this.isVersionQuery()) {
result = data[0].VERSION;
} else if (this.isForeignKeysQuery()) {
result = data;
} else if (this.isInsertQuery() || this.isUpdateQuery()) {
result = [result, rowCount];
} else if (this.isShowConstraintsQuery()) {
result = this.handleShowConstraintsQuery(data);
} else if (this.isRawQuery()) {
result = [data, metadata];
} else {
result = data;
}
return result;
}
handleShowTablesQuery(results) {
return results.map((resultSet) => {
return {
tableName: resultSet.TABLE_NAME,
schema: resultSet.TABLE_SCHEMA
};
});
}
handleShowConstraintsQuery(data) {
return _.remove(data, (constraint) => {
return !_.startsWith(constraint.constraintName, "SQL");
});
}
formatError(err, errStack, conn, parameters) {
let match;
if (!(err && err.message)) {
err["message"] = "No error message found.";
}
match = err.message.match(/SQL0803N {2}One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "(\d)+" constrains table "(.*)\.(.*)" from having duplicate values for the index key./);
if (match && match.length > 0) {
let uniqueIndexName = "";
let uniqueKey = "";
const fields = {};
let message = err.message;
const query = `SELECT INDNAME FROM SYSCAT.INDEXES WHERE IID = ${match[1]} AND TABSCHEMA = '${match[2]}' AND TABNAME = '${match[3]}'`;
if (!!conn && match.length > 3) {
uniqueIndexName = conn.querySync(query);
uniqueIndexName = uniqueIndexName[0]["INDNAME"];
}
if (this.model && !!uniqueIndexName) {
uniqueKey = this.model.uniqueKeys[uniqueIndexName];
}
if (!uniqueKey && this.options.fields) {
uniqueKey = this.options.fields[match[1] - 1];
}
if (uniqueKey) {
if (this.options.where && this.options.where[uniqueKey.column] !== void 0) {
fields[uniqueKey.column] = this.options.where[uniqueKey.column];
} else if (this.options.instance && this.options.instance.dataValues && this.options.instance.dataValues[uniqueKey.column]) {
fields[uniqueKey.column] = this.options.instance.dataValues[uniqueKey.column];
} else if (parameters) {
fields[uniqueKey.column] = parameters["0"];
}
}
if (uniqueKey && !!uniqueKey.msg) {
message = uniqueKey.msg;
}
const errors = [];
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
match = err.message.match(/SQL0532N {2}A parent row cannot be deleted because the relationship "(.*)" restricts the deletion/) || err.message.match(/SQL0530N/) || err.message.match(/SQL0531N/);
if (match && match.length > 0) {
return new sequelizeErrors.ForeignKeyConstraintError({
fields: null,
index: match[1],
parent: err,
stack: errStack
});
}
match = err.message.match(/SQL0204N {2}"(.*)" is an undefined name./);
if (match && match.length > 1) {
const constraint = match[1];
let table = err.sql.match(/table "(.+?)"/i);
table = table ? table[1] : void 0;
return new sequelizeErrors.UnknownConstraintError({
message: match[0],
constraint,
table,
parent: err,
stack: errStack
});
}
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
isDropSchemaQuery() {
let result = false;
if (_.startsWith(this.sql, "CALL SYSPROC.ADMIN_DROP_SCHEMA")) {
result = true;
}
return result;
}
isShowOrDescribeQuery() {
let result = false;
result = result || this.sql.toLowerCase().startsWith("select c.column_name as 'name', c.data_type as 'type', c.is_nullable as 'isnull'");
result = result || this.sql.toLowerCase().startsWith("select tablename = t.name, name = ind.name,");
result = result || this.sql.toLowerCase().startsWith("exec sys.sp_helpindex @objname");
return result;
}
isShowIndexesQuery() {
let result = false;
result = result || this.sql.toLowerCase().startsWith("exec sys.sp_helpindex @objname");
result = result || this.sql.startsWith('SELECT NAME AS "name", TBNAME AS "tableName", UNIQUERULE AS "keyType", COLNAMES, INDEXTYPE AS "type" FROM SYSIBM.SYSINDEXES');
return result;
}
handleShowIndexesQuery(data) {
let currItem;
const result = [];
data.forEach((item) => {
if (!currItem || currItem.name !== item.Key_name) {
currItem = {
primary: item.keyType === "P",
fields: [],
name: item.name,
tableName: item.tableName,
unique: item.keyType === "U",
type: item.type
};
_.forEach(item.COLNAMES.replace(/\+|-/g, (x) => {
return ` ${x}`;
}).split(" "), (column) => {
let columnName = column.trim();
if (columnName) {
columnName = columnName.replace(/\+|-/, "");
currItem.fields.push({
attribute: columnName,
length: void 0,
order: column.indexOf("-") === -1 ? "ASC" : "DESC",
collate: void 0
});
}
});
result.push(currItem);
}
});
return result;
}
handleInsertQuery(results, metaData) {
if (this.instance) {
const autoIncrementAttribute = this.model.autoIncrementAttribute;
let id = null;
let autoIncrementAttributeAlias = null;
if (Object.prototype.hasOwnProperty.call(this.model.rawAttributes, autoIncrementAttribute) && this.model.rawAttributes[autoIncrementAttribute].field !== void 0)
autoIncrementAttributeAlias = this.model.rawAttributes[autoIncrementAttribute].field;
id = id || results && results[0][this.getInsertIdField()];
id = id || metaData && metaData[this.getInsertIdField()];
id = id || results && results[0][autoIncrementAttribute];
id = id || autoIncrementAttributeAlias && results && results[0][autoIncrementAttributeAlias];
this.instance[autoIncrementAttribute] = id;
}
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,118 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const semver = require("semver");
const AbstractConnectionManager = require("../abstract/connection-manager");
const SequelizeErrors = require("../../errors");
const { logger } = require("../../utils/logger");
const DataTypes = require("../../data-types").mariadb;
const momentTz = require("moment-timezone");
const debug = logger.debugContext("connection:mariadb");
const parserStore = require("../parserStore")("mariadb");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 3306;
super(dialect, sequelize);
this.lib = this._loadDialectModule("mariadb");
this.refreshTypeParser(DataTypes);
}
static _typecast(field, next) {
if (parserStore.get(field.type)) {
return parserStore.get(field.type)(field, this.sequelize.options, next);
}
return next();
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async connect(config) {
let tzOffset = this.sequelize.options.timezone;
tzOffset = /\//.test(tzOffset) ? momentTz.tz(tzOffset).format("Z") : tzOffset;
const connectionConfig = __spreadValues({
host: config.host,
port: config.port,
user: config.username,
password: config.password,
database: config.database,
timezone: tzOffset,
typeCast: ConnectionManager._typecast.bind(this),
bigNumberStrings: false,
supportBigNumbers: true,
foundRows: false
}, config.dialectOptions);
if (!this.sequelize.config.keepDefaultTimezone) {
if (connectionConfig.initSql) {
if (!Array.isArray(connectionConfig.initSql)) {
connectionConfig.initSql = [connectionConfig.initSql];
}
connectionConfig.initSql.push(`SET time_zone = '${tzOffset}'`);
} else {
connectionConfig.initSql = `SET time_zone = '${tzOffset}'`;
}
}
try {
const connection = await this.lib.createConnection(connectionConfig);
this.sequelize.options.databaseVersion = semver.coerce(connection.serverVersion()).version;
debug("connection acquired");
connection.on("error", (error) => {
switch (error.code) {
case "ESOCKET":
case "ECONNRESET":
case "EPIPE":
case "PROTOCOL_CONNECTION_LOST":
this.pool.destroy(connection);
}
});
return connection;
} catch (err) {
switch (err.code) {
case "ECONNREFUSED":
throw new SequelizeErrors.ConnectionRefusedError(err);
case "ER_ACCESS_DENIED_ERROR":
case "ER_ACCESS_DENIED_NO_PASSWORD_ERROR":
throw new SequelizeErrors.AccessDeniedError(err);
case "ENOTFOUND":
throw new SequelizeErrors.HostNotFoundError(err);
case "EHOSTUNREACH":
case "ENETUNREACH":
case "EADDRNOTAVAIL":
throw new SequelizeErrors.HostNotReachableError(err);
case "EINVAL":
throw new SequelizeErrors.InvalidConnectionError(err);
default:
throw new SequelizeErrors.ConnectionError(err);
}
}
}
async disconnect(connection) {
if (!connection.isValid()) {
debug("connection tried to disconnect but was already at CLOSED state");
return;
}
return await connection.end();
}
validate(connection) {
return connection && connection.isValid();
}
}
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/mariadb/connection-manager.js"],
"sourcesContent": ["'use strict';\n\nconst semver = require('semver');\nconst AbstractConnectionManager = require('../abstract/connection-manager');\nconst SequelizeErrors = require('../../errors');\nconst { logger } = require('../../utils/logger');\nconst DataTypes = require('../../data-types').mariadb;\nconst momentTz = require('moment-timezone');\nconst debug = logger.debugContext('connection:mariadb');\nconst parserStore = require('../parserStore')('mariadb');\n\n/**\n * MariaDB Connection Manager\n *\n * Get connections, validate and disconnect them.\n * AbstractConnectionManager pooling use it to handle MariaDB specific connections\n * Use https://github.com/MariaDB/mariadb-connector-nodejs to connect with MariaDB server\n *\n * @private\n */\nclass ConnectionManager extends AbstractConnectionManager {\n constructor(dialect, sequelize) {\n sequelize.config.port = sequelize.config.port || 3306;\n super(dialect, sequelize);\n this.lib = this._loadDialectModule('mariadb');\n this.refreshTypeParser(DataTypes);\n }\n\n static _typecast(field, next) {\n if (parserStore.get(field.type)) {\n return parserStore.get(field.type)(field, this.sequelize.options, next);\n }\n return next();\n }\n\n _refreshTypeParser(dataType) {\n parserStore.refresh(dataType);\n }\n\n _clearTypeParser() {\n parserStore.clear();\n }\n\n /**\n * Connect with MariaDB database based on config, Handle any errors in connection\n * Set the pool handlers on connection.error\n * Also set proper timezone once connection is connected.\n *\n * @param {object} config\n * @returns {Promise<Connection>}\n * @private\n */\n async connect(config) {\n // Named timezone is not supported in mariadb, convert to offset\n let tzOffset = this.sequelize.options.timezone;\n tzOffset = /\\//.test(tzOffset) ? momentTz.tz(tzOffset).format('Z')\n : tzOffset;\n\n const connectionConfig = {\n host: config.host,\n port: config.port,\n user: config.username,\n password: config.password,\n database: config.database,\n timezone: tzOffset,\n typeCast: ConnectionManager._typecast.bind(this),\n bigNumberStrings: false,\n supportBigNumbers: true,\n foundRows: false,\n ...config.dialectOptions\n };\n\n if (!this.sequelize.config.keepDefaultTimezone) {\n // set timezone for this connection\n if (connectionConfig.initSql) {\n if (!Array.isArray(\n connectionConfig.initSql)) {\n connectionConfig.initSql = [connectionConfig.initSql];\n }\n connectionConfig.initSql.push(`SET time_zone = '${tzOffset}'`);\n } else {\n connectionConfig.initSql = `SET time_zone = '${tzOffset}'`;\n }\n }\n\n try {\n const connection = await this.lib.createConnection(connectionConfig);\n this.sequelize.options.databaseVersion = semver.coerce(connection.serverVersion()).version;\n\n debug('connection acquired');\n connection.on('error', error => {\n switch (error.code) {\n case 'ESOCKET':\n case 'ECONNRESET':\n case 'EPIPE':\n case 'PROTOCOL_CONNECTION_LOST':\n this.pool.destroy(connection);\n }\n });\n return connection;\n } catch (err) {\n switch (err.code) {\n case 'ECONNREFUSED':\n throw new SequelizeErrors.ConnectionRefusedError(err);\n case 'ER_ACCESS_DENIED_ERROR':\n case 'ER_ACCESS_DENIED_NO_PASSWORD_ERROR':\n throw new SequelizeErrors.AccessDeniedError(err);\n case 'ENOTFOUND':\n throw new SequelizeErrors.HostNotFoundError(err);\n case 'EHOSTUNREACH':\n case 'ENETUNREACH':\n case 'EADDRNOTAVAIL':\n throw new SequelizeErrors.HostNotReachableError(err);\n case 'EINVAL':\n throw new SequelizeErrors.InvalidConnectionError(err);\n default:\n throw new SequelizeErrors.ConnectionError(err);\n }\n }\n }\n\n async disconnect(connection) {\n // Don't disconnect connections with CLOSED state\n if (!connection.isValid()) {\n debug('connection tried to disconnect but was already at CLOSED state');\n return;\n }\n return await connection.end();\n }\n\n validate(connection) {\n return connection && connection.isValid();\n }\n}\n\nmodule.exports = ConnectionManager;\nmodule.exports.ConnectionManager = ConnectionManager;\nmodule.exports.default = ConnectionManager;\n"],
"mappings": ";;;;;;;;;;;;;;;;;AAEA,MAAM,SAAS,QAAQ;AACvB,MAAM,4BAA4B,QAAQ;AAC1C,MAAM,kBAAkB,QAAQ;AAChC,MAAM,EAAE,WAAW,QAAQ;AAC3B,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,WAAW,QAAQ;AACzB,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAM,cAAc,QAAQ,kBAAkB;AAW9C,gCAAgC,0BAA0B;AAAA,EACxD,YAAY,SAAS,WAAW;AAC9B,cAAU,OAAO,OAAO,UAAU,OAAO,QAAQ;AACjD,UAAM,SAAS;AACf,SAAK,MAAM,KAAK,mBAAmB;AACnC,SAAK,kBAAkB;AAAA;AAAA,SAGlB,UAAU,OAAO,MAAM;AAC5B,QAAI,YAAY,IAAI,MAAM,OAAO;AAC/B,aAAO,YAAY,IAAI,MAAM,MAAM,OAAO,KAAK,UAAU,SAAS;AAAA;AAEpE,WAAO;AAAA;AAAA,EAGT,mBAAmB,UAAU;AAC3B,gBAAY,QAAQ;AAAA;AAAA,EAGtB,mBAAmB;AACjB,gBAAY;AAAA;AAAA,QAYR,QAAQ,QAAQ;AAEpB,QAAI,WAAW,KAAK,UAAU,QAAQ;AACtC,eAAW,KAAK,KAAK,YAAY,SAAS,GAAG,UAAU,OAAO,OAC1D;AAEJ,UAAM,mBAAmB;AAAA,MACvB,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,UAAU;AAAA,MACV,UAAU,kBAAkB,UAAU,KAAK;AAAA,MAC3C,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,WAAW;AAAA,OACR,OAAO;AAGZ,QAAI,CAAC,KAAK,UAAU,OAAO,qBAAqB;AAE9C,UAAI,iBAAiB,SAAS;AAC5B,YAAI,CAAC,MAAM,QACT,iBAAiB,UAAU;AAC3B,2BAAiB,UAAU,CAAC,iBAAiB;AAAA;AAE/C,yBAAiB,QAAQ,KAAK,oBAAoB;AAAA,aAC7C;AACL,yBAAiB,UAAU,oBAAoB;AAAA;AAAA;AAInD,QAAI;AACF,YAAM,aAAa,MAAM,KAAK,IAAI,iBAAiB;AACnD,WAAK,UAAU,QAAQ,kBAAkB,OAAO,OAAO,WAAW,iBAAiB;AAEnF,YAAM;AACN,iBAAW,GAAG,SAAS,WAAS;AAC9B,gBAAQ,MAAM;AAAA,eACP;AAAA,eACA;AAAA,eACA;AAAA,eACA;AACH,iBAAK,KAAK,QAAQ;AAAA;AAAA;AAGxB,aAAO;AAAA,aACA,KAAP;AACA,cAAQ,IAAI;AAAA,aACL;AACH,gBAAM,IAAI,gBAAgB,uBAAuB;AAAA,aAC9C;AAAA,aACA;AACH,gBAAM,IAAI,gBAAgB,kBAAkB;AAAA,aACzC;AACH,gBAAM,IAAI,gBAAgB,kBAAkB;AAAA,aACzC;AAAA,aACA;AAAA,aACA;AACH,gBAAM,IAAI,gBAAgB,sBAAsB;AAAA,aAC7C;AACH,gBAAM,IAAI,gBAAgB,uBAAuB;AAAA;AAEjD,gBAAM,IAAI,gBAAgB,gBAAgB;AAAA;AAAA;AAAA;AAAA,QAK5C,WAAW,YAAY;AAE3B,QAAI,CAAC,WAAW,WAAW;AACzB,YAAM;AACN;AAAA;AAEF,WAAO,MAAM,WAAW;AAAA;AAAA,EAG1B,SAAS,YAAY;AACnB,WAAO,cAAc,WAAW;AAAA;AAAA;AAIpC,OAAO,UAAU;AACjB,OAAO,QAAQ,oBAAoB;AACnC,OAAO,QAAQ,UAAU;",
"names": []
}
+115
View File
@@ -0,0 +1,115 @@
"use strict";
const wkx = require("wkx");
const _ = require("lodash");
const momentTz = require("moment-timezone");
const moment = require("moment");
module.exports = (BaseTypes) => {
BaseTypes.ABSTRACT.prototype.dialectTypes = "https://mariadb.com/kb/en/library/resultset/#field-types";
BaseTypes.DATE.types.mariadb = ["DATETIME"];
BaseTypes.STRING.types.mariadb = ["VAR_STRING"];
BaseTypes.CHAR.types.mariadb = ["STRING"];
BaseTypes.TEXT.types.mariadb = ["BLOB"];
BaseTypes.TINYINT.types.mariadb = ["TINY"];
BaseTypes.SMALLINT.types.mariadb = ["SHORT"];
BaseTypes.MEDIUMINT.types.mariadb = ["INT24"];
BaseTypes.INTEGER.types.mariadb = ["LONG"];
BaseTypes.BIGINT.types.mariadb = ["LONGLONG"];
BaseTypes.FLOAT.types.mariadb = ["FLOAT"];
BaseTypes.TIME.types.mariadb = ["TIME"];
BaseTypes.DATEONLY.types.mariadb = ["DATE"];
BaseTypes.BOOLEAN.types.mariadb = ["TINY"];
BaseTypes.BLOB.types.mariadb = ["TINYBLOB", "BLOB", "LONGBLOB"];
BaseTypes.DECIMAL.types.mariadb = ["NEWDECIMAL"];
BaseTypes.UUID.types.mariadb = false;
BaseTypes.ENUM.types.mariadb = false;
BaseTypes.REAL.types.mariadb = ["DOUBLE"];
BaseTypes.DOUBLE.types.mariadb = ["DOUBLE"];
BaseTypes.GEOMETRY.types.mariadb = ["GEOMETRY"];
BaseTypes.JSON.types.mariadb = ["JSON"];
class DECIMAL extends BaseTypes.DECIMAL {
toSql() {
let definition = super.toSql();
if (this._unsigned) {
definition += " UNSIGNED";
}
if (this._zerofill) {
definition += " ZEROFILL";
}
return definition;
}
}
class DATE extends BaseTypes.DATE {
toSql() {
return this._length ? `DATETIME(${this._length})` : "DATETIME";
}
_stringify(date, options) {
if (!moment.isMoment(date)) {
date = this._applyTimezone(date, options);
}
return date.format("YYYY-MM-DD HH:mm:ss.SSS");
}
static parse(value, options) {
value = value.string();
if (value === null) {
return value;
}
if (momentTz.tz.zone(options.timezone)) {
value = momentTz.tz(value, options.timezone).toDate();
} else {
value = new Date(`${value} ${options.timezone}`);
}
return value;
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return value.string();
}
}
class UUID extends BaseTypes.UUID {
toSql() {
return "CHAR(36) BINARY";
}
}
class GEOMETRY extends BaseTypes.GEOMETRY {
constructor(type, srid) {
super(type, srid);
if (_.isEmpty(this.type)) {
this.sqlType = this.key;
} else {
this.sqlType = this.type;
}
}
static parse(value) {
value = value.buffer();
if (!value || value.length === 0) {
return null;
}
value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });
}
toSql() {
return this.sqlType;
}
}
class ENUM extends BaseTypes.ENUM {
toSql(options) {
return `ENUM(${this.values.map((value) => options.escape(value)).join(", ")})`;
}
}
class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
return options.operation === "where" && typeof value === "string" ? value : JSON.stringify(value);
}
}
return {
ENUM,
DATE,
DATEONLY,
UUID,
GEOMETRY,
DECIMAL,
JSON: JSONTYPE
};
};
//# sourceMappingURL=data-types.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mariadb/data-types.js"],
"sourcesContent": ["'use strict';\n\nconst wkx = require('wkx');\nconst _ = require('lodash');\nconst momentTz = require('moment-timezone');\nconst moment = require('moment');\n\nmodule.exports = BaseTypes => {\n BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://mariadb.com/kb/en/library/resultset/#field-types';\n\n /**\n * types: [buffer_type, ...]\n *\n * @see documentation : https://mariadb.com/kb/en/library/resultset/#field-types\n * @see connector implementation : https://github.com/MariaDB/mariadb-connector-nodejs/blob/master/lib/const/field-type.js\n */\n\n BaseTypes.DATE.types.mariadb = ['DATETIME'];\n BaseTypes.STRING.types.mariadb = ['VAR_STRING'];\n BaseTypes.CHAR.types.mariadb = ['STRING'];\n BaseTypes.TEXT.types.mariadb = ['BLOB'];\n BaseTypes.TINYINT.types.mariadb = ['TINY'];\n BaseTypes.SMALLINT.types.mariadb = ['SHORT'];\n BaseTypes.MEDIUMINT.types.mariadb = ['INT24'];\n BaseTypes.INTEGER.types.mariadb = ['LONG'];\n BaseTypes.BIGINT.types.mariadb = ['LONGLONG'];\n BaseTypes.FLOAT.types.mariadb = ['FLOAT'];\n BaseTypes.TIME.types.mariadb = ['TIME'];\n BaseTypes.DATEONLY.types.mariadb = ['DATE'];\n BaseTypes.BOOLEAN.types.mariadb = ['TINY'];\n BaseTypes.BLOB.types.mariadb = ['TINYBLOB', 'BLOB', 'LONGBLOB'];\n BaseTypes.DECIMAL.types.mariadb = ['NEWDECIMAL'];\n BaseTypes.UUID.types.mariadb = false;\n BaseTypes.ENUM.types.mariadb = false;\n BaseTypes.REAL.types.mariadb = ['DOUBLE'];\n BaseTypes.DOUBLE.types.mariadb = ['DOUBLE'];\n BaseTypes.GEOMETRY.types.mariadb = ['GEOMETRY'];\n BaseTypes.JSON.types.mariadb = ['JSON'];\n\n class DECIMAL extends BaseTypes.DECIMAL {\n toSql() {\n let definition = super.toSql();\n if (this._unsigned) {\n definition += ' UNSIGNED';\n }\n if (this._zerofill) {\n definition += ' ZEROFILL';\n }\n return definition;\n }\n }\n\n class DATE extends BaseTypes.DATE {\n toSql() {\n return this._length ? `DATETIME(${this._length})` : 'DATETIME';\n }\n _stringify(date, options) {\n if (!moment.isMoment(date)) {\n date = this._applyTimezone(date, options);\n }\n\n return date.format('YYYY-MM-DD HH:mm:ss.SSS');\n }\n static parse(value, options) {\n value = value.string();\n if (value === null) {\n return value;\n }\n if (momentTz.tz.zone(options.timezone)) {\n value = momentTz.tz(value, options.timezone).toDate();\n }\n else {\n value = new Date(`${value} ${options.timezone}`);\n }\n return value;\n }\n }\n\n class DATEONLY extends BaseTypes.DATEONLY {\n static parse(value) {\n return value.string();\n }\n }\n\n class UUID extends BaseTypes.UUID {\n toSql() {\n return 'CHAR(36) BINARY';\n }\n }\n\n class GEOMETRY extends BaseTypes.GEOMETRY {\n constructor(type, srid) {\n super(type, srid);\n if (_.isEmpty(this.type)) {\n this.sqlType = this.key;\n }\n else {\n this.sqlType = this.type;\n }\n }\n static parse(value) {\n value = value.buffer();\n // Empty buffer, MySQL doesn't support POINT EMPTY\n // check, https://dev.mysql.com/worklog/task/?id=2381\n if (!value || value.length === 0) {\n return null;\n }\n // For some reason, discard the first 4 bytes\n value = value.slice(4);\n return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });\n }\n toSql() {\n return this.sqlType;\n }\n }\n\n class ENUM extends BaseTypes.ENUM {\n toSql(options) {\n return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;\n }\n }\n\n class JSONTYPE extends BaseTypes.JSON {\n _stringify(value, options) {\n return options.operation === 'where' && typeof value === 'string' ? value\n : JSON.stringify(value);\n }\n }\n\n return {\n ENUM,\n DATE,\n DATEONLY,\n UUID,\n GEOMETRY,\n DECIMAL,\n JSON: JSONTYPE\n };\n};\n"],
"mappings": ";AAEA,MAAM,MAAM,QAAQ;AACpB,MAAM,IAAI,QAAQ;AAClB,MAAM,WAAW,QAAQ;AACzB,MAAM,SAAS,QAAQ;AAEvB,OAAO,UAAU,eAAa;AAC5B,YAAU,SAAS,UAAU,eAAe;AAS5C,YAAU,KAAK,MAAM,UAAU,CAAC;AAChC,YAAU,OAAO,MAAM,UAAU,CAAC;AAClC,YAAU,KAAK,MAAM,UAAU,CAAC;AAChC,YAAU,KAAK,MAAM,UAAU,CAAC;AAChC,YAAU,QAAQ,MAAM,UAAU,CAAC;AACnC,YAAU,SAAS,MAAM,UAAU,CAAC;AACpC,YAAU,UAAU,MAAM,UAAU,CAAC;AACrC,YAAU,QAAQ,MAAM,UAAU,CAAC;AACnC,YAAU,OAAO,MAAM,UAAU,CAAC;AAClC,YAAU,MAAM,MAAM,UAAU,CAAC;AACjC,YAAU,KAAK,MAAM,UAAU,CAAC;AAChC,YAAU,SAAS,MAAM,UAAU,CAAC;AACpC,YAAU,QAAQ,MAAM,UAAU,CAAC;AACnC,YAAU,KAAK,MAAM,UAAU,CAAC,YAAY,QAAQ;AACpD,YAAU,QAAQ,MAAM,UAAU,CAAC;AACnC,YAAU,KAAK,MAAM,UAAU;AAC/B,YAAU,KAAK,MAAM,UAAU;AAC/B,YAAU,KAAK,MAAM,UAAU,CAAC;AAChC,YAAU,OAAO,MAAM,UAAU,CAAC;AAClC,YAAU,SAAS,MAAM,UAAU,CAAC;AACpC,YAAU,KAAK,MAAM,UAAU,CAAC;AAEhC,wBAAsB,UAAU,QAAQ;AAAA,IACtC,QAAQ;AACN,UAAI,aAAa,MAAM;AACvB,UAAI,KAAK,WAAW;AAClB,sBAAc;AAAA;AAEhB,UAAI,KAAK,WAAW;AAClB,sBAAc;AAAA;AAEhB,aAAO;AAAA;AAAA;AAIX,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO,KAAK,UAAU,YAAY,KAAK,aAAa;AAAA;AAAA,IAEtD,WAAW,MAAM,SAAS;AACxB,UAAI,CAAC,OAAO,SAAS,OAAO;AAC1B,eAAO,KAAK,eAAe,MAAM;AAAA;AAGnC,aAAO,KAAK,OAAO;AAAA;AAAA,WAEd,MAAM,OAAO,SAAS;AAC3B,cAAQ,MAAM;AACd,UAAI,UAAU,MAAM;AAClB,eAAO;AAAA;AAET,UAAI,SAAS,GAAG,KAAK,QAAQ,WAAW;AACtC,gBAAQ,SAAS,GAAG,OAAO,QAAQ,UAAU;AAAA,aAE1C;AACH,gBAAQ,IAAI,KAAK,GAAG,SAAS,QAAQ;AAAA;AAEvC,aAAO;AAAA;AAAA;AAIX,yBAAuB,UAAU,SAAS;AAAA,WACjC,MAAM,OAAO;AAClB,aAAO,MAAM;AAAA;AAAA;AAIjB,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA;AAAA;AAIX,yBAAuB,UAAU,SAAS;AAAA,IACxC,YAAY,MAAM,MAAM;AACtB,YAAM,MAAM;AACZ,UAAI,EAAE,QAAQ,KAAK,OAAO;AACxB,aAAK,UAAU,KAAK;AAAA,aAEjB;AACH,aAAK,UAAU,KAAK;AAAA;AAAA;AAAA,WAGjB,MAAM,OAAO;AAClB,cAAQ,MAAM;AAGd,UAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,eAAO;AAAA;AAGT,cAAQ,MAAM,MAAM;AACpB,aAAO,IAAI,SAAS,MAAM,OAAO,UAAU,EAAE,UAAU;AAAA;AAAA,IAEzD,QAAQ;AACN,aAAO,KAAK;AAAA;AAAA;AAIhB,qBAAmB,UAAU,KAAK;AAAA,IAChC,MAAM,SAAS;AACb,aAAO,QAAQ,KAAK,OAAO,IAAI,WAAS,QAAQ,OAAO,QAAQ,KAAK;AAAA;AAAA;AAIxE,yBAAuB,UAAU,KAAK;AAAA,IACpC,WAAW,OAAO,SAAS;AACzB,aAAO,QAAQ,cAAc,WAAW,OAAO,UAAU,WAAW,QAChE,KAAK,UAAU;AAAA;AAAA;AAIvB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA;AAAA;",
"names": []
}
+62
View File
@@ -0,0 +1,62 @@
"use strict";
const _ = require("lodash");
const AbstractDialect = require("../abstract");
const ConnectionManager = require("./connection-manager");
const Query = require("./query");
const QueryGenerator = require("./query-generator");
const { MySQLQueryInterface } = require("../mysql/query-interface");
const DataTypes = require("../../data-types").mariadb;
class MariadbDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new MySQLQueryInterface(sequelize, this.queryGenerator);
}
canBackslashEscape() {
return true;
}
}
MariadbDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"VALUES ()": true,
"LIMIT ON UPDATE": true,
lock: true,
forShare: "LOCK IN SHARE MODE",
settingIsolationLevelDuringTransaction: false,
schemas: true,
inserts: {
ignoreDuplicates: " IGNORE",
updateOnDuplicate: " ON DUPLICATE KEY UPDATE"
},
index: {
collate: false,
length: true,
parser: true,
type: true,
using: 1
},
constraints: {
dropConstraint: false,
check: false
},
indexViaAlter: true,
indexHints: true,
NUMERIC: true,
GEOMETRY: true,
JSON: true,
REGEXP: true
});
MariadbDialect.prototype.defaultVersion = "10.1.44";
MariadbDialect.prototype.Query = Query;
MariadbDialect.prototype.QueryGenerator = QueryGenerator;
MariadbDialect.prototype.DataTypes = DataTypes;
MariadbDialect.prototype.name = "mariadb";
MariadbDialect.prototype.TICK_CHAR = "`";
MariadbDialect.prototype.TICK_CHAR_LEFT = MariadbDialect.prototype.TICK_CHAR;
MariadbDialect.prototype.TICK_CHAR_RIGHT = MariadbDialect.prototype.TICK_CHAR;
module.exports = MariadbDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mariadb/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 { MySQLQueryInterface } = require('../mysql/query-interface');\nconst DataTypes = require('../../data-types').mariadb;\n\nclass MariadbDialect 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 this.queryInterface = new MySQLQueryInterface(\n sequelize,\n this.queryGenerator\n );\n }\n\n canBackslashEscape() {\n return true;\n }\n}\n\nMariadbDialect.prototype.supports = _.merge(\n _.cloneDeep(AbstractDialect.prototype.supports),\n {\n 'VALUES ()': true,\n 'LIMIT ON UPDATE': true,\n lock: true,\n forShare: 'LOCK IN SHARE MODE',\n settingIsolationLevelDuringTransaction: false,\n schemas: true,\n inserts: {\n ignoreDuplicates: ' IGNORE',\n updateOnDuplicate: ' ON DUPLICATE KEY UPDATE'\n },\n index: {\n collate: false,\n length: true,\n parser: true,\n type: true,\n using: 1\n },\n constraints: {\n dropConstraint: false,\n check: false\n },\n indexViaAlter: true,\n indexHints: true,\n NUMERIC: true,\n GEOMETRY: true,\n JSON: true,\n REGEXP: true\n }\n);\n\nMariadbDialect.prototype.defaultVersion = '10.1.44'; // minimum supported version\nMariadbDialect.prototype.Query = Query;\nMariadbDialect.prototype.QueryGenerator = QueryGenerator;\nMariadbDialect.prototype.DataTypes = DataTypes;\nMariadbDialect.prototype.name = 'mariadb';\nMariadbDialect.prototype.TICK_CHAR = '`';\nMariadbDialect.prototype.TICK_CHAR_LEFT = MariadbDialect.prototype.TICK_CHAR;\nMariadbDialect.prototype.TICK_CHAR_RIGHT = MariadbDialect.prototype.TICK_CHAR;\n\nmodule.exports = MariadbDialect;\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,EAAE,wBAAwB,QAAQ;AACxC,MAAM,YAAY,QAAQ,oBAAoB;AAE9C,6BAA6B,gBAAgB;AAAA,EAC3C,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,oBACxB,WACA,KAAK;AAAA;AAAA,EAIT,qBAAqB;AACnB,WAAO;AAAA;AAAA;AAIX,eAAe,UAAU,WAAW,EAAE,MACpC,EAAE,UAAU,gBAAgB,UAAU,WACtC;AAAA,EACE,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wCAAwC;AAAA,EACxC,SAAS;AAAA,EACT,SAAS;AAAA,IACP,kBAAkB;AAAA,IAClB,mBAAmB;AAAA;AAAA,EAErB,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,aAAa;AAAA,IACX,gBAAgB;AAAA,IAChB,OAAO;AAAA;AAAA,EAET,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA;AAIZ,eAAe,UAAU,iBAAiB;AAC1C,eAAe,UAAU,QAAQ;AACjC,eAAe,UAAU,iBAAiB;AAC1C,eAAe,UAAU,YAAY;AACrC,eAAe,UAAU,OAAO;AAChC,eAAe,UAAU,YAAY;AACrC,eAAe,UAAU,iBAAiB,eAAe,UAAU;AACnE,eAAe,UAAU,kBAAkB,eAAe,UAAU;AAEpE,OAAO,UAAU;",
"names": []
}
+69
View File
@@ -0,0 +1,69 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const MySQLQueryGenerator = require("../mysql/query-generator");
const Utils = require("./../../utils");
class MariaDBQueryGenerator extends MySQLQueryGenerator {
createSchema(schema, options) {
options = __spreadValues({
charset: null,
collate: null
}, options);
return Utils.joinSQLFragments([
"CREATE SCHEMA IF NOT EXISTS",
this.quoteIdentifier(schema),
options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`,
options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`,
";"
]);
}
dropSchema(schema) {
return `DROP SCHEMA IF EXISTS ${this.quoteIdentifier(schema)};`;
}
showSchemasQuery(options) {
const schemasToSkip = [
"'MYSQL'",
"'INFORMATION_SCHEMA'",
"'PERFORMANCE_SCHEMA'"
];
if (options.skip && Array.isArray(options.skip) && options.skip.length > 0) {
for (const schemaName of options.skip) {
schemasToSkip.push(this.escape(schemaName));
}
}
return Utils.joinSQLFragments([
"SELECT SCHEMA_NAME as schema_name",
"FROM INFORMATION_SCHEMA.SCHEMATA",
`WHERE SCHEMA_NAME NOT IN (${schemasToSkip.join(", ")})`,
";"
]);
}
showTablesQuery(database) {
let query = "SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'";
if (database) {
query += ` AND TABLE_SCHEMA = ${this.escape(database)}`;
} else {
query += " AND TABLE_SCHEMA NOT IN ('MYSQL', 'INFORMATION_SCHEMA', 'PERFORMANCE_SCHEMA')";
}
return `${query};`;
}
quoteIdentifier(identifier, force) {
return Utils.addTicks(Utils.removeTicks(identifier, "`"), "`");
}
}
module.exports = MariaDBQueryGenerator;
//# sourceMappingURL=query-generator.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mariadb/query-generator.js"],
"sourcesContent": ["'use strict';\n\nconst MySQLQueryGenerator = require('../mysql/query-generator');\nconst Utils = require('./../../utils');\n\nclass MariaDBQueryGenerator extends MySQLQueryGenerator {\n createSchema(schema, options) {\n options = {\n charset: null,\n collate: null,\n ...options\n };\n\n return Utils.joinSQLFragments([\n 'CREATE SCHEMA IF NOT EXISTS',\n this.quoteIdentifier(schema),\n options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`,\n options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`,\n ';'\n ]);\n }\n\n dropSchema(schema) {\n return `DROP SCHEMA IF EXISTS ${this.quoteIdentifier(schema)};`;\n }\n\n showSchemasQuery(options) {\n const schemasToSkip = [\n '\\'MYSQL\\'',\n '\\'INFORMATION_SCHEMA\\'',\n '\\'PERFORMANCE_SCHEMA\\''\n ];\n if (options.skip && Array.isArray(options.skip) && options.skip.length > 0) {\n for (const schemaName of options.skip) {\n schemasToSkip.push(this.escape(schemaName));\n }\n }\n return Utils.joinSQLFragments([\n 'SELECT SCHEMA_NAME as schema_name',\n 'FROM INFORMATION_SCHEMA.SCHEMATA',\n `WHERE SCHEMA_NAME NOT IN (${schemasToSkip.join(', ')})`,\n ';'\n ]);\n }\n\n showTablesQuery(database) {\n let query = 'SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = \\'BASE TABLE\\'';\n if (database) {\n query += ` AND TABLE_SCHEMA = ${this.escape(database)}`;\n } else {\n query += ' AND TABLE_SCHEMA NOT IN (\\'MYSQL\\', \\'INFORMATION_SCHEMA\\', \\'PERFORMANCE_SCHEMA\\')';\n }\n return `${query};`;\n }\n\n /**\n * Quote identifier in sql clause\n *\n * @param {string} identifier\n * @param {boolean} force\n *\n * @returns {string}\n */\n quoteIdentifier(identifier, force) {\n return Utils.addTicks(Utils.removeTicks(identifier, '`'), '`');\n }\n}\n\nmodule.exports = MariaDBQueryGenerator;\n"],
"mappings": ";;;;;;;;;;;;;;;;;AAEA,MAAM,sBAAsB,QAAQ;AACpC,MAAM,QAAQ,QAAQ;AAEtB,oCAAoC,oBAAoB;AAAA,EACtD,aAAa,QAAQ,SAAS;AAC5B,cAAU;AAAA,MACR,SAAS;AAAA,MACT,SAAS;AAAA,OACN;AAGL,WAAO,MAAM,iBAAiB;AAAA,MAC5B;AAAA,MACA,KAAK,gBAAgB;AAAA,MACrB,QAAQ,WAAW,yBAAyB,KAAK,OAAO,QAAQ;AAAA,MAChE,QAAQ,WAAW,mBAAmB,KAAK,OAAO,QAAQ;AAAA,MAC1D;AAAA;AAAA;AAAA,EAIJ,WAAW,QAAQ;AACjB,WAAO,yBAAyB,KAAK,gBAAgB;AAAA;AAAA,EAGvD,iBAAiB,SAAS;AACxB,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA;AAEF,QAAI,QAAQ,QAAQ,MAAM,QAAQ,QAAQ,SAAS,QAAQ,KAAK,SAAS,GAAG;AAC1E,iBAAW,cAAc,QAAQ,MAAM;AACrC,sBAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAGnC,WAAO,MAAM,iBAAiB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,6BAA6B,cAAc,KAAK;AAAA,MAChD;AAAA;AAAA;AAAA,EAIJ,gBAAgB,UAAU;AACxB,QAAI,QAAQ;AACZ,QAAI,UAAU;AACZ,eAAS,uBAAuB,KAAK,OAAO;AAAA,WACvC;AACL,eAAS;AAAA;AAEX,WAAO,GAAG;AAAA;AAAA,EAWZ,gBAAgB,YAAY,OAAO;AACjC,WAAO,MAAM,SAAS,MAAM,YAAY,YAAY,MAAM;AAAA;AAAA;AAI9D,OAAO,UAAU;",
"names": []
}
+254
View File
@@ -0,0 +1,254 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const AbstractQuery = require("../abstract/query");
const sequelizeErrors = require("../../errors");
const _ = require("lodash");
const DataTypes = require("../../data-types");
const { logger } = require("../../utils/logger");
const ER_DUP_ENTRY = 1062;
const ER_DEADLOCK = 1213;
const ER_ROW_IS_REFERENCED = 1451;
const ER_NO_REFERENCED_ROW = 1452;
const debug = logger.debugContext("sql:mariadb");
class Query extends AbstractQuery {
constructor(connection, sequelize, options) {
super(connection, sequelize, __spreadValues({ showWarnings: false }, options));
}
static formatBindParameters(sql, values, dialect) {
const bindParam = [];
const replacementFunc = (match, key, values_) => {
if (values_[key] !== void 0) {
bindParam.push(values_[key]);
return "?";
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
return [sql, bindParam.length > 0 ? bindParam : void 0];
}
async run(sql, parameters) {
this.sql = sql;
const { connection, options } = this;
const showWarnings = this.sequelize.options.showWarnings || options.showWarnings;
const complete = this._logQuery(sql, debug, parameters);
if (parameters) {
debug("parameters(%j)", parameters);
}
let results;
const errForStack = new Error();
try {
results = await connection.query(this.sql, parameters);
} catch (error) {
if (options.transaction && error.errno === ER_DEADLOCK) {
try {
await options.transaction.rollback();
} catch (error_) {
}
options.transaction.finished = "rollback";
}
error.sql = sql;
error.parameters = parameters;
throw this.formatError(error, errForStack.stack);
} finally {
complete();
}
if (showWarnings && results && results.warningStatus > 0) {
await this.logWarnings(results);
}
return this.formatResults(results);
}
formatResults(data) {
let result = this.instance;
if (this.isBulkUpdateQuery() || this.isBulkDeleteQuery()) {
return data.affectedRows;
}
if (this.isUpsertQuery()) {
return [result, data.affectedRows === 1];
}
if (this.isInsertQuery(data)) {
this.handleInsertQuery(data);
if (!this.instance) {
if (this.model && this.model.autoIncrementAttribute && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute && this.model.rawAttributes[this.model.primaryKeyAttribute]) {
const startId = data[this.getInsertIdField()];
result = new Array(data.affectedRows);
const pkField = this.model.rawAttributes[this.model.primaryKeyAttribute].field;
for (let i = 0; i < data.affectedRows; i++) {
result[i] = { [pkField]: startId + i };
}
return [result, data.affectedRows];
}
return [data[this.getInsertIdField()], data.affectedRows];
}
}
if (this.isSelectQuery()) {
this.handleJsonSelectQuery(data);
return this.handleSelectQuery(data);
}
if (this.isInsertQuery() || this.isUpdateQuery()) {
return [result, data.affectedRows];
}
if (this.isCallQuery()) {
return data[0];
}
if (this.isRawQuery()) {
const meta = data.meta;
delete data.meta;
return [data, meta];
}
if (this.isShowIndexesQuery()) {
return this.handleShowIndexesQuery(data);
}
if (this.isForeignKeysQuery() || this.isShowConstraintsQuery()) {
return data;
}
if (this.isShowTablesQuery()) {
return this.handleShowTablesQuery(data);
}
if (this.isDescribeQuery()) {
result = {};
for (const _result of data) {
result[_result.Field] = {
type: _result.Type.toLowerCase().startsWith("enum") ? _result.Type.replace(/^enum/i, "ENUM") : _result.Type.toUpperCase(),
allowNull: _result.Null === "YES",
defaultValue: _result.Default,
primaryKey: _result.Key === "PRI",
autoIncrement: Object.prototype.hasOwnProperty.call(_result, "Extra") && _result.Extra.toLowerCase() === "auto_increment",
comment: _result.Comment ? _result.Comment : null
};
}
return result;
}
if (this.isVersionQuery()) {
return data[0].version;
}
return result;
}
handleJsonSelectQuery(rows) {
if (!this.model || !this.model.fieldRawAttributesMap) {
return;
}
for (const _field of Object.keys(this.model.fieldRawAttributesMap)) {
const modelField = this.model.fieldRawAttributesMap[_field];
if (modelField.type instanceof DataTypes.JSON) {
rows = rows.map((row) => {
if (row[modelField.fieldName] && typeof row[modelField.fieldName] === "string" && !this.connection.info.hasMinVersion(10, 5, 2)) {
row[modelField.fieldName] = JSON.parse(row[modelField.fieldName]);
}
if (DataTypes.JSON.parse) {
return DataTypes.JSON.parse(modelField, this.sequelize.options, row[modelField.fieldName]);
}
return row;
});
}
}
}
async logWarnings(results) {
const warningResults = await this.run("SHOW WARNINGS");
const warningMessage = `MariaDB Warnings (${this.connection.uuid || "default"}): `;
const messages = [];
for (const _warningRow of warningResults) {
if (_warningRow === void 0 || typeof _warningRow[Symbol.iterator] !== "function") {
continue;
}
for (const _warningResult of _warningRow) {
if (Object.prototype.hasOwnProperty.call(_warningResult, "Message")) {
messages.push(_warningResult.Message);
} else {
for (const _objectKey of _warningResult.keys()) {
messages.push([_objectKey, _warningResult[_objectKey]].join(": "));
}
}
}
}
this.sequelize.log(warningMessage + messages.join("; "), this.options);
return results;
}
formatError(err, errStack) {
switch (err.errno) {
case ER_DUP_ENTRY: {
const match = err.message.match(/Duplicate entry '([\s\S]*)' for key '?((.|\s)*?)'?\s.*$/);
let fields = {};
let message = "Validation error";
const values = match ? match[1].split("-") : void 0;
const fieldKey = match ? match[2] : void 0;
const fieldVal = match ? match[1] : void 0;
const uniqueKey = this.model && this.model.uniqueKeys[fieldKey];
if (uniqueKey) {
if (uniqueKey.msg)
message = uniqueKey.msg;
fields = _.zipObject(uniqueKey.fields, values);
} else {
fields[fieldKey] = fieldVal;
}
const errors = [];
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
case ER_ROW_IS_REFERENCED:
case ER_NO_REFERENCED_ROW: {
const match = err.message.match(/CONSTRAINT ([`"])(.*)\1 FOREIGN KEY \(\1(.*)\1\) REFERENCES \1(.*)\1 \(\1(.*)\1\)/);
const quoteChar = match ? match[1] : "`";
const fields = match ? match[3].split(new RegExp(`${quoteChar}, *${quoteChar}`)) : void 0;
return new sequelizeErrors.ForeignKeyConstraintError({
reltype: err.errno === ER_ROW_IS_REFERENCED ? "parent" : "child",
table: match ? match[4] : void 0,
fields,
value: fields && fields.length && this.instance && this.instance[fields[0]] || void 0,
index: match ? match[2] : void 0,
parent: err,
stack: errStack
});
}
default:
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
}
handleShowTablesQuery(results) {
return results.map((resultSet) => ({
tableName: resultSet.TABLE_NAME,
schema: resultSet.TABLE_SCHEMA
}));
}
handleShowIndexesQuery(data) {
let currItem;
const result = [];
data.forEach((item) => {
if (!currItem || currItem.name !== item.Key_name) {
currItem = {
primary: item.Key_name === "PRIMARY",
fields: [],
name: item.Key_name,
tableName: item.Table,
unique: item.Non_unique !== 1,
type: item.Index_type
};
result.push(currItem);
}
currItem.fields[item.Seq_in_index - 1] = {
attribute: item.Column_name,
length: item.Sub_part || void 0,
order: item.Collation === "A" ? "ASC" : void 0
};
});
return result;
}
}
module.exports = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
+68
View File
@@ -0,0 +1,68 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
AsyncQueueError: () => AsyncQueueError,
default: () => async_queue_default
});
var import_base_error = __toModule(require("../../errors/base-error"));
var import_connection_error = __toModule(require("../../errors/connection-error"));
class AsyncQueueError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeAsyncQueueError";
}
}
class AsyncQueue {
constructor() {
__publicField(this, "previous");
__publicField(this, "closed");
__publicField(this, "rejectCurrent");
this.previous = Promise.resolve();
this.closed = false;
this.rejectCurrent = () => {
};
}
close() {
this.closed = true;
this.rejectCurrent(new import_connection_error.default(new AsyncQueueError("the connection was closed before this query could finish executing")));
}
enqueue(asyncFunction) {
return new Promise((resolve, reject) => {
this.previous = this.previous.then(() => {
this.rejectCurrent = reject;
if (this.closed) {
return reject(new import_connection_error.default(new AsyncQueueError("the connection was closed before this query could be executed")));
}
return asyncFunction().then(resolve, reject);
});
});
}
}
var async_queue_default = AsyncQueue;
//# sourceMappingURL=async-queue.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mssql/async-queue.ts"],
"sourcesContent": ["import BaseError from '../../errors/base-error';\nimport ConnectionError from '../../errors/connection-error';\n\n/**\n * Thrown when a connection to a database is closed while an operation is in progress\n */\nexport class AsyncQueueError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeAsyncQueueError';\n }\n}\n\nclass AsyncQueue {\n previous: Promise<unknown>;\n closed: boolean;\n rejectCurrent: (reason?: any) => void;\n\n constructor() {\n this.previous = Promise.resolve();\n this.closed = false;\n this.rejectCurrent = () => {\n /** do nothing */\n };\n }\n\n close() {\n this.closed = true;\n this.rejectCurrent(\n new ConnectionError(\n new AsyncQueueError(\n 'the connection was closed before this query could finish executing'\n )\n )\n );\n }\n\n enqueue(asyncFunction: (...args: any[]) => Promise<unknown>) {\n // This outer promise might seems superflous since down below we return asyncFunction().then(resolve, reject).\n // However, this ensures that this.previous will never be a rejected promise so the queue will\n // always keep going, while still communicating rejection from asyncFunction to the user.\n return new Promise((resolve, reject) => {\n this.previous = this.previous.then(() => {\n this.rejectCurrent = reject;\n if (this.closed) {\n return reject(\n new ConnectionError(\n new AsyncQueueError(\n 'the connection was closed before this query could be executed'\n )\n )\n );\n }\n return asyncFunction().then(resolve, reject);\n });\n });\n }\n}\n\nexport default AsyncQueue;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAsB;AACtB,8BAA4B;AAKrB,8BAA8B,0BAAU;AAAA,EAC7C,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,iBAAiB;AAAA,EAKf,cAAc;AAJd;AACA;AACA;AAGE,SAAK,WAAW,QAAQ;AACxB,SAAK,SAAS;AACd,SAAK,gBAAgB,MAAM;AAAA;AAAA;AAAA,EAK7B,QAAQ;AACN,SAAK,SAAS;AACd,SAAK,cACH,IAAI,gCACF,IAAI,gBACF;AAAA;AAAA,EAMR,QAAQ,eAAqD;AAI3D,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,WAAK,WAAW,KAAK,SAAS,KAAK,MAAM;AACvC,aAAK,gBAAgB;AACrB,YAAI,KAAK,QAAQ;AACf,iBAAO,OACL,IAAI,gCACF,IAAI,gBACF;AAAA;AAKR,eAAO,gBAAgB,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAM7C,IAAO,sBAAQ;",
"names": []
}
+141
View File
@@ -0,0 +1,141 @@
"use strict";
const AbstractConnectionManager = require("../abstract/connection-manager");
const AsyncQueue = require("./async-queue").default;
const { logger } = require("../../utils/logger");
const sequelizeErrors = require("../../errors");
const DataTypes = require("../../data-types").mssql;
const parserStore = require("../parserStore")("mssql");
const debug = logger.debugContext("connection:mssql");
const debugTedious = logger.debugContext("connection:mssql:tedious");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 1433;
super(dialect, sequelize);
this.lib = this._loadDialectModule("tedious");
this.refreshTypeParser(DataTypes);
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async connect(config) {
const connectionConfig = {
server: config.host,
authentication: {
type: "default",
options: {
userName: config.username || void 0,
password: config.password || void 0
}
},
options: {
port: parseInt(config.port, 10),
database: config.database,
trustServerCertificate: true
}
};
if (config.dialectOptions) {
if (config.dialectOptions.options && config.dialectOptions.options.instanceName) {
delete connectionConfig.options.port;
}
if (config.dialectOptions.authentication) {
Object.assign(connectionConfig.authentication, config.dialectOptions.authentication);
}
Object.assign(connectionConfig.options, config.dialectOptions.options);
}
try {
return await new Promise((resolve, reject) => {
const connection = new this.lib.Connection(connectionConfig);
if (connection.state === connection.STATE.INITIALIZED) {
connection.connect();
}
connection.queue = new AsyncQueue();
connection.lib = this.lib;
const connectHandler = (error) => {
connection.removeListener("end", endHandler);
connection.removeListener("error", errorHandler);
if (error)
return reject(error);
debug("connection acquired");
resolve(connection);
};
const endHandler = () => {
connection.removeListener("connect", connectHandler);
connection.removeListener("error", errorHandler);
reject(new Error("Connection was closed by remote server"));
};
const errorHandler = (error) => {
connection.removeListener("connect", connectHandler);
connection.removeListener("end", endHandler);
reject(error);
};
connection.once("error", errorHandler);
connection.once("end", endHandler);
connection.once("connect", connectHandler);
connection.on("error", (error) => {
switch (error.code) {
case "ESOCKET":
case "ECONNRESET":
this.pool.destroy(connection);
}
});
if (config.dialectOptions && config.dialectOptions.debug) {
connection.on("debug", debugTedious.log.bind(debugTedious));
}
});
} catch (error) {
if (!error.code) {
throw new sequelizeErrors.ConnectionError(error);
}
switch (error.code) {
case "ESOCKET":
if (error.message.includes("connect EHOSTUNREACH")) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes("connect ENETUNREACH")) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes("connect EADDRNOTAVAIL")) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes("connect EAFNOSUPPORT")) {
throw new sequelizeErrors.HostNotReachableError(error);
}
if (error.message.includes("getaddrinfo ENOTFOUND")) {
throw new sequelizeErrors.HostNotFoundError(error);
}
if (error.message.includes("connect ECONNREFUSED")) {
throw new sequelizeErrors.ConnectionRefusedError(error);
}
throw new sequelizeErrors.ConnectionError(error);
case "ER_ACCESS_DENIED_ERROR":
case "ELOGIN":
throw new sequelizeErrors.AccessDeniedError(error);
case "EINVAL":
throw new sequelizeErrors.InvalidConnectionError(error);
default:
throw new sequelizeErrors.ConnectionError(error);
}
}
}
async disconnect(connection) {
if (connection.closed) {
return;
}
connection.queue.close();
return new Promise((resolve) => {
connection.on("end", resolve);
connection.close();
debug("connection closed");
});
}
validate(connection) {
return connection && (connection.loggedIn || connection.state.name === "LoggedIn");
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
File diff suppressed because one or more lines are too long
+181
View File
@@ -0,0 +1,181 @@
"use strict";
const moment = require("moment");
module.exports = (BaseTypes) => {
const warn = BaseTypes.ABSTRACT.warn.bind(void 0, "https://msdn.microsoft.com/en-us/library/ms187752%28v=sql.110%29.aspx");
function removeUnsupportedIntegerOptions(dataType) {
if (dataType._length || dataType.options.length || dataType._unsigned || dataType._zerofill) {
warn(`MSSQL does not support '${dataType.key}' with options. Plain '${dataType.key}' will be used instead.`);
dataType._length = void 0;
dataType.options.length = void 0;
dataType._unsigned = void 0;
dataType._zerofill = void 0;
}
}
BaseTypes.DATE.types.mssql = [43];
BaseTypes.STRING.types.mssql = [231, 173];
BaseTypes.CHAR.types.mssql = [175];
BaseTypes.TEXT.types.mssql = false;
BaseTypes.TINYINT.types.mssql = [30];
BaseTypes.SMALLINT.types.mssql = [34];
BaseTypes.MEDIUMINT.types.mssql = false;
BaseTypes.INTEGER.types.mssql = [38];
BaseTypes.BIGINT.types.mssql = false;
BaseTypes.FLOAT.types.mssql = [109];
BaseTypes.TIME.types.mssql = [41];
BaseTypes.DATEONLY.types.mssql = [40];
BaseTypes.BOOLEAN.types.mssql = [104];
BaseTypes.BLOB.types.mssql = [165];
BaseTypes.DECIMAL.types.mssql = [106];
BaseTypes.UUID.types.mssql = false;
BaseTypes.ENUM.types.mssql = false;
BaseTypes.REAL.types.mssql = [109];
BaseTypes.DOUBLE.types.mssql = [109];
BaseTypes.GEOMETRY.types.mssql = false;
class BLOB extends BaseTypes.BLOB {
toSql() {
if (this._length) {
if (this._length.toLowerCase() === "tiny") {
warn("MSSQL does not support BLOB with the `length` = `tiny` option. `VARBINARY(256)` will be used instead.");
return "VARBINARY(256)";
}
warn("MSSQL does not support BLOB with the `length` option. `VARBINARY(MAX)` will be used instead.");
}
return "VARBINARY(MAX)";
}
_hexify(hex) {
return `0x${hex}`;
}
}
class STRING extends BaseTypes.STRING {
toSql() {
if (!this._binary) {
return `NVARCHAR(${this._length})`;
}
return `BINARY(${this._length})`;
}
_stringify(value, options) {
if (this._binary) {
return BLOB.prototype._stringify(value);
}
return options.escape(value);
}
_bindParam(value, options) {
return options.bindParam(this._binary ? Buffer.from(value) : value);
}
}
STRING.prototype.escape = false;
class TEXT extends BaseTypes.TEXT {
toSql() {
if (this._length) {
if (this._length.toLowerCase() === "tiny") {
warn("MSSQL does not support TEXT with the `length` = `tiny` option. `NVARCHAR(256)` will be used instead.");
return "NVARCHAR(256)";
}
warn("MSSQL does not support TEXT with the `length` option. `NVARCHAR(MAX)` will be used instead.");
}
return "NVARCHAR(MAX)";
}
}
class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return "BIT";
}
}
class UUID extends BaseTypes.UUID {
toSql() {
return "CHAR(36)";
}
}
class NOW extends BaseTypes.NOW {
toSql() {
return "GETDATE()";
}
}
class DATE extends BaseTypes.DATE {
toSql() {
return "DATETIMEOFFSET";
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return moment(value).format("YYYY-MM-DD");
}
}
class INTEGER extends BaseTypes.INTEGER {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class TINYINT extends BaseTypes.TINYINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class SMALLINT extends BaseTypes.SMALLINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
class REAL extends BaseTypes.REAL {
constructor(length, decimals) {
super(length, decimals);
if (this._length || this.options.length || this._unsigned || this._zerofill) {
warn("MSSQL does not support REAL with options. Plain `REAL` will be used instead.");
this._length = void 0;
this.options.length = void 0;
this._unsigned = void 0;
this._zerofill = void 0;
}
}
}
class FLOAT extends BaseTypes.FLOAT {
constructor(length, decimals) {
super(length, decimals);
if (this._decimals) {
warn("MSSQL does not support Float with decimals. Plain `FLOAT` will be used instead.");
this._length = void 0;
this.options.length = void 0;
}
if (this._unsigned) {
warn("MSSQL does not support Float unsigned. `UNSIGNED` was removed.");
this._unsigned = void 0;
}
if (this._zerofill) {
warn("MSSQL does not support Float zerofill. `ZEROFILL` was removed.");
this._zerofill = void 0;
}
}
}
class ENUM extends BaseTypes.ENUM {
toSql() {
return "VARCHAR(255)";
}
}
return {
BLOB,
BOOLEAN,
ENUM,
STRING,
UUID,
DATE,
DATEONLY,
NOW,
TINYINT,
SMALLINT,
INTEGER,
BIGINT,
REAL,
FLOAT,
TEXT
};
};
//# sourceMappingURL=data-types.js.map
File diff suppressed because one or more lines are too long
+61
View File
@@ -0,0 +1,61 @@
"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").mssql;
const { MSSqlQueryInterface } = require("./query-interface");
class MssqlDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new MSSqlQueryInterface(sequelize, this.queryGenerator);
}
}
MssqlDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
DEFAULT: true,
"DEFAULT VALUES": true,
"LIMIT ON UPDATE": true,
"ORDER NULLS": false,
lock: false,
transactions: true,
migrations: false,
returnValues: {
output: true
},
schemas: true,
autoIncrement: {
identityInsert: true,
defaultValue: false,
update: false
},
constraints: {
restrict: false,
default: true
},
index: {
collate: false,
length: false,
parser: false,
type: true,
using: false,
where: true
},
NUMERIC: true,
tmpTableTrigger: true
});
MssqlDialect.prototype.defaultVersion = "12.0.2000";
MssqlDialect.prototype.Query = Query;
MssqlDialect.prototype.name = "mssql";
MssqlDialect.prototype.TICK_CHAR = '"';
MssqlDialect.prototype.TICK_CHAR_LEFT = "[";
MssqlDialect.prototype.TICK_CHAR_RIGHT = "]";
MssqlDialect.prototype.DataTypes = DataTypes;
module.exports = MssqlDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mssql/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').mssql;\nconst { MSSqlQueryInterface } = require('./query-interface');\n\nclass MssqlDialect 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 this.queryInterface = new MSSqlQueryInterface(\n sequelize,\n this.queryGenerator\n );\n }\n}\n\nMssqlDialect.prototype.supports = _.merge(\n _.cloneDeep(AbstractDialect.prototype.supports),\n {\n DEFAULT: true,\n 'DEFAULT VALUES': true,\n 'LIMIT ON UPDATE': true,\n 'ORDER NULLS': false,\n lock: false,\n transactions: true,\n migrations: false,\n returnValues: {\n output: true\n },\n schemas: true,\n autoIncrement: {\n identityInsert: true,\n defaultValue: false,\n update: false\n },\n constraints: {\n restrict: false,\n default: true\n },\n index: {\n collate: false,\n length: false,\n parser: false,\n type: true,\n using: false,\n where: true\n },\n NUMERIC: true,\n tmpTableTrigger: true\n }\n);\n\nMssqlDialect.prototype.defaultVersion = '12.0.2000'; // SQL Server 2014 Express, minimum supported version\nMssqlDialect.prototype.Query = Query;\nMssqlDialect.prototype.name = 'mssql';\nMssqlDialect.prototype.TICK_CHAR = '\"';\nMssqlDialect.prototype.TICK_CHAR_LEFT = '[';\nMssqlDialect.prototype.TICK_CHAR_RIGHT = ']';\nMssqlDialect.prototype.DataTypes = DataTypes;\n\nmodule.exports = MssqlDialect;\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,wBAAwB,QAAQ;AAExC,2BAA2B,gBAAgB;AAAA,EACzC,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,oBACxB,WACA,KAAK;AAAA;AAAA;AAKX,aAAa,UAAU,WAAW,EAAE,MAClC,EAAE,UAAU,gBAAgB,UAAU,WACtC;AAAA,EACE,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,MAAM;AAAA,EACN,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,cAAc;AAAA,IACZ,QAAQ;AAAA;AAAA,EAEV,SAAS;AAAA,EACT,eAAe;AAAA,IACb,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,QAAQ;AAAA;AAAA,EAEV,aAAa;AAAA,IACX,UAAU;AAAA,IACV,SAAS;AAAA;AAAA,EAEX,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA;AAAA,EAET,SAAS;AAAA,EACT,iBAAiB;AAAA;AAIrB,aAAa,UAAU,iBAAiB;AACxC,aAAa,UAAU,QAAQ;AAC/B,aAAa,UAAU,OAAO;AAC9B,aAAa,UAAU,YAAY;AACnC,aAAa,UAAU,iBAAiB;AACxC,aAAa,UAAU,kBAAkB;AACzC,aAAa,UAAU,YAAY;AAEnC,OAAO,UAAU;",
"names": []
}
+826
View File
@@ -0,0 +1,826 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const _ = require("lodash");
const Utils = require("../../utils");
const DataTypes = require("../../data-types");
const TableHints = require("../../table-hints");
const AbstractQueryGenerator = require("../abstract/query-generator");
const randomBytes = require("crypto").randomBytes;
const semver = require("semver");
const Op = require("../../operators");
const throwMethodUndefined = function(methodName) {
throw new Error(`The method "${methodName}" is not defined! Please add it to your sql dialect.`);
};
class MSSQLQueryGenerator extends AbstractQueryGenerator {
createDatabaseQuery(databaseName, options) {
options = __spreadValues({ collate: null }, options);
const collation = options.collate ? `COLLATE ${this.escape(options.collate)}` : "";
return [
"IF NOT EXISTS (SELECT * FROM sys.databases WHERE name =",
wrapSingleQuote(databaseName),
")",
"BEGIN",
"CREATE DATABASE",
this.quoteIdentifier(databaseName),
`${collation};`,
"END;"
].join(" ");
}
dropDatabaseQuery(databaseName) {
return [
"IF EXISTS (SELECT * FROM sys.databases WHERE name =",
wrapSingleQuote(databaseName),
")",
"BEGIN",
"DROP DATABASE",
this.quoteIdentifier(databaseName),
";",
"END;"
].join(" ");
}
createSchema(schema) {
return [
"IF NOT EXISTS (SELECT schema_name",
"FROM information_schema.schemata",
"WHERE schema_name =",
wrapSingleQuote(schema),
")",
"BEGIN",
"EXEC sp_executesql N'CREATE SCHEMA",
this.quoteIdentifier(schema),
";'",
"END;"
].join(" ");
}
dropSchema(schema) {
const quotedSchema = wrapSingleQuote(schema);
return [
"IF EXISTS (SELECT schema_name",
"FROM information_schema.schemata",
"WHERE schema_name =",
quotedSchema,
")",
"BEGIN",
"DECLARE @id INT, @ms_sql NVARCHAR(2000);",
"DECLARE @cascade TABLE (",
"id INT NOT NULL IDENTITY PRIMARY KEY,",
"ms_sql NVARCHAR(2000) NOT NULL );",
"INSERT INTO @cascade ( ms_sql )",
"SELECT CASE WHEN o.type IN ('F','PK')",
"THEN N'ALTER TABLE ['+ s.name + N'].[' + p.name + N'] DROP CONSTRAINT [' + o.name + N']'",
"ELSE N'DROP TABLE ['+ s.name + N'].[' + o.name + N']' END",
"FROM sys.objects o",
"JOIN sys.schemas s on o.schema_id = s.schema_id",
"LEFT OUTER JOIN sys.objects p on o.parent_object_id = p.object_id",
"WHERE o.type IN ('F', 'PK', 'U') AND s.name = ",
quotedSchema,
"ORDER BY o.type ASC;",
"SELECT TOP 1 @id = id, @ms_sql = ms_sql FROM @cascade ORDER BY id;",
"WHILE @id IS NOT NULL",
"BEGIN",
"BEGIN TRY EXEC sp_executesql @ms_sql; END TRY",
"BEGIN CATCH BREAK; THROW; END CATCH;",
"DELETE FROM @cascade WHERE id = @id;",
"SELECT @id = NULL, @ms_sql = NULL;",
"SELECT TOP 1 @id = id, @ms_sql = ms_sql FROM @cascade ORDER BY id;",
"END",
"EXEC sp_executesql N'DROP SCHEMA",
this.quoteIdentifier(schema),
";'",
"END;"
].join(" ");
}
showSchemasQuery() {
return [
'SELECT "name" as "schema_name" FROM sys.schemas as s',
'WHERE "s"."name" NOT IN (',
"'INFORMATION_SCHEMA', 'dbo', 'guest', 'sys', 'archive'",
")",
"AND",
'"s"."name" NOT LIKE',
"'db_%'"
].join(" ");
}
versionQuery() {
return [
"DECLARE @ms_ver NVARCHAR(20);",
"SET @ms_ver = REVERSE(CONVERT(NVARCHAR(20), SERVERPROPERTY('ProductVersion')));",
"SELECT REVERSE(SUBSTRING(@ms_ver, CHARINDEX('.', @ms_ver)+1, 20)) AS 'version'"
].join(" ");
}
createTableQuery(tableName, attributes, options) {
const primaryKeys = [], foreignKeys = {}, attributesClauseParts = [];
let commentStr = "";
for (const attr in attributes) {
if (Object.prototype.hasOwnProperty.call(attributes, attr)) {
let dataType = attributes[attr];
let match;
if (dataType.includes("COMMENT ")) {
const commentMatch = dataType.match(/^(.+) (COMMENT.*)$/);
const commentText = commentMatch[2].replace("COMMENT", "").trim();
commentStr += this.commentTemplate(commentText, tableName, attr);
dataType = commentMatch[1];
}
if (dataType.includes("PRIMARY KEY")) {
primaryKeys.push(attr);
if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attributesClauseParts.push(`${this.quoteIdentifier(attr)} ${match[1].replace("PRIMARY KEY", "")}`);
foreignKeys[attr] = match[2];
} else {
attributesClauseParts.push(`${this.quoteIdentifier(attr)} ${dataType.replace("PRIMARY KEY", "")}`);
}
} else if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attributesClauseParts.push(`${this.quoteIdentifier(attr)} ${match[1]}`);
foreignKeys[attr] = match[2];
} else {
attributesClauseParts.push(`${this.quoteIdentifier(attr)} ${dataType}`);
}
}
}
const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
if (options.uniqueKeys) {
_.each(options.uniqueKeys, (columns, indexName) => {
if (columns.customIndex) {
if (typeof indexName !== "string") {
indexName = `uniq_${tableName}_${columns.fields.join("_")}`;
}
attributesClauseParts.push(`CONSTRAINT ${this.quoteIdentifier(indexName)} UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`);
}
});
}
if (pkString.length > 0) {
attributesClauseParts.push(`PRIMARY KEY (${pkString})`);
}
for (const fkey in foreignKeys) {
if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) {
attributesClauseParts.push(`FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`);
}
}
const quotedTableName = this.quoteTable(tableName);
return Utils.joinSQLFragments([
`IF OBJECT_ID('${quotedTableName}', 'U') IS NULL`,
`CREATE TABLE ${quotedTableName} (${attributesClauseParts.join(", ")})`,
";",
commentStr
]);
}
describeTableQuery(tableName, schema) {
let sql = [
"SELECT",
"c.COLUMN_NAME AS 'Name',",
"c.DATA_TYPE AS 'Type',",
"c.CHARACTER_MAXIMUM_LENGTH AS 'Length',",
"c.IS_NULLABLE as 'IsNull',",
"COLUMN_DEFAULT AS 'Default',",
"pk.CONSTRAINT_TYPE AS 'Constraint',",
"COLUMNPROPERTY(OBJECT_ID('[' + c.TABLE_SCHEMA + '].[' + c.TABLE_NAME + ']'), c.COLUMN_NAME, 'IsIdentity') as 'IsIdentity',",
"CAST(prop.value AS NVARCHAR) AS 'Comment'",
"FROM",
"INFORMATION_SCHEMA.TABLES t",
"INNER JOIN",
"INFORMATION_SCHEMA.COLUMNS c ON t.TABLE_NAME = c.TABLE_NAME AND t.TABLE_SCHEMA = c.TABLE_SCHEMA",
"LEFT JOIN (SELECT tc.table_schema, tc.table_name, ",
"cu.column_name, tc.CONSTRAINT_TYPE ",
"FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc ",
"JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu ",
"ON tc.table_schema=cu.table_schema and tc.table_name=cu.table_name ",
"and tc.constraint_name=cu.constraint_name ",
"and tc.CONSTRAINT_TYPE='PRIMARY KEY') pk ",
"ON pk.table_schema=c.table_schema ",
"AND pk.table_name=c.table_name ",
"AND pk.column_name=c.column_name ",
"INNER JOIN sys.columns AS sc",
"ON sc.object_id = OBJECT_ID('[' + t.TABLE_SCHEMA + '].[' + t.TABLE_NAME + ']') AND sc.name = c.column_name",
"LEFT JOIN sys.extended_properties prop ON prop.major_id = sc.object_id",
"AND prop.minor_id = sc.column_id",
"AND prop.name = 'MS_Description'",
"WHERE t.TABLE_NAME =",
wrapSingleQuote(tableName)
].join(" ");
if (schema) {
sql += `AND t.TABLE_SCHEMA =${wrapSingleQuote(schema)}`;
}
return sql;
}
renameTableQuery(before, after) {
return `EXEC sp_rename ${this.quoteTable(before)}, ${this.quoteTable(after)};`;
}
showTablesQuery() {
return "SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE';";
}
tableExistsQuery(table) {
const tableName = table.tableName || table;
const schemaName = table.schema || "dbo";
return `SELECT TABLE_NAME, TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ${this.escape(tableName)} AND TABLE_SCHEMA = ${this.escape(schemaName)}`;
}
dropTableQuery(tableName) {
const quoteTbl = this.quoteTable(tableName);
return Utils.joinSQLFragments([
`IF OBJECT_ID('${quoteTbl}', 'U') IS NOT NULL`,
"DROP TABLE",
quoteTbl,
";"
]);
}
addColumnQuery(table, key, dataType) {
dataType.field = key;
let commentStr = "";
if (dataType.comment && _.isString(dataType.comment)) {
commentStr = this.commentTemplate(dataType.comment, table, key);
delete dataType["comment"];
}
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(table),
"ADD",
this.quoteIdentifier(key),
this.attributeToSQL(dataType, { context: "addColumn" }),
";",
commentStr
]);
}
commentTemplate(comment, table, column) {
return ` EXEC sp_addextendedproperty @name = N'MS_Description', @value = ${this.escape(comment)}, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = ${this.quoteIdentifier(table)}, @level2type = N'Column', @level2name = ${this.quoteIdentifier(column)};`;
}
removeColumnQuery(tableName, attributeName) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP COLUMN",
this.quoteIdentifier(attributeName),
";"
]);
}
changeColumnQuery(tableName, attributes) {
const attrString = [], constraintString = [];
let commentString = "";
for (const attributeName in attributes) {
const quotedAttrName = this.quoteIdentifier(attributeName);
let definition = attributes[attributeName];
if (definition.includes("COMMENT ")) {
const commentMatch = definition.match(/^(.+) (COMMENT.*)$/);
const commentText = commentMatch[2].replace("COMMENT", "").trim();
commentString += this.commentTemplate(commentText, tableName, attributeName);
definition = commentMatch[1];
}
if (definition.includes("REFERENCES")) {
constraintString.push(`FOREIGN KEY (${quotedAttrName}) ${definition.replace(/.+?(?=REFERENCES)/, "")}`);
} else {
attrString.push(`${quotedAttrName} ${definition}`);
}
}
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
attrString.length && `ALTER COLUMN ${attrString.join(", ")}`,
constraintString.length && `ADD ${constraintString.join(", ")}`,
";",
commentString
]);
}
renameColumnQuery(tableName, attrBefore, attributes) {
const newName = Object.keys(attributes)[0];
return Utils.joinSQLFragments([
"EXEC sp_rename",
`'${this.quoteTable(tableName)}.${attrBefore}',`,
`'${newName}',`,
"'COLUMN'",
";"
]);
}
bulkInsertQuery(tableName, attrValueHashes, options, attributes) {
const quotedTable = this.quoteTable(tableName);
options = options || {};
attributes = attributes || {};
const tuples = [];
const allAttributes = [];
const allQueries = [];
let needIdentityInsertWrapper = false, outputFragment = "";
if (options.returning) {
const returnValues = this.generateReturnValues(attributes, options);
outputFragment = returnValues.outputFragment;
}
const emptyQuery = `INSERT INTO ${quotedTable}${outputFragment} DEFAULT VALUES`;
attrValueHashes.forEach((attrValueHash) => {
const fields = Object.keys(attrValueHash);
const firstAttr = attributes[fields[0]];
if (fields.length === 1 && firstAttr && firstAttr.autoIncrement && attrValueHash[fields[0]] === null) {
allQueries.push(emptyQuery);
return;
}
_.forOwn(attrValueHash, (value, key) => {
if (value !== null && attributes[key] && attributes[key].autoIncrement) {
needIdentityInsertWrapper = true;
}
if (!allAttributes.includes(key)) {
if (value === null && attributes[key] && attributes[key].autoIncrement)
return;
allAttributes.push(key);
}
});
});
if (allAttributes.length > 0) {
attrValueHashes.forEach((attrValueHash) => {
tuples.push(`(${allAttributes.map((key) => this.escape(attrValueHash[key])).join(",")})`);
});
const quotedAttributes = allAttributes.map((attr) => this.quoteIdentifier(attr)).join(",");
allQueries.push((tupleStr) => `INSERT INTO ${quotedTable} (${quotedAttributes})${outputFragment} VALUES ${tupleStr};`);
}
const commands = [];
let offset = 0;
const batch = Math.floor(250 / (allAttributes.length + 1)) + 1;
while (offset < Math.max(tuples.length, 1)) {
const tupleStr = tuples.slice(offset, Math.min(tuples.length, offset + batch));
let generatedQuery = allQueries.map((v) => typeof v === "string" ? v : v(tupleStr)).join(";");
if (needIdentityInsertWrapper) {
generatedQuery = `SET IDENTITY_INSERT ${quotedTable} ON; ${generatedQuery}; SET IDENTITY_INSERT ${quotedTable} OFF;`;
}
commands.push(generatedQuery);
offset += batch;
}
return commands.join(";");
}
updateQuery(tableName, attrValueHash, where, options, attributes) {
const sql = super.updateQuery(tableName, attrValueHash, where, options, attributes);
if (options.limit) {
const updateArgs = `UPDATE TOP(${this.escape(options.limit)})`;
sql.query = sql.query.replace("UPDATE", updateArgs);
}
return sql;
}
upsertQuery(tableName, insertValues, updateValues, where, model) {
const targetTableAlias = this.quoteTable(`${tableName}_target`);
const sourceTableAlias = this.quoteTable(`${tableName}_source`);
const primaryKeysAttrs = [];
const identityAttrs = [];
const uniqueAttrs = [];
const tableNameQuoted = this.quoteTable(tableName);
let needIdentityInsertWrapper = false;
for (const key in model.rawAttributes) {
if (model.rawAttributes[key].primaryKey) {
primaryKeysAttrs.push(model.rawAttributes[key].field || key);
}
if (model.rawAttributes[key].unique) {
uniqueAttrs.push(model.rawAttributes[key].field || key);
}
if (model.rawAttributes[key].autoIncrement) {
identityAttrs.push(model.rawAttributes[key].field || key);
}
}
for (const index of model._indexes) {
if (index.unique && index.fields) {
for (const field of index.fields) {
const fieldName = typeof field === "string" ? field : field.name || field.attribute;
if (!uniqueAttrs.includes(fieldName) && model.rawAttributes[fieldName]) {
uniqueAttrs.push(fieldName);
}
}
}
}
const updateKeys = Object.keys(updateValues);
const insertKeys = Object.keys(insertValues);
const insertKeysQuoted = insertKeys.map((key) => this.quoteIdentifier(key)).join(", ");
const insertValuesEscaped = insertKeys.map((key) => this.escape(insertValues[key])).join(", ");
const sourceTableQuery = `VALUES(${insertValuesEscaped})`;
let joinCondition;
identityAttrs.forEach((key) => {
if (insertValues[key] && insertValues[key] !== null) {
needIdentityInsertWrapper = true;
}
});
const clauses = where[Op.or].filter((clause) => {
let valid = true;
for (const key in clause) {
if (typeof clause[key] === "undefined" || clause[key] == null) {
valid = false;
break;
}
}
return valid;
});
const getJoinSnippet = (array) => {
return array.map((key) => {
key = this.quoteIdentifier(key);
return `${targetTableAlias}.${key} = ${sourceTableAlias}.${key}`;
});
};
if (clauses.length === 0) {
throw new Error("Primary Key or Unique key should be passed to upsert query");
} else {
for (const key in clauses) {
const keys = Object.keys(clauses[key]);
if (primaryKeysAttrs.includes(keys[0])) {
joinCondition = getJoinSnippet(primaryKeysAttrs).join(" AND ");
break;
}
}
if (!joinCondition) {
joinCondition = getJoinSnippet(uniqueAttrs).join(" AND ");
}
}
const filteredUpdateClauses = updateKeys.filter((key) => !identityAttrs.includes(key)).map((key) => {
const value = this.escape(updateValues[key]);
key = this.quoteIdentifier(key);
return `${targetTableAlias}.${key} = ${value}`;
});
const updateSnippet = filteredUpdateClauses.length > 0 ? `WHEN MATCHED THEN UPDATE SET ${filteredUpdateClauses.join(", ")}` : "";
const insertSnippet = `(${insertKeysQuoted}) VALUES(${insertValuesEscaped})`;
let query = `MERGE INTO ${tableNameQuoted} WITH(HOLDLOCK) AS ${targetTableAlias} USING (${sourceTableQuery}) AS ${sourceTableAlias}(${insertKeysQuoted}) ON ${joinCondition}`;
query += ` ${updateSnippet} WHEN NOT MATCHED THEN INSERT ${insertSnippet} OUTPUT $action, INSERTED.*;`;
if (needIdentityInsertWrapper) {
query = `SET IDENTITY_INSERT ${tableNameQuoted} ON; ${query} SET IDENTITY_INSERT ${tableNameQuoted} OFF;`;
}
return query;
}
truncateTableQuery(tableName) {
return `TRUNCATE TABLE ${this.quoteTable(tableName)}`;
}
deleteQuery(tableName, where, options = {}, model) {
const table = this.quoteTable(tableName);
const whereClause = this.getWhereConditions(where, null, model, options);
return Utils.joinSQLFragments([
"DELETE",
options.limit && `TOP(${this.escape(options.limit)})`,
"FROM",
table,
whereClause && `WHERE ${whereClause}`,
";",
"SELECT @@ROWCOUNT AS AFFECTEDROWS",
";"
]);
}
showIndexesQuery(tableName) {
return `EXEC sys.sp_helpindex @objname = N'${this.quoteTable(tableName)}';`;
}
showConstraintsQuery(tableName) {
return `EXEC sp_helpconstraint @objname = ${this.escape(this.quoteTable(tableName))};`;
}
removeIndexQuery(tableName, indexNameOrAttributes) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return `DROP INDEX ${this.quoteIdentifiers(indexName)} ON ${this.quoteIdentifiers(tableName)}`;
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
if (attribute.references) {
if (attribute.Model && attribute.Model.tableName === attribute.references.model) {
this.sequelize.log("MSSQL does not support self referencial constraints, we will remove it but we recommend restructuring your query");
attribute.onDelete = "";
attribute.onUpdate = "";
}
}
let template;
if (attribute.type instanceof DataTypes.ENUM) {
if (attribute.type.values && !attribute.values)
attribute.values = attribute.type.values;
template = attribute.type.toSql();
template += ` CHECK (${this.quoteIdentifier(attribute.field)} IN(${attribute.values.map((value) => {
return this.escape(value);
}).join(", ")}))`;
return template;
}
template = attribute.type.toString();
if (attribute.allowNull === false) {
template += " NOT NULL";
} else if (!attribute.primaryKey && !Utils.defaultValueSchemable(attribute.defaultValue)) {
template += " NULL";
}
if (attribute.autoIncrement) {
template += " IDENTITY(1,1)";
}
if (attribute.type !== "TEXT" && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (attribute.unique === true) {
template += " UNIQUE";
}
if (attribute.primaryKey) {
template += " PRIMARY KEY";
}
if ((!options || !options.withoutForeignKeyConstraints) && attribute.references) {
template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
if (attribute.references.key) {
template += ` (${this.quoteIdentifier(attribute.references.key)})`;
} else {
template += ` (${this.quoteIdentifier("id")})`;
}
if (attribute.onDelete) {
template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
if (attribute.onUpdate) {
template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
}
}
if (attribute.comment && typeof attribute.comment === "string") {
template += ` COMMENT ${attribute.comment}`;
}
return template;
}
attributesToSQL(attributes, options) {
const result = {}, existingConstraints = [];
let key, attribute;
for (key in attributes) {
attribute = attributes[key];
if (attribute.references) {
if (existingConstraints.includes(attribute.references.model.toString())) {
attribute.onDelete = "";
attribute.onUpdate = "";
} else {
existingConstraints.push(attribute.references.model.toString());
attribute.onUpdate = "";
}
}
if (key && !attribute.field)
attribute.field = key;
result[attribute.field || key] = this.attributeToSQL(attribute, options);
}
return result;
}
createTrigger() {
throwMethodUndefined("createTrigger");
}
dropTrigger() {
throwMethodUndefined("dropTrigger");
}
renameTrigger() {
throwMethodUndefined("renameTrigger");
}
createFunction() {
throwMethodUndefined("createFunction");
}
dropFunction() {
throwMethodUndefined("dropFunction");
}
renameFunction() {
throwMethodUndefined("renameFunction");
}
_getForeignKeysQueryPrefix(catalogName) {
return `${"SELECT constraint_name = OBJ.NAME, constraintName = OBJ.NAME, "}${catalogName ? `constraintCatalog = '${catalogName}', ` : ""}constraintSchema = SCHEMA_NAME(OBJ.SCHEMA_ID), tableName = TB.NAME, tableSchema = SCHEMA_NAME(TB.SCHEMA_ID), ${catalogName ? `tableCatalog = '${catalogName}', ` : ""}columnName = COL.NAME, referencedTableSchema = SCHEMA_NAME(RTB.SCHEMA_ID), ${catalogName ? `referencedCatalog = '${catalogName}', ` : ""}referencedTableName = RTB.NAME, referencedColumnName = RCOL.NAME FROM sys.foreign_key_columns FKC INNER JOIN sys.objects OBJ ON OBJ.OBJECT_ID = FKC.CONSTRAINT_OBJECT_ID INNER JOIN sys.tables TB ON TB.OBJECT_ID = FKC.PARENT_OBJECT_ID INNER JOIN sys.columns COL ON COL.COLUMN_ID = PARENT_COLUMN_ID AND COL.OBJECT_ID = TB.OBJECT_ID INNER JOIN sys.tables RTB ON RTB.OBJECT_ID = FKC.REFERENCED_OBJECT_ID INNER JOIN sys.columns RCOL ON RCOL.COLUMN_ID = REFERENCED_COLUMN_ID AND RCOL.OBJECT_ID = RTB.OBJECT_ID`;
}
getForeignKeysQuery(table, catalogName) {
const tableName = table.tableName || table;
let sql = `${this._getForeignKeysQueryPrefix(catalogName)} WHERE TB.NAME =${wrapSingleQuote(tableName)}`;
if (table.schema) {
sql += ` AND SCHEMA_NAME(TB.SCHEMA_ID) =${wrapSingleQuote(table.schema)}`;
}
return sql;
}
getForeignKeyQuery(table, attributeName) {
const tableName = table.tableName || table;
return Utils.joinSQLFragments([
this._getForeignKeysQueryPrefix(),
"WHERE",
`TB.NAME =${wrapSingleQuote(tableName)}`,
"AND",
`COL.NAME =${wrapSingleQuote(attributeName)}`,
table.schema && `AND SCHEMA_NAME(TB.SCHEMA_ID) =${wrapSingleQuote(table.schema)}`
]);
}
getPrimaryKeyConstraintQuery(table, attributeName) {
const tableName = wrapSingleQuote(table.tableName || table);
return Utils.joinSQLFragments([
"SELECT K.TABLE_NAME AS tableName,",
"K.COLUMN_NAME AS columnName,",
"K.CONSTRAINT_NAME AS constraintName",
"FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C",
"JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K",
"ON C.TABLE_NAME = K.TABLE_NAME",
"AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG",
"AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA",
"AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME",
"WHERE C.CONSTRAINT_TYPE = 'PRIMARY KEY'",
`AND K.COLUMN_NAME = ${wrapSingleQuote(attributeName)}`,
`AND K.TABLE_NAME = ${tableName}`,
";"
]);
}
dropForeignKeyQuery(tableName, foreignKey) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP",
this.quoteIdentifier(foreignKey)
]);
}
getDefaultConstraintQuery(tableName, attributeName) {
const quotedTable = this.quoteTable(tableName);
return Utils.joinSQLFragments([
"SELECT name FROM sys.default_constraints",
`WHERE PARENT_OBJECT_ID = OBJECT_ID('${quotedTable}', 'U')`,
`AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = ('${attributeName}')`,
`AND object_id = OBJECT_ID('${quotedTable}', 'U'))`,
";"
]);
}
dropConstraintQuery(tableName, constraintName) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP CONSTRAINT",
this.quoteIdentifier(constraintName),
";"
]);
}
setIsolationLevelQuery() {
}
generateTransactionId() {
return randomBytes(10).toString("hex");
}
startTransactionQuery(transaction) {
if (transaction.parent) {
return `SAVE TRANSACTION ${this.quoteIdentifier(transaction.name)};`;
}
return "BEGIN TRANSACTION;";
}
commitTransactionQuery(transaction) {
if (transaction.parent) {
return;
}
return "COMMIT TRANSACTION;";
}
rollbackTransactionQuery(transaction) {
if (transaction.parent) {
return `ROLLBACK TRANSACTION ${this.quoteIdentifier(transaction.name)};`;
}
return "ROLLBACK TRANSACTION;";
}
selectFromTableFragment(options, model, attributes, tables, mainTableAs, where) {
this._throwOnEmptyAttributes(attributes, { modelName: model && model.name, as: mainTableAs });
const dbVersion = this.sequelize.options.databaseVersion;
const isSQLServer2008 = semver.valid(dbVersion) && semver.lt(dbVersion, "11.0.0");
if (isSQLServer2008 && options.offset) {
const offset = options.offset || 0;
const isSubQuery = options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation;
let orders = { mainQueryOrder: [] };
if (options.order) {
orders = this.getQueryOrders(options, model, isSubQuery);
}
if (orders.mainQueryOrder.length === 0) {
orders.mainQueryOrder.push(this.quoteIdentifier(model.primaryKeyField));
}
const tmpTable = mainTableAs || "OffsetTable";
if (options.include) {
const subQuery = options.subQuery === void 0 ? options.limit && options.hasMultiAssociation : options.subQuery;
const mainTable = {
name: mainTableAs,
quotedName: null,
as: null,
model
};
const topLevelInfo = {
names: mainTable,
options,
subQuery
};
let mainJoinQueries = [];
for (const include of options.include) {
if (include.separate) {
continue;
}
const joinQueries = this.generateInclude(include, { externalAs: mainTableAs, internalAs: mainTableAs }, topLevelInfo);
mainJoinQueries = mainJoinQueries.concat(joinQueries.mainQuery);
}
return Utils.joinSQLFragments([
"SELECT TOP 100 PERCENT",
attributes.join(", "),
"FROM (",
[
"SELECT",
options.limit && `TOP ${options.limit}`,
"* FROM (",
[
"SELECT ROW_NUMBER() OVER (",
[
"ORDER BY",
orders.mainQueryOrder.join(", ")
],
`) as row_num, ${tmpTable}.* FROM (`,
[
"SELECT DISTINCT",
`${tmpTable}.* FROM ${tables} AS ${tmpTable}`,
mainJoinQueries,
where && `WHERE ${where}`
],
`) AS ${tmpTable}`
],
`) AS ${tmpTable} WHERE row_num > ${offset}`
],
`) AS ${tmpTable}`
]);
}
return Utils.joinSQLFragments([
"SELECT TOP 100 PERCENT",
attributes.join(", "),
"FROM (",
[
"SELECT",
options.limit && `TOP ${options.limit}`,
"* FROM (",
[
"SELECT ROW_NUMBER() OVER (",
[
"ORDER BY",
orders.mainQueryOrder.join(", ")
],
`) as row_num, * FROM ${tables} AS ${tmpTable}`,
where && `WHERE ${where}`
],
`) AS ${tmpTable} WHERE row_num > ${offset}`
],
`) AS ${tmpTable}`
]);
}
return Utils.joinSQLFragments([
"SELECT",
isSQLServer2008 && options.limit && `TOP ${options.limit}`,
attributes.join(", "),
`FROM ${tables}`,
mainTableAs && `AS ${mainTableAs}`,
options.tableHint && TableHints[options.tableHint] && `WITH (${TableHints[options.tableHint]})`
]);
}
addLimitAndOffset(options, model) {
if (semver.valid(this.sequelize.options.databaseVersion) && semver.lt(this.sequelize.options.databaseVersion, "11.0.0")) {
return "";
}
const offset = options.offset || 0;
const isSubQuery = options.subQuery === void 0 ? options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation : options.subQuery;
let fragment = "";
let orders = {};
if (options.order) {
orders = this.getQueryOrders(options, model, isSubQuery);
}
if (options.limit || options.offset) {
if (!options.order || options.order.length === 0 || options.include && orders.subQueryOrder.length === 0) {
let primaryKey = model.primaryKeyField;
const tablePkFragment = `${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(primaryKey)}`;
const aliasedAttribute = (options.attributes || []).find((attr) => Array.isArray(attr) && attr[1] && (attr[0] === primaryKey || attr[1] === primaryKey));
if (aliasedAttribute) {
const modelName = this.quoteIdentifier(options.tableAs || model.name);
const alias = this._getAliasForField(modelName, aliasedAttribute[1], options);
primaryKey = new Utils.Col(alias || aliasedAttribute[1]);
}
if (!options.order || !options.order.length) {
fragment += ` ORDER BY ${tablePkFragment}`;
} else {
const orderFieldNames = (options.order || []).map((order) => {
const value = Array.isArray(order) ? order[0] : order;
if (value instanceof Utils.Col) {
return value.col;
}
if (value instanceof Utils.Literal) {
return value.val;
}
return value;
});
const primaryKeyFieldAlreadyPresent = orderFieldNames.some((fieldName) => fieldName === (primaryKey.col || primaryKey));
if (!primaryKeyFieldAlreadyPresent) {
fragment += options.order && !isSubQuery ? ", " : " ORDER BY ";
fragment += tablePkFragment;
}
}
}
if (options.offset || options.limit) {
fragment += ` OFFSET ${this.escape(offset)} ROWS`;
}
if (options.limit) {
fragment += ` FETCH NEXT ${this.escape(options.limit)} ROWS ONLY`;
}
}
return fragment;
}
booleanValue(value) {
return value ? 1 : 0;
}
quoteIdentifier(identifier, force) {
return `[${identifier.replace(/[[\]']+/g, "")}]`;
}
}
function wrapSingleQuote(identifier) {
return Utils.addTicks(Utils.removeTicks(identifier, "'"), "'");
}
module.exports = MSSQLQueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
+74
View File
@@ -0,0 +1,74 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const _ = require("lodash");
const Utils = require("../../utils");
const QueryTypes = require("../../query-types");
const Op = require("../../operators");
const { QueryInterface } = require("../abstract/query-interface");
class MSSqlQueryInterface extends QueryInterface {
async removeColumn(tableName, attributeName, options) {
options = __spreadValues({ raw: true }, options || {});
const findConstraintSql = this.queryGenerator.getDefaultConstraintQuery(tableName, attributeName);
const [results0] = await this.sequelize.query(findConstraintSql, options);
if (results0.length) {
const dropConstraintSql = this.queryGenerator.dropConstraintQuery(tableName, results0[0].name);
await this.sequelize.query(dropConstraintSql, options);
}
const findForeignKeySql = this.queryGenerator.getForeignKeyQuery(tableName, attributeName);
const [results] = await this.sequelize.query(findForeignKeySql, options);
if (results.length) {
const dropForeignKeySql = this.queryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name);
await this.sequelize.query(dropForeignKeySql, options);
}
const primaryKeyConstraintSql = this.queryGenerator.getPrimaryKeyConstraintQuery(tableName, attributeName);
const [result] = await this.sequelize.query(primaryKeyConstraintSql, options);
if (result.length) {
const dropConstraintSql = this.queryGenerator.dropConstraintQuery(tableName, result[0].constraintName);
await this.sequelize.query(dropConstraintSql, options);
}
const removeSql = this.queryGenerator.removeColumnQuery(tableName, attributeName);
return this.sequelize.query(removeSql, options);
}
async upsert(tableName, insertValues, updateValues, where, options) {
const model = options.model;
const wheres = [];
options = __spreadValues({}, options);
if (!Utils.isWhereEmpty(where)) {
wheres.push(where);
}
let indexes = Object.values(model.uniqueKeys).map((item) => item.fields);
indexes = indexes.concat(Object.values(model._indexes).filter((item) => item.unique).map((item) => item.fields));
const attributes = Object.keys(insertValues);
for (const index of indexes) {
if (_.intersection(attributes, index).length === index.length) {
where = {};
for (const field of index) {
where[field] = insertValues[field];
}
wheres.push(where);
}
}
where = { [Op.or]: wheres };
options.type = QueryTypes.UPSERT;
options.raw = true;
const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);
return await this.sequelize.query(sql, options);
}
}
exports.MSSqlQueryInterface = MSSqlQueryInterface;
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mssql/query-interface.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\n\nconst Utils = require('../../utils');\nconst QueryTypes = require('../../query-types');\nconst Op = require('../../operators');\nconst { QueryInterface } = require('../abstract/query-interface');\n\n/**\n * The interface that Sequelize uses to talk with MSSQL database\n */\nclass MSSqlQueryInterface extends QueryInterface {\n /**\n * A wrapper that fixes MSSQL's inability to cleanly remove columns from existing tables if they have a default constraint.\n *\n * @override\n */\n async removeColumn(tableName, attributeName, options) {\n options = { raw: true, ...options || {} };\n\n const findConstraintSql = this.queryGenerator.getDefaultConstraintQuery(tableName, attributeName);\n const [results0] = await this.sequelize.query(findConstraintSql, options);\n if (results0.length) {\n // No default constraint found -- we can cleanly remove the column\n const dropConstraintSql = this.queryGenerator.dropConstraintQuery(tableName, results0[0].name);\n await this.sequelize.query(dropConstraintSql, options);\n }\n const findForeignKeySql = this.queryGenerator.getForeignKeyQuery(tableName, attributeName);\n const [results] = await this.sequelize.query(findForeignKeySql, options);\n if (results.length) {\n // No foreign key constraints found, so we can remove the column\n const dropForeignKeySql = this.queryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name);\n await this.sequelize.query(dropForeignKeySql, options);\n }\n //Check if the current column is a primaryKey\n const primaryKeyConstraintSql = this.queryGenerator.getPrimaryKeyConstraintQuery(tableName, attributeName);\n const [result] = await this.sequelize.query(primaryKeyConstraintSql, options);\n if (result.length) {\n const dropConstraintSql = this.queryGenerator.dropConstraintQuery(tableName, result[0].constraintName);\n await this.sequelize.query(dropConstraintSql, options);\n }\n const removeSql = this.queryGenerator.removeColumnQuery(tableName, attributeName);\n return this.sequelize.query(removeSql, options);\n }\n\n /**\n * @override\n */\n async upsert(tableName, insertValues, updateValues, where, options) {\n const model = options.model;\n const wheres = [];\n\n options = { ...options };\n\n if (!Utils.isWhereEmpty(where)) {\n wheres.push(where);\n }\n\n // Lets combine unique keys and indexes into one\n let indexes = Object.values(model.uniqueKeys).map(item => item.fields);\n indexes = indexes.concat(Object.values(model._indexes).filter(item => item.unique).map(item => item.fields));\n\n const attributes = Object.keys(insertValues);\n for (const index of indexes) {\n if (_.intersection(attributes, index).length === index.length) {\n where = {};\n for (const field of index) {\n where[field] = insertValues[field];\n }\n wheres.push(where);\n }\n }\n\n where = { [Op.or]: wheres };\n\n options.type = QueryTypes.UPSERT;\n options.raw = true;\n\n const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);\n return await this.sequelize.query(sql, options);\n }\n}\n\nexports.MSSqlQueryInterface = MSSqlQueryInterface;\n"],
"mappings": ";;;;;;;;;;;;;;;;;AAEA,MAAM,IAAI,QAAQ;AAElB,MAAM,QAAQ,QAAQ;AACtB,MAAM,aAAa,QAAQ;AAC3B,MAAM,KAAK,QAAQ;AACnB,MAAM,EAAE,mBAAmB,QAAQ;AAKnC,kCAAkC,eAAe;AAAA,QAMzC,aAAa,WAAW,eAAe,SAAS;AACpD,cAAU,iBAAE,KAAK,QAAS,WAAW;AAErC,UAAM,oBAAoB,KAAK,eAAe,0BAA0B,WAAW;AACnF,UAAM,CAAC,YAAY,MAAM,KAAK,UAAU,MAAM,mBAAmB;AACjE,QAAI,SAAS,QAAQ;AAEnB,YAAM,oBAAoB,KAAK,eAAe,oBAAoB,WAAW,SAAS,GAAG;AACzF,YAAM,KAAK,UAAU,MAAM,mBAAmB;AAAA;AAEhD,UAAM,oBAAoB,KAAK,eAAe,mBAAmB,WAAW;AAC5E,UAAM,CAAC,WAAW,MAAM,KAAK,UAAU,MAAM,mBAAmB;AAChE,QAAI,QAAQ,QAAQ;AAElB,YAAM,oBAAoB,KAAK,eAAe,oBAAoB,WAAW,QAAQ,GAAG;AACxF,YAAM,KAAK,UAAU,MAAM,mBAAmB;AAAA;AAGhD,UAAM,0BAA0B,KAAK,eAAe,6BAA6B,WAAW;AAC5F,UAAM,CAAC,UAAU,MAAM,KAAK,UAAU,MAAM,yBAAyB;AACrE,QAAI,OAAO,QAAQ;AACjB,YAAM,oBAAoB,KAAK,eAAe,oBAAoB,WAAW,OAAO,GAAG;AACvF,YAAM,KAAK,UAAU,MAAM,mBAAmB;AAAA;AAEhD,UAAM,YAAY,KAAK,eAAe,kBAAkB,WAAW;AACnE,WAAO,KAAK,UAAU,MAAM,WAAW;AAAA;AAAA,QAMnC,OAAO,WAAW,cAAc,cAAc,OAAO,SAAS;AAClE,UAAM,QAAQ,QAAQ;AACtB,UAAM,SAAS;AAEf,cAAU,mBAAK;AAEf,QAAI,CAAC,MAAM,aAAa,QAAQ;AAC9B,aAAO,KAAK;AAAA;AAId,QAAI,UAAU,OAAO,OAAO,MAAM,YAAY,IAAI,UAAQ,KAAK;AAC/D,cAAU,QAAQ,OAAO,OAAO,OAAO,MAAM,UAAU,OAAO,UAAQ,KAAK,QAAQ,IAAI,UAAQ,KAAK;AAEpG,UAAM,aAAa,OAAO,KAAK;AAC/B,eAAW,SAAS,SAAS;AAC3B,UAAI,EAAE,aAAa,YAAY,OAAO,WAAW,MAAM,QAAQ;AAC7D,gBAAQ;AACR,mBAAW,SAAS,OAAO;AACzB,gBAAM,SAAS,aAAa;AAAA;AAE9B,eAAO,KAAK;AAAA;AAAA;AAIhB,YAAQ,GAAG,GAAG,KAAK;AAEnB,YAAQ,OAAO,WAAW;AAC1B,YAAQ,MAAM;AAEd,UAAM,MAAM,KAAK,eAAe,YAAY,WAAW,cAAc,cAAc,OAAO,OAAO;AACjG,WAAO,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA;AAAA;AAI3C,QAAQ,sBAAsB;",
"names": []
}
+330
View File
@@ -0,0 +1,330 @@
"use strict";
const AbstractQuery = require("../abstract/query");
const sequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("mssql");
const _ = require("lodash");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("sql:mssql");
const minSafeIntegerAsBigInt = BigInt(Number.MIN_SAFE_INTEGER);
const maxSafeIntegerAsBigInt = BigInt(Number.MAX_SAFE_INTEGER);
function getScale(aNum) {
if (!Number.isFinite(aNum))
return 0;
let e = 1;
while (Math.round(aNum * e) / e !== aNum)
e *= 10;
return Math.log10(e);
}
class Query extends AbstractQuery {
getInsertIdField() {
return "id";
}
getSQLTypeFromJsType(value, TYPES) {
const paramType = { type: TYPES.NVarChar, typeOptions: {}, value };
if (typeof value === "number") {
if (Number.isInteger(value)) {
if (value >= -2147483648 && value <= 2147483647) {
paramType.type = TYPES.Int;
} else {
paramType.type = TYPES.BigInt;
}
} else {
paramType.type = TYPES.Numeric;
paramType.typeOptions = { precision: 30, scale: getScale(value) };
}
} else if (typeof value === "bigint") {
if (value < minSafeIntegerAsBigInt || value > maxSafeIntegerAsBigInt) {
paramType.type = TYPES.VarChar;
paramType.value = value.toString();
} else {
return this.getSQLTypeFromJsType(Number(value), TYPES);
}
} else if (typeof value === "boolean") {
paramType.type = TYPES.Bit;
}
if (Buffer.isBuffer(value)) {
paramType.type = TYPES.VarBinary;
}
return paramType;
}
async _run(connection, sql, parameters, errStack) {
this.sql = sql;
const { options } = this;
const complete = this._logQuery(sql, debug, parameters);
const query = new Promise((resolve, reject) => {
if (sql.startsWith("BEGIN TRANSACTION")) {
return connection.beginTransaction((error) => error ? reject(error) : resolve([]), options.transaction.name, connection.lib.ISOLATION_LEVEL[options.isolationLevel]);
}
if (sql.startsWith("COMMIT TRANSACTION")) {
return connection.commitTransaction((error) => error ? reject(error) : resolve([]));
}
if (sql.startsWith("ROLLBACK TRANSACTION")) {
return connection.rollbackTransaction((error) => error ? reject(error) : resolve([]), options.transaction.name);
}
if (sql.startsWith("SAVE TRANSACTION")) {
return connection.saveTransaction((error) => error ? reject(error) : resolve([]), options.transaction.name);
}
const rows2 = [];
const request = new connection.lib.Request(sql, (err, rowCount2) => err ? reject(err) : resolve([rows2, rowCount2]));
if (parameters) {
_.forOwn(parameters, (value, key) => {
const paramType = this.getSQLTypeFromJsType(value, connection.lib.TYPES);
request.addParameter(key, paramType.type, value, paramType.typeOptions);
});
}
request.on("row", (columns) => {
rows2.push(columns);
});
connection.execSql(request);
});
let rows, rowCount;
try {
[rows, rowCount] = await query;
} catch (err) {
err.sql = sql;
err.parameters = parameters;
throw this.formatError(err, errStack);
}
complete();
if (Array.isArray(rows)) {
rows = rows.map((columns) => {
const row = {};
for (const column of columns) {
const typeid = column.metadata.type.id;
const parse = parserStore.get(typeid);
let value = column.value;
if (value !== null & !!parse) {
value = parse(value);
}
row[column.metadata.colName] = value;
}
return row;
});
}
return this.formatResults(rows, rowCount);
}
run(sql, parameters) {
const errForStack = new Error();
return this.connection.queue.enqueue(() => this._run(this.connection, sql, parameters, errForStack.stack));
}
static formatBindParameters(sql, values, dialect) {
const bindParam = {};
const replacementFunc = (match, key, values2) => {
if (values2[key] !== void 0) {
bindParam[key] = values2[key];
return `@${key}`;
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
return [sql, bindParam];
}
formatResults(data, rowCount) {
if (this.isInsertQuery(data)) {
this.handleInsertQuery(data);
return [this.instance || data, rowCount];
}
if (this.isShowTablesQuery()) {
return this.handleShowTablesQuery(data);
}
if (this.isDescribeQuery()) {
const result = {};
for (const _result of data) {
if (_result.Default) {
_result.Default = _result.Default.replace("('", "").replace("')", "").replace(/'/g, "");
}
result[_result.Name] = {
type: _result.Type.toUpperCase(),
allowNull: _result.IsNull === "YES" ? true : false,
defaultValue: _result.Default,
primaryKey: _result.Constraint === "PRIMARY KEY",
autoIncrement: _result.IsIdentity === 1,
comment: _result.Comment
};
if (result[_result.Name].type.includes("CHAR") && _result.Length) {
if (_result.Length === -1) {
result[_result.Name].type += "(MAX)";
} else {
result[_result.Name].type += `(${_result.Length})`;
}
}
}
return result;
}
if (this.isSelectQuery()) {
return this.handleSelectQuery(data);
}
if (this.isShowIndexesQuery()) {
return this.handleShowIndexesQuery(data);
}
if (this.isCallQuery()) {
return data[0];
}
if (this.isBulkUpdateQuery()) {
if (this.options.returning) {
return this.handleSelectQuery(data);
}
return rowCount;
}
if (this.isBulkDeleteQuery()) {
return data[0] ? data[0].AFFECTEDROWS : 0;
}
if (this.isVersionQuery()) {
return data[0].version;
}
if (this.isForeignKeysQuery()) {
return data;
}
if (this.isUpsertQuery()) {
if (data && data.length === 0) {
return [this.instance || data, false];
}
this.handleInsertQuery(data);
return [this.instance || data, data[0].$action === "INSERT"];
}
if (this.isUpdateQuery()) {
return [this.instance || data, rowCount];
}
if (this.isShowConstraintsQuery()) {
return this.handleShowConstraintsQuery(data);
}
if (this.isRawQuery()) {
return [data, rowCount];
}
return data;
}
handleShowTablesQuery(results) {
return results.map((resultSet) => {
return {
tableName: resultSet.TABLE_NAME,
schema: resultSet.TABLE_SCHEMA
};
});
}
handleShowConstraintsQuery(data) {
return data.slice(1).map((result) => {
const constraint = {};
for (const key in result) {
constraint[_.camelCase(key)] = result[key];
}
return constraint;
});
}
formatError(err, errStack) {
let match;
match = err.message.match(/Violation of (?:UNIQUE|PRIMARY) KEY constraint '([^']*)'. Cannot insert duplicate key in object '.*'.(:? The duplicate key value is \((.*)\).)?/);
match = match || err.message.match(/Cannot insert duplicate key row in object .* with unique index '(.*)'/);
if (match && match.length > 1) {
let fields = {};
const uniqueKey = this.model && this.model.uniqueKeys[match[1]];
let message = "Validation error";
if (uniqueKey && !!uniqueKey.msg) {
message = uniqueKey.msg;
}
if (match[3]) {
const values = match[3].split(",").map((part) => part.trim());
if (uniqueKey) {
fields = _.zipObject(uniqueKey.fields, values);
} else {
fields[match[1]] = match[3];
}
}
const errors = [];
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
match = err.message.match(/Failed on step '(.*)'.Could not create constraint. See previous errors./) || err.message.match(/The DELETE statement conflicted with the REFERENCE constraint "(.*)". The conflict occurred in database "(.*)", table "(.*)", column '(.*)'./) || err.message.match(/The (?:INSERT|MERGE|UPDATE) statement conflicted with the FOREIGN KEY constraint "(.*)". The conflict occurred in database "(.*)", table "(.*)", column '(.*)'./);
if (match && match.length > 0) {
return new sequelizeErrors.ForeignKeyConstraintError({
fields: null,
index: match[1],
parent: err,
stack: errStack
});
}
match = err.message.match(/Could not drop constraint. See previous errors./);
if (match && match.length > 0) {
let constraint = err.sql.match(/(?:constraint|index) \[(.+?)\]/i);
constraint = constraint ? constraint[1] : void 0;
let table = err.sql.match(/table \[(.+?)\]/i);
table = table ? table[1] : void 0;
return new sequelizeErrors.UnknownConstraintError({
message: match[1],
constraint,
table,
parent: err,
stack: errStack
});
}
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
isShowOrDescribeQuery() {
let result = false;
result = result || this.sql.toLowerCase().startsWith("select c.column_name as 'name', c.data_type as 'type', c.is_nullable as 'isnull'");
result = result || this.sql.toLowerCase().startsWith("select tablename = t.name, name = ind.name,");
result = result || this.sql.toLowerCase().startsWith("exec sys.sp_helpindex @objname");
return result;
}
isShowIndexesQuery() {
return this.sql.toLowerCase().startsWith("exec sys.sp_helpindex @objname");
}
handleShowIndexesQuery(data) {
data = data.reduce((acc, item) => {
if (!(item.index_name in acc)) {
acc[item.index_name] = item;
item.fields = [];
}
item.index_keys.split(",").forEach((column) => {
let columnName = column.trim();
if (columnName.includes("(-)")) {
columnName = columnName.replace("(-)", "");
}
acc[item.index_name].fields.push({
attribute: columnName,
length: void 0,
order: column.includes("(-)") ? "DESC" : "ASC",
collate: void 0
});
});
delete item.index_keys;
return acc;
}, {});
return _.map(data, (item) => ({
primary: item.index_name.toLowerCase().startsWith("pk"),
fields: item.fields,
name: item.index_name,
tableName: void 0,
unique: item.index_description.toLowerCase().includes("unique"),
type: void 0
}));
}
handleInsertQuery(results, metaData) {
if (this.instance) {
const autoIncrementAttribute = this.model.autoIncrementAttribute;
let id = null;
let autoIncrementAttributeAlias = null;
if (Object.prototype.hasOwnProperty.call(this.model.rawAttributes, autoIncrementAttribute) && this.model.rawAttributes[autoIncrementAttribute].field !== void 0)
autoIncrementAttributeAlias = this.model.rawAttributes[autoIncrementAttribute].field;
id = id || results && results[0][this.getInsertIdField()];
id = id || metaData && metaData[this.getInsertIdField()];
id = id || results && results[0][autoIncrementAttribute];
id = id || autoIncrementAttributeAlias && results && results[0][autoIncrementAttributeAlias];
this.instance[autoIncrementAttribute] = id;
if (this.instance.dataValues) {
for (const key in results[0]) {
if (Object.prototype.hasOwnProperty.call(results[0], key)) {
const record = results[0][key];
const attr = _.find(this.model.rawAttributes, (attribute) => attribute.fieldName === key || attribute.field === key);
this.instance.dataValues[attr && attr.fieldName || key] = record;
}
}
}
}
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
+120
View File
@@ -0,0 +1,120 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const AbstractConnectionManager = require("../abstract/connection-manager");
const SequelizeErrors = require("../../errors");
const { logger } = require("../../utils/logger");
const DataTypes = require("../../data-types").mysql;
const momentTz = require("moment-timezone");
const debug = logger.debugContext("connection:mysql");
const parserStore = require("../parserStore")("mysql");
const { promisify } = require("util");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 3306;
super(dialect, sequelize);
this.lib = this._loadDialectModule("mysql2");
this.refreshTypeParser(DataTypes);
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
static _typecast(field, next) {
if (parserStore.get(field.type)) {
return parserStore.get(field.type)(field, this.sequelize.options, next);
}
return next();
}
async connect(config) {
const connectionConfig = __spreadValues({
host: config.host,
port: config.port,
user: config.username,
flags: "-FOUND_ROWS",
password: config.password,
database: config.database,
timezone: this.sequelize.options.timezone,
typeCast: ConnectionManager._typecast.bind(this),
bigNumberStrings: false,
supportBigNumbers: true
}, config.dialectOptions);
try {
const connection = await new Promise((resolve, reject) => {
const connection2 = this.lib.createConnection(connectionConfig);
const errorHandler = (e) => {
connection2.removeListener("connect", connectHandler);
connection2.removeListener("error", connectHandler);
reject(e);
};
const connectHandler = () => {
connection2.removeListener("error", errorHandler);
resolve(connection2);
};
connection2.on("error", errorHandler);
connection2.once("connect", connectHandler);
});
debug("connection acquired");
connection.on("error", (error) => {
switch (error.code) {
case "ESOCKET":
case "ECONNRESET":
case "EPIPE":
case "PROTOCOL_CONNECTION_LOST":
this.pool.destroy(connection);
}
});
if (!this.sequelize.config.keepDefaultTimezone) {
let tzOffset = this.sequelize.options.timezone;
tzOffset = /\//.test(tzOffset) ? momentTz.tz(tzOffset).format("Z") : tzOffset;
await promisify((cb) => connection.query(`SET time_zone = '${tzOffset}'`, cb))();
}
return connection;
} catch (err) {
switch (err.code) {
case "ECONNREFUSED":
throw new SequelizeErrors.ConnectionRefusedError(err);
case "ER_ACCESS_DENIED_ERROR":
throw new SequelizeErrors.AccessDeniedError(err);
case "ENOTFOUND":
throw new SequelizeErrors.HostNotFoundError(err);
case "EHOSTUNREACH":
throw new SequelizeErrors.HostNotReachableError(err);
case "EINVAL":
throw new SequelizeErrors.InvalidConnectionError(err);
default:
throw new SequelizeErrors.ConnectionError(err);
}
}
}
async disconnect(connection) {
if (connection._closing) {
debug("connection tried to disconnect but was already at CLOSED state");
return;
}
return await promisify((callback) => connection.end(callback))();
}
validate(connection) {
return connection && !connection._fatalError && !connection._protocolError && !connection._closing && !connection.stream.destroyed;
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
File diff suppressed because one or more lines are too long
+123
View File
@@ -0,0 +1,123 @@
"use strict";
const wkx = require("wkx");
const _ = require("lodash");
const momentTz = require("moment-timezone");
const moment = require("moment");
module.exports = (BaseTypes) => {
BaseTypes.ABSTRACT.prototype.dialectTypes = "https://dev.mysql.com/doc/refman/5.7/en/data-types.html";
BaseTypes.DATE.types.mysql = ["DATETIME"];
BaseTypes.STRING.types.mysql = ["VAR_STRING"];
BaseTypes.CHAR.types.mysql = ["STRING"];
BaseTypes.TEXT.types.mysql = ["BLOB"];
BaseTypes.TINYINT.types.mysql = ["TINY"];
BaseTypes.SMALLINT.types.mysql = ["SHORT"];
BaseTypes.MEDIUMINT.types.mysql = ["INT24"];
BaseTypes.INTEGER.types.mysql = ["LONG"];
BaseTypes.BIGINT.types.mysql = ["LONGLONG"];
BaseTypes.FLOAT.types.mysql = ["FLOAT"];
BaseTypes.TIME.types.mysql = ["TIME"];
BaseTypes.DATEONLY.types.mysql = ["DATE"];
BaseTypes.BOOLEAN.types.mysql = ["TINY"];
BaseTypes.BLOB.types.mysql = ["TINYBLOB", "BLOB", "LONGBLOB"];
BaseTypes.DECIMAL.types.mysql = ["NEWDECIMAL"];
BaseTypes.UUID.types.mysql = false;
BaseTypes.ENUM.types.mysql = false;
BaseTypes.REAL.types.mysql = ["DOUBLE"];
BaseTypes.DOUBLE.types.mysql = ["DOUBLE"];
BaseTypes.GEOMETRY.types.mysql = ["GEOMETRY"];
BaseTypes.JSON.types.mysql = ["JSON"];
class DECIMAL extends BaseTypes.DECIMAL {
toSql() {
let definition = super.toSql();
if (this._unsigned) {
definition += " UNSIGNED";
}
if (this._zerofill) {
definition += " ZEROFILL";
}
return definition;
}
}
class DATE extends BaseTypes.DATE {
toSql() {
return this._length ? `DATETIME(${this._length})` : "DATETIME";
}
_stringify(date, options) {
if (!moment.isMoment(date)) {
date = this._applyTimezone(date, options);
}
if (this._length) {
return date.format("YYYY-MM-DD HH:mm:ss.SSS");
}
return date.format("YYYY-MM-DD HH:mm:ss");
}
static parse(value, options) {
value = value.string();
if (value === null) {
return value;
}
if (momentTz.tz.zone(options.timezone)) {
value = momentTz.tz(value, options.timezone).toDate();
} else {
value = new Date(`${value} ${options.timezone}`);
}
return value;
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return value.string();
}
}
class UUID extends BaseTypes.UUID {
toSql() {
return "CHAR(36) BINARY";
}
}
const SUPPORTED_GEOMETRY_TYPES = ["POINT", "LINESTRING", "POLYGON"];
class GEOMETRY extends BaseTypes.GEOMETRY {
constructor(type, srid) {
super(type, srid);
if (_.isEmpty(this.type)) {
this.sqlType = this.key;
return;
}
if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) {
this.sqlType = this.type;
return;
}
throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(", ")}`);
}
static parse(value) {
value = value.buffer();
if (!value || value.length === 0) {
return null;
}
value = value.slice(4);
return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });
}
toSql() {
return this.sqlType;
}
}
class ENUM extends BaseTypes.ENUM {
toSql(options) {
return `ENUM(${this.values.map((value) => options.escape(value)).join(", ")})`;
}
}
class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
return options.operation === "where" && typeof value === "string" ? value : JSON.stringify(value);
}
}
return {
ENUM,
DATE,
DATEONLY,
UUID,
GEOMETRY,
DECIMAL,
JSON: JSONTYPE
};
};
//# sourceMappingURL=data-types.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mysql/data-types.js"],
"sourcesContent": ["'use strict';\n\nconst wkx = require('wkx');\nconst _ = require('lodash');\nconst momentTz = require('moment-timezone');\nconst moment = require('moment');\n\nmodule.exports = BaseTypes => {\n BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://dev.mysql.com/doc/refman/5.7/en/data-types.html';\n\n /**\n * types: [buffer_type, ...]\n *\n * @see buffer_type here https://dev.mysql.com/doc/refman/5.7/en/c-api-prepared-statement-type-codes.html\n * @see hex here https://github.com/sidorares/node-mysql2/blob/master/lib/constants/types.js\n */\n\n BaseTypes.DATE.types.mysql = ['DATETIME'];\n BaseTypes.STRING.types.mysql = ['VAR_STRING'];\n BaseTypes.CHAR.types.mysql = ['STRING'];\n BaseTypes.TEXT.types.mysql = ['BLOB'];\n BaseTypes.TINYINT.types.mysql = ['TINY'];\n BaseTypes.SMALLINT.types.mysql = ['SHORT'];\n BaseTypes.MEDIUMINT.types.mysql = ['INT24'];\n BaseTypes.INTEGER.types.mysql = ['LONG'];\n BaseTypes.BIGINT.types.mysql = ['LONGLONG'];\n BaseTypes.FLOAT.types.mysql = ['FLOAT'];\n BaseTypes.TIME.types.mysql = ['TIME'];\n BaseTypes.DATEONLY.types.mysql = ['DATE'];\n BaseTypes.BOOLEAN.types.mysql = ['TINY'];\n BaseTypes.BLOB.types.mysql = ['TINYBLOB', 'BLOB', 'LONGBLOB'];\n BaseTypes.DECIMAL.types.mysql = ['NEWDECIMAL'];\n BaseTypes.UUID.types.mysql = false;\n BaseTypes.ENUM.types.mysql = false;\n BaseTypes.REAL.types.mysql = ['DOUBLE'];\n BaseTypes.DOUBLE.types.mysql = ['DOUBLE'];\n BaseTypes.GEOMETRY.types.mysql = ['GEOMETRY'];\n BaseTypes.JSON.types.mysql = ['JSON'];\n\n class DECIMAL extends BaseTypes.DECIMAL {\n toSql() {\n let definition = super.toSql();\n if (this._unsigned) {\n definition += ' UNSIGNED';\n }\n if (this._zerofill) {\n definition += ' ZEROFILL';\n }\n return definition;\n }\n }\n\n class DATE extends BaseTypes.DATE {\n toSql() {\n return this._length ? `DATETIME(${this._length})` : 'DATETIME';\n }\n _stringify(date, options) {\n if (!moment.isMoment(date)) {\n date = this._applyTimezone(date, options);\n }\n // Fractional DATETIMEs only supported on MySQL 5.6.4+\n if (this._length) {\n return date.format('YYYY-MM-DD HH:mm:ss.SSS');\n }\n return date.format('YYYY-MM-DD HH:mm:ss');\n }\n static parse(value, options) {\n value = value.string();\n if (value === null) {\n return value;\n }\n if (momentTz.tz.zone(options.timezone)) {\n value = momentTz.tz(value, options.timezone).toDate();\n }\n else {\n value = new Date(`${value} ${options.timezone}`);\n }\n return value;\n }\n }\n\n class DATEONLY extends BaseTypes.DATEONLY {\n static parse(value) {\n return value.string();\n }\n }\n class UUID extends BaseTypes.UUID {\n toSql() {\n return 'CHAR(36) BINARY';\n }\n }\n\n const SUPPORTED_GEOMETRY_TYPES = ['POINT', 'LINESTRING', 'POLYGON'];\n\n class GEOMETRY extends BaseTypes.GEOMETRY {\n constructor(type, srid) {\n super(type, srid);\n if (_.isEmpty(this.type)) {\n this.sqlType = this.key;\n return;\n }\n if (SUPPORTED_GEOMETRY_TYPES.includes(this.type)) {\n this.sqlType = this.type;\n return;\n }\n throw new Error(`Supported geometry types are: ${SUPPORTED_GEOMETRY_TYPES.join(', ')}`);\n }\n static parse(value) {\n value = value.buffer();\n // Empty buffer, MySQL doesn't support POINT EMPTY\n // check, https://dev.mysql.com/worklog/task/?id=2381\n if (!value || value.length === 0) {\n return null;\n }\n // For some reason, discard the first 4 bytes\n value = value.slice(4);\n return wkx.Geometry.parse(value).toGeoJSON({ shortCrs: true });\n }\n toSql() {\n return this.sqlType;\n }\n }\n\n class ENUM extends BaseTypes.ENUM {\n toSql(options) {\n return `ENUM(${this.values.map(value => options.escape(value)).join(', ')})`;\n }\n }\n\n class JSONTYPE extends BaseTypes.JSON {\n _stringify(value, options) {\n return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value);\n }\n }\n\n return {\n ENUM,\n DATE,\n DATEONLY,\n UUID,\n GEOMETRY,\n DECIMAL,\n JSON: JSONTYPE\n };\n};\n"],
"mappings": ";AAEA,MAAM,MAAM,QAAQ;AACpB,MAAM,IAAI,QAAQ;AAClB,MAAM,WAAW,QAAQ;AACzB,MAAM,SAAS,QAAQ;AAEvB,OAAO,UAAU,eAAa;AAC5B,YAAU,SAAS,UAAU,eAAe;AAS5C,YAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,YAAU,OAAO,MAAM,QAAQ,CAAC;AAChC,YAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,YAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,YAAU,QAAQ,MAAM,QAAQ,CAAC;AACjC,YAAU,SAAS,MAAM,QAAQ,CAAC;AAClC,YAAU,UAAU,MAAM,QAAQ,CAAC;AACnC,YAAU,QAAQ,MAAM,QAAQ,CAAC;AACjC,YAAU,OAAO,MAAM,QAAQ,CAAC;AAChC,YAAU,MAAM,MAAM,QAAQ,CAAC;AAC/B,YAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,YAAU,SAAS,MAAM,QAAQ,CAAC;AAClC,YAAU,QAAQ,MAAM,QAAQ,CAAC;AACjC,YAAU,KAAK,MAAM,QAAQ,CAAC,YAAY,QAAQ;AAClD,YAAU,QAAQ,MAAM,QAAQ,CAAC;AACjC,YAAU,KAAK,MAAM,QAAQ;AAC7B,YAAU,KAAK,MAAM,QAAQ;AAC7B,YAAU,KAAK,MAAM,QAAQ,CAAC;AAC9B,YAAU,OAAO,MAAM,QAAQ,CAAC;AAChC,YAAU,SAAS,MAAM,QAAQ,CAAC;AAClC,YAAU,KAAK,MAAM,QAAQ,CAAC;AAE9B,wBAAsB,UAAU,QAAQ;AAAA,IACtC,QAAQ;AACN,UAAI,aAAa,MAAM;AACvB,UAAI,KAAK,WAAW;AAClB,sBAAc;AAAA;AAEhB,UAAI,KAAK,WAAW;AAClB,sBAAc;AAAA;AAEhB,aAAO;AAAA;AAAA;AAIX,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO,KAAK,UAAU,YAAY,KAAK,aAAa;AAAA;AAAA,IAEtD,WAAW,MAAM,SAAS;AACxB,UAAI,CAAC,OAAO,SAAS,OAAO;AAC1B,eAAO,KAAK,eAAe,MAAM;AAAA;AAGnC,UAAI,KAAK,SAAS;AAChB,eAAO,KAAK,OAAO;AAAA;AAErB,aAAO,KAAK,OAAO;AAAA;AAAA,WAEd,MAAM,OAAO,SAAS;AAC3B,cAAQ,MAAM;AACd,UAAI,UAAU,MAAM;AAClB,eAAO;AAAA;AAET,UAAI,SAAS,GAAG,KAAK,QAAQ,WAAW;AACtC,gBAAQ,SAAS,GAAG,OAAO,QAAQ,UAAU;AAAA,aAE1C;AACH,gBAAQ,IAAI,KAAK,GAAG,SAAS,QAAQ;AAAA;AAEvC,aAAO;AAAA;AAAA;AAIX,yBAAuB,UAAU,SAAS;AAAA,WACjC,MAAM,OAAO;AAClB,aAAO,MAAM;AAAA;AAAA;AAGjB,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA;AAAA;AAIX,QAAM,2BAA2B,CAAC,SAAS,cAAc;AAEzD,yBAAuB,UAAU,SAAS;AAAA,IACxC,YAAY,MAAM,MAAM;AACtB,YAAM,MAAM;AACZ,UAAI,EAAE,QAAQ,KAAK,OAAO;AACxB,aAAK,UAAU,KAAK;AACpB;AAAA;AAEF,UAAI,yBAAyB,SAAS,KAAK,OAAO;AAChD,aAAK,UAAU,KAAK;AACpB;AAAA;AAEF,YAAM,IAAI,MAAM,iCAAiC,yBAAyB,KAAK;AAAA;AAAA,WAE1E,MAAM,OAAO;AAClB,cAAQ,MAAM;AAGd,UAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,eAAO;AAAA;AAGT,cAAQ,MAAM,MAAM;AACpB,aAAO,IAAI,SAAS,MAAM,OAAO,UAAU,EAAE,UAAU;AAAA;AAAA,IAEzD,QAAQ;AACN,aAAO,KAAK;AAAA;AAAA;AAIhB,qBAAmB,UAAU,KAAK;AAAA,IAChC,MAAM,SAAS;AACb,aAAO,QAAQ,KAAK,OAAO,IAAI,WAAS,QAAQ,OAAO,QAAQ,KAAK;AAAA;AAAA;AAIxE,yBAAuB,UAAU,KAAK;AAAA,IACpC,WAAW,OAAO,SAAS;AACzB,aAAO,QAAQ,cAAc,WAAW,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU;AAAA;AAAA;AAI/F,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA;AAAA;",
"names": []
}
+61
View File
@@ -0,0 +1,61 @@
"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").mysql;
const { MySQLQueryInterface } = require("./query-interface");
class MysqlDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new MySQLQueryInterface(sequelize, this.queryGenerator);
}
canBackslashEscape() {
return true;
}
}
MysqlDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"VALUES ()": true,
"LIMIT ON UPDATE": true,
lock: true,
forShare: "LOCK IN SHARE MODE",
settingIsolationLevelDuringTransaction: false,
inserts: {
ignoreDuplicates: " IGNORE",
updateOnDuplicate: " ON DUPLICATE KEY UPDATE"
},
index: {
collate: false,
length: true,
parser: true,
type: true,
using: 1
},
constraints: {
dropConstraint: false,
check: false
},
indexViaAlter: true,
indexHints: true,
NUMERIC: true,
GEOMETRY: true,
JSON: true,
REGEXP: true
});
MysqlDialect.prototype.defaultVersion = "5.7.0";
MysqlDialect.prototype.Query = Query;
MysqlDialect.prototype.QueryGenerator = QueryGenerator;
MysqlDialect.prototype.DataTypes = DataTypes;
MysqlDialect.prototype.name = "mysql";
MysqlDialect.prototype.TICK_CHAR = "`";
MysqlDialect.prototype.TICK_CHAR_LEFT = MysqlDialect.prototype.TICK_CHAR;
MysqlDialect.prototype.TICK_CHAR_RIGHT = MysqlDialect.prototype.TICK_CHAR;
module.exports = MysqlDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mysql/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').mysql;\nconst { MySQLQueryInterface } = require('./query-interface');\n\nclass MysqlDialect 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 this.queryInterface = new MySQLQueryInterface(\n sequelize,\n this.queryGenerator\n );\n }\n\n canBackslashEscape() {\n return true;\n }\n}\n\nMysqlDialect.prototype.supports = _.merge(\n _.cloneDeep(AbstractDialect.prototype.supports),\n {\n 'VALUES ()': true,\n 'LIMIT ON UPDATE': true,\n lock: true,\n forShare: 'LOCK IN SHARE MODE',\n settingIsolationLevelDuringTransaction: false,\n inserts: {\n ignoreDuplicates: ' IGNORE',\n updateOnDuplicate: ' ON DUPLICATE KEY UPDATE'\n },\n index: {\n collate: false,\n length: true,\n parser: true,\n type: true,\n using: 1\n },\n constraints: {\n dropConstraint: false,\n check: false\n },\n indexViaAlter: true,\n indexHints: true,\n NUMERIC: true,\n GEOMETRY: true,\n JSON: true,\n REGEXP: true\n }\n);\n\nMysqlDialect.prototype.defaultVersion = '5.7.0'; // minimum supported version\nMysqlDialect.prototype.Query = Query;\nMysqlDialect.prototype.QueryGenerator = QueryGenerator;\nMysqlDialect.prototype.DataTypes = DataTypes;\nMysqlDialect.prototype.name = 'mysql';\nMysqlDialect.prototype.TICK_CHAR = '`';\nMysqlDialect.prototype.TICK_CHAR_LEFT = MysqlDialect.prototype.TICK_CHAR;\nMysqlDialect.prototype.TICK_CHAR_RIGHT = MysqlDialect.prototype.TICK_CHAR;\n\nmodule.exports = MysqlDialect;\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,wBAAwB,QAAQ;AAExC,2BAA2B,gBAAgB;AAAA,EACzC,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,oBACxB,WACA,KAAK;AAAA;AAAA,EAIT,qBAAqB;AACnB,WAAO;AAAA;AAAA;AAIX,aAAa,UAAU,WAAW,EAAE,MAClC,EAAE,UAAU,gBAAgB,UAAU,WACtC;AAAA,EACE,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wCAAwC;AAAA,EACxC,SAAS;AAAA,IACP,kBAAkB;AAAA,IAClB,mBAAmB;AAAA;AAAA,EAErB,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,aAAa;AAAA,IACX,gBAAgB;AAAA,IAChB,OAAO;AAAA;AAAA,EAET,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA;AAIZ,aAAa,UAAU,iBAAiB;AACxC,aAAa,UAAU,QAAQ;AAC/B,aAAa,UAAU,iBAAiB;AACxC,aAAa,UAAU,YAAY;AACnC,aAAa,UAAU,OAAO;AAC9B,aAAa,UAAU,YAAY;AACnC,aAAa,UAAU,iBAAiB,aAAa,UAAU;AAC/D,aAAa,UAAU,kBAAkB,aAAa,UAAU;AAEhE,OAAO,UAAU;",
"names": []
}
+470
View File
@@ -0,0 +1,470 @@
"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 _ = require("lodash");
const Utils = require("../../utils");
const AbstractQueryGenerator = require("../abstract/query-generator");
const util = require("util");
const Op = require("../../operators");
const JSON_FUNCTION_REGEX = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i;
const JSON_OPERATOR_REGEX = /^\s*(->>?|@>|<@|\?[|&]?|\|{2}|#-)/i;
const TOKEN_CAPTURE_REGEX = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i;
const FOREIGN_KEY_FIELDS = [
"CONSTRAINT_NAME as constraint_name",
"CONSTRAINT_NAME as constraintName",
"CONSTRAINT_SCHEMA as constraintSchema",
"CONSTRAINT_SCHEMA as constraintCatalog",
"TABLE_NAME as tableName",
"TABLE_SCHEMA as tableSchema",
"TABLE_SCHEMA as tableCatalog",
"COLUMN_NAME as columnName",
"REFERENCED_TABLE_SCHEMA as referencedTableSchema",
"REFERENCED_TABLE_SCHEMA as referencedTableCatalog",
"REFERENCED_TABLE_NAME as referencedTableName",
"REFERENCED_COLUMN_NAME as referencedColumnName"
].join(",");
const typeWithoutDefault = /* @__PURE__ */ new Set(["BLOB", "TEXT", "GEOMETRY", "JSON"]);
class MySQLQueryGenerator extends AbstractQueryGenerator {
constructor(options) {
super(options);
this.OperatorMap = __spreadProps(__spreadValues({}, this.OperatorMap), {
[Op.regexp]: "REGEXP",
[Op.notRegexp]: "NOT REGEXP"
});
}
createDatabaseQuery(databaseName, options) {
options = __spreadValues({
charset: null,
collate: null
}, options);
return Utils.joinSQLFragments([
"CREATE DATABASE IF NOT EXISTS",
this.quoteIdentifier(databaseName),
options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`,
options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`,
";"
]);
}
dropDatabaseQuery(databaseName) {
return `DROP DATABASE IF EXISTS ${this.quoteIdentifier(databaseName)};`;
}
createSchema() {
return "SHOW TABLES";
}
showSchemasQuery() {
return "SHOW TABLES";
}
versionQuery() {
return "SELECT VERSION() as `version`";
}
createTableQuery(tableName, attributes, options) {
options = __spreadValues({
engine: "InnoDB",
charset: null,
rowFormat: null
}, options);
const primaryKeys = [];
const foreignKeys = {};
const attrStr = [];
for (const attr in attributes) {
if (!Object.prototype.hasOwnProperty.call(attributes, attr))
continue;
const dataType = attributes[attr];
let match;
if (dataType.includes("PRIMARY KEY")) {
primaryKeys.push(attr);
if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1].replace("PRIMARY KEY", "")}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType.replace("PRIMARY KEY", "")}`);
}
} else if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1]}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType}`);
}
}
const table = this.quoteTable(tableName);
let attributesClause = attrStr.join(", ");
const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
if (options.uniqueKeys) {
_.each(options.uniqueKeys, (columns, indexName) => {
if (columns.customIndex) {
if (typeof indexName !== "string") {
indexName = `uniq_${tableName}_${columns.fields.join("_")}`;
}
attributesClause += `, UNIQUE ${this.quoteIdentifier(indexName)} (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
});
}
if (pkString.length > 0) {
attributesClause += `, PRIMARY KEY (${pkString})`;
}
for (const fkey in foreignKeys) {
if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) {
attributesClause += `, FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`;
}
}
return Utils.joinSQLFragments([
"CREATE TABLE IF NOT EXISTS",
table,
`(${attributesClause})`,
`ENGINE=${options.engine}`,
options.comment && typeof options.comment === "string" && `COMMENT ${this.escape(options.comment)}`,
options.charset && `DEFAULT CHARSET=${options.charset}`,
options.collate && `COLLATE ${options.collate}`,
options.initialAutoIncrement && `AUTO_INCREMENT=${options.initialAutoIncrement}`,
options.rowFormat && `ROW_FORMAT=${options.rowFormat}`,
";"
]);
}
describeTableQuery(tableName, schema, schemaDelimiter) {
const table = this.quoteTable(this.addSchema({
tableName,
_schema: schema,
_schemaDelimiter: schemaDelimiter
}));
return `SHOW FULL COLUMNS FROM ${table};`;
}
showTablesQuery(database) {
let query = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'";
if (database) {
query += ` AND TABLE_SCHEMA = ${this.escape(database)}`;
} else {
query += " AND TABLE_SCHEMA NOT IN ('MYSQL', 'INFORMATION_SCHEMA', 'PERFORMANCE_SCHEMA', 'SYS', 'mysql', 'information_schema', 'performance_schema', 'sys')";
}
return `${query};`;
}
tableExistsQuery(table) {
const tableName = this.escape(this.quoteTable(table).slice(1, -1));
return `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ${tableName} AND TABLE_SCHEMA = ${this.escape(this.sequelize.config.database)}`;
}
addColumnQuery(table, key, dataType) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(table),
"ADD",
this.quoteIdentifier(key),
this.attributeToSQL(dataType, {
context: "addColumn",
tableName: table,
foreignKey: key
}),
";"
]);
}
removeColumnQuery(tableName, attributeName) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP",
this.quoteIdentifier(attributeName),
";"
]);
}
changeColumnQuery(tableName, attributes) {
const attrString = [];
const constraintString = [];
for (const attributeName in attributes) {
let definition = attributes[attributeName];
if (definition.includes("REFERENCES")) {
const attrName = this.quoteIdentifier(attributeName);
definition = definition.replace(/.+?(?=REFERENCES)/, "");
constraintString.push(`FOREIGN KEY (${attrName}) ${definition}`);
} else {
attrString.push(`\`${attributeName}\` \`${attributeName}\` ${definition}`);
}
}
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
attrString.length && `CHANGE ${attrString.join(", ")}`,
constraintString.length && `ADD ${constraintString.join(", ")}`,
";"
]);
}
renameColumnQuery(tableName, attrBefore, attributes) {
const attrString = [];
for (const attrName in attributes) {
const definition = attributes[attrName];
attrString.push(`\`${attrBefore}\` \`${attrName}\` ${definition}`);
}
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"CHANGE",
attrString.join(", "),
";"
]);
}
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
if (smth instanceof Utils.Json) {
if (smth.conditions) {
const conditions = this.parseConditionObject(smth.conditions).map((condition) => `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`);
return conditions.join(" AND ");
}
if (smth.path) {
let str;
if (this._checkValidJsonStatement(smth.path)) {
str = smth.path;
} else {
const paths = _.toPath(smth.path);
const column = paths.shift();
str = this.jsonPathExtractionQuery(column, paths);
}
if (smth.value) {
str += util.format(" = %s", this.escape(smth.value));
}
return str;
}
} else if (smth instanceof Utils.Cast) {
if (/timestamp/i.test(smth.type)) {
smth.type = "datetime";
} else if (smth.json && /boolean/i.test(smth.type)) {
smth.type = "char";
} else if (/double precision/i.test(smth.type) || /boolean/i.test(smth.type) || /integer/i.test(smth.type)) {
smth.type = "decimal";
} else if (/text/i.test(smth.type)) {
smth.type = "char";
}
}
return super.handleSequelizeMethod(smth, tableName, factory, options, prepend);
}
_toJSONValue(value) {
if (typeof value === "boolean") {
return value.toString();
}
if (value === null) {
return "null";
}
return value;
}
truncateTableQuery(tableName) {
return `TRUNCATE ${this.quoteTable(tableName)}`;
}
deleteQuery(tableName, where, options = {}, model) {
let limit = "";
let query = `DELETE FROM ${this.quoteTable(tableName)}`;
if (options.limit) {
limit = ` LIMIT ${this.escape(options.limit)}`;
}
where = this.getWhereConditions(where, null, model, options);
if (where) {
query += ` WHERE ${where}`;
}
return query + limit;
}
showIndexesQuery(tableName, options) {
return Utils.joinSQLFragments([
`SHOW INDEX FROM ${this.quoteTable(tableName)}`,
options && options.database && `FROM \`${options.database}\``
]);
}
showConstraintsQuery(table, constraintName) {
const tableName = table.tableName || table;
const schemaName = table.schema;
return Utils.joinSQLFragments([
"SELECT CONSTRAINT_CATALOG AS constraintCatalog,",
"CONSTRAINT_NAME AS constraintName,",
"CONSTRAINT_SCHEMA AS constraintSchema,",
"CONSTRAINT_TYPE AS constraintType,",
"TABLE_NAME AS tableName,",
"TABLE_SCHEMA AS tableSchema",
"from INFORMATION_SCHEMA.TABLE_CONSTRAINTS",
`WHERE table_name='${tableName}'`,
constraintName && `AND constraint_name = '${constraintName}'`,
schemaName && `AND TABLE_SCHEMA = '${schemaName}'`,
";"
]);
}
removeIndexQuery(tableName, indexNameOrAttributes) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return Utils.joinSQLFragments([
"DROP INDEX",
this.quoteIdentifier(indexName),
"ON",
this.quoteTable(tableName)
]);
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
const attributeString = attribute.type.toString({ escape: this.escape.bind(this) });
let template = attributeString;
if (attribute.allowNull === false) {
template += " NOT NULL";
}
if (attribute.autoIncrement) {
template += " auto_increment";
}
if (!typeWithoutDefault.has(attributeString) && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (attribute.unique === true) {
template += " UNIQUE";
}
if (attribute.primaryKey) {
template += " PRIMARY KEY";
}
if (attribute.comment) {
template += ` COMMENT ${this.escape(attribute.comment)}`;
}
if (attribute.first) {
template += " FIRST";
}
if (attribute.after) {
template += ` AFTER ${this.quoteIdentifier(attribute.after)}`;
}
if ((!options || !options.withoutForeignKeyConstraints) && attribute.references) {
if (options && options.context === "addColumn" && options.foreignKey) {
const attrName = this.quoteIdentifier(options.foreignKey);
const fkName = this.quoteIdentifier(`${options.tableName}_${attrName}_foreign_idx`);
template += `, ADD CONSTRAINT ${fkName} FOREIGN KEY (${attrName})`;
}
template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
if (attribute.references.key) {
template += ` (${this.quoteIdentifier(attribute.references.key)})`;
} else {
template += ` (${this.quoteIdentifier("id")})`;
}
if (attribute.onDelete) {
template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
if (attribute.onUpdate) {
template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
}
}
return template;
}
attributesToSQL(attributes, options) {
const result = {};
for (const key in attributes) {
const attribute = attributes[key];
result[attribute.field || key] = this.attributeToSQL(attribute, options);
}
return result;
}
_checkValidJsonStatement(stmt) {
if (typeof stmt !== "string") {
return false;
}
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 = JSON_FUNCTION_REGEX.exec(string);
if (functionMatches) {
currentIndex += functionMatches[0].indexOf("(");
hasJsonFunction = true;
continue;
}
const operatorMatches = JSON_OPERATOR_REGEX.exec(string);
if (operatorMatches) {
currentIndex += operatorMatches[0].length;
hasJsonFunction = true;
continue;
}
const tokenMatches = TOKEN_CAPTURE_REGEX.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;
}
if (hasJsonFunction && (hasInvalidToken || openingBrackets !== closingBrackets)) {
throw new Error(`Invalid json statement: ${stmt}`);
}
return hasJsonFunction;
}
getForeignKeysQuery(table, schemaName) {
const tableName = table.tableName || table;
return Utils.joinSQLFragments([
"SELECT",
FOREIGN_KEY_FIELDS,
`FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '${tableName}'`,
`AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='${schemaName}'`,
"AND REFERENCED_TABLE_NAME IS NOT NULL",
";"
]);
}
getForeignKeyQuery(table, columnName) {
const quotedSchemaName = table.schema ? wrapSingleQuote(table.schema) : "";
const quotedTableName = wrapSingleQuote(table.tableName || table);
const quotedColumnName = wrapSingleQuote(columnName);
return Utils.joinSQLFragments([
"SELECT",
FOREIGN_KEY_FIELDS,
"FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE",
"WHERE (",
[
`REFERENCED_TABLE_NAME = ${quotedTableName}`,
table.schema && `AND REFERENCED_TABLE_SCHEMA = ${quotedSchemaName}`,
`AND REFERENCED_COLUMN_NAME = ${quotedColumnName}`
],
") OR (",
[
`TABLE_NAME = ${quotedTableName}`,
table.schema && `AND TABLE_SCHEMA = ${quotedSchemaName}`,
`AND COLUMN_NAME = ${quotedColumnName}`,
"AND REFERENCED_TABLE_NAME IS NOT NULL"
],
")"
]);
}
dropForeignKeyQuery(tableName, foreignKey) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP FOREIGN KEY",
this.quoteIdentifier(foreignKey),
";"
]);
}
quoteIdentifier(identifier, force) {
return Utils.addTicks(Utils.removeTicks(identifier, "`"), "`");
}
}
function wrapSingleQuote(identifier) {
return Utils.addTicks(identifier, "'");
}
module.exports = MySQLQueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
+71
View File
@@ -0,0 +1,71 @@
"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 { QueryInterface } = require("../abstract/query-interface");
const QueryTypes = require("../../query-types");
class MySQLQueryInterface extends QueryInterface {
async removeColumn(tableName, columnName, options) {
options = options || {};
const [results] = await this.sequelize.query(this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
}, columnName), __spreadValues({ raw: true }, options));
if (results.length && results[0].constraint_name !== "PRIMARY") {
await Promise.all(results.map((constraint) => this.sequelize.query(this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name), __spreadValues({ raw: true }, options))));
}
return await this.sequelize.query(this.queryGenerator.removeColumnQuery(tableName, columnName), __spreadValues({ raw: true }, options));
}
async upsert(tableName, insertValues, updateValues, where, options) {
options = __spreadValues({}, options);
options.type = QueryTypes.UPSERT;
options.updateOnDuplicate = Object.keys(updateValues);
options.upsertKeys = Object.values(options.model.primaryKeys).map((item) => item.field);
const model = options.model;
const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);
return await this.sequelize.query(sql, options);
}
async removeConstraint(tableName, constraintName, options) {
const sql = this.queryGenerator.showConstraintsQuery(tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
}, constraintName);
const constraints = await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), {
type: this.sequelize.QueryTypes.SHOWCONSTRAINTS
}));
const constraint = constraints[0];
let query;
if (!constraint || !constraint.constraintType) {
throw new sequelizeErrors.UnknownConstraintError({
message: `Constraint ${constraintName} on table ${tableName} does not exist`,
constraint: constraintName,
table: tableName
});
}
if (constraint.constraintType === "FOREIGN KEY") {
query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName);
} else {
query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
}
return await this.sequelize.query(query, options);
}
}
exports.MySQLQueryInterface = MySQLQueryInterface;
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/mysql/query-interface.js"],
"sourcesContent": ["'use strict';\n\nconst sequelizeErrors = require('../../errors');\nconst { QueryInterface } = require('../abstract/query-interface');\nconst QueryTypes = require('../../query-types');\n\n/**\n * The interface that Sequelize uses to talk with MySQL/MariaDB database\n */\nclass MySQLQueryInterface extends QueryInterface {\n /**\n * A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint.\n *\n * @override\n */\n async removeColumn(tableName, columnName, options) {\n options = options || {};\n\n const [results] = await this.sequelize.query(\n this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {\n tableName,\n schema: this.sequelize.config.database\n }, columnName),\n { raw: true, ...options }\n );\n\n //Exclude primary key constraint\n if (results.length && results[0].constraint_name !== 'PRIMARY') {\n await Promise.all(results.map(constraint => this.sequelize.query(\n this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),\n { raw: true, ...options }\n )));\n }\n\n return await this.sequelize.query(\n this.queryGenerator.removeColumnQuery(tableName, columnName),\n { raw: true, ...options }\n );\n }\n\n /**\n * @override\n */\n async upsert(tableName, insertValues, updateValues, where, options) {\n options = { ...options };\n\n options.type = QueryTypes.UPSERT;\n options.updateOnDuplicate = Object.keys(updateValues);\n options.upsertKeys = Object.values(options.model.primaryKeys).map(item => item.field);\n\n const model = options.model;\n const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);\n return await this.sequelize.query(sql, options);\n }\n\n /**\n * @override\n */\n async removeConstraint(tableName, constraintName, options) {\n const sql = this.queryGenerator.showConstraintsQuery(\n tableName.tableName ? tableName : {\n tableName,\n schema: this.sequelize.config.database\n }, constraintName);\n\n const constraints = await this.sequelize.query(sql, { ...options,\n type: this.sequelize.QueryTypes.SHOWCONSTRAINTS });\n\n const constraint = constraints[0];\n let query;\n if (!constraint || !constraint.constraintType) {\n throw new sequelizeErrors.UnknownConstraintError(\n {\n message: `Constraint ${constraintName} on table ${tableName} does not exist`,\n constraint: constraintName,\n table: tableName\n });\n }\n\n if (constraint.constraintType === 'FOREIGN KEY') {\n query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName);\n } else {\n query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);\n }\n\n return await this.sequelize.query(query, options);\n }\n}\n\nexports.MySQLQueryInterface = MySQLQueryInterface;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAEA,MAAM,kBAAkB,QAAQ;AAChC,MAAM,EAAE,mBAAmB,QAAQ;AACnC,MAAM,aAAa,QAAQ;AAK3B,kCAAkC,eAAe;AAAA,QAMzC,aAAa,WAAW,YAAY,SAAS;AACjD,cAAU,WAAW;AAErB,UAAM,CAAC,WAAW,MAAM,KAAK,UAAU,MACrC,KAAK,eAAe,mBAAmB,UAAU,YAAY,YAAY;AAAA,MACvE;AAAA,MACA,QAAQ,KAAK,UAAU,OAAO;AAAA,OAC7B,aACH,iBAAE,KAAK,QAAS;AAIlB,QAAI,QAAQ,UAAU,QAAQ,GAAG,oBAAoB,WAAW;AAC9D,YAAM,QAAQ,IAAI,QAAQ,IAAI,gBAAc,KAAK,UAAU,MACzD,KAAK,eAAe,oBAAoB,WAAW,WAAW,kBAC9D,iBAAE,KAAK,QAAS;AAAA;AAIpB,WAAO,MAAM,KAAK,UAAU,MAC1B,KAAK,eAAe,kBAAkB,WAAW,aACjD,iBAAE,KAAK,QAAS;AAAA;AAAA,QAOd,OAAO,WAAW,cAAc,cAAc,OAAO,SAAS;AAClE,cAAU,mBAAK;AAEf,YAAQ,OAAO,WAAW;AAC1B,YAAQ,oBAAoB,OAAO,KAAK;AACxC,YAAQ,aAAa,OAAO,OAAO,QAAQ,MAAM,aAAa,IAAI,UAAQ,KAAK;AAE/E,UAAM,QAAQ,QAAQ;AACtB,UAAM,MAAM,KAAK,eAAe,YAAY,WAAW,cAAc,MAAM,eAAe;AAC1F,WAAO,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA;AAAA,QAMnC,iBAAiB,WAAW,gBAAgB,SAAS;AACzD,UAAM,MAAM,KAAK,eAAe,qBAC9B,UAAU,YAAY,YAAY;AAAA,MAChC;AAAA,MACA,QAAQ,KAAK,UAAU,OAAO;AAAA,OAC7B;AAEL,UAAM,cAAc,MAAM,KAAK,UAAU,MAAM,KAAK,iCAAK,UAAL;AAAA,MAClD,MAAM,KAAK,UAAU,WAAW;AAAA;AAElC,UAAM,aAAa,YAAY;AAC/B,QAAI;AACJ,QAAI,CAAC,cAAc,CAAC,WAAW,gBAAgB;AAC7C,YAAM,IAAI,gBAAgB,uBACxB;AAAA,QACE,SAAS,cAAc,2BAA2B;AAAA,QAClD,YAAY;AAAA,QACZ,OAAO;AAAA;AAAA;AAIb,QAAI,WAAW,mBAAmB,eAAe;AAC/C,cAAQ,KAAK,eAAe,oBAAoB,WAAW;AAAA,WACtD;AACL,cAAQ,KAAK,eAAe,iBAAiB,WAAW,WAAW,WAAW;AAAA;AAGhF,WAAO,MAAM,KAAK,UAAU,MAAM,OAAO;AAAA;AAAA;AAI7C,QAAQ,sBAAsB;",
"names": []
}
+239
View File
@@ -0,0 +1,239 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const AbstractQuery = require("../abstract/query");
const sequelizeErrors = require("../../errors");
const _ = require("lodash");
const { logger } = require("../../utils/logger");
const ER_DUP_ENTRY = 1062;
const ER_DEADLOCK = 1213;
const ER_ROW_IS_REFERENCED = 1451;
const ER_NO_REFERENCED_ROW = 1452;
const debug = logger.debugContext("sql:mysql");
class Query extends AbstractQuery {
constructor(connection, sequelize, options) {
super(connection, sequelize, __spreadValues({ showWarnings: false }, options));
}
static formatBindParameters(sql, values, dialect) {
const bindParam = [];
const replacementFunc = (match, key, values_) => {
if (values_[key] !== void 0) {
bindParam.push(values_[key]);
return "?";
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
return [sql, bindParam.length > 0 ? bindParam : void 0];
}
async run(sql, parameters) {
this.sql = sql;
const { connection, options } = this;
const showWarnings = this.sequelize.options.showWarnings || options.showWarnings;
const complete = this._logQuery(sql, debug, parameters);
if (parameters) {
debug("parameters(%j)", parameters);
}
let results;
const errForStack = new Error();
try {
if (parameters && parameters.length) {
results = await new Promise((resolve, reject) => {
connection.execute(sql, parameters, (error, result) => error ? reject(error) : resolve(result)).setMaxListeners(100);
});
} else {
results = await new Promise((resolve, reject) => {
connection.query({ sql }, (error, result) => error ? reject(error) : resolve(result)).setMaxListeners(100);
});
}
} catch (error) {
if (options.transaction && error.errno === ER_DEADLOCK) {
try {
await options.transaction.rollback();
} catch (error_) {
}
options.transaction.finished = "rollback";
}
error.sql = sql;
error.parameters = parameters;
throw this.formatError(error, errForStack.stack);
} finally {
complete();
}
if (showWarnings && results && results.warningStatus > 0) {
await this.logWarnings(results);
}
return this.formatResults(results);
}
formatResults(data) {
let result = this.instance;
if (this.isInsertQuery(data)) {
this.handleInsertQuery(data);
if (!this.instance) {
if (data.constructor.name === "ResultSetHeader" && this.model && this.model.autoIncrementAttribute && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute && this.model.rawAttributes[this.model.primaryKeyAttribute]) {
const startId = data[this.getInsertIdField()];
result = [];
for (let i = startId; i < startId + data.affectedRows; i++) {
result.push({ [this.model.rawAttributes[this.model.primaryKeyAttribute].field]: i });
}
} else {
result = data[this.getInsertIdField()];
}
}
}
if (this.isSelectQuery()) {
return this.handleSelectQuery(data);
}
if (this.isShowTablesQuery()) {
return this.handleShowTablesQuery(data);
}
if (this.isDescribeQuery()) {
result = {};
for (const _result of data) {
const enumRegex = /^enum/i;
result[_result.Field] = {
type: enumRegex.test(_result.Type) ? _result.Type.replace(enumRegex, "ENUM") : _result.Type.toUpperCase(),
allowNull: _result.Null === "YES",
defaultValue: _result.Default,
primaryKey: _result.Key === "PRI",
autoIncrement: Object.prototype.hasOwnProperty.call(_result, "Extra") && _result.Extra.toLowerCase() === "auto_increment",
comment: _result.Comment ? _result.Comment : null
};
}
return result;
}
if (this.isShowIndexesQuery()) {
return this.handleShowIndexesQuery(data);
}
if (this.isCallQuery()) {
return data[0];
}
if (this.isBulkUpdateQuery() || this.isBulkDeleteQuery()) {
return data.affectedRows;
}
if (this.isVersionQuery()) {
return data[0].version;
}
if (this.isForeignKeysQuery()) {
return data;
}
if (this.isUpsertQuery()) {
return [result, data.affectedRows === 1];
}
if (this.isInsertQuery() || this.isUpdateQuery()) {
return [result, data.affectedRows];
}
if (this.isShowConstraintsQuery()) {
return data;
}
if (this.isRawQuery()) {
return [data, data];
}
return result;
}
async logWarnings(results) {
const warningResults = await this.run("SHOW WARNINGS");
const warningMessage = `MySQL Warnings (${this.connection.uuid || "default"}): `;
const messages = [];
for (const _warningRow of warningResults) {
if (_warningRow === void 0 || typeof _warningRow[Symbol.iterator] !== "function") {
continue;
}
for (const _warningResult of _warningRow) {
if (Object.prototype.hasOwnProperty.call(_warningResult, "Message")) {
messages.push(_warningResult.Message);
} else {
for (const _objectKey of _warningResult.keys()) {
messages.push([_objectKey, _warningResult[_objectKey]].join(": "));
}
}
}
}
this.sequelize.log(warningMessage + messages.join("; "), this.options);
return results;
}
formatError(err, errStack) {
const errCode = err.errno || err.code;
switch (errCode) {
case ER_DUP_ENTRY: {
const match = err.message.match(/Duplicate entry '([\s\S]*)' for key '?((.|\s)*?)'?$/);
let fields = {};
let message = "Validation error";
const values = match ? match[1].split("-") : void 0;
const fieldKey = match ? match[2].split(".").pop() : void 0;
const fieldVal = match ? match[1] : void 0;
const uniqueKey = this.model && this.model.uniqueKeys[fieldKey];
if (uniqueKey) {
if (uniqueKey.msg)
message = uniqueKey.msg;
fields = _.zipObject(uniqueKey.fields, values);
} else {
fields[fieldKey] = fieldVal;
}
const errors = [];
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
case ER_ROW_IS_REFERENCED:
case ER_NO_REFERENCED_ROW: {
const match = err.message.match(/CONSTRAINT ([`"])(.*)\1 FOREIGN KEY \(\1(.*)\1\) REFERENCES \1(.*)\1 \(\1(.*)\1\)/);
const quoteChar = match ? match[1] : "`";
const fields = match ? match[3].split(new RegExp(`${quoteChar}, *${quoteChar}`)) : void 0;
return new sequelizeErrors.ForeignKeyConstraintError({
reltype: String(errCode) === String(ER_ROW_IS_REFERENCED) ? "parent" : "child",
table: match ? match[4] : void 0,
fields,
value: fields && fields.length && this.instance && this.instance[fields[0]] || void 0,
index: match ? match[2] : void 0,
parent: err,
stack: errStack
});
}
default:
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
}
handleShowIndexesQuery(data) {
data = data.reduce((acc, item) => {
if (!(item.Key_name in acc)) {
acc[item.Key_name] = item;
item.fields = [];
}
acc[item.Key_name].fields[item.Seq_in_index - 1] = {
attribute: item.Column_name,
length: item.Sub_part || void 0,
order: item.Collation === "A" ? "ASC" : void 0
};
delete item.column_name;
return acc;
}, {});
return _.map(data, (item) => ({
primary: item.Key_name === "PRIMARY",
fields: item.fields,
name: item.Key_name,
tableName: item.Table,
unique: item.Non_unique !== 1,
type: item.Index_type
}));
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,147 @@
"use strict";
var __defProp = Object.defineProperty;
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 __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, {
OracleConnectionManager: () => OracleConnectionManager
});
const AbstractConnectionManager = require("../abstract/connection-manager");
const SequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("oracle");
const { logger } = require("../../utils/logger");
const semver = require("semver");
const debug = logger.debugContext("connection:oracle");
const DataTypes = require("../../data-types").oracle;
const { promisify } = require("util");
class OracleConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
super(dialect, sequelize);
this.sequelize = sequelize;
this.sequelize.config.port = this.sequelize.config.port || 1521;
this.lib = this._loadDialectModule("oracledb");
this.extendLib();
this.refreshTypeParser(DataTypes);
}
extendLib() {
if (this.sequelize.config && "dialectOptions" in this.sequelize.config) {
const dialectOptions = this.sequelize.config.dialectOptions;
if (dialectOptions && "maxRows" in dialectOptions) {
this.lib.maxRows = this.sequelize.config.dialectOptions.maxRows;
}
if (dialectOptions && "fetchAsString" in dialectOptions) {
this.lib.fetchAsString = this.sequelize.config.dialectOptions.fetchAsString;
} else {
this.lib.fetchAsString = [this.lib.CLOB];
}
}
this.lib.fetchAsBuffer = [this.lib.BLOB];
}
buildConnectString(config) {
if (!config.host || config.host.length === 0)
return config.database;
let connectString = config.host;
if (config.port && config.port > 0) {
connectString += `:${config.port}`;
} else {
connectString += ":1521";
}
if (config.database && config.database.length > 0) {
connectString += `/${config.database}`;
}
return connectString;
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
async connect(config) {
const connectionConfig = __spreadValues({
user: config.username,
password: config.password,
externalAuth: config.externalAuth,
stmtCacheSize: 0,
connectString: this.buildConnectString(config)
}, config.dialectOptions);
try {
const connection = await this.lib.getConnection(connectionConfig);
this.sequelize.options.databaseVersion = semver.coerce(connection.oracleServerVersionString).version;
debug("connection acquired");
connection.on("error", (error) => {
switch (error.code) {
case "ESOCKET":
case "ECONNRESET":
case "EPIPE":
case "PROTOCOL_CONNECTION_LOST":
this.pool.destroy(connection);
}
});
return connection;
} catch (err) {
let errorCode = err.message.split(":");
errorCode = errorCode[0];
switch (errorCode) {
case "ORA-12560":
case "ORA-12154":
case "ORA-12505":
case "ORA-12514":
case "NJS-511":
case "NJS-516":
case "NJS-517":
case "NJS-520":
throw new SequelizeErrors.ConnectionRefusedError(err);
case "ORA-28000":
case "ORA-28040":
case "ORA-01017":
case "NJS-506":
throw new SequelizeErrors.AccessDeniedError(err);
case "ORA-12541":
case "NJS-503":
case "NJS-508":
case "NJS-507":
throw new SequelizeErrors.HostNotReachableError(err);
case "NJS-512":
case "NJS-515":
case "NJS-518":
case "NJS-519":
throw new SequelizeErrors.InvalidConnectionError(err);
case "ORA-12170":
case "NJS-510":
throw new SequelizeErrors.ConnectionTimedOutError(err);
default:
throw new SequelizeErrors.ConnectionError(err);
}
}
}
async disconnect(connection) {
if (!connection.isHealthy()) {
debug("connection tried to disconnect but was already at CLOSED state");
return;
}
return await promisify((callback) => connection.close(callback))();
}
validate(connection) {
return connection && connection.isHealthy();
}
}
//# sourceMappingURL=connection-manager.js.map
File diff suppressed because one or more lines are too long
+377
View File
@@ -0,0 +1,377 @@
"use strict";
const moment = require("moment");
const momentTz = require("moment-timezone");
module.exports = (BaseTypes) => {
const warn = BaseTypes.ABSTRACT.warn.bind(void 0, "https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-D424D23B-0933-425F-BC69-9C0E6724693C");
BaseTypes.DATE.types.oracle = ["TIMESTAMP", "TIMESTAMP WITH LOCAL TIME ZONE"];
BaseTypes.STRING.types.oracle = ["VARCHAR2", "NVARCHAR2"];
BaseTypes.CHAR.types.oracle = ["CHAR", "RAW"];
BaseTypes.TEXT.types.oracle = ["CLOB"];
BaseTypes.TINYINT.types.oracle = ["NUMBER"];
BaseTypes.SMALLINT.types.oracle = ["NUMBER"];
BaseTypes.MEDIUMINT.types.oracle = ["NUMBER"];
BaseTypes.INTEGER.types.oracle = ["INTEGER"];
BaseTypes.BIGINT.types.oracle = ["NUMBER"];
BaseTypes.FLOAT.types.oracle = ["BINARY_FLOAT"];
BaseTypes.DATEONLY.types.oracle = ["DATE"];
BaseTypes.BOOLEAN.types.oracle = ["CHAR(1)"];
BaseTypes.BLOB.types.oracle = ["BLOB"];
BaseTypes.DECIMAL.types.oracle = ["NUMBER"];
BaseTypes.UUID.types.oracle = ["VARCHAR2"];
BaseTypes.ENUM.types.oracle = ["VARCHAR2"];
BaseTypes.REAL.types.oracle = ["BINARY_DOUBLE"];
BaseTypes.DOUBLE.types.oracle = ["BINARY_DOUBLE"];
BaseTypes.JSON.types.oracle = ["BLOB"];
BaseTypes.GEOMETRY.types.oracle = false;
class STRING extends BaseTypes.STRING {
toSql() {
if (this.length > 4e3 || this._binary && this._length > 2e3) {
warn("Oracle supports length up to 32764 bytes or characters; Be sure that your administrator has extended the MAX_STRING_SIZE parameter. Check https://docs.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-7B72E154-677A-4342-A1EA-C74C1EA928E6");
}
if (!this._binary) {
return `NVARCHAR2(${this._length})`;
}
return `RAW(${this._length})`;
}
_stringify(value, options) {
if (this._binary) {
return options.escape(value.toString("hex"));
}
return options.escape(value);
}
_getBindDef(oracledb) {
if (this._binary) {
return { type: oracledb.DB_TYPE_RAW, maxSize: this._length };
}
return { type: oracledb.DB_TYPE_VARCHAR, maxSize: this._length };
}
_bindParam(value, options) {
return options.bindParam(value);
}
}
STRING.prototype.escape = false;
class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return "CHAR(1)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_CHAR, maxSize: 1 };
}
_stringify(value) {
return value === true ? "1" : value === false ? "0" : value;
}
_sanitize(value) {
if (typeof value === "string") {
return value === "1" || value === "true" ? true : value === "0" || value === "false" ? false : value;
}
return super._sanitize(value);
}
}
class UUID extends BaseTypes.UUID {
toSql() {
return "VARCHAR2(36)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_VARCHAR, maxSize: 36 };
}
}
class NOW extends BaseTypes.NOW {
toSql() {
return "SYSDATE";
}
_stringify() {
return "SYSDATE";
}
}
class ENUM extends BaseTypes.ENUM {
toSql() {
return "VARCHAR2(512)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_VARCHAR, maxSize: 512 };
}
}
class TEXT extends BaseTypes.TEXT {
toSql() {
return "CLOB";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_CLOB };
}
}
class CHAR extends BaseTypes.CHAR {
toSql() {
if (this._binary) {
warn("Oracle CHAR.BINARY datatype is not of Fixed Length.");
return `RAW(${this._length})`;
}
return super.toSql();
}
_getBindDef(oracledb) {
if (this._binary) {
return { type: oracledb.DB_TYPE_RAW, maxSize: this._length };
}
return { type: oracledb.DB_TYPE_CHAR, maxSize: this._length };
}
_bindParam(value, options) {
return options.bindParam(value);
}
}
class DATE extends BaseTypes.DATE {
toSql() {
return "TIMESTAMP WITH LOCAL TIME ZONE";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_TIMESTAMP_LTZ };
}
_stringify(date, options) {
const format = "YYYY-MM-DD HH24:MI:SS.FFTZH:TZM";
date = this._applyTimezone(date, options);
const formatedDate = date.format("YYYY-MM-DD HH:mm:ss.SSS Z");
return `TO_TIMESTAMP_TZ('${formatedDate}','${format}')`;
}
_applyTimezone(date, options) {
if (options.timezone) {
if (momentTz.tz.zone(options.timezone)) {
date = momentTz(date).tz(options.timezone);
} else {
date = moment(date).utcOffset(options.timezone);
}
} else {
date = momentTz(date);
}
return date;
}
static parse(value, options) {
if (value === null) {
return value;
}
if (options && moment.tz.zone(options.timezone)) {
value = moment.tz(value.toString(), options.timezone).toDate();
}
return value;
}
_bindParam(value, options) {
return options.bindParam(value);
}
}
DATE.prototype.escape = false;
class DECIMAL extends BaseTypes.DECIMAL {
toSql() {
let result = "";
if (this._length) {
result += `(${this._length}`;
if (typeof this._decimals === "number") {
result += `,${this._decimals}`;
}
result += ")";
}
if (!this._length && this._precision) {
result += `(${this._precision}`;
if (typeof this._scale === "number") {
result += `,${this._scale}`;
}
result += ")";
}
return `NUMBER${result}`;
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class TINYINT extends BaseTypes.TINYINT {
toSql() {
return "NUMBER(3)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class SMALLINT extends BaseTypes.SMALLINT {
toSql() {
if (this._length) {
return `NUMBER(${this._length},0)`;
}
return "SMALLINT";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class MEDIUMINT extends BaseTypes.MEDIUMINT {
toSql() {
return "NUMBER(8)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
if (!(this instanceof BIGINT))
return new BIGINT(length);
BaseTypes.BIGINT.apply(this, arguments);
if (this._length || this.options.length || this._unsigned || this._zerofill) {
warn("Oracle does not support BIGINT with options");
this._length = void 0;
this.options.length = void 0;
this._unsigned = void 0;
this._zerofill = void 0;
}
}
toSql() {
return "NUMBER(19)";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
_sanitize(value) {
if (typeof value === "bigint" || typeof value === "number") {
return value.toString();
}
return value;
}
}
class NUMBER extends BaseTypes.NUMBER {
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class INTEGER extends BaseTypes.INTEGER {
toSql() {
if (this._length) {
return `NUMBER(${this._length},0)`;
}
return "INTEGER";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_NUMBER };
}
}
class FLOAT extends BaseTypes.FLOAT {
toSql() {
return "BINARY_FLOAT";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_BINARY_FLOAT };
}
}
class REAL extends BaseTypes.REAL {
toSql() {
return "BINARY_DOUBLE";
}
_stringify(value) {
if (value === Number.POSITIVE_INFINITY) {
return "inf";
}
if (value === Number.NEGATIVE_INFINITY) {
return "-inf";
}
return value;
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_BINARY_DOUBLE };
}
}
class BLOB extends BaseTypes.BLOB {
_hexify(hex) {
return `'${hex}'`;
}
toSql() {
return "BLOB";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_BLOB };
}
}
class JSONTYPE extends BaseTypes.JSON {
toSql() {
return "BLOB";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_BLOB };
}
_stringify(value, options) {
return options.operation === "where" && typeof value === "string" ? value : JSON.stringify(value);
}
_bindParam(value, options) {
return options.bindParam(Buffer.from(JSON.stringify(value)));
}
}
class DOUBLE extends BaseTypes.DOUBLE {
constructor(length, decimals) {
super(length, decimals);
if (!(this instanceof DOUBLE))
return new BaseTypes.DOUBLE(length, decimals);
BaseTypes.DOUBLE.apply(this, arguments);
if (this._length || this._unsigned || this._zerofill) {
warn("Oracle does not support DOUBLE with options.");
this._length = void 0;
this.options.length = void 0;
this._unsigned = void 0;
this._zerofill = void 0;
}
this.key = "DOUBLE PRECISION";
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_BINARY_DOUBLE };
}
toSql() {
return "BINARY_DOUBLE";
}
}
class DATEONLY extends BaseTypes.DATEONLY {
parse(value) {
return moment(value).format("YYYY-MM-DD");
}
_sanitize(value) {
if (value) {
return moment(value).format("YYYY-MM-DD");
}
return value;
}
_stringify(date, options) {
if (date) {
const format = "YYYY/MM/DD";
return options.escape(`TO_DATE('${date}','${format}')`);
}
return options.escape(date);
}
_getBindDef(oracledb) {
return { type: oracledb.DB_TYPE_DATE };
}
_bindParam(value, options) {
if (typeof value === "string") {
return options.bindParam(new Date(value));
}
return options.bindParam(value);
}
}
DATEONLY.prototype.escape = false;
return {
BOOLEAN,
"DOUBLE PRECISION": DOUBLE,
DOUBLE,
STRING,
TINYINT,
SMALLINT,
MEDIUMINT,
BIGINT,
NUMBER,
INTEGER,
FLOAT,
UUID,
DATEONLY,
DATE,
NOW,
BLOB,
ENUM,
TEXT,
CHAR,
JSON: JSONTYPE,
REAL,
DECIMAL
};
};
//# sourceMappingURL=data-types.js.map
File diff suppressed because one or more lines are too long
+62
View File
@@ -0,0 +1,62 @@
"use strict";
const _ = require("lodash");
const { AbstractDialect } = require("../abstract");
const { OracleConnectionManager } = require("./connection-manager");
const { OracleQuery } = require("./query");
const { OracleQueryGenerator } = require("./query-generator");
const DataTypes = require("../../data-types").oracle;
const { OracleQueryInterface } = require("./query-interface");
class OracleDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new OracleConnectionManager(this, sequelize);
this.connectionManager.initPools();
this.queryGenerator = new OracleQueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new OracleQueryInterface(sequelize, this.queryGenerator);
}
}
OracleDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"VALUES ()": true,
"LIMIT ON UPDATE": true,
IGNORE: " IGNORE",
lock: true,
lockOuterJoinFailure: true,
forShare: "FOR UPDATE",
skipLocked: true,
index: {
collate: false,
length: false,
parser: false,
type: false,
using: false
},
constraints: {
restrict: false
},
returnValues: false,
returnIntoValues: true,
"ORDER NULLS": true,
schemas: true,
updateOnDuplicate: false,
indexViaAlter: false,
NUMERIC: true,
JSON: true,
upserts: true,
bulkDefault: true,
topLevelOrderByRequired: true,
GEOMETRY: false
});
OracleDialect.prototype.defaultVersion = "18.0.0";
OracleDialect.prototype.Query = OracleQuery;
OracleDialect.prototype.queryGenerator = OracleQueryGenerator;
OracleDialect.prototype.DataTypes = DataTypes;
OracleDialect.prototype.name = "oracle";
OracleDialect.prototype.TICK_CHAR = '"';
OracleDialect.prototype.TICK_CHAR_LEFT = OracleDialect.prototype.TICK_CHAR;
OracleDialect.prototype.TICK_CHAR_RIGHT = OracleDialect.prototype.TICK_CHAR;
module.exports = OracleDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/oracle/index.js"],
"sourcesContent": ["// Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved\n\n'use strict';\n\nconst _ = require('lodash');\nconst { AbstractDialect } = require('../abstract');\nconst { OracleConnectionManager } = require('./connection-manager');\nconst { OracleQuery } = require('./query');\nconst { OracleQueryGenerator } = require('./query-generator');\nconst DataTypes = require('../../data-types').oracle;\nconst { OracleQueryInterface } = require('./query-interface');\n\nclass OracleDialect extends AbstractDialect {\n constructor(sequelize) {\n super();\n this.sequelize = sequelize;\n this.connectionManager = new OracleConnectionManager(this, sequelize);\n this.connectionManager.initPools();\n this.queryGenerator = new OracleQueryGenerator({\n _dialect: this,\n sequelize\n });\n this.queryInterface = new OracleQueryInterface(sequelize, this.queryGenerator);\n }\n}\n\nOracleDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {\n 'VALUES ()': true,\n 'LIMIT ON UPDATE': true,\n IGNORE: ' IGNORE',\n lock: true,\n lockOuterJoinFailure: true,\n forShare: 'FOR UPDATE',\n skipLocked: true,\n index: {\n collate: false,\n length: false,\n parser: false,\n type: false,\n using: false\n },\n constraints: {\n restrict: false\n },\n returnValues: false,\n returnIntoValues: true,\n 'ORDER NULLS': true,\n schemas: true,\n updateOnDuplicate: false,\n indexViaAlter: false,\n NUMERIC: true,\n JSON: true,\n upserts: true,\n bulkDefault: true,\n topLevelOrderByRequired: true,\n GEOMETRY: false\n});\n\nOracleDialect.prototype.defaultVersion = '18.0.0';\nOracleDialect.prototype.Query = OracleQuery;\nOracleDialect.prototype.queryGenerator = OracleQueryGenerator;\nOracleDialect.prototype.DataTypes = DataTypes;\nOracleDialect.prototype.name = 'oracle';\nOracleDialect.prototype.TICK_CHAR = '\"';\nOracleDialect.prototype.TICK_CHAR_LEFT = OracleDialect.prototype.TICK_CHAR;\nOracleDialect.prototype.TICK_CHAR_RIGHT = OracleDialect.prototype.TICK_CHAR;\n\nmodule.exports = OracleDialect;\n"],
"mappings": ";AAIA,MAAM,IAAI,QAAQ;AAClB,MAAM,EAAE,oBAAoB,QAAQ;AACpC,MAAM,EAAE,4BAA4B,QAAQ;AAC5C,MAAM,EAAE,gBAAgB,QAAQ;AAChC,MAAM,EAAE,yBAAyB,QAAQ;AACzC,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,EAAE,yBAAyB,QAAQ;AAEzC,4BAA4B,gBAAgB;AAAA,EAC1C,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,wBAAwB,MAAM;AAC3D,SAAK,kBAAkB;AACvB,SAAK,iBAAiB,IAAI,qBAAqB;AAAA,MAC7C,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,qBAAqB,WAAW,KAAK;AAAA;AAAA;AAInE,cAAc,UAAU,WAAW,EAAE,MAAM,EAAE,UAAU,gBAAgB,UAAU,WAAW;AAAA,EAC1F,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,sBAAsB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,aAAa;AAAA,IACX,UAAU;AAAA;AAAA,EAEZ,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,yBAAyB;AAAA,EACzB,UAAU;AAAA;AAGZ,cAAc,UAAU,iBAAiB;AACzC,cAAc,UAAU,QAAQ;AAChC,cAAc,UAAU,iBAAiB;AACzC,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;",
"names": []
}
+939
View File
@@ -0,0 +1,939 @@
"use strict";
var __defProp = Object.defineProperty;
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 __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, {
OracleQueryGenerator: () => OracleQueryGenerator
});
const Utils = require("../../utils");
const DataTypes = require("../../data-types");
const AbstractQueryGenerator = require("../abstract/query-generator");
const _ = require("lodash");
const util = require("util");
const Transaction = require("../../transaction");
const ORACLE_RESERVED_WORDS = ["ACCESS", "ADD", "ALL", "ALTER", "AND", "ANY", "ARRAYLEN", "AS", "ASC", "AUDIT", "BETWEEN", "BY", "CHAR", "CHECK", "CLUSTER", "COLUMN", "COMMENT", "COMPRESS", "CONNECT", "CREATE", "CURRENT", "DATE", "DECIMAL", "DEFAULT", "DELETE", "DESC", "DISTINCT", "DROP", "ELSE", "EXCLUSIVE", "EXISTS", "FILE", "FLOAT", "FOR", "FROM", "GRANT", "GROUP", "HAVING", "IDENTIFIED", "IMMEDIATE", "IN", "INCREMENT", "INDEX", "INITIAL", "INSERT", "INTEGER", "INTERSECT", "INTO", "IS", "LEVEL", "LIKE", "LOCK", "LONG", "MAXEXTENTS", "MINUS", "MODE", "MODIFY", "NOAUDIT", "NOCOMPRESS", "NOT", "NOTFOUND", "NOWAIT", "NULL", "NUMBER", "OF", "OFFLINE", "ON", "ONLINE", "OPTION", "OR", "ORDER", "PCTFREE", "PRIOR", "PRIVILEGES", "PUBLIC", "RAW", "RENAME", "RESOURCE", "REVOKE", "ROW", "ROWID", "ROWLABEL", "ROWNUM", "ROWS", "SELECT", "SESSION", "SET", "SHARE", "SIZE", "SMALLINT", "SQLBUF", "START", "SUCCESSFUL", "SYNONYM", "SYSDATE", "TABLE", "THEN", "TO", "TRIGGER", "UID", "UNION", "UNIQUE", "UPDATE", "USER", "VALIDATE", "VALUES", "VARCHAR", "VARCHAR2", "VIEW", "WHENEVER", "WHERE", "WITH"];
const JSON_FUNCTION_REGEX = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i;
const JSON_OPERATOR_REGEX = /^\s*(->>?|@>|<@|\?[|&]?|\|{2}|#-)/i;
const TOKEN_CAPTURE_REGEX = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i;
class OracleQueryGenerator extends AbstractQueryGenerator {
constructor(options) {
super(options);
}
getCatalogName(value) {
if (value) {
if (this.options.quoteIdentifiers === false) {
const quotedValue = this.quoteIdentifier(value);
if (quotedValue === value) {
value = value.toUpperCase();
}
}
}
return value;
}
getSchemaNameAndTableName(table) {
const tableName = this.getCatalogName(table.tableName || table);
const schemaName = this.getCatalogName(table.schema);
return [tableName, schemaName];
}
createSchema(schema) {
const quotedSchema = this.quoteIdentifier(schema);
return [
"DECLARE",
"USER_FOUND BOOLEAN := FALSE;",
"BEGIN",
" BEGIN",
" EXECUTE IMMEDIATE ",
this.escape(`CREATE USER ${quotedSchema} IDENTIFIED BY 12345 DEFAULT TABLESPACE USERS`),
";",
" EXCEPTION WHEN OTHERS THEN",
" IF SQLCODE != -1920 THEN",
" RAISE;",
" ELSE",
" USER_FOUND := TRUE;",
" END IF;",
" END;",
" IF NOT USER_FOUND THEN",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT "CONNECT" TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE TABLE TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE VIEW TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE ANY TRIGGER TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE ANY PROCEDURE TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE SEQUENCE TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`GRANT CREATE SYNONYM TO ${quotedSchema}`),
";",
" EXECUTE IMMEDIATE ",
this.escape(`ALTER USER ${quotedSchema} QUOTA UNLIMITED ON USERS`),
";",
" END IF;",
"END;"
].join(" ");
}
showSchemasQuery() {
return `SELECT USERNAME AS "schema_name" FROM ALL_USERS WHERE COMMON = ('NO') AND USERNAME != user`;
}
dropSchema(schema) {
return [
"BEGIN",
"EXECUTE IMMEDIATE ",
this.escape(`DROP USER ${this.quoteTable(schema)} CASCADE`),
";",
"EXCEPTION WHEN OTHERS THEN",
" IF SQLCODE != -1918 THEN",
" RAISE;",
" END IF;",
"END;"
].join(" ");
}
versionQuery() {
return "SELECT VERSION_FULL FROM PRODUCT_COMPONENT_VERSION WHERE PRODUCT LIKE 'Oracle%'";
}
createTableQuery(tableName, attributes, options) {
const primaryKeys = [], foreignKeys = Object.create(null), attrStr = [], checkStr = [];
const values = {
table: this.quoteTable(tableName)
};
for (let attr in attributes) {
if (!Object.prototype.hasOwnProperty.call(attributes, attr))
continue;
const dataType = attributes[attr];
attr = this.quoteIdentifier(attr);
if (dataType.includes("PRIMARY KEY")) {
primaryKeys.push(attr);
if (dataType.includes("REFERENCES")) {
const match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${attr} ${match[1].replace(/PRIMARY KEY/, "")}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${attr} ${dataType.replace(/PRIMARY KEY/, "").trim()}`);
}
} else if (dataType.includes("REFERENCES")) {
const match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${attr} ${match[1]}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${attr} ${dataType}`);
}
}
values["attributes"] = attrStr.join(", ");
const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
if (pkString.length > 0) {
values.attributes += `,PRIMARY KEY (${pkString})`;
}
for (const fkey in foreignKeys) {
if (!Object.prototype.hasOwnProperty.call(foreignKeys, fkey))
continue;
if (foreignKeys[fkey].indexOf("ON DELETE NO ACTION") > -1) {
foreignKeys[fkey] = foreignKeys[fkey].replace("ON DELETE NO ACTION", "");
}
values.attributes += `,FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`;
}
if (checkStr.length > 0) {
values.attributes += `, ${checkStr.join(", ")}`;
}
if (options && options.indexes && options.indexes.length > 0) {
const idxToDelete = [];
options.indexes.forEach((index, idx) => {
if ("unique" in index && (index.unique === true || index.unique.length > 0 && index.unique !== false)) {
const fields = index.fields.map((field) => {
if (typeof field === "string") {
return field;
}
return field.attribute;
});
let canContinue = true;
if (options.uniqueKeys) {
const keys = Object.keys(options.uniqueKeys);
for (let fieldIdx = 0; fieldIdx < keys.length; fieldIdx++) {
const currUnique = options.uniqueKeys[keys[fieldIdx]];
if (currUnique.fields.length === fields.length) {
for (let i = 0; i < currUnique.fields.length; i++) {
const field = currUnique.fields[i];
if (_.includes(fields, field)) {
canContinue = false;
} else {
canContinue = true;
break;
}
}
}
}
if (canContinue) {
const indexName = "name" in index ? index.name : "";
const constraintToAdd = {
name: indexName,
fields
};
if (!("uniqueKeys" in options)) {
options.uniqueKeys = {};
}
options.uniqueKeys[indexName] = constraintToAdd;
idxToDelete.push(idx);
} else {
idxToDelete.push(idx);
}
}
}
});
idxToDelete.forEach((idx) => {
options.indexes.splice(idx, 1);
});
}
if (options && !!options.uniqueKeys) {
_.each(options.uniqueKeys, (columns, indexName) => {
let canBeUniq = false;
primaryKeys.forEach((primaryKey) => {
primaryKey = primaryKey.replace(/"/g, "");
if (!_.includes(columns.fields, primaryKey)) {
canBeUniq = true;
}
});
columns.fields.forEach((field) => {
let currField = "";
if (!_.isString(field)) {
currField = field.attribute.replace(/[.,"\s]/g, "");
} else {
currField = field.replace(/[.,"\s]/g, "");
}
if (currField in attributes) {
if (attributes[currField].toUpperCase().indexOf("UNIQUE") > -1 && canBeUniq) {
const attrToReplace = attributes[currField].replace("UNIQUE", "");
values.attributes = values.attributes.replace(attributes[currField], attrToReplace);
}
}
});
if (canBeUniq) {
const index = options.uniqueKeys[columns.name];
delete options.uniqueKeys[columns.name];
indexName = indexName.replace(/[.,\s]/g, "");
columns.name = indexName;
options.uniqueKeys[indexName] = index;
if (indexName.length === 0) {
values.attributes += `,UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
} else {
values.attributes += `, CONSTRAINT ${this.quoteIdentifier(indexName)} UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
}
});
}
const query = Utils.joinSQLFragments([
"CREATE TABLE",
values.table,
`(${values.attributes})`
]);
return Utils.joinSQLFragments([
"BEGIN",
"EXECUTE IMMEDIATE",
`${this.escape(query)};`,
"EXCEPTION WHEN OTHERS THEN",
"IF SQLCODE != -955 THEN",
"RAISE;",
"END IF;",
"END;"
]);
}
tableExistsQuery(table) {
const [tableName, schemaName] = this.getSchemaNameAndTableName(table);
return `SELECT TABLE_NAME FROM ALL_TABLES WHERE TABLE_NAME = ${this.escape(tableName)} AND OWNER = ${table.schema ? this.escape(schemaName) : "USER"}`;
}
describeTableQuery(tableName, schema) {
const currTableName = this.getCatalogName(tableName.tableName || tableName);
schema = this.getCatalogName(schema);
return [
"SELECT atc.COLUMN_NAME, atc.DATA_TYPE, atc.DATA_LENGTH, atc.CHAR_LENGTH, atc.DEFAULT_LENGTH, atc.NULLABLE, ucc.constraint_type ",
"FROM all_tab_columns atc ",
"LEFT OUTER JOIN ",
"(SELECT acc.column_name, acc.table_name, ac.constraint_type FROM all_cons_columns acc INNER JOIN all_constraints ac ON acc.constraint_name = ac.constraint_name) ucc ",
"ON (atc.table_name = ucc.table_name AND atc.COLUMN_NAME = ucc.COLUMN_NAME) ",
schema ? `WHERE (atc.OWNER = ${this.escape(schema)}) ` : "WHERE atc.OWNER = USER ",
`AND (atc.TABLE_NAME = ${this.escape(currTableName)})`,
"ORDER BY atc.COLUMN_NAME, CONSTRAINT_TYPE DESC"
].join("");
}
renameTableQuery(before, after) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(before),
"RENAME TO",
this.quoteTable(after)
]);
}
showConstraintsQuery(table) {
const tableName = this.getCatalogName(table.tableName || table);
return `SELECT CONSTRAINT_NAME constraint_name FROM user_cons_columns WHERE table_name = ${this.escape(tableName)}`;
}
showTablesQuery() {
return `SELECT owner as table_schema, table_name, 0 as lvl FROM all_tables where OWNER IN(SELECT USERNAME AS "schema_name" FROM ALL_USERS WHERE ORACLE_MAINTAINED = 'N')`;
}
dropTableQuery(tableName) {
return Utils.joinSQLFragments([
"BEGIN ",
"EXECUTE IMMEDIATE 'DROP TABLE",
this.quoteTable(tableName),
"CASCADE CONSTRAINTS PURGE';",
"EXCEPTION WHEN OTHERS THEN",
" IF SQLCODE != -942 THEN",
" RAISE;",
" END IF;",
"END;"
]);
}
addIndexQuery(tableName, attributes, options, rawTablename) {
if (typeof tableName !== "string" && attributes.name) {
attributes.name = `${tableName.schema}.${attributes.name}`;
}
return super.addIndexQuery(tableName, attributes, options, rawTablename);
}
addConstraintQuery(tableName, options) {
options = options || {};
if (options.onUpdate) {
delete options.onUpdate;
}
if (options.onDelete && options.onDelete.toUpperCase() === "NO ACTION") {
delete options.onDelete;
}
const constraintSnippet = this.getConstraintSnippet(tableName, options);
tableName = this.quoteTable(tableName);
return `ALTER TABLE ${tableName} ADD ${constraintSnippet};`;
}
addColumnQuery(table, key, dataType) {
dataType.field = key;
const attribute = Utils.joinSQLFragments([
this.quoteIdentifier(key),
this.attributeToSQL(dataType, {
attributeName: key,
context: "addColumn"
})
]);
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(table),
"ADD",
attribute
]);
}
removeColumnQuery(tableName, attributeName) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP COLUMN",
this.quoteIdentifier(attributeName),
";"
]);
}
_alterForeignKeyConstraint(definition, table, attributeName) {
const [tableName, schemaName] = this.getSchemaNameAndTableName(table);
const attributeNameConstant = this.escape(this.getCatalogName(attributeName));
const schemaNameConstant = table.schema ? this.escape(this.getCatalogName(schemaName)) : "USER";
const tableNameConstant = this.escape(this.getCatalogName(tableName));
const getConsNameQuery = [
"SELECT constraint_name INTO cons_name",
"FROM (",
" SELECT DISTINCT cc.owner, cc.table_name, cc.constraint_name, cc.column_name AS cons_columns",
" FROM all_cons_columns cc, all_constraints c",
" WHERE cc.owner = c.owner",
" AND cc.table_name = c.table_name",
" AND cc.constraint_name = c.constraint_name",
" AND c.constraint_type = 'R'",
" GROUP BY cc.owner, cc.table_name, cc.constraint_name, cc.column_name",
")",
"WHERE owner =",
schemaNameConstant,
"AND table_name =",
tableNameConstant,
"AND cons_columns =",
attributeNameConstant,
";"
].join(" ");
const secondQuery = Utils.joinSQLFragments([
`ALTER TABLE ${this.quoteIdentifier(tableName)}`,
"ADD FOREIGN KEY",
`(${this.quoteIdentifier(attributeName)})`,
definition.replace(/.+?(?=REFERENCES)/, "")
]);
return [
"BEGIN",
getConsNameQuery,
"EXCEPTION",
"WHEN NO_DATA_FOUND THEN",
" CONS_NAME := NULL;",
"END;",
"IF CONS_NAME IS NOT NULL THEN",
` EXECUTE IMMEDIATE 'ALTER TABLE ${this.quoteTable(table)} DROP CONSTRAINT "'||CONS_NAME||'"';`,
"END IF;",
`EXECUTE IMMEDIATE ${this.escape(secondQuery)};`
].join(" ");
}
_modifyQuery(definition, table, attributeName) {
definition = definition.startsWith("BLOB") ? definition.replace("BLOB ", "") : definition;
const query = Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(table),
"MODIFY",
this.quoteIdentifier(attributeName),
definition
]);
const secondQuery = query.replace("NOT NULL", "").replace("NULL", "");
return [
"BEGIN",
`EXECUTE IMMEDIATE ${this.escape(query)};`,
"EXCEPTION",
"WHEN OTHERS THEN",
" IF SQLCODE = -1442 OR SQLCODE = -1451 THEN",
` EXECUTE IMMEDIATE ${this.escape(secondQuery)};`,
" ELSE",
" RAISE;",
" END IF;",
"END;"
].join(" ");
}
changeColumnQuery(table, attributes) {
const sql = [
"DECLARE",
"CONS_NAME VARCHAR2(200);",
"BEGIN"
];
for (const attributeName in attributes) {
if (!Object.prototype.hasOwnProperty.call(attributes, attributeName))
continue;
const definition = attributes[attributeName];
if (definition.match(/REFERENCES/)) {
sql.push(this._alterForeignKeyConstraint(definition, table, attributeName));
} else {
sql.push(this._modifyQuery(definition, table, attributeName));
}
}
sql.push("END;");
return sql.join(" ");
}
renameColumnQuery(tableName, attrBefore, attributes) {
const newName = Object.keys(attributes)[0];
return `ALTER TABLE ${this.quoteTable(tableName)} RENAME COLUMN ${this.quoteIdentifier(attrBefore)} TO ${this.quoteIdentifier(newName)}`;
}
populateInsertQueryReturnIntoBinds(returningModelAttributes, returnTypes, inbindLength, returnAttributes, options) {
const oracledb = this.sequelize.connectionManager.lib;
const outBindAttributes = Object.create(null);
const outbind = [];
const outbindParam = this.bindParam(outbind, inbindLength);
returningModelAttributes.forEach((element, index) => {
if (element.startsWith('"')) {
element = element.substring(1, element.length - 1);
}
outBindAttributes[element] = Object.assign(returnTypes[index]._getBindDef(oracledb), { dir: oracledb.BIND_OUT });
const returnAttribute = `${this.format(void 0, void 0, { context: "INSERT" }, outbindParam)}`;
returnAttributes.push(returnAttribute);
});
options.outBindAttributes = outBindAttributes;
}
upsertQuery(tableName, insertValues, updateValues, where, model, options) {
const rawAttributes = model.rawAttributes;
const updateQuery = this.updateQuery(tableName, updateValues, where, options, rawAttributes);
options.bind = updateQuery.bind;
const insertQuery = this.insertQuery(tableName, insertValues, rawAttributes, options);
const sql = [
"DECLARE ",
"BEGIN ",
updateQuery.query ? [
updateQuery.query,
"; ",
" IF ( SQL%ROWCOUNT = 0 ) THEN ",
insertQuery.query,
" :isUpdate := 0; ",
"ELSE ",
" :isUpdate := 1; ",
" END IF; "
].join("") : [
insertQuery.query,
" :isUpdate := 0; ",
"EXCEPTION WHEN OTHERS THEN",
" IF SQLCODE != -1 THEN",
" RAISE;",
" END IF;"
].join(""),
"END;"
];
const query = sql.join("");
const result = { query };
if (options.bindParam !== false) {
result.bind = updateQuery.bind || insertQuery.bind;
}
return result;
}
bulkInsertQuery(tableName, fieldValueHashes, options, fieldMappedAttributes) {
options = options || {};
options.executeMany = true;
fieldMappedAttributes = fieldMappedAttributes || {};
const tuples = [];
const allColumns = {};
const inBindBindDefMap = {};
const outBindBindDefMap = {};
const oracledb = this.sequelize.connectionManager.lib;
for (const fieldValueHash of fieldValueHashes) {
_.forOwn(fieldValueHash, (value, key) => {
allColumns[key] = fieldMappedAttributes[key] && fieldMappedAttributes[key].autoIncrement === true && value === null;
});
}
let inBindPosition;
for (const fieldValueHash of fieldValueHashes) {
const tuple = [];
const inbindParam = options.bindParam === void 0 ? this.bindParam(tuple) : options.bindParam;
const tempBindPositions = Object.keys(allColumns).map((key) => {
if (allColumns[key] === true) {
if (fieldValueHash[key] !== null) {
throw Error("For an auto-increment column either all row must be null or non-null, a mix of null and non-null is not allowed!");
}
return "DEFAULT";
}
return this.format(fieldValueHash[key], fieldMappedAttributes[key], { context: "INSERT" }, inbindParam);
});
if (!inBindPosition) {
inBindPosition = tempBindPositions;
}
tuples.push(tuple);
}
const returnColumn = [];
const returnColumnBindPositions = [];
const insertColumns = [];
for (const key of Object.keys(allColumns)) {
if (fieldMappedAttributes[key]) {
const bindDef = fieldMappedAttributes[key].type._getBindDef(oracledb);
if (allColumns[key]) {
bindDef.dir = oracledb.BIND_OUT;
outBindBindDefMap[key] = bindDef;
returnColumn.push(this.quoteIdentifier(key));
returnColumnBindPositions.push(`:${tuples[0].length + returnColumn.length}`);
} else {
bindDef.dir = oracledb.BIND_IN;
inBindBindDefMap[key] = bindDef;
}
}
insertColumns.push(this.quoteIdentifier(key));
}
let query = Utils.joinSQLFragments([
"INSERT",
"INTO",
this.quoteTable(tableName),
`(${insertColumns.join(",")})`,
"VALUES",
`(${inBindPosition})`
]);
if (returnColumn.length > 0) {
options.outBindAttributes = outBindBindDefMap;
query = Utils.joinSQLFragments([
query,
"RETURNING",
`${returnColumn.join(",")}`,
"INTO",
`${returnColumnBindPositions}`
]);
}
const result = { query };
result.bind = tuples;
options.inbindAttributes = inBindBindDefMap;
return result;
}
truncateTableQuery(tableName) {
return `TRUNCATE TABLE ${this.quoteTable(tableName)}`;
}
deleteQuery(tableName, where, options, model) {
options = options || {};
const table = tableName;
where = this.getWhereConditions(where, null, model, options);
let queryTmpl;
if (options.limit) {
const whereTmpl = where ? ` AND ${where}` : "";
queryTmpl = `DELETE FROM ${this.quoteTable(table)} WHERE rowid IN (SELECT rowid FROM ${this.quoteTable(table)} WHERE rownum <= ${this.escape(options.limit)}${whereTmpl})`;
} else {
const whereTmpl = where ? ` WHERE ${where}` : "";
queryTmpl = `DELETE FROM ${this.quoteTable(table)}${whereTmpl}`;
}
return queryTmpl;
}
showIndexesQuery(table) {
const [tableName, owner] = this.getSchemaNameAndTableName(table);
const sql = [
"SELECT i.index_name,i.table_name, i.column_name, u.uniqueness, i.descend, c.constraint_type ",
"FROM all_ind_columns i ",
"INNER JOIN all_indexes u ",
"ON (u.table_name = i.table_name AND u.index_name = i.index_name) ",
"LEFT OUTER JOIN all_constraints c ",
"ON (c.table_name = i.table_name AND c.index_name = i.index_name) ",
`WHERE i.table_name = ${this.escape(tableName)}`,
" AND u.table_owner = ",
owner ? this.escape(owner) : "USER",
" ORDER BY index_name, column_position"
];
return sql.join("");
}
removeIndexQuery(tableName, indexNameOrAttributes) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return `DROP INDEX ${this.quoteIdentifier(indexName)}`;
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
attribute.onUpdate = "";
if (attribute.references) {
if (attribute.Model && attribute.Model.tableName === attribute.references.model) {
this.sequelize.log("Oracle does not support self referencial constraints, we will remove it but we recommend restructuring your query");
attribute.onDelete = "";
}
}
let template;
template = attribute.type.toSql ? attribute.type.toSql() : "";
if (attribute.type instanceof DataTypes.JSON) {
template += ` CHECK (${this.quoteIdentifier(options.attributeName)} IS JSON)`;
return template;
}
if (Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (attribute.allowNull === false) {
template += " NOT NULL";
}
if (attribute.type instanceof DataTypes.ENUM) {
if (attribute.type.values && !attribute.values)
attribute.values = attribute.type.values;
template += ` CHECK (${this.quoteIdentifier(options.attributeName)} IN(${_.map(attribute.values, (value) => {
return this.escape(value);
}).join(", ")}))`;
return template;
}
if (attribute.type instanceof DataTypes.BOOLEAN) {
template += ` CHECK (${this.quoteIdentifier(options.attributeName)} IN('1', '0'))`;
return template;
}
if (attribute.autoIncrement) {
template = " NUMBER(*,0) GENERATED BY DEFAULT ON NULL AS IDENTITY";
} else if (attribute.type && attribute.type.key === DataTypes.DOUBLE.key) {
template = attribute.type.toSql();
} else if (attribute.type) {
let unsignedTemplate = "";
if (attribute.type._unsigned) {
attribute.type._unsigned = false;
unsignedTemplate += ` check(${this.quoteIdentifier(options.attributeName)} >= 0)`;
}
template = attribute.type.toString();
if (attribute.type && attribute.type !== "TEXT" && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (!attribute.autoIncrement) {
if (attribute.allowNull === false) {
template += " NOT NULL";
} else if (!attribute.primaryKey && !Utils.defaultValueSchemable(attribute.defaultValue)) {
template += " NULL";
}
}
template += unsignedTemplate;
} else {
template = "";
}
if (attribute.unique === true && !attribute.primaryKey) {
template += " UNIQUE";
}
if (attribute.primaryKey) {
template += " PRIMARY KEY";
}
if ((!options || !options.withoutForeignKeyConstraints) && attribute.references) {
template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
if (attribute.references.key) {
template += ` (${this.quoteIdentifier(attribute.references.key)})`;
} else {
template += ` (${this.quoteIdentifier("id")})`;
}
if (attribute.onDelete && attribute.onDelete.toUpperCase() !== "NO ACTION") {
template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
}
return template;
}
attributesToSQL(attributes, options) {
const result = {};
for (const key in attributes) {
const attribute = attributes[key];
const attributeName = attribute.field || key;
result[attributeName] = this.attributeToSQL(attribute, __spreadValues({ attributeName }, options));
}
return result;
}
createTrigger() {
throwMethodUndefined("createTrigger");
}
dropTrigger() {
throwMethodUndefined("dropTrigger");
}
renameTrigger() {
throwMethodUndefined("renameTrigger");
}
createFunction() {
throwMethodUndefined("createFunction");
}
dropFunction() {
throwMethodUndefined("dropFunction");
}
renameFunction() {
throwMethodUndefined("renameFunction");
}
getConstraintsOnColumn(table, column) {
const [tableName, schemaName] = this.getSchemaNameAndTableName(table);
column = this.getCatalogName(column);
const sql = [
"SELECT CONSTRAINT_NAME FROM user_cons_columns WHERE TABLE_NAME = ",
this.escape(tableName),
" and OWNER = ",
table.schema ? this.escape(schemaName) : "USER",
" and COLUMN_NAME = ",
this.escape(column),
" AND POSITION IS NOT NULL ORDER BY POSITION"
].join("");
return sql;
}
getForeignKeysQuery(table) {
const [tableName, schemaName] = this.getSchemaNameAndTableName(table);
const sql = [
'SELECT DISTINCT a.table_name "tableName", a.constraint_name "constraintName", a.owner "owner", a.column_name "columnName",',
' b.table_name "referencedTableName", b.column_name "referencedColumnName"',
" FROM all_cons_columns a",
" JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name",
" JOIN all_cons_columns b ON c.owner = b.owner AND c.r_constraint_name = b.constraint_name",
" WHERE c.constraint_type = 'R'",
" AND a.table_name = ",
this.escape(tableName),
" AND a.owner = ",
table.schema ? this.escape(schemaName) : "USER",
" ORDER BY a.table_name, a.constraint_name"
].join("");
return sql;
}
dropForeignKeyQuery(tableName, foreignKey) {
return this.dropConstraintQuery(tableName, foreignKey);
}
getPrimaryKeyConstraintQuery(table) {
const [tableName, schemaName] = this.getSchemaNameAndTableName(table);
const sql = [
"SELECT cols.column_name, atc.identity_column ",
"FROM all_constraints cons, all_cons_columns cols ",
"INNER JOIN all_tab_columns atc ON(atc.table_name = cols.table_name AND atc.COLUMN_NAME = cols.COLUMN_NAME )",
"WHERE cols.table_name = ",
this.escape(tableName),
"AND cols.owner = ",
table.schema ? this.escape(schemaName) : "USER ",
"AND cons.constraint_type = 'P' ",
"AND cons.constraint_name = cols.constraint_name ",
"AND cons.owner = cols.owner ",
"ORDER BY cols.table_name, cols.position"
].join("");
return sql;
}
dropConstraintQuery(tableName, constraintName) {
return `ALTER TABLE ${this.quoteTable(tableName)} DROP CONSTRAINT ${constraintName}`;
}
setIsolationLevelQuery(value, options) {
if (options.parent) {
return;
}
switch (value) {
case Transaction.ISOLATION_LEVELS.READ_UNCOMMITTED:
case Transaction.ISOLATION_LEVELS.READ_COMMITTED:
return "SET TRANSACTION ISOLATION LEVEL READ COMMITTED;";
case Transaction.ISOLATION_LEVELS.REPEATABLE_READ:
return "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;";
default:
throw new Error(`isolation level "${value}" is not supported`);
}
}
getAliasToken() {
return "";
}
startTransactionQuery(transaction) {
if (transaction.parent) {
return `SAVEPOINT ${this.quoteIdentifier(transaction.name)}`;
}
return "BEGIN TRANSACTION";
}
commitTransactionQuery(transaction) {
if (transaction.parent) {
return;
}
return "COMMIT TRANSACTION";
}
rollbackTransactionQuery(transaction) {
if (transaction.parent) {
return `ROLLBACK TO SAVEPOINT ${this.quoteIdentifier(transaction.name)}`;
}
return "ROLLBACK TRANSACTION";
}
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
let str;
if (smth instanceof Utils.Json) {
if (smth.conditions) {
const conditions = this.parseConditionObject(smth.conditions).map((condition) => `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`);
return conditions.join(" AND ");
}
if (smth.path) {
if (this._checkValidJsonStatement(smth.path)) {
str = smth.path;
} else {
const paths = _.toPath(smth.path);
const column = paths.shift();
str = this.jsonPathExtractionQuery(column, paths);
}
if (smth.value) {
str += util.format(" = %s", this.escape(smth.value));
}
return str;
}
}
if (smth instanceof Utils.Cast) {
if (smth.val instanceof Utils.SequelizeMethod) {
str = this.handleSequelizeMethod(smth.val, tableName, factory, options, prepend);
if (smth.type === "boolean") {
str = `(CASE WHEN ${str}='true' THEN 1 ELSE 0 END)`;
return `CAST(${str} AS NUMBER)`;
}
if (smth.type === "timestamptz" && /json_value\(/.test(str)) {
str = str.slice(0, -1);
return `${str} RETURNING TIMESTAMP WITH TIME ZONE)`;
}
}
}
return super.handleSequelizeMethod(smth, tableName, factory, options, prepend);
}
_checkValidJsonStatement(stmt) {
if (typeof stmt !== "string") {
return false;
}
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 = JSON_FUNCTION_REGEX.exec(string);
if (functionMatches) {
currentIndex += functionMatches[0].indexOf("(");
hasJsonFunction = true;
continue;
}
const operatorMatches = JSON_OPERATOR_REGEX.exec(string);
if (operatorMatches) {
currentIndex += operatorMatches[0].length;
hasJsonFunction = true;
continue;
}
const tokenMatches = TOKEN_CAPTURE_REGEX.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;
}
if (hasJsonFunction && (hasInvalidToken || openingBrackets !== closingBrackets)) {
throw new Error(`Invalid json statement: ${stmt}`);
}
return hasJsonFunction;
}
jsonPathExtractionQuery(column, path) {
let paths = _.toPath(path);
const quotedColumn = this.isIdentifierQuoted(column) ? column : this.quoteIdentifier(column);
paths = paths.map((subPath) => {
return /\D/.test(subPath) ? Utils.addTicks(subPath, '"') : subPath;
});
const pathStr = this.escape(["$"].concat(paths).join(".").replace(/\.(\d+)(?:(?=\.)|$)/g, (__, digit) => `[${digit}]`));
return `json_value(${quotedColumn},${pathStr})`;
}
addLimitAndOffset(options, model) {
let fragment = "";
const offset = options.offset || 0, isSubQuery = options.hasIncludeWhere || options.hasIncludeRequired || options.hasMultiAssociation;
let orders = {};
if (options.order) {
orders = this.getQueryOrders(options, model, isSubQuery);
}
if (options.limit || options.offset) {
if (!orders.mainQueryOrder || !orders.mainQueryOrder.length || isSubQuery && (!orders.subQueryOrder || !orders.subQueryOrder.length)) {
const tablePkFragment = `${this.quoteTable(options.tableAs || model.name)}.${this.quoteIdentifier(model.primaryKeyField)}`;
fragment += ` ORDER BY ${tablePkFragment}`;
}
if (options.offset || options.limit) {
fragment += ` OFFSET ${this.escape(offset)} ROWS`;
}
if (options.limit) {
fragment += ` FETCH NEXT ${this.escape(options.limit)} ROWS ONLY`;
}
}
return fragment;
}
booleanValue(value) {
return value ? 1 : 0;
}
quoteIdentifier(identifier, force = false) {
const optForceQuote = force;
const optQuoteIdentifiers = this.options.quoteIdentifiers !== false;
const rawIdentifier = Utils.removeTicks(identifier, '"');
const regExp = /^(([\w][\w\d_]*))$/g;
if (optForceQuote !== true && optQuoteIdentifiers === false && regExp.test(rawIdentifier) && !ORACLE_RESERVED_WORDS.includes(rawIdentifier.toUpperCase())) {
return rawIdentifier;
}
return Utils.addTicks(rawIdentifier, '"');
}
bindParam(bind, posOffset = 0) {
return (value) => {
bind.push(value);
return `:${bind.length + posOffset}`;
};
}
authTestQuery() {
return "SELECT 1+1 AS result FROM DUAL";
}
}
function throwMethodUndefined(methodName) {
throw new Error(`The method "${methodName}" is not defined! Please add it to your sql dialect.`);
}
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
+75
View File
@@ -0,0 +1,75 @@
"use strict";
var __defProp = Object.defineProperty;
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 __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, {
OracleQueryInterface: () => OracleQueryInterface
});
const { QueryInterface } = require("../abstract/query-interface");
const QueryTypes = require("../../query-types");
const _ = require("lodash");
class OracleQueryInterface extends QueryInterface {
async upsert(tableName, insertValues, updateValues, where, options) {
options = __spreadValues({}, options);
const model = options.model;
const primaryKeys = Object.values(model.primaryKeys).map((item) => item.field);
const uniqueKeys = Object.values(model.uniqueKeys).filter((c) => c.fields.length > 0).map((c) => c.fields);
const indexKeys = Object.values(model._indexes).filter((c) => c.unique && c.fields.length > 0).map((c) => c.fields);
options.type = QueryTypes.UPSERT;
options.updateOnDuplicate = Object.keys(updateValues);
options.upsertKeys = [];
for (const field of options.updateOnDuplicate) {
const uniqueKey = uniqueKeys.find((fields) => fields.includes(field));
if (uniqueKey) {
options.upsertKeys = uniqueKey;
break;
}
const indexKey = indexKeys.find((fields) => fields.includes(field));
if (indexKey) {
options.upsertKeys = indexKey;
break;
}
}
if (options.upsertKeys.length === 0 || _.intersection(options.updateOnDuplicate, primaryKeys).length) {
options.upsertKeys = primaryKeys;
}
options.upsertKeys = _.uniq(options.upsertKeys);
let whereHasNull = false;
primaryKeys.forEach((element) => {
if (where[element] === null) {
whereHasNull = true;
}
});
if (whereHasNull === true) {
where = options.upsertKeys.reduce((result, attribute) => {
result[attribute] = insertValues[attribute];
return result;
}, {});
}
const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);
if (sql.bind) {
options.bind = void 0;
}
return await this.sequelize.query(sql, options);
}
}
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/oracle/query-interface.js"],
"sourcesContent": ["// Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved\n\n'use strict';\nconst { QueryInterface } = require('../abstract/query-interface');\nconst QueryTypes = require('../../query-types');\n\nconst _ = require('lodash');\n/**\n * The interface that Sequelize uses to talk with Oracle database\n */\nexport class OracleQueryInterface extends QueryInterface {\n\n /**\n * Upsert\n *\n * @param {string} tableName table to upsert on\n * @param {object} insertValues values to be inserted, mapped to field name\n * @param {object} updateValues values to be updated, mapped to field name\n * @param {object} where where conditions, which can be used for UPDATE part when INSERT fails\n * @param {object} options query options\n *\n * @returns {Promise<boolean,?number>} Resolves an array with <created, primaryKey>\n */\n async upsert(tableName, insertValues, updateValues, where, options) {\n options = { ...options };\n\n const model = options.model;\n const primaryKeys = Object.values(model.primaryKeys).map(item => item.field);\n const uniqueKeys = Object.values(model.uniqueKeys).filter(c => c.fields.length > 0).map(c => c.fields);\n const indexKeys = Object.values(model._indexes).filter(c => c.unique && c.fields.length > 0).map(c => c.fields);\n\n options.type = QueryTypes.UPSERT;\n options.updateOnDuplicate = Object.keys(updateValues);\n options.upsertKeys = [];\n\n // For fields in updateValues, try to find a constraint or unique index\n // that includes given field. Only first matching upsert key is used.\n for (const field of options.updateOnDuplicate) {\n const uniqueKey = uniqueKeys.find(fields => fields.includes(field));\n if (uniqueKey) {\n options.upsertKeys = uniqueKey;\n break;\n }\n\n const indexKey = indexKeys.find(fields => fields.includes(field));\n if (indexKey) {\n options.upsertKeys = indexKey;\n break;\n }\n }\n\n // Always use PK, if no constraint available OR update data contains PK\n if (\n options.upsertKeys.length === 0\n || _.intersection(options.updateOnDuplicate, primaryKeys).length\n ) {\n options.upsertKeys = primaryKeys;\n }\n\n options.upsertKeys = _.uniq(options.upsertKeys);\n\n let whereHasNull = false;\n\n primaryKeys.forEach(element => {\n if (where[element] === null) {\n whereHasNull = true;\n }\n });\n\n if (whereHasNull === true) {\n where = options.upsertKeys.reduce((result, attribute) => {\n result[attribute] = insertValues[attribute];\n return result;\n }, {}); \n }\n\n const sql = this.queryGenerator.upsertQuery(tableName, insertValues, updateValues, where, model, options);\n // we need set this to undefined otherwise sequelize would raise an error\n // Error: Both `sql.bind` and `options.bind` cannot be set at the same time\n if (sql.bind) {\n options.bind = undefined;\n }\n return await this.sequelize.query(sql, options);\n }\n}\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAGA,MAAM,EAAE,mBAAmB,QAAQ;AACnC,MAAM,aAAa,QAAQ;AAE3B,MAAM,IAAI,QAAQ;AAIX,mCAAmC,eAAe;AAAA,QAajD,OAAO,WAAW,cAAc,cAAc,OAAO,SAAS;AAClE,cAAU,mBAAK;AAEf,UAAM,QAAQ,QAAQ;AACtB,UAAM,cAAc,OAAO,OAAO,MAAM,aAAa,IAAI,UAAQ,KAAK;AACtE,UAAM,aAAa,OAAO,OAAO,MAAM,YAAY,OAAO,OAAK,EAAE,OAAO,SAAS,GAAG,IAAI,OAAK,EAAE;AAC/F,UAAM,YAAY,OAAO,OAAO,MAAM,UAAU,OAAO,OAAK,EAAE,UAAU,EAAE,OAAO,SAAS,GAAG,IAAI,OAAK,EAAE;AAExG,YAAQ,OAAO,WAAW;AAC1B,YAAQ,oBAAoB,OAAO,KAAK;AACxC,YAAQ,aAAa;AAIrB,eAAW,SAAS,QAAQ,mBAAmB;AAC7C,YAAM,YAAY,WAAW,KAAK,YAAU,OAAO,SAAS;AAC5D,UAAI,WAAW;AACb,gBAAQ,aAAa;AACrB;AAAA;AAGF,YAAM,WAAW,UAAU,KAAK,YAAU,OAAO,SAAS;AAC1D,UAAI,UAAU;AACZ,gBAAQ,aAAa;AACrB;AAAA;AAAA;AAKJ,QACE,QAAQ,WAAW,WAAW,KAC3B,EAAE,aAAa,QAAQ,mBAAmB,aAAa,QAC1D;AACA,cAAQ,aAAa;AAAA;AAGvB,YAAQ,aAAa,EAAE,KAAK,QAAQ;AAEpC,QAAI,eAAe;AAEnB,gBAAY,QAAQ,aAAW;AAC7B,UAAI,MAAM,aAAa,MAAM;AAC3B,uBAAe;AAAA;AAAA;AAInB,QAAI,iBAAiB,MAAM;AACzB,cAAQ,QAAQ,WAAW,OAAO,CAAC,QAAQ,cAAc;AACvD,eAAO,aAAa,aAAa;AACjC,eAAO;AAAA,SACN;AAAA;AAGL,UAAM,MAAM,KAAK,eAAe,YAAY,WAAW,cAAc,cAAc,OAAO,OAAO;AAGjG,QAAI,IAAI,MAAM;AACZ,cAAQ,OAAO;AAAA;AAEjB,WAAO,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA;AAAA;",
"names": []
}
+518
View File
@@ -0,0 +1,518 @@
"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));
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, {
OracleQuery: () => OracleQuery
});
const AbstractQuery = require("../abstract/query");
const SequelizeErrors = require("../../errors");
const parserStore = require("../parserStore")("oracle");
const _ = require("lodash");
const Utils = require("../../utils");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("sql:oracle");
class OracleQuery extends AbstractQuery {
constructor(connection, sequelize, options) {
super(connection, sequelize, options);
this.options = _.extend({
logging: console.log,
plain: false,
raw: false
}, options || {});
this.checkLoggingOption();
this.outFormat = options.outFormat || this.sequelize.connectionManager.lib.OBJECT;
}
getInsertIdField() {
return "id";
}
getExecOptions() {
const execOpts = { outFormat: this.outFormat, autoCommit: this.autoCommit };
const oracledb = this.sequelize.connectionManager.lib;
if (this.model && this.isSelectQuery()) {
const fInfo = {};
const keys = Object.keys(this.model.tableAttributes);
for (const key of keys) {
const keyValue = this.model.tableAttributes[key];
if (keyValue.type.key === "DECIMAL") {
fInfo[key] = { type: oracledb.STRING };
}
if (keyValue.type.key === "BIGINT") {
fInfo[key] = { type: oracledb.STRING };
}
}
if (fInfo) {
execOpts.fetchInfo = fInfo;
}
}
return execOpts;
}
_convertBindAttributes(bindingDictionary, oracledb) {
if (this.model && this.options[bindingDictionary]) {
const keys = Object.keys(this.model.tableAttributes);
for (const key of keys) {
const keyValue = this.model.tableAttributes[key];
if (keyValue.type.key === "BIGINT") {
const oldBinding = this.options[bindingDictionary][key];
if (oldBinding) {
this.options[bindingDictionary][key] = __spreadProps(__spreadValues({}, oldBinding), {
type: oracledb.STRING,
maxSize: 1e7
});
}
}
}
}
}
async run(sql, parameters) {
const oracledb = this.sequelize.connectionManager.lib;
const complete = this._logQuery(sql, debug, parameters);
const outParameters = [];
const bindParameters = [];
const bindDef = [];
if (!sql.match(/END;$/)) {
this.sql = sql.replace(/; *$/, "");
} else {
this.sql = sql;
}
if (this.options.outBindAttributes && (Array.isArray(parameters) || _.isPlainObject(parameters))) {
this._convertBindAttributes("outBindAttributes", oracledb);
outParameters.push(...Object.values(this.options.outBindAttributes));
if (this.isUpsertQuery()) {
outParameters.push({ dir: oracledb.BIND_OUT });
}
}
this.bindParameters = outParameters;
if (Array.isArray(parameters) || _.isPlainObject(parameters)) {
if (this.options.executeMany) {
this._convertBindAttributes("inbindAttributes", oracledb);
bindDef.push(...Object.values(this.options.inbindAttributes));
bindDef.push(...outParameters);
this.bindParameters = parameters;
} else if (this.isRawQuery()) {
this.bindParameters = parameters;
} else {
Object.values(parameters).forEach((value) => {
bindParameters.push(value);
});
bindParameters.push(...outParameters);
Object.assign(this.bindParameters, bindParameters);
}
}
if (this.sql.startsWith("BEGIN TRANSACTION")) {
this.autocommit = false;
return Promise.resolve();
}
if (this.sql.startsWith("SET AUTOCOMMIT ON")) {
this.autocommit = true;
return Promise.resolve();
}
if (this.sql.startsWith("SET AUTOCOMMIT OFF")) {
this.autocommit = false;
return Promise.resolve();
}
if (this.sql.startsWith("DECLARE x NUMBER")) {
if (this.autoCommit === void 0) {
if (this.connection.uuid) {
this.autoCommit = false;
} else {
this.autoCommit = true;
}
}
try {
await this.connection.execute(this.sql, this.bindParameters, { autoCommit: this.autoCommit });
return Object.create(null);
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
if (this.sql.startsWith("BEGIN")) {
if (this.autoCommit === void 0) {
if (this.connection.uuid) {
this.autoCommit = false;
} else {
this.autoCommit = true;
}
}
try {
const result = await this.connection.execute(this.sql, this.bindParameters, {
outFormat: this.outFormat,
autoCommit: this.autoCommit
});
if (!Array.isArray(result.outBinds)) {
return [result.outBinds];
}
return result.outBinds;
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
if (this.sql.startsWith("COMMIT TRANSACTION")) {
try {
await this.connection.commit();
return Object.create(null);
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
if (this.sql.startsWith("ROLLBACK TRANSACTION")) {
try {
await this.connection.rollback();
return Object.create(null);
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
if (this.sql.startsWith("SET TRANSACTION")) {
try {
await this.connection.execute(this.sql, [], { autoCommit: false });
return Object.create(null);
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
if (this.autoCommit === void 0) {
if (this.connection.uuid) {
this.autoCommit = false;
} else {
this.autoCommit = true;
}
}
if ("inputParameters" in this.options && this.options.inputParameters !== null) {
Object.assign(this.bindParameters, this.options.inputParameters);
}
const execOpts = this.getExecOptions();
if (this.options.executeMany && bindDef.length > 0) {
execOpts.bindDefs = bindDef;
}
const executePromise = this.options.executeMany ? this.connection.executeMany(this.sql, this.bindParameters, execOpts) : this.connection.execute(this.sql, this.bindParameters, execOpts);
try {
const result = await executePromise;
return this.formatResults(result);
} catch (error) {
throw this.formatError(error);
} finally {
complete();
}
}
static formatBindParameters(sql, values, dialect) {
const replacementFunc = (match, key, values2) => {
if (values2[key] !== void 0) {
return `:${key}`;
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
return [sql, values];
}
_getAttributeMap(attrsMap, rawAttributes) {
attrsMap = Object.assign(attrsMap, _.reduce(rawAttributes, (mp, _2, key) => {
const catalogKey = this.sequelize.queryInterface.queryGenerator.getCatalogName(key);
mp[catalogKey] = key;
return mp;
}, {}));
}
_processRows(rows) {
let result = rows;
let attrsMap = {};
if (this.sequelize.options.quoteIdentifiers === false) {
attrsMap = _.reduce(this.options.attributes, (mp, v) => {
if (typeof v === "object") {
v = v[1];
}
const catalogv = this.sequelize.queryInterface.queryGenerator.getCatalogName(v);
mp[catalogv] = v;
return mp;
}, {});
if (this.model) {
this._getAttributeMap(attrsMap, this.model.rawAttributes);
}
if (this.options.aliasesMapping) {
const obj = Object.fromEntries(this.options.aliasesMapping);
rows = rows.map((row) => _.toPairs(row).reduce((acc, [key, value]) => {
const mapping = Object.values(obj).find((element) => {
const catalogElement = this.sequelize.queryInterface.queryGenerator.getCatalogName(element);
return catalogElement === key;
});
if (mapping)
acc[mapping || key] = value;
return acc;
}, {}));
}
result = rows.map((row) => {
return _.mapKeys(row, (value, key) => {
const targetAttr = attrsMap[key];
if (typeof targetAttr === "string" && targetAttr !== key) {
return targetAttr;
}
return key;
});
});
}
if (this.model) {
result = result.map((row) => {
return _.mapValues(row, (value, key) => {
if (this.model.rawAttributes[key] && this.model.rawAttributes[key].type) {
let typeid = this.model.rawAttributes[key].type.toLocaleString();
if (this.model.rawAttributes[key].type.key === "JSON") {
value = JSON.parse(value);
}
if (typeid.indexOf("(") > -1 && this.model.rawAttributes[key].type.key !== "BOOLEAN") {
typeid = typeid.substr(0, typeid.indexOf("("));
}
const parse = parserStore.get(typeid);
if (value !== null & !!parse) {
value = parse(value);
}
}
return value;
});
});
}
return result;
}
formatResults(data) {
let result = this.instance;
if (this.isInsertQuery(data)) {
let insertData;
if (data.outBinds) {
const keys = Object.keys(this.options.outBindAttributes);
insertData = data.outBinds;
if (this.instance) {
insertData = [insertData];
}
const res = insertData.map((row) => {
const obj = {};
row.forEach((element, index) => {
obj[keys[index]] = element[0];
});
return obj;
});
insertData = res;
if (!this.instance) {
result = res;
}
}
this.handleInsertQuery(insertData);
return [result, data.rowsAffected];
}
if (this.isShowTablesQuery()) {
result = this.handleShowTablesQuery(data.rows);
} else if (this.isDescribeQuery()) {
result = {};
const table = Object.keys(this.sequelize.models);
const modelAttributes = {};
if (this.sequelize.models && table.length > 0) {
this._getAttributeMap(modelAttributes, this.sequelize.models[table[0]].rawAttributes);
}
data.rows.forEach((_result) => {
if (_result.Default) {
_result.Default = _result.Default.replace("('", "").replace("')", "").replace(/'/g, "");
}
if (!(modelAttributes[_result.COLUMN_NAME] in result)) {
let key = modelAttributes[_result.COLUMN_NAME];
if (!key) {
key = _result.COLUMN_NAME;
}
result[key] = {
type: _result.DATA_TYPE.toUpperCase(),
allowNull: _result.NULLABLE === "N" ? false : true,
defaultValue: void 0,
primaryKey: _result.CONSTRAINT_TYPE === "P"
};
}
});
} else if (this.isShowIndexesQuery()) {
result = this.handleShowIndexesQuery(data.rows);
} else if (this.isSelectQuery()) {
const rows = data.rows;
const result2 = this._processRows(rows);
return this.handleSelectQuery(result2);
} else if (this.isCallQuery()) {
result = data.rows[0];
} else if (this.isUpdateQuery()) {
result = [result, data.rowsAffected];
} else if (this.isBulkUpdateQuery()) {
result = data.rowsAffected;
} else if (this.isBulkDeleteQuery()) {
result = data.rowsAffected;
} else if (this.isVersionQuery()) {
const version = data.rows[0].VERSION_FULL;
if (version) {
const versions = version.split(".");
result = `${versions[0]}.${versions[1]}.${versions[2]}`;
} else {
result = "0.0.0";
}
} else if (this.isForeignKeysQuery()) {
result = data.rows;
} else if (this.isUpsertQuery()) {
data = data.outBinds;
const keys = Object.keys(this.options.outBindAttributes);
const obj = {};
for (const k in keys) {
obj[keys[k]] = data[k];
}
obj.isUpdate = data[data.length - 1];
data = obj;
result = [{ isNewRecord: data.isUpdate, value: data }, data.isUpdate == 0];
} else if (this.isShowConstraintsQuery()) {
result = this.handleShowConstraintsQuery(data);
} else if (this.isRawQuery()) {
if (data && data.rows) {
return [data.rows, data.metaData];
}
return [data, data];
}
return result;
}
handleShowConstraintsQuery(data) {
return data.rows.map((result) => {
const constraint = {};
for (const key in result) {
constraint[_.camelCase(key)] = result[key].toLowerCase();
}
return constraint;
});
}
handleShowTablesQuery(results) {
return results.map((resultSet) => {
return {
tableName: resultSet.TABLE_NAME,
schema: resultSet.TABLE_SCHEMA
};
});
}
formatError(err) {
let match;
match = err.message.match(/unique constraint ([\s\S]*) violated/);
if (match && match.length > 1) {
match[1] = match[1].replace("(", "").replace(")", "").split(".")[1];
const errors = [];
let fields = [], message = "Validation error", uniqueKey = null;
if (this.model) {
const uniqueKeys = Object.keys(this.model.uniqueKeys);
const currKey = uniqueKeys.find((key) => {
return key.toUpperCase() === match[1].toUpperCase() || key.toUpperCase() === `"${match[1].toUpperCase()}"`;
});
if (currKey) {
uniqueKey = this.model.uniqueKeys[currKey];
fields = uniqueKey.fields;
}
if (uniqueKey && !!uniqueKey.msg) {
message = uniqueKey.msg;
}
fields.forEach((field) => {
errors.push(new SequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, null));
});
}
return new SequelizeErrors.UniqueConstraintError({
message,
errors,
err,
fields
});
}
match = err.message.match(/ORA-02291/) || err.message.match(/ORA-02292/);
if (match && match.length > 0) {
return new SequelizeErrors.ForeignKeyConstraintError({
fields: null,
index: match[1],
parent: err
});
}
match = err.message.match(/ORA-02443/);
if (match && match.length > 0) {
return new SequelizeErrors.UnknownConstraintError(match[1]);
}
return new SequelizeErrors.DatabaseError(err);
}
isShowIndexesQuery() {
return this.sql.indexOf("SELECT i.index_name,i.table_name, i.column_name, u.uniqueness") > -1;
}
isSelectCountQuery() {
return this.sql.toUpperCase().indexOf("SELECT COUNT(") > -1;
}
handleShowIndexesQuery(data) {
const acc = [];
data.forEach((indexRecord) => {
if (!acc[indexRecord.INDEX_NAME]) {
acc[indexRecord.INDEX_NAME] = {
unique: indexRecord.UNIQUENESS === "UNIQUE" ? true : false,
primary: indexRecord.CONSTRAINT_TYPE === "P",
name: indexRecord.INDEX_NAME.toLowerCase(),
tableName: indexRecord.TABLE_NAME.toLowerCase(),
type: void 0
};
acc[indexRecord.INDEX_NAME].fields = [];
}
acc[indexRecord.INDEX_NAME].fields.push({
attribute: indexRecord.COLUMN_NAME,
length: void 0,
order: indexRecord.DESCEND,
collate: void 0
});
});
const returnIndexes = [];
const accKeys = Object.keys(acc);
for (const accKey of accKeys) {
const columns = {};
columns.fields = acc[accKey].fields;
if (acc[accKey].name.match(/sys_c[0-9]*/)) {
acc[accKey].name = Utils.nameIndex(columns, acc[accKey].tableName).name;
}
returnIndexes.push(acc[accKey]);
}
return returnIndexes;
}
handleInsertQuery(results, metaData) {
if (this.instance && results.length > 0) {
if ("pkReturnVal" in results[0]) {
results[0][this.model.primaryKeyAttribute] = results[0].pkReturnVal;
delete results[0].pkReturnVal;
}
const autoIncrementField = this.model.autoIncrementAttribute;
let autoIncrementFieldAlias = null, id = null;
if (Object.prototype.hasOwnProperty.call(this.model.rawAttributes, autoIncrementField) && this.model.rawAttributes[autoIncrementField].field !== void 0)
autoIncrementFieldAlias = this.model.rawAttributes[autoIncrementField].field;
id = id || results && results[0][this.getInsertIdField()];
id = id || metaData && metaData[this.getInsertIdField()];
id = id || results && results[0][autoIncrementField];
id = id || autoIncrementFieldAlias && results && results[0][autoIncrementFieldAlias];
this.instance[autoIncrementField] = id;
}
}
}
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
"use strict";
const stores = /* @__PURE__ */ new Map();
module.exports = (dialect) => {
if (!stores.has(dialect)) {
stores.set(dialect, /* @__PURE__ */ new Map());
}
return {
clear() {
stores.get(dialect).clear();
},
refresh(dataType) {
for (const type of dataType.types[dialect]) {
stores.get(dialect).set(type, dataType.parse);
}
},
get(type) {
return stores.get(dialect).get(type);
}
};
};
//# sourceMappingURL=parserStore.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/dialects/parserStore.js"],
"sourcesContent": ["'use strict';\n\nconst stores = new Map();\n\nmodule.exports = dialect => {\n if (!stores.has(dialect)) {\n stores.set(dialect, new Map());\n }\n\n return {\n clear() {\n stores.get(dialect).clear();\n },\n refresh(dataType) {\n for (const type of dataType.types[dialect]) {\n stores.get(dialect).set(type, dataType.parse);\n }\n },\n get(type) {\n return stores.get(dialect).get(type);\n }\n };\n};\n"],
"mappings": ";AAEA,MAAM,SAAS,oBAAI;AAEnB,OAAO,UAAU,aAAW;AAC1B,MAAI,CAAC,OAAO,IAAI,UAAU;AACxB,WAAO,IAAI,SAAS,oBAAI;AAAA;AAG1B,SAAO;AAAA,IACL,QAAQ;AACN,aAAO,IAAI,SAAS;AAAA;AAAA,IAEtB,QAAQ,UAAU;AAChB,iBAAW,QAAQ,SAAS,MAAM,UAAU;AAC1C,eAAO,IAAI,SAAS,IAAI,MAAM,SAAS;AAAA;AAAA;AAAA,IAG3C,IAAI,MAAM;AACR,aAAO,OAAO,IAAI,SAAS,IAAI;AAAA;AAAA;AAAA;",
"names": []
}
@@ -0,0 +1,244 @@
"use strict";
const _ = require("lodash");
const AbstractConnectionManager = require("../abstract/connection-manager");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("connection:pg");
const sequelizeErrors = require("../../errors");
const semver = require("semver");
const dataTypes = require("../../data-types");
const momentTz = require("moment-timezone");
const { promisify } = require("util");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 5432;
super(dialect, sequelize);
const pgLib = this._loadDialectModule("pg");
this.lib = this.sequelize.config.native ? pgLib.native : pgLib;
this._clearDynamicOIDs();
this._clearTypeParser();
this.refreshTypeParser(dataTypes.postgres);
}
_refreshTypeParser(dataType) {
const arrayParserBuilder = (parser2) => {
return (value) => this.lib.types.arrayParser.create(value, parser2).parse();
};
const rangeParserBuilder = (parser2) => {
return (value) => dataType.parse(value, { parser: parser2 });
};
if (dataType.key.toLowerCase() === "range") {
for (const name in this.nameOidMap) {
const entry = this.nameOidMap[name];
if (!entry.rangeOid)
continue;
const rangeParser = rangeParserBuilder(this.getTypeParser(entry.oid));
const arrayRangeParser = arrayParserBuilder(rangeParser);
this.oidParserMap.set(entry.rangeOid, rangeParser);
if (!entry.arrayRangeOid)
continue;
this.oidParserMap.set(entry.arrayRangeOid, arrayRangeParser);
}
return;
}
const parser = (value) => dataType.parse(value);
const arrayParser = arrayParserBuilder(parser);
if (dataType.key.toLowerCase() === "enum") {
this.enumOids.oids.forEach((oid) => {
this.oidParserMap.set(oid, parser);
});
this.enumOids.arrayOids.forEach((arrayOid) => {
this.oidParserMap.set(arrayOid, arrayParser);
});
return;
}
dataType.types.postgres.forEach((name) => {
if (!this.nameOidMap[name])
return;
this.oidParserMap.set(this.nameOidMap[name].oid, parser);
if (!this.nameOidMap[name].arrayOid)
return;
this.oidParserMap.set(this.nameOidMap[name].arrayOid, arrayParser);
});
}
_clearTypeParser() {
this.oidParserMap = /* @__PURE__ */ new Map();
}
getTypeParser(oid, ...args) {
if (this.oidParserMap.get(oid))
return this.oidParserMap.get(oid);
return this.lib.types.getTypeParser(oid, ...args);
}
async connect(config) {
config.user = config.username;
const connectionConfig = _.pick(config, [
"user",
"password",
"host",
"database",
"port"
]);
connectionConfig.types = {
getTypeParser: ConnectionManager.prototype.getTypeParser.bind(this)
};
if (config.dialectOptions) {
_.merge(connectionConfig, _.pick(config.dialectOptions, [
"application_name",
"ssl",
"client_encoding",
"binary",
"keepAlive",
"statement_timeout",
"query_timeout",
"connectionTimeoutMillis",
"idle_in_transaction_session_timeout",
"lock_timeout",
"options",
"stream"
]));
}
const connection = await new Promise((resolve, reject) => {
let responded = false;
const connection2 = new this.lib.Client(connectionConfig);
const parameterHandler = (message) => {
switch (message.parameterName) {
case "server_version":
if (this.sequelize.options.databaseVersion === 0) {
const version = semver.coerce(message.parameterValue).version;
this.sequelize.options.databaseVersion = semver.valid(version) ? version : this.dialect.defaultVersion;
}
break;
case "standard_conforming_strings":
connection2["standard_conforming_strings"] = message.parameterValue;
break;
}
};
const endHandler = () => {
debug("connection timeout");
if (!responded) {
reject(new sequelizeErrors.ConnectionTimedOutError(new Error("Connection timed out")));
}
};
connection2.once("end", endHandler);
if (!this.sequelize.config.native) {
connection2.connection.on("parameterStatus", parameterHandler);
}
connection2.connect((err) => {
responded = true;
if (!this.sequelize.config.native) {
connection2.connection.removeListener("parameterStatus", parameterHandler);
}
if (err) {
if (err.code) {
switch (err.code) {
case "ECONNREFUSED":
reject(new sequelizeErrors.ConnectionRefusedError(err));
break;
case "ENOTFOUND":
reject(new sequelizeErrors.HostNotFoundError(err));
break;
case "EHOSTUNREACH":
reject(new sequelizeErrors.HostNotReachableError(err));
break;
case "EINVAL":
reject(new sequelizeErrors.InvalidConnectionError(err));
break;
default:
reject(new sequelizeErrors.ConnectionError(err));
break;
}
} else {
reject(new sequelizeErrors.ConnectionError(err));
}
} else {
debug("connection acquired");
connection2.removeListener("end", endHandler);
resolve(connection2);
}
});
});
connection.on("error", (error) => {
connection._invalid = true;
debug(`connection error ${error.code || error.message}`);
this.pool.destroy(connection);
});
let query = "";
if (this.sequelize.options.standardConformingStrings !== false && connection["standard_conforming_strings"] !== "on") {
query += "SET standard_conforming_strings=on;";
}
if (this.sequelize.options.clientMinMessages !== void 0) {
console.warn('Usage of "options.clientMinMessages" is deprecated and will be removed in v7.');
console.warn('Please use the sequelize option "dialectOptions.clientMinMessages" instead.');
}
if (!(config.dialectOptions && config.dialectOptions.clientMinMessages && config.dialectOptions.clientMinMessages.toLowerCase() === "ignore" || this.sequelize.options.clientMinMessages === false)) {
const clientMinMessages = config.dialectOptions && config.dialectOptions.clientMinMessages || this.sequelize.options.clientMinMessages || "warning";
query += `SET client_min_messages TO ${clientMinMessages};`;
}
if (!this.sequelize.config.keepDefaultTimezone) {
const isZone = !!momentTz.tz.zone(this.sequelize.options.timezone);
if (isZone) {
query += `SET TIME ZONE '${this.sequelize.options.timezone}';`;
} else {
query += `SET TIME ZONE INTERVAL '${this.sequelize.options.timezone}' HOUR TO MINUTE;`;
}
}
if (query) {
await connection.query(query);
}
if (Object.keys(this.nameOidMap).length === 0 && this.enumOids.oids.length === 0 && this.enumOids.arrayOids.length === 0) {
await this._refreshDynamicOIDs(connection);
}
return connection;
}
async disconnect(connection) {
if (connection._ending) {
debug("connection tried to disconnect but was already at ENDING state");
return;
}
return await promisify((callback) => connection.end(callback))();
}
validate(connection) {
return !connection._invalid && !connection._ending;
}
async _refreshDynamicOIDs(connection) {
const databaseVersion = this.sequelize.options.databaseVersion;
const supportedVersion = "8.3.0";
if ((databaseVersion && semver.gte(databaseVersion, supportedVersion)) === false) {
return;
}
const results = await (connection || this.sequelize).query("WITH ranges AS ( SELECT pg_range.rngtypid, pg_type.typname AS rngtypname, pg_type.typarray AS rngtyparray, pg_range.rngsubtype FROM pg_range LEFT OUTER JOIN pg_type ON pg_type.oid = pg_range.rngtypid)SELECT pg_type.typname, pg_type.typtype, pg_type.oid, pg_type.typarray, ranges.rngtypname, ranges.rngtypid, ranges.rngtyparray FROM pg_type LEFT OUTER JOIN ranges ON pg_type.oid = ranges.rngsubtype WHERE (pg_type.typtype IN('b', 'e'));");
let result = Array.isArray(results) ? results.pop() : results;
if (Array.isArray(result)) {
if (result[0].command === "SET") {
result = result.pop();
}
}
const newNameOidMap = {};
const newEnumOids = { oids: [], arrayOids: [] };
for (const row of result.rows) {
if (row.typtype === "e") {
newEnumOids.oids.push(row.oid);
if (row.typarray)
newEnumOids.arrayOids.push(row.typarray);
continue;
}
newNameOidMap[row.typname] = { oid: row.oid };
if (row.typarray)
newNameOidMap[row.typname].arrayOid = row.typarray;
if (row.rngtypid) {
newNameOidMap[row.typname].rangeOid = row.rngtypid;
if (row.rngtyparray)
newNameOidMap[row.typname].arrayRangeOid = row.rngtyparray;
}
}
this.nameOidMap = newNameOidMap;
this.enumOids = newEnumOids;
this.refreshTypeParser(dataTypes.postgres);
}
_clearDynamicOIDs() {
this.nameOidMap = {};
this.enumOids = { oids: [], arrayOids: [] };
}
}
module.exports = ConnectionManager;
module.exports.ConnectionManager = ConnectionManager;
module.exports.default = ConnectionManager;
//# sourceMappingURL=connection-manager.js.map
File diff suppressed because one or more lines are too long
+442
View File
@@ -0,0 +1,442 @@
"use strict";
const _ = require("lodash");
const wkx = require("wkx");
module.exports = (BaseTypes) => {
const warn = BaseTypes.ABSTRACT.warn.bind(void 0, "http://www.postgresql.org/docs/9.4/static/datatype.html");
function removeUnsupportedIntegerOptions(dataType) {
if (dataType._length || dataType.options.length || dataType._unsigned || dataType._zerofill) {
warn(`PostgresSQL does not support '${dataType.key}' with LENGTH, UNSIGNED or ZEROFILL. Plain '${dataType.key}' will be used instead.`);
dataType._length = void 0;
dataType.options.length = void 0;
dataType._unsigned = void 0;
dataType._zerofill = void 0;
}
}
BaseTypes.UUID.types.postgres = ["uuid"];
BaseTypes.CIDR.types.postgres = ["cidr"];
BaseTypes.INET.types.postgres = ["inet"];
BaseTypes.MACADDR.types.postgres = ["macaddr"];
BaseTypes.TSVECTOR.types.postgres = ["tsvector"];
BaseTypes.JSON.types.postgres = ["json"];
BaseTypes.JSONB.types.postgres = ["jsonb"];
BaseTypes.TIME.types.postgres = ["time"];
class DATEONLY extends BaseTypes.DATEONLY {
_stringify(value, options) {
if (value === Infinity) {
return "Infinity";
}
if (value === -Infinity) {
return "-Infinity";
}
return super._stringify(value, options);
}
_sanitize(value, options) {
if ((!options || options && !options.raw) && value !== Infinity && value !== -Infinity) {
if (typeof value === "string") {
const lower = value.toLowerCase();
if (lower === "infinity") {
return Infinity;
}
if (lower === "-infinity") {
return -Infinity;
}
}
return super._sanitize(value);
}
return value;
}
static parse(value) {
if (value === "infinity") {
return Infinity;
}
if (value === "-infinity") {
return -Infinity;
}
return value;
}
}
BaseTypes.DATEONLY.types.postgres = ["date"];
class DECIMAL extends BaseTypes.DECIMAL {
static parse(value) {
return value;
}
}
BaseTypes.DECIMAL.types.postgres = ["numeric"];
class STRING extends BaseTypes.STRING {
toSql() {
if (this._binary) {
return "BYTEA";
}
return super.toSql();
}
}
BaseTypes.STRING.types.postgres = ["varchar"];
class TEXT extends BaseTypes.TEXT {
toSql() {
if (this._length) {
warn("PostgreSQL does not support TEXT with options. Plain `TEXT` will be used instead.");
this._length = void 0;
}
return "TEXT";
}
}
BaseTypes.TEXT.types.postgres = ["text"];
class CITEXT extends BaseTypes.CITEXT {
static parse(value) {
return value;
}
}
BaseTypes.CITEXT.types.postgres = ["citext"];
class CHAR extends BaseTypes.CHAR {
toSql() {
if (this._binary) {
return "BYTEA";
}
return super.toSql();
}
}
BaseTypes.CHAR.types.postgres = ["char", "bpchar"];
class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return "BOOLEAN";
}
_sanitize(value) {
if (value !== null && value !== void 0) {
if (Buffer.isBuffer(value) && value.length === 1) {
value = value[0];
}
if (typeof value === "string") {
return ["true", "t"].includes(value) ? true : ["false", "f"].includes(value) ? false : value;
}
if (typeof value === "number") {
return value === 1 ? true : value === 0 ? false : value;
}
}
return value;
}
}
BOOLEAN.parse = BOOLEAN.prototype._sanitize;
BaseTypes.BOOLEAN.types.postgres = ["bool"];
class DATE extends BaseTypes.DATE {
toSql() {
return "TIMESTAMP WITH TIME ZONE";
}
validate(value) {
if (value !== Infinity && value !== -Infinity) {
return super.validate(value);
}
return true;
}
_stringify(value, options) {
if (value === Infinity) {
return "Infinity";
}
if (value === -Infinity) {
return "-Infinity";
}
return super._stringify(value, options);
}
_sanitize(value, options) {
if ((!options || options && !options.raw) && !(value instanceof Date) && !!value && value !== Infinity && value !== -Infinity) {
if (typeof value === "string") {
const lower = value.toLowerCase();
if (lower === "infinity") {
return Infinity;
}
if (lower === "-infinity") {
return -Infinity;
}
}
return new Date(value);
}
return value;
}
}
BaseTypes.DATE.types.postgres = ["timestamptz"];
class TINYINT extends BaseTypes.TINYINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
BaseTypes.TINYINT.types.postgres = ["int2"];
class SMALLINT extends BaseTypes.SMALLINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
BaseTypes.SMALLINT.types.postgres = ["int2"];
class INTEGER extends BaseTypes.INTEGER {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
INTEGER.parse = function parse(value) {
return parseInt(value, 10);
};
BaseTypes.INTEGER.types.postgres = ["int4"];
class BIGINT extends BaseTypes.BIGINT {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
BaseTypes.BIGINT.types.postgres = ["int8"];
class REAL extends BaseTypes.REAL {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
BaseTypes.REAL.types.postgres = ["float4"];
class DOUBLE extends BaseTypes.DOUBLE {
constructor(length) {
super(length);
removeUnsupportedIntegerOptions(this);
}
}
BaseTypes.DOUBLE.types.postgres = ["float8"];
class FLOAT extends BaseTypes.FLOAT {
constructor(length, decimals) {
super(length, decimals);
if (this._decimals) {
warn("PostgreSQL does not support FLOAT with decimals. Plain `FLOAT` will be used instead.");
this._length = void 0;
this.options.length = void 0;
this._decimals = void 0;
}
if (this._unsigned) {
warn("PostgreSQL does not support FLOAT unsigned. `UNSIGNED` was removed.");
this._unsigned = void 0;
}
if (this._zerofill) {
warn("PostgreSQL does not support FLOAT zerofill. `ZEROFILL` was removed.");
this._zerofill = void 0;
}
}
}
delete FLOAT.parse;
class BLOB extends BaseTypes.BLOB {
toSql() {
if (this._length) {
warn("PostgreSQL does not support BLOB (BYTEA) with options. Plain `BYTEA` will be used instead.");
this._length = void 0;
}
return "BYTEA";
}
_hexify(hex) {
return `E'\\\\x${hex}'`;
}
}
BaseTypes.BLOB.types.postgres = ["bytea"];
class GEOMETRY extends BaseTypes.GEOMETRY {
toSql() {
let result = this.key;
if (this.type) {
result += `(${this.type}`;
if (this.srid) {
result += `,${this.srid}`;
}
result += ")";
}
return result;
}
static parse(value) {
const b = Buffer.from(value, "hex");
return wkx.Geometry.parse(b).toGeoJSON({ shortCrs: true });
}
_stringify(value, options) {
return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`;
}
_bindParam(value, options) {
return `ST_GeomFromGeoJSON(${options.bindParam(value)})`;
}
}
BaseTypes.GEOMETRY.types.postgres = ["geometry"];
class GEOGRAPHY extends BaseTypes.GEOGRAPHY {
toSql() {
let result = "GEOGRAPHY";
if (this.type) {
result += `(${this.type}`;
if (this.srid) {
result += `,${this.srid}`;
}
result += ")";
}
return result;
}
static parse(value) {
const b = Buffer.from(value, "hex");
return wkx.Geometry.parse(b).toGeoJSON({ shortCrs: true });
}
_stringify(value, options) {
return `ST_GeomFromGeoJSON(${options.escape(JSON.stringify(value))})`;
}
bindParam(value, options) {
return `ST_GeomFromGeoJSON(${options.bindParam(value)})`;
}
}
BaseTypes.GEOGRAPHY.types.postgres = ["geography"];
let hstore;
class HSTORE extends BaseTypes.HSTORE {
constructor() {
super();
if (!hstore) {
hstore = require("./hstore");
}
}
_value(value) {
if (!hstore) {
hstore = require("./hstore");
}
return hstore.stringify(value);
}
_stringify(value) {
return `'${this._value(value)}'`;
}
_bindParam(value, options) {
return options.bindParam(this._value(value));
}
static parse(value) {
if (!hstore) {
hstore = require("./hstore");
}
return hstore.parse(value);
}
}
HSTORE.prototype.escape = false;
BaseTypes.HSTORE.types.postgres = ["hstore"];
class RANGE extends BaseTypes.RANGE {
_value(values, options) {
if (!Array.isArray(values)) {
return this.options.subtype.stringify(values, options);
}
const valueInclusivity = [true, false];
const valuesStringified = values.map((value, index) => {
if (_.isObject(value) && Object.prototype.hasOwnProperty.call(value, "value")) {
if (Object.prototype.hasOwnProperty.call(value, "inclusive")) {
valueInclusivity[index] = value.inclusive;
}
value = value.value;
}
if (value === null || value === -Infinity || value === Infinity) {
return value;
}
if (this.options.subtype.stringify) {
return this.options.subtype.stringify(value, options);
}
return options.escape(value);
});
valuesStringified.inclusive = valueInclusivity;
return range.stringify(valuesStringified);
}
_stringify(values, options) {
const value = this._value(values, options);
if (!Array.isArray(values)) {
return `'${value}'::${this.toCastType()}`;
}
return `'${value}'`;
}
_bindParam(values, options) {
const value = this._value(values, options);
if (!Array.isArray(values)) {
return `${options.bindParam(value)}::${this.toCastType()}`;
}
return options.bindParam(value);
}
toSql() {
return BaseTypes.RANGE.types.postgres.subtypes[this._subtype.toLowerCase()];
}
toCastType() {
return BaseTypes.RANGE.types.postgres.castTypes[this._subtype.toLowerCase()];
}
static parse(value, options = { parser: (val) => val }) {
return range.parse(value, options.parser);
}
}
const range = require("./range");
RANGE.prototype.escape = false;
BaseTypes.RANGE.types.postgres = {
subtypes: {
integer: "int4range",
decimal: "numrange",
date: "tstzrange",
dateonly: "daterange",
bigint: "int8range"
},
castTypes: {
integer: "int4",
decimal: "numeric",
date: "timestamptz",
dateonly: "date",
bigint: "int8"
}
};
BaseTypes.ARRAY.prototype.escape = false;
BaseTypes.ARRAY.prototype._value = function _value(values, options) {
return values.map((value) => {
if (options && options.bindParam && this.type && this.type._value) {
return this.type._value(value, options);
}
if (this.type && this.type.stringify) {
value = this.type.stringify(value, options);
if (this.type.escape === false) {
return value;
}
}
return options.escape(value);
}, this);
};
BaseTypes.ARRAY.prototype._stringify = function _stringify(values, options) {
let str = `ARRAY[${this._value(values, options).join(",")}]`;
if (this.type) {
const Utils = require("../../utils");
let castKey = this.toSql();
if (this.type instanceof BaseTypes.ENUM) {
const table = options.field.Model.getTableName();
const useSchema = table.schema !== void 0;
const schemaWithDelimiter = useSchema ? `${Utils.addTicks(table.schema, '"')}${table.delimiter}` : "";
castKey = `${Utils.addTicks(Utils.generateEnumName(useSchema ? table.tableName : table, options.field.field), '"')}[]`;
str += `::${schemaWithDelimiter}${castKey}`;
} else {
str += `::${castKey}`;
}
}
return str;
};
BaseTypes.ARRAY.prototype._bindParam = function _bindParam(values, options) {
return options.bindParam(this._value(values, options));
};
class ENUM extends BaseTypes.ENUM {
static parse(value) {
return value;
}
}
BaseTypes.ENUM.types.postgres = [null];
return {
DECIMAL,
BLOB,
STRING,
CHAR,
TEXT,
CITEXT,
TINYINT,
SMALLINT,
INTEGER,
BIGINT,
BOOLEAN,
DATE,
DATEONLY,
REAL,
"DOUBLE PRECISION": DOUBLE,
FLOAT,
GEOMETRY,
GEOGRAPHY,
HSTORE,
RANGE,
ENUM
};
};
//# sourceMappingURL=data-types.js.map
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
"use strict";
const hstore = require("pg-hstore")({ sanitize: true });
function stringify(data) {
if (data === null)
return null;
return hstore.stringify(data);
}
exports.stringify = stringify;
function parse(value) {
if (value === null)
return null;
return hstore.parse(value);
}
exports.parse = parse;
//# sourceMappingURL=hstore.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/postgres/hstore.js"],
"sourcesContent": ["'use strict';\n\nconst hstore = require('pg-hstore')({ sanitize: true });\n\nfunction stringify(data) {\n if (data === null) return null;\n return hstore.stringify(data);\n}\nexports.stringify = stringify;\n\nfunction parse(value) {\n if (value === null) return null;\n return hstore.parse(value);\n}\nexports.parse = parse;\n"],
"mappings": ";AAEA,MAAM,SAAS,QAAQ,aAAa,EAAE,UAAU;AAEhD,mBAAmB,MAAM;AACvB,MAAI,SAAS;AAAM,WAAO;AAC1B,SAAO,OAAO,UAAU;AAAA;AAE1B,QAAQ,YAAY;AAEpB,eAAe,OAAO;AACpB,MAAI,UAAU;AAAM,WAAO;AAC3B,SAAO,OAAO,MAAM;AAAA;AAEtB,QAAQ,QAAQ;",
"names": []
}
+77
View File
@@ -0,0 +1,77 @@
"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").postgres;
const { PostgresQueryInterface } = require("./query-interface");
class PostgresDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new PostgresQueryInterface(sequelize, this.queryGenerator);
}
canBackslashEscape() {
return !this.sequelize.options.standardConformingStrings;
}
}
PostgresDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"DEFAULT VALUES": true,
EXCEPTION: true,
"ON DUPLICATE KEY": false,
"ORDER NULLS": true,
returnValues: {
returning: true
},
bulkDefault: true,
schemas: true,
lock: true,
lockOf: true,
lockKey: true,
lockOuterJoinFailure: true,
skipLocked: true,
forShare: "FOR SHARE",
index: {
concurrently: true,
using: 2,
where: true,
functionBased: true,
operator: true
},
inserts: {
onConflictDoNothing: " ON CONFLICT DO NOTHING",
updateOnDuplicate: " ON CONFLICT DO UPDATE SET",
conflictFields: true,
onConflictWhere: true
},
NUMERIC: true,
ARRAY: true,
RANGE: true,
GEOMETRY: true,
REGEXP: true,
GEOGRAPHY: true,
JSON: true,
JSONB: true,
HSTORE: true,
TSVECTOR: true,
deferrableConstraints: true,
searchPath: true,
escapeStringConstants: true
});
PostgresDialect.prototype.defaultVersion = "9.5.0";
PostgresDialect.prototype.Query = Query;
PostgresDialect.prototype.DataTypes = DataTypes;
PostgresDialect.prototype.name = "postgres";
PostgresDialect.prototype.TICK_CHAR = '"';
PostgresDialect.prototype.TICK_CHAR_LEFT = PostgresDialect.prototype.TICK_CHAR;
PostgresDialect.prototype.TICK_CHAR_RIGHT = PostgresDialect.prototype.TICK_CHAR;
module.exports = PostgresDialect;
module.exports.default = PostgresDialect;
module.exports.PostgresDialect = PostgresDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/postgres/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').postgres;\nconst { PostgresQueryInterface } = require('./query-interface');\n\nclass PostgresDialect 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 this.queryInterface = new PostgresQueryInterface(\n sequelize,\n this.queryGenerator\n );\n }\n\n canBackslashEscape() {\n // postgres can use \\ to escape if one of these is true:\n // - standard_conforming_strings is off\n // - the string is prefixed with E (out of scope for this method)\n\n return !this.sequelize.options.standardConformingStrings;\n }\n}\n\nPostgresDialect.prototype.supports = _.merge(\n _.cloneDeep(AbstractDialect.prototype.supports),\n {\n 'DEFAULT VALUES': true,\n EXCEPTION: true,\n 'ON DUPLICATE KEY': false,\n 'ORDER NULLS': true,\n returnValues: {\n returning: true\n },\n bulkDefault: true,\n schemas: true,\n lock: true,\n lockOf: true,\n lockKey: true,\n lockOuterJoinFailure: true,\n skipLocked: true,\n forShare: 'FOR SHARE',\n index: {\n concurrently: true,\n using: 2,\n where: true,\n functionBased: true,\n operator: true\n },\n inserts: {\n onConflictDoNothing: ' ON CONFLICT DO NOTHING',\n updateOnDuplicate: ' ON CONFLICT DO UPDATE SET',\n conflictFields: true,\n onConflictWhere: true\n },\n NUMERIC: true,\n ARRAY: true,\n RANGE: true,\n GEOMETRY: true,\n REGEXP: true,\n GEOGRAPHY: true,\n JSON: true,\n JSONB: true,\n HSTORE: true,\n TSVECTOR: true,\n deferrableConstraints: true,\n searchPath: true,\n escapeStringConstants: true\n }\n);\n\nPostgresDialect.prototype.defaultVersion = '9.5.0'; // minimum supported version\nPostgresDialect.prototype.Query = Query;\nPostgresDialect.prototype.DataTypes = DataTypes;\nPostgresDialect.prototype.name = 'postgres';\nPostgresDialect.prototype.TICK_CHAR = '\"';\nPostgresDialect.prototype.TICK_CHAR_LEFT = PostgresDialect.prototype.TICK_CHAR;\nPostgresDialect.prototype.TICK_CHAR_RIGHT = PostgresDialect.prototype.TICK_CHAR;\n\nmodule.exports = PostgresDialect;\nmodule.exports.default = PostgresDialect;\nmodule.exports.PostgresDialect = PostgresDialect;\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,2BAA2B,QAAQ;AAE3C,8BAA8B,gBAAgB;AAAA,EAC5C,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,uBACxB,WACA,KAAK;AAAA;AAAA,EAIT,qBAAqB;AAKnB,WAAO,CAAC,KAAK,UAAU,QAAQ;AAAA;AAAA;AAInC,gBAAgB,UAAU,WAAW,EAAE,MACrC,EAAE,UAAU,gBAAgB,UAAU,WACtC;AAAA,EACE,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,cAAc;AAAA,IACZ,WAAW;AAAA;AAAA,EAEb,aAAa;AAAA,EACb,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,OAAO;AAAA,IACL,cAAc;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,eAAe;AAAA,IACf,UAAU;AAAA;AAAA,EAEZ,SAAS;AAAA,IACP,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA;AAAA,EAEnB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,uBAAuB;AAAA,EACvB,YAAY;AAAA,EACZ,uBAAuB;AAAA;AAI3B,gBAAgB,UAAU,iBAAiB;AAC3C,gBAAgB,UAAU,QAAQ;AAClC,gBAAgB,UAAU,YAAY;AACtC,gBAAgB,UAAU,OAAO;AACjC,gBAAgB,UAAU,YAAY;AACtC,gBAAgB,UAAU,iBAAiB,gBAAgB,UAAU;AACrE,gBAAgB,UAAU,kBAAkB,gBAAgB,UAAU;AAEtE,OAAO,UAAU;AACjB,OAAO,QAAQ,UAAU;AACzB,OAAO,QAAQ,kBAAkB;",
"names": []
}
+671
View File
@@ -0,0 +1,671 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const Utils = require("../../utils");
const util = require("util");
const DataTypes = require("../../data-types");
const AbstractQueryGenerator = require("../abstract/query-generator");
const semver = require("semver");
const _ = require("lodash");
const POSTGRES_RESERVED_WORDS = "all,analyse,analyze,and,any,array,as,asc,asymmetric,authorization,binary,both,case,cast,check,collate,collation,column,concurrently,constraint,create,cross,current_catalog,current_date,current_role,current_schema,current_time,current_timestamp,current_user,default,deferrable,desc,distinct,do,else,end,except,false,fetch,for,foreign,freeze,from,full,grant,group,having,ilike,in,initially,inner,intersect,into,is,isnull,join,lateral,leading,left,like,limit,localtime,localtimestamp,natural,not,notnull,null,offset,on,only,or,order,outer,overlaps,placing,primary,references,returning,right,select,session_user,similar,some,symmetric,table,tablesample,then,to,trailing,true,union,unique,user,using,variadic,verbose,when,where,window,with".split(",");
class PostgresQueryGenerator extends AbstractQueryGenerator {
setSearchPath(searchPath) {
return `SET search_path to ${searchPath};`;
}
createDatabaseQuery(databaseName, options) {
options = __spreadValues({
encoding: null,
collate: null
}, options);
const values = {
database: this.quoteTable(databaseName),
encoding: options.encoding ? ` ENCODING = ${this.escape(options.encoding)}` : "",
collation: options.collate ? ` LC_COLLATE = ${this.escape(options.collate)}` : "",
ctype: options.ctype ? ` LC_CTYPE = ${this.escape(options.ctype)}` : "",
template: options.template ? ` TEMPLATE = ${this.escape(options.template)}` : ""
};
return `CREATE DATABASE ${values.database}${values.encoding}${values.collation}${values.ctype}${values.template};`;
}
dropDatabaseQuery(databaseName) {
return `DROP DATABASE IF EXISTS ${this.quoteTable(databaseName)};`;
}
createSchema(schema) {
const databaseVersion = _.get(this, "sequelize.options.databaseVersion", 0);
if (databaseVersion && semver.gte(databaseVersion, "9.2.0")) {
return `CREATE SCHEMA IF NOT EXISTS ${this.quoteIdentifier(schema)};`;
}
return `CREATE SCHEMA ${this.quoteIdentifier(schema)};`;
}
dropSchema(schema) {
return `DROP SCHEMA IF EXISTS ${this.quoteIdentifier(schema)} CASCADE;`;
}
showSchemasQuery() {
return "SELECT schema_name FROM information_schema.schemata WHERE schema_name <> 'information_schema' AND schema_name != 'public' AND schema_name !~ E'^pg_';";
}
versionQuery() {
return "SHOW SERVER_VERSION";
}
createTableQuery(tableName, attributes, options) {
options = __spreadValues({}, options);
const databaseVersion = _.get(this, "sequelize.options.databaseVersion", 0);
const attrStr = [];
let comments = "";
let columnComments = "";
const quotedTable = this.quoteTable(tableName);
if (options.comment && typeof options.comment === "string") {
comments += `; COMMENT ON TABLE ${quotedTable} IS ${this.escape(options.comment)}`;
}
for (const attr in attributes) {
const quotedAttr = this.quoteIdentifier(attr);
const i = attributes[attr].indexOf("COMMENT ");
if (i !== -1) {
const escapedCommentText = this.escape(attributes[attr].substring(i + 8));
columnComments += `; COMMENT ON COLUMN ${quotedTable}.${quotedAttr} IS ${escapedCommentText}`;
attributes[attr] = attributes[attr].substring(0, i);
}
const dataType = this.dataTypeMapping(tableName, attr, attributes[attr]);
attrStr.push(`${quotedAttr} ${dataType}`);
}
let attributesClause = attrStr.join(", ");
if (options.uniqueKeys) {
_.each(options.uniqueKeys, (columns) => {
if (columns.customIndex) {
attributesClause += `, UNIQUE (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
});
}
const pks = _.reduce(attributes, (acc, attribute, key) => {
if (attribute.includes("PRIMARY KEY")) {
acc.push(this.quoteIdentifier(key));
}
return acc;
}, []).join(",");
if (pks.length > 0) {
attributesClause += `, PRIMARY KEY (${pks})`;
}
return `CREATE TABLE ${databaseVersion === 0 || semver.gte(databaseVersion, "9.1.0") ? "IF NOT EXISTS " : ""}${quotedTable} (${attributesClause})${comments}${columnComments};`;
}
dropTableQuery(tableName, options) {
options = options || {};
return `DROP TABLE IF EXISTS ${this.quoteTable(tableName)}${options.cascade ? " CASCADE" : ""};`;
}
showTablesQuery() {
const schema = this.options.schema || "public";
return `SELECT table_name FROM information_schema.tables WHERE table_schema = ${this.escape(schema)} AND table_type LIKE '%TABLE' AND table_name != 'spatial_ref_sys';`;
}
tableExistsQuery(tableName) {
const table = tableName.tableName || tableName;
const schema = tableName.schema || "public";
return `SELECT table_name FROM information_schema.tables WHERE table_schema = ${this.escape(schema)} AND table_name = ${this.escape(table)}`;
}
describeTableQuery(tableName, schema) {
schema = schema || this.options.schema || "public";
return `SELECT pk.constraint_type as "Constraint",c.column_name as "Field", c.column_default as "Default",c.is_nullable as "Null", (CASE WHEN c.udt_name = 'hstore' THEN c.udt_name ELSE c.data_type END) || (CASE WHEN c.character_maximum_length IS NOT NULL THEN '(' || c.character_maximum_length || ')' ELSE '' END) as "Type", (SELECT array_agg(e.enumlabel) FROM pg_catalog.pg_type t JOIN pg_catalog.pg_enum e ON t.oid=e.enumtypid WHERE t.typname=c.udt_name) AS "special", (SELECT pgd.description FROM pg_catalog.pg_statio_all_tables AS st INNER JOIN pg_catalog.pg_description pgd on (pgd.objoid=st.relid) WHERE c.ordinal_position=pgd.objsubid AND c.table_name=st.relname) AS "Comment" FROM information_schema.columns c LEFT JOIN (SELECT tc.table_schema, tc.table_name, cu.column_name, tc.constraint_type FROM information_schema.TABLE_CONSTRAINTS tc JOIN information_schema.KEY_COLUMN_USAGE cu ON tc.table_schema=cu.table_schema and tc.table_name=cu.table_name and tc.constraint_name=cu.constraint_name and tc.constraint_type='PRIMARY KEY') pk ON pk.table_schema=c.table_schema AND pk.table_name=c.table_name AND pk.column_name=c.column_name WHERE c.table_name = ${this.escape(tableName)} AND c.table_schema = ${this.escape(schema)}`;
}
_checkValidJsonStatement(stmt) {
if (typeof stmt !== "string") {
return false;
}
const jsonFunctionRegex = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i;
const jsonOperatorRegex = /^\s*(->>?|#>>?|@>|<@|\?[|&]?|\|{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 operatorMatches = jsonOperatorRegex.exec(string);
if (operatorMatches) {
currentIndex += operatorMatches[0].length;
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;
}
handleSequelizeMethod(smth, tableName, factory, options, prepend) {
if (smth instanceof Utils.Json) {
if (smth.conditions) {
const conditions = this.parseConditionObject(smth.conditions).map((condition) => `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`);
return conditions.join(" AND ");
}
if (smth.path) {
let str;
if (this._checkValidJsonStatement(smth.path)) {
str = smth.path;
} else {
const paths = _.toPath(smth.path);
const column = paths.shift();
str = this.jsonPathExtractionQuery(column, paths);
}
if (smth.value) {
str += util.format(" = %s", this.escape(smth.value));
}
return str;
}
}
return super.handleSequelizeMethod.call(this, smth, tableName, factory, options, prepend);
}
addColumnQuery(table, key, attribute) {
const dbDataType = this.attributeToSQL(attribute, { context: "addColumn", table, key });
const dataType = attribute.type || attribute;
const definition = this.dataTypeMapping(table, key, dbDataType);
const quotedKey = this.quoteIdentifier(key);
const quotedTable = this.quoteTable(this.extractTableDetails(table));
let query = `ALTER TABLE ${quotedTable} ADD COLUMN ${quotedKey} ${definition};`;
if (dataType instanceof DataTypes.ENUM) {
query = this.pgEnum(table, key, dataType) + query;
} else if (dataType.type && dataType.type instanceof DataTypes.ENUM) {
query = this.pgEnum(table, key, dataType.type) + query;
}
return query;
}
removeColumnQuery(tableName, attributeName) {
const quotedTableName = this.quoteTable(this.extractTableDetails(tableName));
const quotedAttributeName = this.quoteIdentifier(attributeName);
return `ALTER TABLE ${quotedTableName} DROP COLUMN ${quotedAttributeName};`;
}
changeColumnQuery(tableName, attributes) {
const query = (subQuery) => `ALTER TABLE ${this.quoteTable(tableName)} ALTER COLUMN ${subQuery};`;
const sql = [];
for (const attributeName in attributes) {
let definition = this.dataTypeMapping(tableName, attributeName, attributes[attributeName]);
let attrSql = "";
if (definition.includes("NOT NULL")) {
attrSql += query(`${this.quoteIdentifier(attributeName)} SET NOT NULL`);
definition = definition.replace("NOT NULL", "").trim();
} else if (!definition.includes("REFERENCES")) {
attrSql += query(`${this.quoteIdentifier(attributeName)} DROP NOT NULL`);
}
if (definition.includes("DEFAULT")) {
attrSql += query(`${this.quoteIdentifier(attributeName)} SET DEFAULT ${definition.match(/DEFAULT ([^;]+)/)[1]}`);
definition = definition.replace(/(DEFAULT[^;]+)/, "").trim();
} else if (!definition.includes("REFERENCES")) {
attrSql += query(`${this.quoteIdentifier(attributeName)} DROP DEFAULT`);
}
if (attributes[attributeName].startsWith("ENUM(")) {
attrSql += this.pgEnum(tableName, attributeName, attributes[attributeName]);
definition = definition.replace(/^ENUM\(.+\)/, this.pgEnumName(tableName, attributeName, { schema: false }));
definition += ` USING (${this.quoteIdentifier(attributeName)}::${this.pgEnumName(tableName, attributeName)})`;
}
if (definition.match(/UNIQUE;*$/)) {
definition = definition.replace(/UNIQUE;*$/, "");
attrSql += query(`ADD UNIQUE (${this.quoteIdentifier(attributeName)})`).replace("ALTER COLUMN", "");
}
if (definition.includes("REFERENCES")) {
definition = definition.replace(/.+?(?=REFERENCES)/, "");
attrSql += query(`ADD FOREIGN KEY (${this.quoteIdentifier(attributeName)}) ${definition}`).replace("ALTER COLUMN", "");
} else {
attrSql += query(`${this.quoteIdentifier(attributeName)} TYPE ${definition}`);
}
sql.push(attrSql);
}
return sql.join("");
}
renameColumnQuery(tableName, attrBefore, attributes) {
const attrString = [];
for (const attributeName in attributes) {
attrString.push(`${this.quoteIdentifier(attrBefore)} TO ${this.quoteIdentifier(attributeName)}`);
}
return `ALTER TABLE ${this.quoteTable(tableName)} RENAME COLUMN ${attrString.join(", ")};`;
}
fn(fnName, tableName, parameters, body, returns, language) {
fnName = fnName || "testfunc";
language = language || "plpgsql";
returns = returns ? `RETURNS ${returns}` : "";
parameters = parameters || "";
return `CREATE OR REPLACE FUNCTION pg_temp.${fnName}(${parameters}) ${returns} AS $func$ BEGIN ${body} END; $func$ LANGUAGE ${language}; SELECT * FROM pg_temp.${fnName}();`;
}
truncateTableQuery(tableName, options = {}) {
return [
`TRUNCATE ${this.quoteTable(tableName)}`,
options.restartIdentity ? " RESTART IDENTITY" : "",
options.cascade ? " CASCADE" : ""
].join("");
}
deleteQuery(tableName, where, options = {}, model) {
const table = this.quoteTable(tableName);
let whereClause = this.getWhereConditions(where, null, model, options);
const limit = options.limit ? ` LIMIT ${this.escape(options.limit)}` : "";
let primaryKeys = "";
let primaryKeysSelection = "";
if (whereClause) {
whereClause = ` WHERE ${whereClause}`;
}
if (options.limit) {
if (!model) {
throw new Error("Cannot LIMIT delete without a model.");
}
const pks = Object.values(model.primaryKeys).map((pk) => this.quoteIdentifier(pk.field)).join(",");
primaryKeys = model.primaryKeyAttributes.length > 1 ? `(${pks})` : pks;
primaryKeysSelection = pks;
return `DELETE FROM ${table} WHERE ${primaryKeys} IN (SELECT ${primaryKeysSelection} FROM ${table}${whereClause}${limit})`;
}
return `DELETE FROM ${table}${whereClause}`;
}
showIndexesQuery(tableName) {
let schemaJoin = "";
let schemaWhere = "";
if (typeof tableName !== "string") {
schemaJoin = ", pg_namespace s";
schemaWhere = ` AND s.oid = t.relnamespace AND s.nspname = '${tableName.schema}'`;
tableName = tableName.tableName;
}
return `SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a${schemaJoin} WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = '${tableName}'${schemaWhere} GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;`;
}
showConstraintsQuery(tableName) {
return [
'SELECT constraint_catalog AS "constraintCatalog",',
'constraint_schema AS "constraintSchema",',
'constraint_name AS "constraintName",',
'table_catalog AS "tableCatalog",',
'table_schema AS "tableSchema",',
'table_name AS "tableName",',
'constraint_type AS "constraintType",',
'is_deferrable AS "isDeferrable",',
'initially_deferred AS "initiallyDeferred"',
"from INFORMATION_SCHEMA.table_constraints",
`WHERE table_name='${tableName}';`
].join(" ");
}
removeIndexQuery(tableName, indexNameOrAttributes, options) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return [
"DROP INDEX",
options && options.concurrently && "CONCURRENTLY",
`IF EXISTS ${this.quoteIdentifiers(indexName)}`
].filter(Boolean).join(" ");
}
addLimitAndOffset(options) {
let fragment = "";
if (options.limit != null) {
fragment += " LIMIT " + this.escape(options.limit);
}
if (options.offset != null) {
fragment += " OFFSET " + this.escape(options.offset);
}
return fragment;
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
let type;
if (attribute.type instanceof DataTypes.ENUM || attribute.type instanceof DataTypes.ARRAY && attribute.type.type instanceof DataTypes.ENUM) {
const enumType = attribute.type.type || attribute.type;
let values = attribute.values;
if (enumType.values && !attribute.values) {
values = enumType.values;
}
if (Array.isArray(values) && values.length > 0) {
type = `ENUM(${values.map((value) => this.escape(value)).join(", ")})`;
if (attribute.type instanceof DataTypes.ARRAY) {
type += "[]";
}
} else {
throw new Error("Values for ENUM haven't been defined.");
}
}
if (!type) {
type = attribute.type;
}
let sql = type.toString();
if (Object.prototype.hasOwnProperty.call(attribute, "allowNull") && !attribute.allowNull) {
sql += " NOT NULL";
}
if (attribute.autoIncrement) {
if (attribute.autoIncrementIdentity) {
sql += " GENERATED BY DEFAULT AS IDENTITY";
} else {
sql += " SERIAL";
}
}
if (Utils.defaultValueSchemable(attribute.defaultValue)) {
sql += ` DEFAULT ${this.escape(attribute.defaultValue, attribute)}`;
}
if (attribute.unique === true) {
sql += " UNIQUE";
}
if (attribute.primaryKey) {
sql += " PRIMARY KEY";
}
if (attribute.references) {
let referencesTable = this.quoteTable(attribute.references.model);
let schema;
if (options.schema) {
schema = options.schema;
} else if ((!attribute.references.model || typeof attribute.references.model == "string") && options.table && options.table.schema) {
schema = options.table.schema;
}
if (schema) {
referencesTable = this.quoteTable(this.addSchema({
tableName: referencesTable,
_schema: schema
}));
}
let referencesKey;
if (!options.withoutForeignKeyConstraints) {
if (attribute.references.key) {
referencesKey = this.quoteIdentifiers(attribute.references.key);
} else {
referencesKey = this.quoteIdentifier("id");
}
sql += ` REFERENCES ${referencesTable} (${referencesKey})`;
if (attribute.onDelete) {
sql += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
if (attribute.onUpdate) {
sql += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
}
if (attribute.references.deferrable) {
sql += ` ${attribute.references.deferrable.toString(this)}`;
}
}
}
if (attribute.comment && typeof attribute.comment === "string") {
if (options && ["addColumn", "changeColumn"].includes(options.context)) {
const quotedAttr = this.quoteIdentifier(options.key);
const escapedCommentText = this.escape(attribute.comment);
sql += `; COMMENT ON COLUMN ${this.quoteTable(options.table)}.${quotedAttr} IS ${escapedCommentText}`;
} else {
sql += ` COMMENT ${attribute.comment}`;
}
}
return sql;
}
deferConstraintsQuery(options) {
return options.deferrable.toString(this);
}
setConstraintQuery(columns, type) {
let columnFragment = "ALL";
if (columns) {
columnFragment = columns.map((column) => this.quoteIdentifier(column)).join(", ");
}
return `SET CONSTRAINTS ${columnFragment} ${type}`;
}
setDeferredQuery(columns) {
return this.setConstraintQuery(columns, "DEFERRED");
}
setImmediateQuery(columns) {
return this.setConstraintQuery(columns, "IMMEDIATE");
}
attributesToSQL(attributes, options) {
const result = {};
for (const key in attributes) {
const attribute = attributes[key];
result[attribute.field || key] = this.attributeToSQL(attribute, __spreadValues({ key }, options));
}
return result;
}
createTrigger(tableName, triggerName, eventType, fireOnSpec, functionName, functionParams, optionsArray) {
const decodedEventType = this.decodeTriggerEventType(eventType);
const eventSpec = this.expandTriggerEventSpec(fireOnSpec);
const expandedOptions = this.expandOptions(optionsArray);
const paramList = this._expandFunctionParamList(functionParams);
return `CREATE ${this.triggerEventTypeIsConstraint(eventType)}TRIGGER ${this.quoteIdentifier(triggerName)} ${decodedEventType} ${eventSpec} ON ${this.quoteTable(tableName)}${expandedOptions ? ` ${expandedOptions}` : ""} EXECUTE PROCEDURE ${functionName}(${paramList});`;
}
dropTrigger(tableName, triggerName) {
return `DROP TRIGGER ${this.quoteIdentifier(triggerName)} ON ${this.quoteTable(tableName)} RESTRICT;`;
}
renameTrigger(tableName, oldTriggerName, newTriggerName) {
return `ALTER TRIGGER ${this.quoteIdentifier(oldTriggerName)} ON ${this.quoteTable(tableName)} RENAME TO ${this.quoteIdentifier(newTriggerName)};`;
}
createFunction(functionName, params, returnType, language, body, optionsArray, options) {
if (!functionName || !returnType || !language || !body)
throw new Error("createFunction missing some parameters. Did you pass functionName, returnType, language and body?");
const paramList = this._expandFunctionParamList(params);
const variableList = options && options.variables ? this._expandFunctionVariableList(options.variables) : "";
const expandedOptionsArray = this.expandOptions(optionsArray);
const statement = options && options.force ? "CREATE OR REPLACE FUNCTION" : "CREATE FUNCTION";
return `${statement} ${functionName}(${paramList}) RETURNS ${returnType} AS $func$ ${variableList} BEGIN ${body} END; $func$ language '${language}'${expandedOptionsArray};`;
}
dropFunction(functionName, params) {
if (!functionName)
throw new Error("requires functionName");
const paramList = this._expandFunctionParamList(params);
return `DROP FUNCTION ${functionName}(${paramList}) RESTRICT;`;
}
renameFunction(oldFunctionName, params, newFunctionName) {
const paramList = this._expandFunctionParamList(params);
return `ALTER FUNCTION ${oldFunctionName}(${paramList}) RENAME TO ${newFunctionName};`;
}
pgEscapeAndQuote(val) {
return this.quoteIdentifier(Utils.removeTicks(this.escape(val), "'"));
}
_expandFunctionParamList(params) {
if (params === void 0 || !Array.isArray(params)) {
throw new Error("_expandFunctionParamList: function parameters array required, including an empty one for no arguments");
}
const paramList = [];
params.forEach((curParam) => {
const paramDef = [];
if (curParam.type) {
if (curParam.direction) {
paramDef.push(curParam.direction);
}
if (curParam.name) {
paramDef.push(curParam.name);
}
paramDef.push(curParam.type);
} else {
throw new Error("function or trigger used with a parameter without any type");
}
const joined = paramDef.join(" ");
if (joined)
paramList.push(joined);
});
return paramList.join(", ");
}
_expandFunctionVariableList(variables) {
if (!Array.isArray(variables)) {
throw new Error("_expandFunctionVariableList: function variables must be an array");
}
const variableDefinitions = [];
variables.forEach((variable) => {
if (!variable.name || !variable.type) {
throw new Error("function variable must have a name and type");
}
let variableDefinition = `DECLARE ${variable.name} ${variable.type}`;
if (variable.default) {
variableDefinition += ` := ${variable.default}`;
}
variableDefinition += ";";
variableDefinitions.push(variableDefinition);
});
return variableDefinitions.join(" ");
}
expandOptions(options) {
return options === void 0 || _.isEmpty(options) ? "" : options.join(" ");
}
decodeTriggerEventType(eventSpecifier) {
const EVENT_DECODER = {
"after": "AFTER",
"before": "BEFORE",
"instead_of": "INSTEAD OF",
"after_constraint": "AFTER"
};
if (!EVENT_DECODER[eventSpecifier]) {
throw new Error(`Invalid trigger event specified: ${eventSpecifier}`);
}
return EVENT_DECODER[eventSpecifier];
}
triggerEventTypeIsConstraint(eventSpecifier) {
return eventSpecifier === "after_constraint" ? "CONSTRAINT " : "";
}
expandTriggerEventSpec(fireOnSpec) {
if (_.isEmpty(fireOnSpec)) {
throw new Error("no table change events specified to trigger on");
}
return _.map(fireOnSpec, (fireValue, fireKey) => {
const EVENT_MAP = {
"insert": "INSERT",
"update": "UPDATE",
"delete": "DELETE",
"truncate": "TRUNCATE"
};
if (!EVENT_MAP[fireValue]) {
throw new Error(`parseTriggerEventSpec: undefined trigger event ${fireKey}`);
}
let eventSpec = EVENT_MAP[fireValue];
if (eventSpec === "UPDATE") {
if (Array.isArray(fireValue) && fireValue.length > 0) {
eventSpec += ` OF ${fireValue.join(", ")}`;
}
}
return eventSpec;
}).join(" OR ");
}
pgEnumName(tableName, attr, options) {
options = options || {};
const tableDetails = this.extractTableDetails(tableName, options);
let enumName = Utils.addTicks(Utils.generateEnumName(tableDetails.tableName, attr), '"');
if (options.schema !== false && tableDetails.schema) {
enumName = this.quoteIdentifier(tableDetails.schema) + tableDetails.delimiter + enumName;
}
return enumName;
}
pgListEnums(tableName, attrName, options) {
let enumName = "";
const tableDetails = this.extractTableDetails(tableName, options);
if (tableDetails.tableName && attrName) {
enumName = ` AND t.typname=${this.pgEnumName(tableDetails.tableName, attrName, { schema: false }).replace(/"/g, "'")}`;
}
return `SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = '${tableDetails.schema}'${enumName} GROUP BY 1`;
}
pgEnum(tableName, attr, dataType, options) {
const enumName = this.pgEnumName(tableName, attr, options);
let values;
if (dataType.values) {
values = `ENUM(${dataType.values.map((value) => this.escape(value)).join(", ")})`;
} else {
values = dataType.toString().match(/^ENUM\(.+\)/)[0];
}
let sql = `DO ${this.escape(`BEGIN CREATE TYPE ${enumName} AS ${values}; EXCEPTION WHEN duplicate_object THEN null; END`)};`;
if (!!options && options.force === true) {
sql = this.pgEnumDrop(tableName, attr) + sql;
}
return sql;
}
pgEnumAdd(tableName, attr, value, options) {
const enumName = this.pgEnumName(tableName, attr);
let sql = `ALTER TYPE ${enumName} ADD VALUE `;
if (semver.gte(this.sequelize.options.databaseVersion, "9.3.0")) {
sql += "IF NOT EXISTS ";
}
sql += this.escape(value);
if (options.before) {
sql += ` BEFORE ${this.escape(options.before)}`;
} else if (options.after) {
sql += ` AFTER ${this.escape(options.after)}`;
}
return sql;
}
pgEnumDrop(tableName, attr, enumName) {
enumName = enumName || this.pgEnumName(tableName, attr);
return `DROP TYPE IF EXISTS ${enumName}; `;
}
fromArray(text) {
text = text.replace(/^{/, "").replace(/}$/, "");
let matches = text.match(/("(?:\\.|[^"\\\\])*"|[^,]*)(?:\s*,\s*|\s*$)/ig);
if (matches.length < 1) {
return [];
}
matches = matches.map((m) => m.replace(/",$/, "").replace(/,$/, "").replace(/(^"|"$)/g, ""));
return matches.slice(0, -1);
}
dataTypeMapping(tableName, attr, dataType) {
if (dataType.includes("PRIMARY KEY")) {
dataType = dataType.replace("PRIMARY KEY", "");
}
if (dataType.includes("SERIAL")) {
if (dataType.includes("BIGINT")) {
dataType = dataType.replace("SERIAL", "BIGSERIAL");
dataType = dataType.replace("BIGINT", "");
} else if (dataType.includes("SMALLINT")) {
dataType = dataType.replace("SERIAL", "SMALLSERIAL");
dataType = dataType.replace("SMALLINT", "");
} else {
dataType = dataType.replace("INTEGER", "");
}
dataType = dataType.replace("NOT NULL", "");
}
if (dataType.startsWith("ENUM(")) {
dataType = dataType.replace(/^ENUM\(.+\)/, this.pgEnumName(tableName, attr));
}
return dataType;
}
getForeignKeysQuery(tableName) {
return `SELECT conname as constraint_name, pg_catalog.pg_get_constraintdef(r.oid, true) as condef FROM pg_catalog.pg_constraint r WHERE r.conrelid = (SELECT oid FROM pg_class WHERE relname = '${tableName}' LIMIT 1) AND r.contype = 'f' ORDER BY 1;`;
}
_getForeignKeyReferencesQueryPrefix() {
return "SELECT DISTINCT tc.constraint_name as constraint_name, tc.constraint_schema as constraint_schema, tc.constraint_catalog as constraint_catalog, tc.table_name as table_name,tc.table_schema as table_schema,tc.table_catalog as table_catalog,tc.initially_deferred as initially_deferred,tc.is_deferrable as is_deferrable,kcu.column_name as column_name,ccu.table_schema AS referenced_table_schema,ccu.table_catalog AS referenced_table_catalog,ccu.table_name AS referenced_table_name,ccu.column_name AS referenced_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name ";
}
getForeignKeyReferencesQuery(tableName, catalogName, schemaName) {
return `${this._getForeignKeyReferencesQueryPrefix()}WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name = '${tableName}'${catalogName ? ` AND tc.table_catalog = '${catalogName}'` : ""}${schemaName ? ` AND tc.table_schema = '${schemaName}'` : ""}`;
}
getForeignKeyReferenceQuery(table, columnName) {
const tableName = table.tableName || table;
const schema = table.schema;
return `${this._getForeignKeyReferencesQueryPrefix()}WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='${tableName}' AND kcu.column_name = '${columnName}'${schema ? ` AND tc.table_schema = '${schema}'` : ""}`;
}
dropForeignKeyQuery(tableName, foreignKey) {
return `ALTER TABLE ${this.quoteTable(tableName)} DROP CONSTRAINT ${this.quoteIdentifier(foreignKey)};`;
}
quoteIdentifier(identifier, force) {
const optForceQuote = force || false;
const optQuoteIdentifiers = this.options.quoteIdentifiers !== false;
const rawIdentifier = Utils.removeTicks(identifier, '"');
if (optForceQuote === true || optQuoteIdentifiers !== false || identifier.includes(".") || identifier.includes("->") || POSTGRES_RESERVED_WORDS.includes(rawIdentifier.toLowerCase())) {
return Utils.addTicks(rawIdentifier, '"');
}
return rawIdentifier;
}
}
module.exports = PostgresQueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
+171
View File
@@ -0,0 +1,171 @@
"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));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
const DataTypes = require("../../data-types");
const QueryTypes = require("../../query-types");
const { QueryInterface } = require("../abstract/query-interface");
const Utils = require("../../utils");
const Deferrable = require("../../deferrable");
class PostgresQueryInterface extends QueryInterface {
async ensureEnums(tableName, attributes, options, model) {
const keys = Object.keys(attributes);
const keyLen = keys.length;
let sql = "";
let promises = [];
let i = 0;
for (i = 0; i < keyLen; i++) {
const attribute = attributes[keys[i]];
const type = attribute.type;
if (type instanceof DataTypes.ENUM || type instanceof DataTypes.ARRAY && type.type instanceof DataTypes.ENUM) {
sql = this.queryGenerator.pgListEnums(tableName, attribute.field || keys[i], options);
promises.push(this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { plain: true, raw: true, type: QueryTypes.SELECT })));
}
}
const results = await Promise.all(promises);
promises = [];
let enumIdx = 0;
const addEnumValue = (field, value, relativeValue, position = "before", spliceStart = promises.length) => {
const valueOptions = __spreadValues({}, options);
valueOptions.before = null;
valueOptions.after = null;
switch (position) {
case "after":
valueOptions.after = relativeValue;
break;
case "before":
default:
valueOptions.before = relativeValue;
break;
}
promises.splice(spliceStart, 0, () => {
return this.sequelize.query(this.queryGenerator.pgEnumAdd(tableName, field, value, valueOptions), valueOptions);
});
};
for (i = 0; i < keyLen; i++) {
const attribute = attributes[keys[i]];
const type = attribute.type;
const enumType = type.type || type;
const field = attribute.field || keys[i];
if (type instanceof DataTypes.ENUM || type instanceof DataTypes.ARRAY && enumType instanceof DataTypes.ENUM) {
if (!results[enumIdx]) {
promises.push(() => {
return this.sequelize.query(this.queryGenerator.pgEnum(tableName, field, enumType, options), __spreadProps(__spreadValues({}, options), { raw: true }));
});
} else if (!!results[enumIdx] && !!model) {
const enumVals = this.queryGenerator.fromArray(results[enumIdx].enum_value);
const vals = enumType.values;
let lastOldEnumValue;
let rightestPosition = -1;
for (let oldIndex = 0; oldIndex < enumVals.length; oldIndex++) {
const enumVal = enumVals[oldIndex];
const newIdx = vals.indexOf(enumVal);
lastOldEnumValue = enumVal;
if (newIdx === -1) {
continue;
}
const newValuesBefore = vals.slice(0, newIdx);
const promisesLength = promises.length;
for (let reverseIdx = newValuesBefore.length - 1; reverseIdx >= 0; reverseIdx--) {
if (~enumVals.indexOf(newValuesBefore[reverseIdx])) {
break;
}
addEnumValue(field, newValuesBefore[reverseIdx], lastOldEnumValue, "before", promisesLength);
}
if (newIdx > rightestPosition) {
rightestPosition = newIdx;
}
}
if (lastOldEnumValue && rightestPosition < vals.length - 1) {
const remainingEnumValues = vals.slice(rightestPosition + 1);
for (let reverseIdx = remainingEnumValues.length - 1; reverseIdx >= 0; reverseIdx--) {
addEnumValue(field, remainingEnumValues[reverseIdx], lastOldEnumValue, "after");
}
}
enumIdx++;
}
}
}
const result = await promises.reduce(async (promise, asyncFunction) => await asyncFunction(await promise), Promise.resolve());
if (promises.length) {
await this.sequelize.dialect.connectionManager._refreshDynamicOIDs();
}
return result;
}
async getForeignKeyReferencesForTable(table, options) {
const queryOptions = __spreadProps(__spreadValues({}, options), {
type: QueryTypes.FOREIGNKEYS
});
const query = this.queryGenerator.getForeignKeyReferencesQuery(table.tableName || table, this.sequelize.config.database, table.schema);
const result = await this.sequelize.query(query, queryOptions);
return result.map((fkMeta) => {
const _a = Utils.camelizeObjectKeys(fkMeta), { initiallyDeferred, isDeferrable } = _a, remaining = __objRest(_a, ["initiallyDeferred", "isDeferrable"]);
return __spreadProps(__spreadValues({}, remaining), {
deferrable: isDeferrable === "NO" ? Deferrable.NOT : initiallyDeferred === "NO" ? Deferrable.INITIALLY_IMMEDIATE : Deferrable.INITIALLY_DEFERRED
});
});
}
async dropEnum(enumName, options) {
options = options || {};
return this.sequelize.query(this.queryGenerator.pgEnumDrop(null, null, this.queryGenerator.pgEscapeAndQuote(enumName)), __spreadProps(__spreadValues({}, options), { raw: true }));
}
async dropAllEnums(options) {
options = options || {};
const enums = await this.pgListEnums(null, options);
return await Promise.all(enums.map((result) => this.sequelize.query(this.queryGenerator.pgEnumDrop(null, null, this.queryGenerator.pgEscapeAndQuote(result.enum_name)), __spreadProps(__spreadValues({}, options), { raw: true }))));
}
async pgListEnums(tableName, options) {
options = options || {};
const sql = this.queryGenerator.pgListEnums(tableName);
return this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { plain: false, raw: true, type: QueryTypes.SELECT }));
}
async dropTable(tableName, options) {
await super.dropTable(tableName, options);
const promises = [];
const instanceTable = this.sequelize.modelManager.getModel(tableName, { attribute: "tableName" });
if (!instanceTable) {
return;
}
const getTableName = (!options || !options.schema || options.schema === "public" ? "" : `${options.schema}_`) + tableName;
const keys = Object.keys(instanceTable.rawAttributes);
const keyLen = keys.length;
for (let i = 0; i < keyLen; i++) {
if (instanceTable.rawAttributes[keys[i]].type instanceof DataTypes.ENUM) {
const sql = this.queryGenerator.pgEnumDrop(getTableName, keys[i]);
options.supportsSearchPath = false;
promises.push(this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), { raw: true })));
}
}
await Promise.all(promises);
}
}
exports.PostgresQueryInterface = PostgresQueryInterface;
//# sourceMappingURL=query-interface.js.map
File diff suppressed because one or more lines are too long
+323
View File
@@ -0,0 +1,323 @@
"use strict";
const AbstractQuery = require("../abstract/query");
const QueryTypes = require("../../query-types");
const sequelizeErrors = require("../../errors");
const _ = require("lodash");
const { logger } = require("../../utils/logger");
const debug = logger.debugContext("sql:pg");
class Query extends AbstractQuery {
static formatBindParameters(sql, values, dialect) {
const stringReplaceFunc = (value) => typeof value === "string" ? value.replace(/\0/g, "\\0") : value;
let bindParam;
if (Array.isArray(values)) {
bindParam = values.map(stringReplaceFunc);
sql = AbstractQuery.formatBindParameters(sql, values, dialect, { skipValueReplace: true })[0];
} else {
bindParam = [];
let i = 0;
const seen = {};
const replacementFunc = (match, key, values2) => {
if (seen[key] !== void 0) {
return seen[key];
}
if (values2[key] !== void 0) {
i = i + 1;
bindParam.push(stringReplaceFunc(values2[key]));
seen[key] = `$${i}`;
return `$${i}`;
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
}
return [sql, bindParam];
}
async run(sql, parameters) {
const { connection } = this;
if (!_.isEmpty(this.options.searchPath)) {
sql = this.sequelize.getQueryInterface().queryGenerator.setSearchPath(this.options.searchPath) + sql;
}
if (this.sequelize.options.minifyAliases && this.options.includeAliases) {
_.toPairs(this.options.includeAliases).sort((a, b) => b[1].length - a[1].length).forEach(([alias, original]) => {
const reg = new RegExp(_.escapeRegExp(original), "g");
sql = sql.replace(reg, alias);
});
}
this.sql = sql;
const query = parameters && parameters.length ? new Promise((resolve, reject) => connection.query(sql, parameters, (error, result) => error ? reject(error) : resolve(result))) : new Promise((resolve, reject) => connection.query(sql, (error, result) => error ? reject(error) : resolve(result)));
const complete = this._logQuery(sql, debug, parameters);
let queryResult;
const errForStack = new Error();
try {
queryResult = await query;
} catch (error) {
if (error.code === "ECONNRESET" || /Unable to set non-blocking to true/i.test(error) || /SSL SYSCALL error: EOF detected/i.test(error) || /Local: Authentication failure/i.test(error) || error.message === "Query read timeout") {
connection._invalid = true;
}
error.sql = sql;
error.parameters = parameters;
throw this.formatError(error, errForStack.stack);
}
complete();
let rows = Array.isArray(queryResult) ? queryResult.reduce((allRows, r) => allRows.concat(r.rows || []), []) : queryResult.rows;
const rowCount = Array.isArray(queryResult) ? queryResult.reduce((count, r) => Number.isFinite(r.rowCount) ? count + r.rowCount : count, 0) : queryResult.rowCount || 0;
if (this.sequelize.options.minifyAliases && this.options.aliasesMapping) {
rows = rows.map((row) => _.toPairs(row).reduce((acc, [key, value]) => {
const mapping = this.options.aliasesMapping.get(key);
acc[mapping || key] = value;
return acc;
}, {}));
}
const isTableNameQuery = sql.startsWith("SELECT table_name FROM information_schema.tables");
const isRelNameQuery = sql.startsWith("SELECT relname FROM pg_class WHERE oid IN");
if (isRelNameQuery) {
return rows.map((row) => ({
name: row.relname,
tableName: row.relname.split("_")[0]
}));
}
if (isTableNameQuery) {
return rows.map((row) => Object.values(row));
}
if (rows[0] && rows[0].sequelize_caught_exception !== void 0) {
if (rows[0].sequelize_caught_exception !== null) {
throw this.formatError({
sql,
parameters,
code: "23505",
detail: rows[0].sequelize_caught_exception
});
}
for (const row of rows) {
delete row.sequelize_caught_exception;
}
}
if (this.isShowIndexesQuery()) {
for (const row of rows) {
const attributes = /ON .*? (?:USING .*?\s)?\(([^]*)\)/gi.exec(row.definition)[1].split(",");
const columns = _.zipObject(row.column_indexes, this.sequelize.getQueryInterface().queryGenerator.fromArray(row.column_names));
delete row.column_indexes;
delete row.column_names;
let field;
let attribute;
row.fields = row.indkey.split(" ").map((indKey, index) => {
field = columns[indKey];
if (!field) {
return null;
}
attribute = attributes[index];
return {
attribute: field,
collate: attribute.match(/COLLATE "(.*?)"/) ? /COLLATE "(.*?)"/.exec(attribute)[1] : void 0,
order: attribute.includes("DESC") ? "DESC" : attribute.includes("ASC") ? "ASC" : void 0,
length: void 0
};
}).filter((n) => n !== null);
delete row.columns;
}
return rows;
}
if (this.isForeignKeysQuery()) {
const result = [];
for (const row of rows) {
let defParts;
if (row.condef !== void 0 && (defParts = row.condef.match(/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)( ON (UPDATE|DELETE) (CASCADE|RESTRICT))?( ON (UPDATE|DELETE) (CASCADE|RESTRICT))?/))) {
row.id = row.constraint_name;
row.table = defParts[2];
row.from = defParts[1];
row.to = defParts[3];
let i;
for (i = 5; i <= 8; i += 3) {
if (/(UPDATE|DELETE)/.test(defParts[i])) {
row[`on_${defParts[i].toLowerCase()}`] = defParts[i + 1];
}
}
}
result.push(row);
}
return result;
}
if (this.isSelectQuery()) {
let result = rows;
if (this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) {
const attrsMap = _.reduce(this.model.rawAttributes, (m, v, k) => {
m[k.toLowerCase()] = k;
return m;
}, {});
result = rows.map((row) => {
return _.mapKeys(row, (value, key) => {
const targetAttr = attrsMap[key];
if (typeof targetAttr === "string" && targetAttr !== key) {
return targetAttr;
}
return key;
});
});
}
return this.handleSelectQuery(result);
}
if (QueryTypes.DESCRIBE === this.options.type) {
const result = {};
for (const row of rows) {
result[row.Field] = {
type: row.Type.toUpperCase(),
allowNull: row.Null === "YES",
defaultValue: row.Default,
comment: row.Comment,
special: row.special ? this.sequelize.getQueryInterface().queryGenerator.fromArray(row.special) : [],
primaryKey: row.Constraint === "PRIMARY KEY"
};
if (result[row.Field].type === "BOOLEAN") {
result[row.Field].defaultValue = { "false": false, "true": true }[result[row.Field].defaultValue];
if (result[row.Field].defaultValue === void 0) {
result[row.Field].defaultValue = null;
}
}
if (typeof result[row.Field].defaultValue === "string") {
result[row.Field].defaultValue = result[row.Field].defaultValue.replace(/'/g, "");
if (result[row.Field].defaultValue.includes("::")) {
const split = result[row.Field].defaultValue.split("::");
if (split[1].toLowerCase() !== "regclass)") {
result[row.Field].defaultValue = split[0];
}
}
}
}
return result;
}
if (this.isVersionQuery()) {
return rows[0].server_version;
}
if (this.isShowOrDescribeQuery()) {
return rows;
}
if (QueryTypes.BULKUPDATE === this.options.type) {
if (!this.options.returning) {
return parseInt(rowCount, 10);
}
return this.handleSelectQuery(rows);
}
if (QueryTypes.BULKDELETE === this.options.type) {
return parseInt(rowCount, 10);
}
if (this.isInsertQuery() || this.isUpdateQuery() || this.isUpsertQuery()) {
if (this.instance && this.instance.dataValues) {
if (this.isInsertQuery() && !this.isUpsertQuery() && rowCount === 0) {
throw new sequelizeErrors.EmptyResultError();
}
for (const key in rows[0]) {
if (Object.prototype.hasOwnProperty.call(rows[0], key)) {
const record = rows[0][key];
const attr = _.find(this.model.rawAttributes, (attribute) => attribute.fieldName === key || attribute.field === key);
this.instance.dataValues[attr && attr.fieldName || key] = record;
}
}
}
if (this.isUpsertQuery()) {
return [
this.instance,
null
];
}
return [
this.instance || rows && (this.options.plain && rows[0] || rows) || void 0,
rowCount
];
}
if (this.isRawQuery()) {
return [rows, queryResult];
}
return rows;
}
formatError(err, errStack) {
let match;
let table;
let index;
let fields;
let errors;
let message;
const code = err.code || err.sqlState;
const errMessage = err.message || err.messagePrimary;
const errDetail = err.detail || err.messageDetail;
switch (code) {
case "23503":
index = errMessage.match(/violates foreign key constraint "(.+?)"/);
index = index ? index[1] : void 0;
table = errMessage.match(/on table "(.+?)"/);
table = table ? table[1] : void 0;
return new sequelizeErrors.ForeignKeyConstraintError({
message: errMessage,
fields: null,
index,
table,
parent: err,
stack: errStack
});
case "23505":
if (errDetail && (match = errDetail.replace(/"/g, "").match(/Key \((.*?)\)=\((.*?)\)/))) {
fields = _.zipObject(match[1].split(", "), match[2].split(", "));
errors = [];
message = "Validation error";
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
if (this.model && this.model.uniqueKeys) {
_.forOwn(this.model.uniqueKeys, (constraint) => {
if (_.isEqual(constraint.fields, Object.keys(fields)) && !!constraint.msg) {
message = constraint.msg;
return false;
}
});
}
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });
}
return new sequelizeErrors.UniqueConstraintError({
message: errMessage,
parent: err,
stack: errStack
});
case "23P01":
match = errDetail.match(/Key \((.*?)\)=\((.*?)\)/);
if (match) {
fields = _.zipObject(match[1].split(", "), match[2].split(", "));
}
message = "Exclusion constraint error";
return new sequelizeErrors.ExclusionConstraintError({
message,
constraint: err.constraint,
fields,
table: err.table,
parent: err,
stack: errStack
});
case "42704":
if (err.sql && /(CONSTRAINT|INDEX)/gi.test(err.sql)) {
message = "Unknown constraint error";
index = errMessage.match(/(?:constraint|index) "(.+?)"/i);
index = index ? index[1] : void 0;
table = errMessage.match(/relation "(.+?)"/i);
table = table ? table[1] : void 0;
throw new sequelizeErrors.UnknownConstraintError({
message,
constraint: index,
fields,
table,
parent: err,
stack: errStack
});
}
default:
return new sequelizeErrors.DatabaseError(err, { stack: errStack });
}
}
isForeignKeysQuery() {
return /SELECT conname as constraint_name, pg_catalog\.pg_get_constraintdef\(r\.oid, true\) as condef FROM pg_catalog\.pg_constraint r WHERE r\.conrelid = \(SELECT oid FROM pg_class WHERE relname = '.*' LIMIT 1\) AND r\.contype = 'f' ORDER BY 1;/.test(this.sql);
}
getInsertIdField() {
return "id";
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
+74
View File
@@ -0,0 +1,74 @@
"use strict";
const _ = require("lodash");
function stringifyRangeBound(bound) {
if (bound === null) {
return "";
}
if (bound === Infinity || bound === -Infinity) {
return bound.toString().toLowerCase();
}
return JSON.stringify(bound);
}
function parseRangeBound(bound, parseType) {
if (!bound) {
return null;
}
if (bound === "infinity") {
return Infinity;
}
if (bound === "-infinity") {
return -Infinity;
}
return parseType(bound);
}
function stringify(data) {
if (data === null)
return null;
if (!Array.isArray(data))
throw new Error("range must be an array");
if (!data.length)
return "empty";
if (data.length !== 2)
throw new Error("range array length must be 0 (empty) or 2 (lower and upper bounds)");
if (Object.prototype.hasOwnProperty.call(data, "inclusive")) {
if (data.inclusive === false)
data.inclusive = [false, false];
else if (!data.inclusive)
data.inclusive = [true, false];
else if (data.inclusive === true)
data.inclusive = [true, true];
} else {
data.inclusive = [true, false];
}
_.each(data, (value, index) => {
if (_.isObject(value)) {
if (Object.prototype.hasOwnProperty.call(value, "inclusive"))
data.inclusive[index] = !!value.inclusive;
if (Object.prototype.hasOwnProperty.call(value, "value"))
data[index] = value.value;
}
});
const lowerBound = stringifyRangeBound(data[0]);
const upperBound = stringifyRangeBound(data[1]);
return `${(data.inclusive[0] ? "[" : "(") + lowerBound},${upperBound}${data.inclusive[1] ? "]" : ")"}`;
}
exports.stringify = stringify;
function parse(value, parser) {
if (value === null)
return null;
if (value === "empty") {
return [];
}
let result = value.substring(1, value.length - 1).split(",", 2);
if (result.length !== 2)
return value;
result = result.map((item, index) => {
return {
value: parseRangeBound(item, parser),
inclusive: index === 0 ? value[0] === "[" : value[value.length - 1] === "]"
};
});
return result;
}
exports.parse = parse;
//# sourceMappingURL=range.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/postgres/range.js"],
"sourcesContent": ["'use strict';\n\nconst _ = require('lodash');\n\nfunction stringifyRangeBound(bound) {\n if (bound === null) {\n return '' ;\n }\n if (bound === Infinity || bound === -Infinity) {\n return bound.toString().toLowerCase();\n }\n return JSON.stringify(bound);\n}\n\nfunction parseRangeBound(bound, parseType) {\n if (!bound) {\n return null;\n }\n if (bound === 'infinity') {\n return Infinity;\n }\n if (bound === '-infinity') {\n return -Infinity;\n }\n return parseType(bound);\n\n}\n\nfunction stringify(data) {\n if (data === null) return null;\n\n if (!Array.isArray(data)) throw new Error('range must be an array');\n if (!data.length) return 'empty';\n if (data.length !== 2) throw new Error('range array length must be 0 (empty) or 2 (lower and upper bounds)');\n\n if (Object.prototype.hasOwnProperty.call(data, 'inclusive')) {\n if (data.inclusive === false) data.inclusive = [false, false];\n else if (!data.inclusive) data.inclusive = [true, false];\n else if (data.inclusive === true) data.inclusive = [true, true];\n } else {\n data.inclusive = [true, false];\n }\n\n _.each(data, (value, index) => {\n if (_.isObject(value)) {\n if (Object.prototype.hasOwnProperty.call(value, 'inclusive')) data.inclusive[index] = !!value.inclusive;\n if (Object.prototype.hasOwnProperty.call(value, 'value')) data[index] = value.value;\n }\n });\n\n const lowerBound = stringifyRangeBound(data[0]);\n const upperBound = stringifyRangeBound(data[1]);\n\n return `${(data.inclusive[0] ? '[' : '(') + lowerBound},${upperBound}${data.inclusive[1] ? ']' : ')'}`;\n}\nexports.stringify = stringify;\n\nfunction parse(value, parser) {\n if (value === null) return null;\n if (value === 'empty') {\n return [];\n }\n\n let result = value\n .substring(1, value.length - 1)\n .split(',', 2);\n\n if (result.length !== 2) return value;\n\n result = result.map((item, index) => {\n return {\n value: parseRangeBound(item, parser),\n inclusive: index === 0 ? value[0] === '[' : value[value.length - 1] === ']'\n };\n });\n\n return result;\n}\nexports.parse = parse;\n"],
"mappings": ";AAEA,MAAM,IAAI,QAAQ;AAElB,6BAA6B,OAAO;AAClC,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA;AAET,MAAI,UAAU,YAAY,UAAU,WAAW;AAC7C,WAAO,MAAM,WAAW;AAAA;AAE1B,SAAO,KAAK,UAAU;AAAA;AAGxB,yBAAyB,OAAO,WAAW;AACzC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA;AAET,MAAI,UAAU,YAAY;AACxB,WAAO;AAAA;AAET,MAAI,UAAU,aAAa;AACzB,WAAO;AAAA;AAET,SAAO,UAAU;AAAA;AAInB,mBAAmB,MAAM;AACvB,MAAI,SAAS;AAAM,WAAO;AAE1B,MAAI,CAAC,MAAM,QAAQ;AAAO,UAAM,IAAI,MAAM;AAC1C,MAAI,CAAC,KAAK;AAAQ,WAAO;AACzB,MAAI,KAAK,WAAW;AAAG,UAAM,IAAI,MAAM;AAEvC,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,cAAc;AAC3D,QAAI,KAAK,cAAc;AAAO,WAAK,YAAY,CAAC,OAAO;AAAA,aAC9C,CAAC,KAAK;AAAW,WAAK,YAAY,CAAC,MAAM;AAAA,aACzC,KAAK,cAAc;AAAM,WAAK,YAAY,CAAC,MAAM;AAAA,SACrD;AACL,SAAK,YAAY,CAAC,MAAM;AAAA;AAG1B,IAAE,KAAK,MAAM,CAAC,OAAO,UAAU;AAC7B,QAAI,EAAE,SAAS,QAAQ;AACrB,UAAI,OAAO,UAAU,eAAe,KAAK,OAAO;AAAc,aAAK,UAAU,SAAS,CAAC,CAAC,MAAM;AAC9F,UAAI,OAAO,UAAU,eAAe,KAAK,OAAO;AAAU,aAAK,SAAS,MAAM;AAAA;AAAA;AAIlF,QAAM,aAAa,oBAAoB,KAAK;AAC5C,QAAM,aAAa,oBAAoB,KAAK;AAE5C,SAAO,GAAI,MAAK,UAAU,KAAK,MAAM,OAAO,cAAc,aAAa,KAAK,UAAU,KAAK,MAAM;AAAA;AAEnG,QAAQ,YAAY;AAEpB,eAAe,OAAO,QAAQ;AAC5B,MAAI,UAAU;AAAM,WAAO;AAC3B,MAAI,UAAU,SAAS;AACrB,WAAO;AAAA;AAGT,MAAI,SAAS,MACV,UAAU,GAAG,MAAM,SAAS,GAC5B,MAAM,KAAK;AAEd,MAAI,OAAO,WAAW;AAAG,WAAO;AAEhC,WAAS,OAAO,IAAI,CAAC,MAAM,UAAU;AACnC,WAAO;AAAA,MACL,OAAO,gBAAgB,MAAM;AAAA,MAC7B,WAAW,UAAU,IAAI,MAAM,OAAO,MAAM,MAAM,MAAM,SAAS,OAAO;AAAA;AAAA;AAI5E,SAAO;AAAA;AAET,QAAQ,QAAQ;",
"names": []
}
@@ -0,0 +1,127 @@
"use strict";
var __defProp = Object.defineProperty;
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;
};
const AbstractConnectionManager = require("../abstract/connection-manager");
const SequelizeErrors = require("../../errors");
const { logger } = require("../../utils/logger");
const DataTypes = require("../../data-types").snowflake;
const debug = logger.debugContext("connection:snowflake");
const parserStore = require("../parserStore")("snowflake");
class ConnectionManager extends AbstractConnectionManager {
constructor(dialect, sequelize) {
sequelize.config.port = sequelize.config.port || 3306;
super(dialect, sequelize);
this.lib = this._loadDialectModule("snowflake-sdk");
this.refreshTypeParser(DataTypes);
}
_refreshTypeParser(dataType) {
parserStore.refresh(dataType);
}
_clearTypeParser() {
parserStore.clear();
}
static _typecast(field, next) {
if (parserStore.get(field.type)) {
return parserStore.get(field.type)(field, this.sequelize.options, next);
}
return next();
}
async connect(config) {
const connectionConfig = __spreadValues({
account: config.host,
username: config.username,
password: config.password,
database: config.database,
warehouse: config.warehouse,
role: config.role
}, config.dialectOptions);
try {
const connection = await new Promise((resolve, reject) => {
this.lib.createConnection(connectionConfig).connect((err, conn) => {
if (err) {
console.log(err);
reject(err);
} else {
resolve(conn);
}
});
});
debug("connection acquired");
if (!this.sequelize.config.keepDefaultTimezone) {
const tzOffset = this.sequelize.options.timezone === "+00:00" ? "Etc/UTC" : this.sequelize.options.timezone;
const isNamedTzOffset = /\//.test(tzOffset);
if (isNamedTzOffset) {
await new Promise((resolve, reject) => {
connection.execute({
sqlText: `ALTER SESSION SET timezone = '${tzOffset}'`,
complete(err) {
if (err) {
console.log(err);
reject(err);
} else {
resolve();
}
}
});
});
} else {
throw Error("only support time zone name for snowflake!");
}
}
return connection;
} catch (err) {
switch (err.code) {
case "ECONNREFUSED":
throw new SequelizeErrors.ConnectionRefusedError(err);
case "ER_ACCESS_DENIED_ERROR":
throw new SequelizeErrors.AccessDeniedError(err);
case "ENOTFOUND":
throw new SequelizeErrors.HostNotFoundError(err);
case "EHOSTUNREACH":
throw new SequelizeErrors.HostNotReachableError(err);
case "EINVAL":
throw new SequelizeErrors.InvalidConnectionError(err);
default:
throw new SequelizeErrors.ConnectionError(err);
}
}
}
async disconnect(connection) {
if (!connection.isUp()) {
debug("connection tried to disconnect but was already at CLOSED state");
return;
}
return new Promise((resolve, reject) => {
connection.destroy((err) => {
if (err) {
console.error(`Unable to disconnect: ${err.message}`);
reject(err);
} else {
console.log(`Disconnected connection with id: ${connection.getId()}`);
resolve(connection.getId());
}
});
});
}
validate(connection) {
return connection.isUp();
}
}
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/snowflake/connection-manager.js"],
"sourcesContent": ["'use strict';\n\nconst AbstractConnectionManager = require('../abstract/connection-manager');\nconst SequelizeErrors = require('../../errors');\nconst { logger } = require('../../utils/logger');\nconst DataTypes = require('../../data-types').snowflake;\nconst debug = logger.debugContext('connection:snowflake');\nconst parserStore = require('../parserStore')('snowflake');\n\n/**\n * Snowflake Connection Manager\n *\n * Get connections, validate and disconnect them.\n *\n * @private\n */\nclass ConnectionManager extends AbstractConnectionManager {\n constructor(dialect, sequelize) {\n sequelize.config.port = sequelize.config.port || 3306;\n super(dialect, sequelize);\n this.lib = this._loadDialectModule('snowflake-sdk');\n this.refreshTypeParser(DataTypes);\n }\n\n _refreshTypeParser(dataType) {\n parserStore.refresh(dataType);\n }\n\n _clearTypeParser() {\n parserStore.clear();\n }\n\n static _typecast(field, next) {\n if (parserStore.get(field.type)) {\n return parserStore.get(field.type)(field, this.sequelize.options, next);\n }\n return next();\n }\n\n /**\n * Connect with a snowflake database based on config, Handle any errors in connection\n * Set the pool handlers on connection.error\n * Also set proper timezone once connection is connected.\n *\n * @param {object} config\n * @returns {Promise<Connection>}\n * @private\n */\n async connect(config) {\n const connectionConfig = {\n account: config.host,\n username: config.username,\n password: config.password,\n database: config.database,\n warehouse: config.warehouse,\n role: config.role,\n /*\n flags: '-FOUND_ROWS',\n timezone: this.sequelize.options.timezone,\n typeCast: ConnectionManager._typecast.bind(this),\n bigNumberStrings: false,\n supportBigNumbers: true,\n */\n ...config.dialectOptions\n };\n\n try {\n\n const connection = await new Promise((resolve, reject) => {\n this.lib.createConnection(connectionConfig).connect((err, conn) => {\n if (err) {\n console.log(err);\n reject(err);\n } else {\n resolve(conn);\n }\n });\n });\n\n debug('connection acquired');\n\n if (!this.sequelize.config.keepDefaultTimezone) {\n // default value is '+00:00', put a quick workaround for it.\n const tzOffset = this.sequelize.options.timezone === '+00:00' ? 'Etc/UTC' : this.sequelize.options.timezone;\n const isNamedTzOffset = /\\//.test(tzOffset);\n if ( isNamedTzOffset ) {\n await new Promise((resolve, reject) => {\n connection.execute({\n sqlText: `ALTER SESSION SET timezone = '${tzOffset}'`,\n complete(err) {\n if (err) {\n console.log(err);\n reject(err);\n } else {\n resolve();\n }\n }\n });\n });\n } else {\n throw Error('only support time zone name for snowflake!');\n }\n }\n\n return connection;\n } catch (err) {\n switch (err.code) {\n case 'ECONNREFUSED':\n throw new SequelizeErrors.ConnectionRefusedError(err);\n case 'ER_ACCESS_DENIED_ERROR':\n throw new SequelizeErrors.AccessDeniedError(err);\n case 'ENOTFOUND':\n throw new SequelizeErrors.HostNotFoundError(err);\n case 'EHOSTUNREACH':\n throw new SequelizeErrors.HostNotReachableError(err);\n case 'EINVAL':\n throw new SequelizeErrors.InvalidConnectionError(err);\n default:\n throw new SequelizeErrors.ConnectionError(err);\n }\n }\n }\n\n async disconnect(connection) {\n // Don't disconnect connections with CLOSED state\n if (!connection.isUp()) {\n debug('connection tried to disconnect but was already at CLOSED state');\n return;\n }\n\n return new Promise((resolve, reject) => {\n connection.destroy(err => {\n if (err) {\n console.error(`Unable to disconnect: ${err.message}`);\n reject(err);\n } else {\n console.log(`Disconnected connection with id: ${connection.getId()}`);\n resolve(connection.getId());\n }\n });\n });\n }\n\n validate(connection) {\n return connection.isUp();\n }\n}\n\nmodule.exports = ConnectionManager;\nmodule.exports.ConnectionManager = ConnectionManager;\nmodule.exports.default = ConnectionManager;\n"],
"mappings": ";;;;;;;;;;;;;;;;;AAEA,MAAM,4BAA4B,QAAQ;AAC1C,MAAM,kBAAkB,QAAQ;AAChC,MAAM,EAAE,WAAW,QAAQ;AAC3B,MAAM,YAAY,QAAQ,oBAAoB;AAC9C,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAM,cAAc,QAAQ,kBAAkB;AAS9C,gCAAgC,0BAA0B;AAAA,EACxD,YAAY,SAAS,WAAW;AAC9B,cAAU,OAAO,OAAO,UAAU,OAAO,QAAQ;AACjD,UAAM,SAAS;AACf,SAAK,MAAM,KAAK,mBAAmB;AACnC,SAAK,kBAAkB;AAAA;AAAA,EAGzB,mBAAmB,UAAU;AAC3B,gBAAY,QAAQ;AAAA;AAAA,EAGtB,mBAAmB;AACjB,gBAAY;AAAA;AAAA,SAGP,UAAU,OAAO,MAAM;AAC5B,QAAI,YAAY,IAAI,MAAM,OAAO;AAC/B,aAAO,YAAY,IAAI,MAAM,MAAM,OAAO,KAAK,UAAU,SAAS;AAAA;AAEpE,WAAO;AAAA;AAAA,QAYH,QAAQ,QAAQ;AACpB,UAAM,mBAAmB;AAAA,MACvB,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,WAAW,OAAO;AAAA,MAClB,MAAM,OAAO;AAAA,OAQV,OAAO;AAGZ,QAAI;AAEF,YAAM,aAAa,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACxD,aAAK,IAAI,iBAAiB,kBAAkB,QAAQ,CAAC,KAAK,SAAS;AACjE,cAAI,KAAK;AACP,oBAAQ,IAAI;AACZ,mBAAO;AAAA,iBACF;AACL,oBAAQ;AAAA;AAAA;AAAA;AAKd,YAAM;AAEN,UAAI,CAAC,KAAK,UAAU,OAAO,qBAAqB;AAE9C,cAAM,WAAW,KAAK,UAAU,QAAQ,aAAa,WAAW,YAAY,KAAK,UAAU,QAAQ;AACnG,cAAM,kBAAkB,KAAK,KAAK;AAClC,YAAK,iBAAkB;AACrB,gBAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,uBAAW,QAAQ;AAAA,cACjB,SAAS,iCAAiC;AAAA,cAC1C,SAAS,KAAK;AACZ,oBAAI,KAAK;AACP,0BAAQ,IAAI;AACZ,yBAAO;AAAA,uBACF;AACL;AAAA;AAAA;AAAA;AAAA;AAAA,eAKH;AACL,gBAAM,MAAM;AAAA;AAAA;AAIhB,aAAO;AAAA,aACA,KAAP;AACA,cAAQ,IAAI;AAAA,aACL;AACH,gBAAM,IAAI,gBAAgB,uBAAuB;AAAA,aAC9C;AACH,gBAAM,IAAI,gBAAgB,kBAAkB;AAAA,aACzC;AACH,gBAAM,IAAI,gBAAgB,kBAAkB;AAAA,aACzC;AACH,gBAAM,IAAI,gBAAgB,sBAAsB;AAAA,aAC7C;AACH,gBAAM,IAAI,gBAAgB,uBAAuB;AAAA;AAEjD,gBAAM,IAAI,gBAAgB,gBAAgB;AAAA;AAAA;AAAA;AAAA,QAK5C,WAAW,YAAY;AAE3B,QAAI,CAAC,WAAW,QAAQ;AACtB,YAAM;AACN;AAAA;AAGF,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,iBAAW,QAAQ,SAAO;AACxB,YAAI,KAAK;AACP,kBAAQ,MAAM,yBAAyB,IAAI;AAC3C,iBAAO;AAAA,eACF;AACL,kBAAQ,IAAI,oCAAoC,WAAW;AAC3D,kBAAQ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3B,SAAS,YAAY;AACnB,WAAO,WAAW;AAAA;AAAA;AAItB,OAAO,UAAU;AACjB,OAAO,QAAQ,oBAAoB;AACnC,OAAO,QAAQ,UAAU;",
"names": []
}
+87
View File
@@ -0,0 +1,87 @@
"use strict";
const momentTz = require("moment-timezone");
const moment = require("moment");
module.exports = (BaseTypes) => {
BaseTypes.ABSTRACT.prototype.dialectTypes = "https://dev.snowflake.com/doc/refman/5.7/en/data-types.html";
BaseTypes.DATE.types.snowflake = ["DATETIME"];
BaseTypes.STRING.types.snowflake = ["VAR_STRING"];
BaseTypes.CHAR.types.snowflake = ["STRING"];
BaseTypes.TEXT.types.snowflake = ["BLOB"];
BaseTypes.TINYINT.types.snowflake = ["TINY"];
BaseTypes.SMALLINT.types.snowflake = ["SHORT"];
BaseTypes.MEDIUMINT.types.snowflake = ["INT24"];
BaseTypes.INTEGER.types.snowflake = ["LONG"];
BaseTypes.BIGINT.types.snowflake = ["LONGLONG"];
BaseTypes.FLOAT.types.snowflake = ["FLOAT"];
BaseTypes.TIME.types.snowflake = ["TIME"];
BaseTypes.DATEONLY.types.snowflake = ["DATE"];
BaseTypes.BOOLEAN.types.snowflake = ["TINY"];
BaseTypes.BLOB.types.snowflake = ["TINYBLOB", "BLOB", "LONGBLOB"];
BaseTypes.DECIMAL.types.snowflake = ["NEWDECIMAL"];
BaseTypes.UUID.types.snowflake = false;
BaseTypes.ENUM.types.snowflake = false;
BaseTypes.REAL.types.snowflake = ["DOUBLE"];
BaseTypes.DOUBLE.types.snowflake = ["DOUBLE"];
BaseTypes.GEOMETRY.types.snowflake = ["GEOMETRY"];
BaseTypes.JSON.types.snowflake = ["JSON"];
class DATE extends BaseTypes.DATE {
toSql() {
return "TIMESTAMP";
}
_stringify(date, options) {
if (!moment.isMoment(date)) {
date = this._applyTimezone(date, options);
}
if (this._length) {
return date.format("YYYY-MM-DD HH:mm:ss.SSS");
}
return date.format("YYYY-MM-DD HH:mm:ss");
}
static parse(value, options) {
value = value.string();
if (value === null) {
return value;
}
if (momentTz.tz.zone(options.timezone)) {
value = momentTz.tz(value, options.timezone).toDate();
} else {
value = new Date(`${value} ${options.timezone}`);
}
return value;
}
}
class DATEONLY extends BaseTypes.DATEONLY {
static parse(value) {
return value.string();
}
}
class UUID extends BaseTypes.UUID {
toSql() {
return "VARCHAR(36)";
}
}
class TEXT extends BaseTypes.TEXT {
toSql() {
return "TEXT";
}
}
class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return "BOOLEAN";
}
}
class JSONTYPE extends BaseTypes.JSON {
_stringify(value, options) {
return options.operation === "where" && typeof value === "string" ? value : JSON.stringify(value);
}
}
return {
TEXT,
DATE,
BOOLEAN,
DATEONLY,
UUID,
JSON: JSONTYPE
};
};
//# sourceMappingURL=data-types.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/snowflake/data-types.js"],
"sourcesContent": ["'use strict';\n\nconst momentTz = require('moment-timezone');\nconst moment = require('moment');\n\nmodule.exports = BaseTypes => {\n BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://dev.snowflake.com/doc/refman/5.7/en/data-types.html';\n\n /**\n * types: [buffer_type, ...]\n *\n * @see buffer_type here https://dev.snowflake.com/doc/refman/5.7/en/c-api-prepared-statement-type-codes.html\n * @see hex here https://github.com/sidorares/node-mysql2/blob/master/lib/constants/types.js\n */\n\n BaseTypes.DATE.types.snowflake = ['DATETIME'];\n BaseTypes.STRING.types.snowflake = ['VAR_STRING'];\n BaseTypes.CHAR.types.snowflake = ['STRING'];\n BaseTypes.TEXT.types.snowflake = ['BLOB'];\n BaseTypes.TINYINT.types.snowflake = ['TINY'];\n BaseTypes.SMALLINT.types.snowflake = ['SHORT'];\n BaseTypes.MEDIUMINT.types.snowflake = ['INT24'];\n BaseTypes.INTEGER.types.snowflake = ['LONG'];\n BaseTypes.BIGINT.types.snowflake = ['LONGLONG'];\n BaseTypes.FLOAT.types.snowflake = ['FLOAT'];\n BaseTypes.TIME.types.snowflake = ['TIME'];\n BaseTypes.DATEONLY.types.snowflake = ['DATE'];\n BaseTypes.BOOLEAN.types.snowflake = ['TINY'];\n BaseTypes.BLOB.types.snowflake = ['TINYBLOB', 'BLOB', 'LONGBLOB'];\n BaseTypes.DECIMAL.types.snowflake = ['NEWDECIMAL'];\n BaseTypes.UUID.types.snowflake = false;\n // Enum is not supported\n // https://docs.snowflake.com/en/sql-reference/data-types-unsupported.html\n BaseTypes.ENUM.types.snowflake = false;\n BaseTypes.REAL.types.snowflake = ['DOUBLE'];\n BaseTypes.DOUBLE.types.snowflake = ['DOUBLE'];\n BaseTypes.GEOMETRY.types.snowflake = ['GEOMETRY'];\n BaseTypes.JSON.types.snowflake = ['JSON'];\n\n class DATE extends BaseTypes.DATE {\n toSql() {\n return 'TIMESTAMP';\n }\n _stringify(date, options) {\n if (!moment.isMoment(date)) {\n date = this._applyTimezone(date, options);\n }\n if (this._length) {\n return date.format('YYYY-MM-DD HH:mm:ss.SSS');\n }\n return date.format('YYYY-MM-DD HH:mm:ss');\n }\n static parse(value, options) {\n value = value.string();\n if (value === null) {\n return value;\n }\n if (momentTz.tz.zone(options.timezone)) {\n value = momentTz.tz(value, options.timezone).toDate();\n }\n else {\n value = new Date(`${value} ${options.timezone}`);\n }\n return value;\n }\n }\n\n class DATEONLY extends BaseTypes.DATEONLY {\n static parse(value) {\n return value.string();\n }\n }\n class UUID extends BaseTypes.UUID {\n toSql() {\n // https://community.snowflake.com/s/question/0D50Z00009LH2fl/what-is-the-best-way-to-store-uuids\n return 'VARCHAR(36)';\n }\n }\n\n class TEXT extends BaseTypes.TEXT {\n toSql() {\n return 'TEXT';\n }\n }\n\n class BOOLEAN extends BaseTypes.BOOLEAN {\n toSql() {\n return 'BOOLEAN';\n }\n }\n\n class JSONTYPE extends BaseTypes.JSON {\n _stringify(value, options) {\n return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value);\n }\n }\n\n return {\n TEXT,\n DATE,\n BOOLEAN,\n DATEONLY,\n UUID,\n JSON: JSONTYPE\n };\n};\n"],
"mappings": ";AAEA,MAAM,WAAW,QAAQ;AACzB,MAAM,SAAS,QAAQ;AAEvB,OAAO,UAAU,eAAa;AAC5B,YAAU,SAAS,UAAU,eAAe;AAS5C,YAAU,KAAK,MAAM,YAAY,CAAC;AAClC,YAAU,OAAO,MAAM,YAAY,CAAC;AACpC,YAAU,KAAK,MAAM,YAAY,CAAC;AAClC,YAAU,KAAK,MAAM,YAAY,CAAC;AAClC,YAAU,QAAQ,MAAM,YAAY,CAAC;AACrC,YAAU,SAAS,MAAM,YAAY,CAAC;AACtC,YAAU,UAAU,MAAM,YAAY,CAAC;AACvC,YAAU,QAAQ,MAAM,YAAY,CAAC;AACrC,YAAU,OAAO,MAAM,YAAY,CAAC;AACpC,YAAU,MAAM,MAAM,YAAY,CAAC;AACnC,YAAU,KAAK,MAAM,YAAY,CAAC;AAClC,YAAU,SAAS,MAAM,YAAY,CAAC;AACtC,YAAU,QAAQ,MAAM,YAAY,CAAC;AACrC,YAAU,KAAK,MAAM,YAAY,CAAC,YAAY,QAAQ;AACtD,YAAU,QAAQ,MAAM,YAAY,CAAC;AACrC,YAAU,KAAK,MAAM,YAAY;AAGjC,YAAU,KAAK,MAAM,YAAY;AACjC,YAAU,KAAK,MAAM,YAAY,CAAC;AAClC,YAAU,OAAO,MAAM,YAAY,CAAC;AACpC,YAAU,SAAS,MAAM,YAAY,CAAC;AACtC,YAAU,KAAK,MAAM,YAAY,CAAC;AAElC,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA;AAAA,IAET,WAAW,MAAM,SAAS;AACxB,UAAI,CAAC,OAAO,SAAS,OAAO;AAC1B,eAAO,KAAK,eAAe,MAAM;AAAA;AAEnC,UAAI,KAAK,SAAS;AAChB,eAAO,KAAK,OAAO;AAAA;AAErB,aAAO,KAAK,OAAO;AAAA;AAAA,WAEd,MAAM,OAAO,SAAS;AAC3B,cAAQ,MAAM;AACd,UAAI,UAAU,MAAM;AAClB,eAAO;AAAA;AAET,UAAI,SAAS,GAAG,KAAK,QAAQ,WAAW;AACtC,gBAAQ,SAAS,GAAG,OAAO,QAAQ,UAAU;AAAA,aAE1C;AACH,gBAAQ,IAAI,KAAK,GAAG,SAAS,QAAQ;AAAA;AAEvC,aAAO;AAAA;AAAA;AAIX,yBAAuB,UAAU,SAAS;AAAA,WACjC,MAAM,OAAO;AAClB,aAAO,MAAM;AAAA;AAAA;AAGjB,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AAEN,aAAO;AAAA;AAAA;AAIX,qBAAmB,UAAU,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA;AAAA;AAIX,wBAAsB,UAAU,QAAQ;AAAA,IACtC,QAAQ;AACN,aAAO;AAAA;AAAA;AAIX,yBAAuB,UAAU,KAAK;AAAA,IACpC,WAAW,OAAO,SAAS;AACzB,aAAO,QAAQ,cAAc,WAAW,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU;AAAA;AAAA;AAI/F,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA;AAAA;",
"names": []
}
+59
View File
@@ -0,0 +1,59 @@
"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").snowflake;
const { SnowflakeQueryInterface } = require("./query-interface");
class SnowflakeDialect extends AbstractDialect {
constructor(sequelize) {
super();
this.sequelize = sequelize;
this.connectionManager = new ConnectionManager(this, sequelize);
this.queryGenerator = new QueryGenerator({
_dialect: this,
sequelize
});
this.queryInterface = new SnowflakeQueryInterface(sequelize, this.queryGenerator);
}
}
SnowflakeDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {
"VALUES ()": true,
"LIMIT ON UPDATE": true,
lock: true,
forShare: "LOCK IN SHARE MODE",
settingIsolationLevelDuringTransaction: false,
inserts: {
ignoreDuplicates: " IGNORE",
updateOnDuplicate: false
},
index: {
collate: false,
length: true,
parser: true,
type: true,
using: 1
},
constraints: {
dropConstraint: false,
check: false
},
indexViaAlter: true,
indexHints: true,
NUMERIC: true,
GEOMETRY: false,
JSON: false,
REGEXP: true,
schemas: true
});
SnowflakeDialect.prototype.defaultVersion = "5.7.0";
SnowflakeDialect.prototype.Query = Query;
SnowflakeDialect.prototype.QueryGenerator = QueryGenerator;
SnowflakeDialect.prototype.DataTypes = DataTypes;
SnowflakeDialect.prototype.name = "snowflake";
SnowflakeDialect.prototype.TICK_CHAR = '"';
SnowflakeDialect.prototype.TICK_CHAR_LEFT = SnowflakeDialect.prototype.TICK_CHAR;
SnowflakeDialect.prototype.TICK_CHAR_RIGHT = SnowflakeDialect.prototype.TICK_CHAR;
module.exports = SnowflakeDialect;
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/snowflake/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').snowflake;\nconst { SnowflakeQueryInterface } = require('./query-interface');\n\nclass SnowflakeDialect 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 this.queryInterface = new SnowflakeQueryInterface(sequelize, this.queryGenerator);\n }\n}\n\nSnowflakeDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), {\n 'VALUES ()': true,\n 'LIMIT ON UPDATE': true,\n lock: true,\n forShare: 'LOCK IN SHARE MODE',\n settingIsolationLevelDuringTransaction: false,\n inserts: {\n ignoreDuplicates: ' IGNORE',\n // disable for now, but could be enable by approach below\n // https://stackoverflow.com/questions/54828745/how-to-migrate-on-conflict-do-nothing-from-postgresql-to-snowflake\n updateOnDuplicate: false\n },\n index: {\n collate: false,\n length: true,\n parser: true,\n type: true,\n using: 1\n },\n constraints: {\n dropConstraint: false,\n check: false\n },\n indexViaAlter: true,\n indexHints: true,\n NUMERIC: true,\n // disable for now, need more work to enable the GEOGRAPHY MAPPING\n GEOMETRY: false,\n JSON: false,\n REGEXP: true,\n schemas: true\n});\n\nSnowflakeDialect.prototype.defaultVersion = '5.7.0';\nSnowflakeDialect.prototype.Query = Query;\nSnowflakeDialect.prototype.QueryGenerator = QueryGenerator;\nSnowflakeDialect.prototype.DataTypes = DataTypes;\nSnowflakeDialect.prototype.name = 'snowflake';\nSnowflakeDialect.prototype.TICK_CHAR = '\"';\nSnowflakeDialect.prototype.TICK_CHAR_LEFT = SnowflakeDialect.prototype.TICK_CHAR;\nSnowflakeDialect.prototype.TICK_CHAR_RIGHT = SnowflakeDialect.prototype.TICK_CHAR;\n\nmodule.exports = SnowflakeDialect;\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,4BAA4B,QAAQ;AAE5C,+BAA+B,gBAAgB;AAAA,EAC7C,YAAY,WAAW;AACrB;AACA,SAAK,YAAY;AACjB,SAAK,oBAAoB,IAAI,kBAAkB,MAAM;AACrD,SAAK,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU;AAAA,MACV;AAAA;AAEF,SAAK,iBAAiB,IAAI,wBAAwB,WAAW,KAAK;AAAA;AAAA;AAItE,iBAAiB,UAAU,WAAW,EAAE,MAAM,EAAE,UAAU,gBAAgB,UAAU,WAAW;AAAA,EAC7F,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,wCAAwC;AAAA,EACxC,SAAS;AAAA,IACP,kBAAkB;AAAA,IAGlB,mBAAmB;AAAA;AAAA,EAErB,OAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA;AAAA,EAET,aAAa;AAAA,IACX,gBAAgB;AAAA,IAChB,OAAO;AAAA;AAAA,EAET,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,SAAS;AAAA,EAET,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA;AAGX,iBAAiB,UAAU,iBAAiB;AAC5C,iBAAiB,UAAU,QAAQ;AACnC,iBAAiB,UAAU,iBAAiB;AAC5C,iBAAiB,UAAU,YAAY;AACvC,iBAAiB,UAAU,OAAO;AAClC,iBAAiB,UAAU,YAAY;AACvC,iBAAiB,UAAU,iBAAiB,iBAAiB,UAAU;AACvE,iBAAiB,UAAU,kBAAkB,iBAAiB,UAAU;AAExE,OAAO,UAAU;",
"names": []
}
@@ -0,0 +1,540 @@
"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 _ = require("lodash");
const Utils = require("../../utils");
const AbstractQueryGenerator = require("../abstract/query-generator");
const util = require("util");
const Op = require("../../operators");
const JSON_FUNCTION_REGEX = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i;
const JSON_OPERATOR_REGEX = /^\s*(->>?|@>|<@|\?[|&]?|\|{2}|#-)/i;
const TOKEN_CAPTURE_REGEX = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i;
const FOREIGN_KEY_FIELDS = [
"CONSTRAINT_NAME as constraint_name",
"CONSTRAINT_NAME as constraintName",
"CONSTRAINT_SCHEMA as constraintSchema",
"CONSTRAINT_SCHEMA as constraintCatalog",
"TABLE_NAME as tableName",
"TABLE_SCHEMA as tableSchema",
"TABLE_SCHEMA as tableCatalog",
"COLUMN_NAME as columnName",
"REFERENCED_TABLE_SCHEMA as referencedTableSchema",
"REFERENCED_TABLE_SCHEMA as referencedTableCatalog",
"REFERENCED_TABLE_NAME as referencedTableName",
"REFERENCED_COLUMN_NAME as referencedColumnName"
].join(",");
const SNOWFLAKE_RESERVED_WORDS = "account,all,alter,and,any,as,between,by,case,cast,check,column,connect,connections,constraint,create,cross,current,current_date,current_time,current_timestamp,current_user,database,delete,distinct,drop,else,exists,false,following,for,from,full,grant,group,gscluster,having,ilike,in,increment,inner,insert,intersect,into,is,issue,join,lateral,left,like,localtime,localtimestamp,minus,natural,not,null,of,on,or,order,organization,qualify,regexp,revoke,right,rlike,row,rows,sample,schema,select,set,some,start,table,tablesample,then,to,trigger,true,try_cast,union,unique,update,using,values,view,when,whenever,where,with".split(",");
const typeWithoutDefault = /* @__PURE__ */ new Set(["BLOB", "TEXT", "GEOMETRY", "JSON"]);
class SnowflakeQueryGenerator extends AbstractQueryGenerator {
constructor(options) {
super(options);
this.OperatorMap = __spreadProps(__spreadValues({}, this.OperatorMap), {
[Op.regexp]: "REGEXP",
[Op.notRegexp]: "NOT REGEXP"
});
}
createDatabaseQuery(databaseName, options) {
options = __spreadValues({
charset: null,
collate: null
}, options);
return Utils.joinSQLFragments([
"CREATE DATABASE IF NOT EXISTS",
this.quoteIdentifier(databaseName),
options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`,
options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`,
";"
]);
}
dropDatabaseQuery(databaseName) {
return `DROP DATABASE IF EXISTS ${this.quoteIdentifier(databaseName)};`;
}
createSchema() {
return "SHOW TABLES";
}
showSchemasQuery() {
return "SHOW TABLES";
}
versionQuery() {
return "SELECT CURRENT_VERSION()";
}
createTableQuery(tableName, attributes, options) {
options = __spreadValues({
charset: null,
rowFormat: null
}, options);
const primaryKeys = [];
const foreignKeys = {};
const attrStr = [];
for (const attr in attributes) {
if (!Object.prototype.hasOwnProperty.call(attributes, attr))
continue;
const dataType = attributes[attr];
let match;
if (dataType.includes("PRIMARY KEY")) {
primaryKeys.push(attr);
if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1].replace("PRIMARY KEY", "")}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType.replace("PRIMARY KEY", "")}`);
}
} else if (dataType.includes("REFERENCES")) {
match = dataType.match(/^(.+) (REFERENCES.*)$/);
attrStr.push(`${this.quoteIdentifier(attr)} ${match[1]}`);
foreignKeys[attr] = match[2];
} else {
attrStr.push(`${this.quoteIdentifier(attr)} ${dataType}`);
}
}
const table = this.quoteTable(tableName);
let attributesClause = attrStr.join(", ");
const pkString = primaryKeys.map((pk) => this.quoteIdentifier(pk)).join(", ");
if (options.uniqueKeys) {
_.each(options.uniqueKeys, (columns, indexName) => {
if (columns.customIndex) {
if (typeof indexName !== "string") {
indexName = `uniq_${tableName}_${columns.fields.join("_")}`;
}
attributesClause += `, UNIQUE ${this.quoteIdentifier(indexName)} (${columns.fields.map((field) => this.quoteIdentifier(field)).join(", ")})`;
}
});
}
if (pkString.length > 0) {
attributesClause += `, PRIMARY KEY (${pkString})`;
}
for (const fkey in foreignKeys) {
if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) {
attributesClause += `, FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`;
}
}
return Utils.joinSQLFragments([
"CREATE TABLE IF NOT EXISTS",
table,
`(${attributesClause})`,
options.comment && typeof options.comment === "string" && `COMMENT ${this.escape(options.comment)}`,
options.charset && `DEFAULT CHARSET=${options.charset}`,
options.collate && `COLLATE ${options.collate}`,
options.rowFormat && `ROW_FORMAT=${options.rowFormat}`,
";"
]);
}
describeTableQuery(tableName, schema, schemaDelimiter) {
const table = this.quoteTable(this.addSchema({
tableName,
_schema: schema,
_schemaDelimiter: schemaDelimiter
}));
return `SHOW FULL COLUMNS FROM ${table};`;
}
showTablesQuery(database) {
return Utils.joinSQLFragments([
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'",
database ? `AND TABLE_SCHEMA = ${this.escape(database)}` : "AND TABLE_SCHEMA NOT IN ( 'INFORMATION_SCHEMA', 'PERFORMANCE_SCHEMA', 'SYS')",
";"
]);
}
tableExistsQuery(table) {
const tableName = table.tableName || table;
const schema = table.schema;
return Utils.joinSQLFragments([
"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'",
`AND TABLE_SCHEMA = ${schema !== void 0 ? this.escape(schema) : "CURRENT_SCHEMA()"}`,
`AND TABLE_NAME = ${this.escape(tableName)}`,
";"
]);
}
addColumnQuery(table, key, dataType) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(table),
"ADD",
this.quoteIdentifier(key),
this.attributeToSQL(dataType, {
context: "addColumn",
tableName: table,
foreignKey: key
}),
";"
]);
}
removeColumnQuery(tableName, attributeName) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP",
this.quoteIdentifier(attributeName),
";"
]);
}
changeColumnQuery(tableName, attributes) {
const query = (...subQuerys) => Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"ALTER COLUMN",
...subQuerys,
";"
]);
const sql = [];
for (const attributeName in attributes) {
let definition = this.dataTypeMapping(tableName, attributeName, attributes[attributeName]);
const attrSql = [];
if (definition.includes("NOT NULL")) {
attrSql.push(query(this.quoteIdentifier(attributeName), "SET NOT NULL"));
definition = definition.replace("NOT NULL", "").trim();
} else if (!definition.includes("REFERENCES")) {
attrSql.push(query(this.quoteIdentifier(attributeName), "DROP NOT NULL"));
}
if (definition.includes("DEFAULT")) {
attrSql.push(query(this.quoteIdentifier(attributeName), "SET DEFAULT", definition.match(/DEFAULT ([^;]+)/)[1]));
definition = definition.replace(/(DEFAULT[^;]+)/, "").trim();
} else if (!definition.includes("REFERENCES")) {
attrSql.push(query(this.quoteIdentifier(attributeName), "DROP DEFAULT"));
}
if (definition.match(/UNIQUE;*$/)) {
definition = definition.replace(/UNIQUE;*$/, "");
attrSql.push(query("ADD UNIQUE (", this.quoteIdentifier(attributeName), ")").replace("ALTER COLUMN", ""));
}
if (definition.includes("REFERENCES")) {
definition = definition.replace(/.+?(?=REFERENCES)/, "");
attrSql.push(query("ADD FOREIGN KEY (", this.quoteIdentifier(attributeName), ")", definition).replace("ALTER COLUMN", ""));
} else {
attrSql.push(query(this.quoteIdentifier(attributeName), "TYPE", definition));
}
sql.push(attrSql.join(""));
}
return sql.join("");
}
renameColumnQuery(tableName, attrBefore, attributes) {
const attrString = [];
for (const attrName in attributes) {
const definition = attributes[attrName];
attrString.push(`'${attrBefore}' '${attrName}' ${definition}`);
}
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"RENAME COLUMN",
attrString.join(" to "),
";"
]);
}
handleSequelizeMethod(attr, tableName, factory, options, prepend) {
if (attr instanceof Utils.Json) {
if (attr.conditions) {
const conditions = this.parseConditionObject(attr.conditions).map((condition) => `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'`);
return conditions.join(" AND ");
}
if (attr.path) {
let str;
if (this._checkValidJsonStatement(attr.path)) {
str = attr.path;
} else {
const paths = _.toPath(attr.path);
const column = paths.shift();
str = this.jsonPathExtractionQuery(column, paths);
}
if (attr.value) {
str += util.format(" = %s", this.escape(attr.value));
}
return str;
}
} else if (attr instanceof Utils.Cast) {
if (/timestamp/i.test(attr.type)) {
attr.type = "datetime";
} else if (attr.json && /boolean/i.test(attr.type)) {
attr.type = "char";
} else if (/double precision/i.test(attr.type) || /boolean/i.test(attr.type) || /integer/i.test(attr.type)) {
attr.type = "decimal";
} else if (/text/i.test(attr.type)) {
attr.type = "char";
}
}
return super.handleSequelizeMethod(attr, tableName, factory, options, prepend);
}
truncateTableQuery(tableName) {
return Utils.joinSQLFragments([
"TRUNCATE",
this.quoteTable(tableName)
]);
}
deleteQuery(tableName, where, options = {}, model) {
const table = this.quoteTable(tableName);
let whereClause = this.getWhereConditions(where, null, model, options);
const limit = options.limit && ` LIMIT ${this.escape(options.limit)}`;
let primaryKeys = "";
let primaryKeysSelection = "";
if (whereClause) {
whereClause = `WHERE ${whereClause}`;
}
if (limit) {
if (!model) {
throw new Error("Cannot LIMIT delete without a model.");
}
const pks = Object.values(model.primaryKeys).map((pk) => this.quoteIdentifier(pk.field)).join(",");
primaryKeys = model.primaryKeyAttributes.length > 1 ? `(${pks})` : pks;
primaryKeysSelection = pks;
return Utils.joinSQLFragments([
"DELETE FROM",
table,
"WHERE",
primaryKeys,
"IN (SELECT",
primaryKeysSelection,
"FROM",
table,
whereClause,
limit,
")",
";"
]);
}
return Utils.joinSQLFragments([
"DELETE FROM",
table,
whereClause,
";"
]);
}
showIndexesQuery() {
return "SELECT '' FROM DUAL";
}
showConstraintsQuery(table, constraintName) {
const tableName = table.tableName || table;
const schemaName = table.schema;
return Utils.joinSQLFragments([
"SELECT CONSTRAINT_CATALOG AS constraintCatalog,",
"CONSTRAINT_NAME AS constraintName,",
"CONSTRAINT_SCHEMA AS constraintSchema,",
"CONSTRAINT_TYPE AS constraintType,",
"TABLE_NAME AS tableName,",
"TABLE_SCHEMA AS tableSchema",
"from INFORMATION_SCHEMA.TABLE_CONSTRAINTS",
`WHERE table_name='${tableName}'`,
constraintName && `AND constraint_name = '${constraintName}'`,
schemaName && `AND TABLE_SCHEMA = '${schemaName}'`,
";"
]);
}
removeIndexQuery(tableName, indexNameOrAttributes) {
let indexName = indexNameOrAttributes;
if (typeof indexName !== "string") {
indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join("_")}`);
}
return Utils.joinSQLFragments([
"DROP INDEX",
this.quoteIdentifier(indexName),
"ON",
this.quoteTable(tableName),
";"
]);
}
attributeToSQL(attribute, options) {
if (!_.isPlainObject(attribute)) {
attribute = {
type: attribute
};
}
const attributeString = attribute.type.toString({ escape: this.escape.bind(this) });
let template = attributeString;
if (attribute.allowNull === false) {
template += " NOT NULL";
}
if (attribute.autoIncrement) {
template += " AUTOINCREMENT";
}
if (!typeWithoutDefault.has(attributeString) && attribute.type._binary !== true && Utils.defaultValueSchemable(attribute.defaultValue)) {
template += ` DEFAULT ${this.escape(attribute.defaultValue)}`;
}
if (attribute.unique === true) {
template += " UNIQUE";
}
if (attribute.primaryKey) {
template += " PRIMARY KEY";
}
if (attribute.comment) {
template += ` COMMENT ${this.escape(attribute.comment)}`;
}
if (attribute.first) {
template += " FIRST";
}
if (attribute.after) {
template += ` AFTER ${this.quoteIdentifier(attribute.after)}`;
}
if (attribute.references) {
if (options && options.context === "addColumn" && options.foreignKey) {
const attrName = this.quoteIdentifier(options.foreignKey);
const fkName = this.quoteIdentifier(`${options.tableName}_${attrName}_foreign_idx`);
template += `, ADD CONSTRAINT ${fkName} FOREIGN KEY (${attrName})`;
}
template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`;
if (attribute.references.key) {
template += ` (${this.quoteIdentifier(attribute.references.key)})`;
} else {
template += ` (${this.quoteIdentifier("id")})`;
}
if (attribute.onDelete) {
template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`;
}
if (attribute.onUpdate) {
template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`;
}
}
return template;
}
attributesToSQL(attributes, options) {
const result = {};
for (const key in attributes) {
const attribute = attributes[key];
result[attribute.field || key] = this.attributeToSQL(attribute, options);
}
return result;
}
_checkValidJsonStatement(stmt) {
if (typeof stmt !== "string") {
return false;
}
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 = JSON_FUNCTION_REGEX.exec(string);
if (functionMatches) {
currentIndex += functionMatches[0].indexOf("(");
hasJsonFunction = true;
continue;
}
const operatorMatches = JSON_OPERATOR_REGEX.exec(string);
if (operatorMatches) {
currentIndex += operatorMatches[0].length;
hasJsonFunction = true;
continue;
}
const tokenMatches = TOKEN_CAPTURE_REGEX.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;
}
if (hasJsonFunction && (hasInvalidToken || openingBrackets !== closingBrackets)) {
throw new Error(`Invalid json statement: ${stmt}`);
}
return hasJsonFunction;
}
dataTypeMapping(tableName, attr, dataType) {
if (dataType.includes("PRIMARY KEY")) {
dataType = dataType.replace("PRIMARY KEY", "");
}
if (dataType.includes("SERIAL")) {
if (dataType.includes("BIGINT")) {
dataType = dataType.replace("SERIAL", "BIGSERIAL");
dataType = dataType.replace("BIGINT", "");
} else if (dataType.includes("SMALLINT")) {
dataType = dataType.replace("SERIAL", "SMALLSERIAL");
dataType = dataType.replace("SMALLINT", "");
} else {
dataType = dataType.replace("INTEGER", "");
}
dataType = dataType.replace("NOT NULL", "");
}
return dataType;
}
getForeignKeysQuery(table, schemaName) {
const tableName = table.tableName || table;
return Utils.joinSQLFragments([
"SELECT",
FOREIGN_KEY_FIELDS,
`FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '${tableName}'`,
`AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='${schemaName}'`,
"AND REFERENCED_TABLE_NAME IS NOT NULL",
";"
]);
}
getForeignKeyQuery(table, columnName) {
const quotedSchemaName = table.schema ? wrapSingleQuote(table.schema) : "";
const quotedTableName = wrapSingleQuote(table.tableName || table);
const quotedColumnName = wrapSingleQuote(columnName);
return Utils.joinSQLFragments([
"SELECT",
FOREIGN_KEY_FIELDS,
"FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE",
"WHERE (",
[
`REFERENCED_TABLE_NAME = ${quotedTableName}`,
table.schema && `AND REFERENCED_TABLE_SCHEMA = ${quotedSchemaName}`,
`AND REFERENCED_COLUMN_NAME = ${quotedColumnName}`
],
") OR (",
[
`TABLE_NAME = ${quotedTableName}`,
table.schema && `AND TABLE_SCHEMA = ${quotedSchemaName}`,
`AND COLUMN_NAME = ${quotedColumnName}`,
"AND REFERENCED_TABLE_NAME IS NOT NULL"
],
")"
]);
}
dropForeignKeyQuery(tableName, foreignKey) {
return Utils.joinSQLFragments([
"ALTER TABLE",
this.quoteTable(tableName),
"DROP FOREIGN KEY",
this.quoteIdentifier(foreignKey),
";"
]);
}
addLimitAndOffset(options) {
let fragment = [];
if (options.offset !== null && options.offset !== void 0 && options.offset !== 0) {
fragment = fragment.concat([" LIMIT ", this.escape(options.limit), " OFFSET ", this.escape(options.offset)]);
} else if (options.limit !== null && options.limit !== void 0) {
fragment = [" LIMIT ", this.escape(options.limit)];
}
return fragment.join("");
}
quoteIdentifier(identifier, force) {
const optForceQuote = force || false;
const optQuoteIdentifiers = this.options.quoteIdentifiers !== false;
const rawIdentifier = Utils.removeTicks(identifier, '"');
if (optForceQuote === true || optQuoteIdentifiers !== false || identifier.includes(".") || identifier.includes("->") || SNOWFLAKE_RESERVED_WORDS.includes(rawIdentifier.toLowerCase())) {
return Utils.addTicks(rawIdentifier, '"');
}
return rawIdentifier;
}
}
function wrapSingleQuote(identifier) {
return Utils.addTicks(identifier, "'");
}
module.exports = SnowflakeQueryGenerator;
//# sourceMappingURL=query-generator.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,70 @@
"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 { QueryInterface } = require("../abstract/query-interface");
const QueryTypes = require("../../query-types");
class SnowflakeQueryInterface extends QueryInterface {
async removeColumn(tableName, columnName, options) {
options = options || {};
const [results] = await this.sequelize.query(this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
}, columnName), __spreadValues({ raw: true }, options));
if (results.length && results[0].constraint_name !== "PRIMARY") {
await Promise.all(results.map((constraint) => this.sequelize.query(this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name), __spreadValues({ raw: true }, options))));
}
return await this.sequelize.query(this.queryGenerator.removeColumnQuery(tableName, columnName), __spreadValues({ raw: true }, options));
}
async upsert(tableName, insertValues, updateValues, where, options) {
options = __spreadValues({}, options);
options.type = QueryTypes.UPSERT;
options.updateOnDuplicate = Object.keys(updateValues);
const model = options.model;
const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);
return await this.sequelize.query(sql, options);
}
async removeConstraint(tableName, constraintName, options) {
const sql = this.queryGenerator.showConstraintsQuery(tableName.tableName ? tableName : {
tableName,
schema: this.sequelize.config.database
}, constraintName);
const constraints = await this.sequelize.query(sql, __spreadProps(__spreadValues({}, options), {
type: this.sequelize.QueryTypes.SHOWCONSTRAINTS
}));
const constraint = constraints[0];
let query;
if (!constraint || !constraint.constraintType) {
throw new sequelizeErrors.UnknownConstraintError({
message: `Constraint ${constraintName} on table ${tableName} does not exist`,
constraint: constraintName,
table: tableName
});
}
if (constraint.constraintType === "FOREIGN KEY") {
query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName);
} else {
query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
}
return await this.sequelize.query(query, options);
}
}
exports.SnowflakeQueryInterface = SnowflakeQueryInterface;
//# sourceMappingURL=query-interface.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/dialects/snowflake/query-interface.js"],
"sourcesContent": ["'use strict';\n\nconst sequelizeErrors = require('../../errors');\nconst { QueryInterface } = require('../abstract/query-interface');\nconst QueryTypes = require('../../query-types');\n\n/**\n * The interface that Sequelize uses to talk with Snowflake database\n */\nclass SnowflakeQueryInterface extends QueryInterface {\n /**\n * A wrapper that fixes Snowflake's inability to cleanly remove columns from existing tables if they have a foreign key constraint.\n *\n * @override\n */\n async removeColumn(tableName, columnName, options) {\n options = options || {};\n\n const [results] = await this.sequelize.query(\n this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {\n tableName,\n schema: this.sequelize.config.database\n }, columnName),\n { raw: true, ...options }\n );\n\n //Exclude primary key constraint\n if (results.length && results[0].constraint_name !== 'PRIMARY') {\n await Promise.all(results.map(constraint => this.sequelize.query(\n this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),\n { raw: true, ...options }\n )));\n }\n\n return await this.sequelize.query(\n this.queryGenerator.removeColumnQuery(tableName, columnName),\n { raw: true, ...options }\n );\n }\n\n /** @override */\n async upsert(tableName, insertValues, updateValues, where, options) {\n options = { ...options };\n\n options.type = QueryTypes.UPSERT;\n options.updateOnDuplicate = Object.keys(updateValues);\n\n const model = options.model;\n const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);\n return await this.sequelize.query(sql, options);\n }\n\n /** @override */\n async removeConstraint(tableName, constraintName, options) {\n const sql = this.queryGenerator.showConstraintsQuery(\n tableName.tableName ? tableName : {\n tableName,\n schema: this.sequelize.config.database\n }, constraintName);\n\n const constraints = await this.sequelize.query(sql, { ...options,\n type: this.sequelize.QueryTypes.SHOWCONSTRAINTS });\n\n const constraint = constraints[0];\n let query;\n if (!constraint || !constraint.constraintType) {\n throw new sequelizeErrors.UnknownConstraintError(\n {\n message: `Constraint ${constraintName} on table ${tableName} does not exist`,\n constraint: constraintName,\n table: tableName\n });\n }\n\n if (constraint.constraintType === 'FOREIGN KEY') {\n query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName);\n } else {\n query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);\n }\n\n return await this.sequelize.query(query, options);\n }\n}\n\nexports.SnowflakeQueryInterface = SnowflakeQueryInterface;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;AAEA,MAAM,kBAAkB,QAAQ;AAChC,MAAM,EAAE,mBAAmB,QAAQ;AACnC,MAAM,aAAa,QAAQ;AAK3B,sCAAsC,eAAe;AAAA,QAM7C,aAAa,WAAW,YAAY,SAAS;AACjD,cAAU,WAAW;AAErB,UAAM,CAAC,WAAW,MAAM,KAAK,UAAU,MACrC,KAAK,eAAe,mBAAmB,UAAU,YAAY,YAAY;AAAA,MACvE;AAAA,MACA,QAAQ,KAAK,UAAU,OAAO;AAAA,OAC7B,aACH,iBAAE,KAAK,QAAS;AAIlB,QAAI,QAAQ,UAAU,QAAQ,GAAG,oBAAoB,WAAW;AAC9D,YAAM,QAAQ,IAAI,QAAQ,IAAI,gBAAc,KAAK,UAAU,MACzD,KAAK,eAAe,oBAAoB,WAAW,WAAW,kBAC9D,iBAAE,KAAK,QAAS;AAAA;AAIpB,WAAO,MAAM,KAAK,UAAU,MAC1B,KAAK,eAAe,kBAAkB,WAAW,aACjD,iBAAE,KAAK,QAAS;AAAA;AAAA,QAKd,OAAO,WAAW,cAAc,cAAc,OAAO,SAAS;AAClE,cAAU,mBAAK;AAEf,YAAQ,OAAO,WAAW;AAC1B,YAAQ,oBAAoB,OAAO,KAAK;AAExC,UAAM,QAAQ,QAAQ;AACtB,UAAM,MAAM,KAAK,eAAe,YAAY,WAAW,cAAc,MAAM,eAAe;AAC1F,WAAO,MAAM,KAAK,UAAU,MAAM,KAAK;AAAA;AAAA,QAInC,iBAAiB,WAAW,gBAAgB,SAAS;AACzD,UAAM,MAAM,KAAK,eAAe,qBAC9B,UAAU,YAAY,YAAY;AAAA,MAChC;AAAA,MACA,QAAQ,KAAK,UAAU,OAAO;AAAA,OAC7B;AAEL,UAAM,cAAc,MAAM,KAAK,UAAU,MAAM,KAAK,iCAAK,UAAL;AAAA,MAClD,MAAM,KAAK,UAAU,WAAW;AAAA;AAElC,UAAM,aAAa,YAAY;AAC/B,QAAI;AACJ,QAAI,CAAC,cAAc,CAAC,WAAW,gBAAgB;AAC7C,YAAM,IAAI,gBAAgB,uBACxB;AAAA,QACE,SAAS,cAAc,2BAA2B;AAAA,QAClD,YAAY;AAAA,QACZ,OAAO;AAAA;AAAA;AAIb,QAAI,WAAW,mBAAmB,eAAe;AAC/C,cAAQ,KAAK,eAAe,oBAAoB,WAAW;AAAA,WACtD;AACL,cAAQ,KAAK,eAAe,iBAAiB,WAAW,WAAW,WAAW;AAAA;AAGhF,WAAO,MAAM,KAAK,UAAU,MAAM,OAAO;AAAA;AAAA;AAI7C,QAAQ,0BAA0B;",
"names": []
}
+237
View File
@@ -0,0 +1,237 @@
"use strict";
const AbstractQuery = require("../abstract/query");
const sequelizeErrors = require("../../errors");
const _ = require("lodash");
const { logger } = require("../../utils/logger");
const ER_DUP_ENTRY = 1062;
const ER_DEADLOCK = 1213;
const ER_ROW_IS_REFERENCED = 1451;
const ER_NO_REFERENCED_ROW = 1452;
const debug = logger.debugContext("sql:snowflake");
class Query extends AbstractQuery {
static formatBindParameters(sql, values, dialect) {
const bindParam = [];
const replacementFunc = (_match, key, values_) => {
if (values_[key] !== void 0) {
bindParam.push(values_[key]);
return "?";
}
return void 0;
};
sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];
return [sql, bindParam.length > 0 ? bindParam : void 0];
}
async run(sql, parameters) {
this.sql = sql;
const { connection, options } = this;
const showWarnings = this.sequelize.options.showWarnings || options.showWarnings;
const complete = this._logQuery(sql, debug, parameters);
if (parameters) {
debug("parameters(%j)", parameters);
}
let results;
try {
results = await new Promise((resolve, reject) => {
connection.execute({
sqlText: sql,
binds: parameters,
complete(err, _stmt, rows) {
if (err) {
reject(err);
} else {
resolve(rows);
}
}
});
});
} catch (error) {
if (options.transaction && error.errno === ER_DEADLOCK) {
try {
await options.transaction.rollback();
} catch (error_) {
}
options.transaction.finished = "rollback";
}
error.sql = sql;
error.parameters = parameters;
throw this.formatError(error);
} finally {
complete();
}
if (showWarnings && results && results.warningStatus > 0) {
await this.logWarnings(results);
}
return this.formatResults(results);
}
formatResults(data) {
let result = this.instance;
if (this.isInsertQuery(data)) {
this.handleInsertQuery(data);
if (!this.instance) {
if (data.constructor.name === "ResultSetHeader" && this.model && this.model.autoIncrementAttribute && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute && this.model.rawAttributes[this.model.primaryKeyAttribute]) {
const startId = data[this.getInsertIdField()];
result = [];
for (let i = startId; i < startId + data.affectedRows; i++) {
result.push({ [this.model.rawAttributes[this.model.primaryKeyAttribute].field]: i });
}
} else {
result = data[this.getInsertIdField()];
}
}
}
if (this.isSelectQuery()) {
if (this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) {
const sfAttrMap = _.reduce(this.model.rawAttributes, (m, v, k) => {
m[k.toUpperCase()] = k;
return m;
}, {});
data = data.map((data2) => _.reduce(data2, (prev, value, key) => {
if (value !== void 0 && sfAttrMap[key]) {
prev[sfAttrMap[key]] = value;
delete prev[key];
}
return prev;
}, data2));
}
this.options.fieldMap = _.mapKeys(this.options.fieldMap, (v, k) => {
return k.toUpperCase();
});
return this.handleSelectQuery(data);
}
if (this.isShowTablesQuery()) {
return this.handleShowTablesQuery(data);
}
if (this.isDescribeQuery()) {
result = {};
for (const _result of data) {
result[_result.Field] = {
type: _result.Type.toUpperCase(),
allowNull: _result.Null === "YES",
defaultValue: _result.Default,
primaryKey: _result.Key === "PRI",
autoIncrement: Object.prototype.hasOwnProperty.call(_result, "Extra") && _result.Extra.toLowerCase() === "auto_increment",
comment: _result.Comment ? _result.Comment : null
};
}
return result;
}
if (this.isShowIndexesQuery()) {
return this.handleShowIndexesQuery(data);
}
if (this.isCallQuery()) {
return data[0];
}
if (this.isBulkUpdateQuery() || this.isBulkDeleteQuery()) {
return data[0]["number of rows updated"];
}
if (this.isVersionQuery()) {
return data[0].version;
}
if (this.isForeignKeysQuery()) {
return data;
}
if (this.isUpsertQuery()) {
return [result, data.affectedRows === 1];
}
if (this.isInsertQuery() || this.isUpdateQuery()) {
return [result, data.affectedRows];
}
if (this.isShowConstraintsQuery()) {
return data;
}
if (this.isRawQuery()) {
return [data, data];
}
return result;
}
async logWarnings(results) {
const warningResults = await this.run("SHOW WARNINGS");
const warningMessage = `Snowflake Warnings (${this.connection.uuid || "default"}): `;
const messages = [];
for (const _warningRow of warningResults) {
if (_warningRow === void 0 || typeof _warningRow[Symbol.iterator] !== "function") {
continue;
}
for (const _warningResult of _warningRow) {
if (Object.prototype.hasOwnProperty.call(_warningResult, "Message")) {
messages.push(_warningResult.Message);
} else {
for (const _objectKey of _warningResult.keys()) {
messages.push([_objectKey, _warningResult[_objectKey]].join(": "));
}
}
}
}
this.sequelize.log(warningMessage + messages.join("; "), this.options);
return results;
}
formatError(err) {
const errCode = err.errno || err.code;
switch (errCode) {
case ER_DUP_ENTRY: {
const match = err.message.match(/Duplicate entry '([\s\S]*)' for key '?((.|\s)*?)'?$/);
let fields = {};
let message = "Validation error";
const values = match ? match[1].split("-") : void 0;
const fieldKey = match ? match[2] : void 0;
const fieldVal = match ? match[1] : void 0;
const uniqueKey = this.model && this.model.uniqueKeys[fieldKey];
if (uniqueKey) {
if (uniqueKey.msg)
message = uniqueKey.msg;
fields = _.zipObject(uniqueKey.fields, values);
} else {
fields[fieldKey] = fieldVal;
}
const errors = [];
_.forOwn(fields, (value, field) => {
errors.push(new sequelizeErrors.ValidationErrorItem(this.getUniqueConstraintErrorMessage(field), "unique violation", field, value, this.instance, "not_unique"));
});
return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields });
}
case ER_ROW_IS_REFERENCED:
case ER_NO_REFERENCED_ROW: {
const match = err.message.match(/CONSTRAINT ([`"])(.*)\1 FOREIGN KEY \(\1(.*)\1\) REFERENCES \1(.*)\1 \(\1(.*)\1\)/);
const quoteChar = match ? match[1] : "`";
const fields = match ? match[3].split(new RegExp(`${quoteChar}, *${quoteChar}`)) : void 0;
return new sequelizeErrors.ForeignKeyConstraintError({
reltype: String(errCode) === String(ER_ROW_IS_REFERENCED) ? "parent" : "child",
table: match ? match[4] : void 0,
fields,
value: fields && fields.length && this.instance && this.instance[fields[0]] || void 0,
index: match ? match[2] : void 0,
parent: err
});
}
default:
return new sequelizeErrors.DatabaseError(err);
}
}
handleShowIndexesQuery(data) {
data = data.reduce((acc, item) => {
if (!(item.Key_name in acc)) {
acc[item.Key_name] = item;
item.fields = [];
}
acc[item.Key_name].fields[item.Seq_in_index - 1] = {
attribute: item.Column_name,
length: item.Sub_part || void 0,
order: item.Collation === "A" ? "ASC" : void 0
};
delete item.column_name;
return acc;
}, {});
return _.map(data, (item) => ({
primary: item.Key_name === "PRIMARY",
fields: item.fields,
name: item.Key_name,
tableName: item.Table,
unique: item.Non_unique !== 1,
type: item.Index_type
}));
}
}
module.exports = Query;
module.exports.Query = Query;
module.exports.default = Query;
//# sourceMappingURL=query.js.map
File diff suppressed because one or more lines are too long
@@ -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
File diff suppressed because one or more lines are too long
+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
File diff suppressed because one or more lines are too long
+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
File diff suppressed because one or more lines are too long
+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
File diff suppressed because one or more lines are too long
+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": []
}
+48
View File
@@ -0,0 +1,48 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => aggregate_error_default
});
var import_base_error = __toModule(require("./base-error"));
class AggregateError extends import_base_error.default {
constructor(errors) {
super();
__publicField(this, "errors");
this.errors = errors;
this.name = "AggregateError";
}
toString() {
const message = `AggregateError of:
${this.errors.map((error) => error === this ? "[Circular AggregateError]" : error instanceof AggregateError ? String(error).replace(/\n$/, "").replace(/^/gm, " ") : String(error).replace(/^/gm, " ").substring(2)).join("\n")}
`;
return message;
}
}
var aggregate_error_default = AggregateError;
//# sourceMappingURL=aggregate-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/aggregate-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * A wrapper for multiple Errors\n *\n * @param errors The aggregated errors that occurred\n */\nclass AggregateError extends BaseError {\n /** the aggregated errors that occurred */\n readonly errors: Array<AggregateError | Error>;\n\n constructor(errors: Array<AggregateError | Error>) {\n super();\n this.errors = errors;\n this.name = 'AggregateError';\n }\n\n toString(): string {\n const message = `AggregateError of:\\n${this.errors\n .map((error: Error | AggregateError) =>\n error === this\n ? '[Circular AggregateError]'\n : error instanceof AggregateError\n ? String(error).replace(/\\n$/, '').replace(/^/gm, ' ')\n : String(error).replace(/^/gm, ' ').substring(2)\n )\n .join('\\n')}\\n`;\n return message;\n }\n}\n\nexport default AggregateError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAOtB,6BAA6B,0BAAU;AAAA,EAIrC,YAAY,QAAuC;AACjD;AAHO;AAIP,SAAK,SAAS;AACd,SAAK,OAAO;AAAA;AAAA,EAGd,WAAmB;AACjB,UAAM,UAAU;AAAA,EAAuB,KAAK,OACzC,IAAI,CAAC,UACJ,UAAU,OACN,8BACA,iBAAiB,iBACf,OAAO,OAAO,QAAQ,OAAO,IAAI,QAAQ,OAAO,QAChD,OAAO,OAAO,QAAQ,OAAO,QAAQ,UAAU,IAEtD,KAAK;AAAA;AACR,WAAO;AAAA;AAAA;AAIX,IAAO,0BAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => association_error_default
});
var import_base_error = __toModule(require("./base-error"));
class AssociationError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeAssociationError";
}
}
var association_error_default = AssociationError;
//# sourceMappingURL=association-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/association-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Thrown when an association is improperly constructed (see message for details)\n */\nclass AssociationError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeAssociationError';\n }\n}\n\nexport default AssociationError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,+BAA+B,0BAAU;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,4BAAQ;",
"names": []
}
+18
View File
@@ -0,0 +1,18 @@
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, {
default: () => base_error_default
});
class BaseError extends Error {
constructor(message) {
super(message);
this.name = "SequelizeBaseError";
}
}
var base_error_default = BaseError;
//# sourceMappingURL=base-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/base-error.ts"],
"sourcesContent": ["export interface ErrorOptions {\n stack?: string;\n}\n\nexport interface CommonErrorProperties {\n /** The database specific error which triggered this one */\n readonly parent: Error;\n\n /** The database specific error which triggered this one */\n readonly original: Error;\n\n /** The SQL that triggered the error */\n readonly sql: string;\n}\n\n/**\n * The Base Error all Sequelize Errors inherit from.\n *\n * Sequelize provides a host of custom error classes, to allow you to do easier debugging. All of these errors are exposed on the sequelize object and the sequelize constructor.\n * All sequelize errors inherit from the base JS error object.\n *\n * This means that errors can be accessed using `Sequelize.ValidationError`\n */\nabstract class BaseError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = 'SequelizeBaseError';\n }\n}\n\nexport default BaseError;\n"],
"mappings": ";;;;;;;AAAA;AAAA;AAAA;AAuBA,wBAAiC,MAAM;AAAA,EACrC,YAAY,SAAkB;AAC5B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,qBAAQ;",
"names": []
}
+44
View File
@@ -0,0 +1,44 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => bulk_record_error_default
});
var import_base_error = __toModule(require("./base-error"));
class BulkRecordError extends import_base_error.default {
constructor(error, record) {
super(error.message);
__publicField(this, "errors");
__publicField(this, "record");
this.name = "SequelizeBulkRecordError";
this.errors = error;
this.record = record;
}
}
var bulk_record_error_default = BulkRecordError;
//# sourceMappingURL=bulk-record-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/bulk-record-error.ts"],
"sourcesContent": ["import type { Model } from '..';\nimport BaseError from './base-error';\n\n/**\n * Thrown when bulk operation fails, it represent per record level error.\n * Used with AggregateError\n *\n * @param error Error for a given record/instance\n * @param record DAO instance that error belongs to\n */\nclass BulkRecordError extends BaseError {\n errors: Error;\n record: Model;\n\n constructor(error: Error, record: Model) {\n super(error.message);\n this.name = 'SequelizeBulkRecordError';\n this.errors = error;\n this.record = record;\n }\n}\n\nexport default BulkRecordError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AACA,wBAAsB;AAStB,8BAA8B,0BAAU;AAAA,EAItC,YAAY,OAAc,QAAe;AACvC,UAAM,MAAM;AAJd;AACA;AAIE,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,SAAS;AAAA;AAAA;AAIlB,IAAO,4BAAQ;",
"names": []
}
+44
View File
@@ -0,0 +1,44 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => connection_error_default
});
var import_base_error = __toModule(require("./base-error"));
class ConnectionError extends import_base_error.default {
constructor(parent) {
super(parent ? parent.message : "");
__publicField(this, "parent");
__publicField(this, "original");
this.name = "SequelizeConnectionError";
this.parent = parent;
this.original = parent;
}
}
var connection_error_default = ConnectionError;
//# sourceMappingURL=connection-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/connection-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * A base class for all connection related errors.\n */\nclass ConnectionError extends BaseError {\n /** The connection specific error which triggered this one */\n parent: Error;\n original: Error;\n\n constructor(parent: Error) {\n super(parent ? parent.message : '');\n this.name = 'SequelizeConnectionError';\n this.parent = parent;\n this.original = parent;\n }\n}\n\nexport default ConnectionError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,8BAA8B,0BAAU;AAAA,EAKtC,YAAY,QAAe;AACzB,UAAM,SAAS,OAAO,UAAU;AAJlC;AACA;AAIE,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,WAAW;AAAA;AAAA;AAIpB,IAAO,2BAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => access_denied_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class AccessDeniedError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeAccessDeniedError";
}
}
var access_denied_error_default = AccessDeniedError;
//# sourceMappingURL=access-denied-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/access-denied-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database is refused due to insufficient privileges\n */\nclass AccessDeniedError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeAccessDeniedError';\n }\n}\n\nexport default AccessDeniedError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,gCAAgC,gCAAgB;AAAA,EAC9C,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,8BAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => connection_acquire_timeout_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class ConnectionAcquireTimeoutError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeConnectionAcquireTimeoutError";
}
}
var connection_acquire_timeout_error_default = ConnectionAcquireTimeoutError;
//# sourceMappingURL=connection-acquire-timeout-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/connection-acquire-timeout-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when connection is not acquired due to timeout\n */\nclass ConnectionAcquireTimeoutError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeConnectionAcquireTimeoutError';\n }\n}\n\nexport default ConnectionAcquireTimeoutError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,4CAA4C,gCAAgB;AAAA,EAC1D,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,2CAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => connection_refused_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class ConnectionRefusedError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeConnectionRefusedError";
}
}
var connection_refused_error_default = ConnectionRefusedError;
//# sourceMappingURL=connection-refused-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/connection-refused-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database is refused\n */\nclass ConnectionRefusedError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeConnectionRefusedError';\n }\n}\n\nexport default ConnectionRefusedError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,qCAAqC,gCAAgB;AAAA,EACnD,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,mCAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => connection_timed_out_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class ConnectionTimedOutError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeConnectionTimedOutError";
}
}
var connection_timed_out_error_default = ConnectionTimedOutError;
//# sourceMappingURL=connection-timed-out-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/connection-timed-out-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database times out\n */\nclass ConnectionTimedOutError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeConnectionTimedOutError';\n }\n}\n\nexport default ConnectionTimedOutError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,sCAAsC,gCAAgB;AAAA,EACpD,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,qCAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => host_not_found_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class HostNotFoundError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeHostNotFoundError";
}
}
var host_not_found_error_default = HostNotFoundError;
//# sourceMappingURL=host-not-found-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/host-not-found-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database has a hostname that was not found\n */\nclass HostNotFoundError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeHostNotFoundError';\n }\n}\n\nexport default HostNotFoundError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,gCAAgC,gCAAgB;AAAA,EAC9C,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,+BAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => host_not_reachable_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class HostNotReachableError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeHostNotReachableError";
}
}
var host_not_reachable_error_default = HostNotReachableError;
//# sourceMappingURL=host-not-reachable-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/host-not-reachable-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database has a hostname that was not reachable\n */\nclass HostNotReachableError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeHostNotReachableError';\n }\n}\n\nexport default HostNotReachableError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,oCAAoC,gCAAgB;AAAA,EAClD,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,mCAAQ;",
"names": []
}
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => invalid_connection_error_default
});
var import_connection_error = __toModule(require("../connection-error"));
class InvalidConnectionError extends import_connection_error.default {
constructor(parent) {
super(parent);
this.name = "SequelizeInvalidConnectionError";
}
}
var invalid_connection_error_default = InvalidConnectionError;
//# sourceMappingURL=invalid-connection-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/connection/invalid-connection-error.ts"],
"sourcesContent": ["import ConnectionError from '../connection-error';\n\n/**\n * Thrown when a connection to a database has invalid values for any of the connection parameters\n */\nclass InvalidConnectionError extends ConnectionError {\n constructor(parent: Error) {\n super(parent);\n this.name = 'SequelizeInvalidConnectionError';\n }\n}\n\nexport default InvalidConnectionError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,8BAA4B;AAK5B,qCAAqC,gCAAgB;AAAA,EACnD,YAAY,QAAe;AACzB,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,mCAAQ;",
"names": []
}
+52
View File
@@ -0,0 +1,52 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => database_error_default
});
var import_base_error = __toModule(require("./base-error"));
class DatabaseError extends import_base_error.default {
constructor(parent, options = {}) {
super(parent.message);
__publicField(this, "parent");
__publicField(this, "original");
__publicField(this, "sql");
__publicField(this, "parameters");
var _a;
this.name = "SequelizeDatabaseError";
this.parent = parent;
this.original = parent;
this.sql = parent.sql;
this.parameters = (_a = parent.parameters) != null ? _a : {};
if (options.stack) {
this.stack = options.stack;
}
}
}
var database_error_default = DatabaseError;
//# sourceMappingURL=database-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/database-error.ts"],
"sourcesContent": ["import BaseError, { CommonErrorProperties, ErrorOptions } from './base-error';\n\nexport interface DatabaseErrorParent\n extends Error,\n Pick<CommonErrorProperties, 'sql'> {\n /** The parameters for the sql that triggered the error */\n readonly parameters?: object;\n}\n\nexport interface DatabaseErrorSubclassOptions extends ErrorOptions {\n parent?: DatabaseErrorParent;\n message?: string;\n}\n\n/**\n * A base class for all database related errors.\n */\nclass DatabaseError\n extends BaseError\n implements DatabaseErrorParent, CommonErrorProperties\n{\n parent: Error;\n original: Error;\n sql: string;\n parameters: object;\n\n /**\n * @param parent The database specific error which triggered this one\n * @param options\n */\n constructor(parent: DatabaseErrorParent, options: ErrorOptions = {}) {\n super(parent.message);\n this.name = 'SequelizeDatabaseError';\n\n this.parent = parent;\n this.original = parent;\n\n this.sql = parent.sql;\n this.parameters = parent.parameters ?? {};\n\n if (options.stack) {\n this.stack = options.stack;\n }\n }\n}\n\nexport default DatabaseError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAA+D;AAiB/D,4BACU,0BAEV;AAAA,EAUE,YAAY,QAA6B,UAAwB,IAAI;AACnE,UAAM,OAAO;AAVf;AACA;AACA;AACA;AAxBF;AAgCI,SAAK,OAAO;AAEZ,SAAK,SAAS;AACd,SAAK,WAAW;AAEhB,SAAK,MAAM,OAAO;AAClB,SAAK,aAAa,aAAO,eAAP,YAAqB;AAEvC,QAAI,QAAQ,OAAO;AACjB,WAAK,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAK3B,IAAO,yBAAQ;",
"names": []
}
@@ -0,0 +1,49 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => exclusion_constraint_error_default
});
var import_database_error = __toModule(require("../database-error"));
class ExclusionConstraintError extends import_database_error.default {
constructor(options) {
options = options || {};
options.parent = options.parent || { sql: "", name: "", message: "" };
super(options.parent, { stack: options.stack });
__publicField(this, "constraint");
__publicField(this, "fields");
__publicField(this, "table");
this.name = "SequelizeExclusionConstraintError";
this.message = options.message || options.parent.message || "";
this.constraint = options.constraint;
this.fields = options.fields;
this.table = options.table;
}
}
var exclusion_constraint_error_default = ExclusionConstraintError;
//# sourceMappingURL=exclusion-constraint-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/database/exclusion-constraint-error.ts"],
"sourcesContent": ["import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error';\n\ninterface ExclusionConstraintErrorOptions {\n constraint?: string;\n fields?: Record<string, string | number>;\n table?: string;\n}\n\n/**\n * Thrown when an exclusion constraint is violated in the database\n */\nclass ExclusionConstraintError extends DatabaseError implements ExclusionConstraintErrorOptions {\n constraint: string | undefined;\n fields: Record<string, string | number> | undefined;\n table: string | undefined;\n\n constructor(\n options: DatabaseErrorSubclassOptions & ExclusionConstraintErrorOptions\n ) {\n options = options || {};\n options.parent = options.parent || { sql: '', name: '', message: '' };\n\n super(options.parent, { stack: options.stack });\n this.name = 'SequelizeExclusionConstraintError';\n\n this.message = options.message || options.parent.message || '';\n this.constraint = options.constraint;\n this.fields = options.fields;\n this.table = options.table;\n }\n}\n\nexport default ExclusionConstraintError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,4BAA4D;AAW5D,uCAAuC,8BAAyD;AAAA,EAK9F,YACE,SACA;AACA,cAAU,WAAW;AACrB,YAAQ,SAAS,QAAQ,UAAU,EAAE,KAAK,IAAI,MAAM,IAAI,SAAS;AAEjE,UAAM,QAAQ,QAAQ,EAAE,OAAO,QAAQ;AAVzC;AACA;AACA;AASE,SAAK,OAAO;AAEZ,SAAK,UAAU,QAAQ,WAAW,QAAQ,OAAO,WAAW;AAC5D,SAAK,aAAa,QAAQ;AAC1B,SAAK,SAAS,QAAQ;AACtB,SAAK,QAAQ,QAAQ;AAAA;AAAA;AAIzB,IAAO,qCAAQ;",
"names": []
}
@@ -0,0 +1,59 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
RelationshipType: () => RelationshipType,
default: () => foreign_key_constraint_error_default
});
var import_database_error = __toModule(require("../database-error"));
var RelationshipType = /* @__PURE__ */ ((RelationshipType2) => {
RelationshipType2["parent"] = "parent";
RelationshipType2["child"] = "child";
return RelationshipType2;
})(RelationshipType || {});
class ForeignKeyConstraintError extends import_database_error.default {
constructor(options) {
options = options || {};
options.parent = options.parent || { sql: "", name: "", message: "" };
super(options.parent, { stack: options.stack });
__publicField(this, "table");
__publicField(this, "fields");
__publicField(this, "value");
__publicField(this, "index");
__publicField(this, "reltype");
this.name = "SequelizeForeignKeyConstraintError";
this.message = options.message || options.parent.message || "Database Error";
this.fields = options.fields;
this.table = options.table;
this.value = options.value;
this.index = options.index;
this.reltype = options.reltype;
}
}
var foreign_key_constraint_error_default = ForeignKeyConstraintError;
//# sourceMappingURL=foreign-key-constraint-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/database/foreign-key-constraint-error.ts"],
"sourcesContent": ["import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error';\n\nexport enum RelationshipType {\n parent = 'parent',\n child = 'child',\n}\n\ninterface ForeignKeyConstraintErrorOptions {\n table?: string;\n fields?: { [field: string]: string };\n value?: unknown;\n index?: string;\n reltype?: RelationshipType;\n}\n\n/**\n * Thrown when a foreign key constraint is violated in the database\n */\nclass ForeignKeyConstraintError extends DatabaseError {\n table: string | undefined;\n fields: { [field: string]: string } | undefined;\n value: unknown;\n index: string | undefined;\n reltype: RelationshipType | undefined;\n\n constructor(\n options: ForeignKeyConstraintErrorOptions & DatabaseErrorSubclassOptions\n ) {\n options = options || {};\n options.parent = options.parent || { sql: '', name: '', message: '' };\n\n super(options.parent, { stack: options.stack });\n this.name = 'SequelizeForeignKeyConstraintError';\n\n this.message =\n options.message || options.parent.message || 'Database Error';\n this.fields = options.fields;\n this.table = options.table;\n this.value = options.value;\n this.index = options.index;\n this.reltype = options.reltype;\n }\n}\n\nexport default ForeignKeyConstraintError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4D;AAErD,IAAK,mBAAL,kBAAK,sBAAL;AACL,gCAAS;AACT,+BAAQ;AAFE;AAAA;AAgBZ,wCAAwC,8BAAc;AAAA,EAOpD,YACE,SACA;AACA,cAAU,WAAW;AACrB,YAAQ,SAAS,QAAQ,UAAU,EAAE,KAAK,IAAI,MAAM,IAAI,SAAS;AAEjE,UAAM,QAAQ,QAAQ,EAAE,OAAO,QAAQ;AAZzC;AACA;AACA;AACA;AACA;AASE,SAAK,OAAO;AAEZ,SAAK,UACH,QAAQ,WAAW,QAAQ,OAAO,WAAW;AAC/C,SAAK,SAAS,QAAQ;AACtB,SAAK,QAAQ,QAAQ;AACrB,SAAK,QAAQ,QAAQ;AACrB,SAAK,QAAQ,QAAQ;AACrB,SAAK,UAAU,QAAQ;AAAA;AAAA;AAI3B,IAAO,uCAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => timeout_error_default
});
var import_database_error = __toModule(require("../database-error"));
class TimeoutError extends import_database_error.default {
constructor(parent, options = {}) {
super(parent, options);
this.name = "SequelizeTimeoutError";
}
}
var timeout_error_default = TimeoutError;
//# sourceMappingURL=timeout-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/database/timeout-error.ts"],
"sourcesContent": ["import { ErrorOptions } from '../base-error';\nimport DatabaseError, { DatabaseErrorParent } from '../database-error';\n\n/**\n * Thrown when a database query times out because of a deadlock\n */\nclass TimeoutError extends DatabaseError {\n constructor(parent: DatabaseErrorParent, options: ErrorOptions = {}) {\n super(parent, options);\n this.name = 'SequelizeTimeoutError';\n }\n}\n\nexport default TimeoutError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AACA,4BAAmD;AAKnD,2BAA2B,8BAAc;AAAA,EACvC,YAAY,QAA6B,UAAwB,IAAI;AACnE,UAAM,QAAQ;AACd,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,wBAAQ;",
"names": []
}
@@ -0,0 +1,49 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => unknown_constraint_error_default
});
var import_database_error = __toModule(require("../database-error"));
class UnknownConstraintError extends import_database_error.default {
constructor(options) {
options = options || {};
options.parent = options.parent || { sql: "", name: "", message: "" };
super(options.parent, { stack: options.stack });
__publicField(this, "constraint");
__publicField(this, "fields");
__publicField(this, "table");
this.name = "SequelizeUnknownConstraintError";
this.message = options.message || "The specified constraint does not exist";
this.constraint = options.constraint;
this.fields = options.fields;
this.table = options.table;
}
}
var unknown_constraint_error_default = UnknownConstraintError;
//# sourceMappingURL=unknown-constraint-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/database/unknown-constraint-error.ts"],
"sourcesContent": ["import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error';\n\ninterface UnknownConstraintErrorOptions {\n constraint?: string;\n fields?: Record<string, string | number>;\n table?: string;\n}\n\n/**\n * Thrown when constraint name is not found in the database\n */\nclass UnknownConstraintError extends DatabaseError implements UnknownConstraintErrorOptions {\n constraint: string | undefined;\n fields: Record<string, string | number> | undefined;\n table: string | undefined;\n\n constructor(\n options: UnknownConstraintErrorOptions & DatabaseErrorSubclassOptions\n ) {\n options = options || {};\n options.parent = options.parent || { sql: '', name: '', message: '' };\n\n super(options.parent, { stack: options.stack });\n this.name = 'SequelizeUnknownConstraintError';\n\n this.message = options.message || 'The specified constraint does not exist';\n this.constraint = options.constraint;\n this.fields = options.fields;\n this.table = options.table;\n }\n}\n\nexport default UnknownConstraintError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,4BAA4D;AAW5D,qCAAqC,8BAAuD;AAAA,EAK1F,YACE,SACA;AACA,cAAU,WAAW;AACrB,YAAQ,SAAS,QAAQ,UAAU,EAAE,KAAK,IAAI,MAAM,IAAI,SAAS;AAEjE,UAAM,QAAQ,QAAQ,EAAE,OAAO,QAAQ;AAVzC;AACA;AACA;AASE,SAAK,OAAO;AAEZ,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,aAAa,QAAQ;AAC1B,SAAK,SAAS,QAAQ;AACtB,SAAK,QAAQ,QAAQ;AAAA;AAAA;AAIzB,IAAO,mCAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => eager_loading_error_default
});
var import_base_error = __toModule(require("./base-error"));
class EagerLoadingError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeEagerLoadingError";
}
}
var eager_loading_error_default = EagerLoadingError;
//# sourceMappingURL=eager-loading-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/eager-loading-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Thrown when an include statement is improperly constructed (see message for details)\n */\nclass EagerLoadingError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeEagerLoadingError';\n }\n}\n\nexport default EagerLoadingError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,gCAAgC,0BAAU;AAAA,EACxC,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,8BAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => empty_result_error_default
});
var import_base_error = __toModule(require("./base-error"));
class EmptyResultError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeEmptyResultError";
}
}
var empty_result_error_default = EmptyResultError;
//# sourceMappingURL=empty-result-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/empty-result-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Thrown when a record was not found, Usually used with rejectOnEmpty mode (see message for details)\n */\nclass EmptyResultError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeEmptyResultError';\n }\n}\n\nexport default EmptyResultError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,+BAA+B,0BAAU;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,6BAAQ;",
"names": []
}
+81
View File
@@ -0,0 +1,81 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
AccessDeniedError: () => import_access_denied_error.default,
AggregateError: () => import_aggregate_error.default,
AssociationError: () => import_association_error.default,
AsyncQueueError: () => import_async_queue.AsyncQueueError,
BaseError: () => import_base_error.default,
BulkRecordError: () => import_bulk_record_error.default,
ConnectionAcquireTimeoutError: () => import_connection_acquire_timeout_error.default,
ConnectionError: () => import_connection_error.default,
ConnectionRefusedError: () => import_connection_refused_error.default,
ConnectionTimedOutError: () => import_connection_timed_out_error.default,
DatabaseError: () => import_database_error.default,
EagerLoadingError: () => import_eager_loading_error.default,
EmptyResultError: () => import_empty_result_error.default,
ExclusionConstraintError: () => import_exclusion_constraint_error.default,
ForeignKeyConstraintError: () => import_foreign_key_constraint_error.default,
HostNotFoundError: () => import_host_not_found_error.default,
HostNotReachableError: () => import_host_not_reachable_error.default,
InstanceError: () => import_instance_error.default,
InvalidConnectionError: () => import_invalid_connection_error.default,
OptimisticLockError: () => import_optimistic_lock_error.default,
QueryError: () => import_query_error.default,
SequelizeScopeError: () => import_sequelize_scope_error.default,
TimeoutError: () => import_timeout_error.default,
UniqueConstraintError: () => import_unique_constraint_error.default,
UnknownConstraintError: () => import_unknown_constraint_error.default,
ValidationError: () => import_validation_error.default,
ValidationErrorItem: () => import_validation_error.ValidationErrorItem,
ValidationErrorItemOrigin: () => import_validation_error.ValidationErrorItemOrigin,
ValidationErrorItemType: () => import_validation_error.ValidationErrorItemType
});
var import_base_error = __toModule(require("./base-error"));
var import_database_error = __toModule(require("./database-error"));
var import_aggregate_error = __toModule(require("./aggregate-error"));
var import_association_error = __toModule(require("./association-error"));
var import_bulk_record_error = __toModule(require("./bulk-record-error"));
var import_connection_error = __toModule(require("./connection-error"));
var import_eager_loading_error = __toModule(require("./eager-loading-error"));
var import_empty_result_error = __toModule(require("./empty-result-error"));
var import_instance_error = __toModule(require("./instance-error"));
var import_optimistic_lock_error = __toModule(require("./optimistic-lock-error"));
var import_query_error = __toModule(require("./query-error"));
var import_sequelize_scope_error = __toModule(require("./sequelize-scope-error"));
var import_validation_error = __toModule(require("./validation-error"));
var import_access_denied_error = __toModule(require("./connection/access-denied-error"));
var import_connection_acquire_timeout_error = __toModule(require("./connection/connection-acquire-timeout-error"));
var import_connection_refused_error = __toModule(require("./connection/connection-refused-error"));
var import_connection_timed_out_error = __toModule(require("./connection/connection-timed-out-error"));
var import_host_not_found_error = __toModule(require("./connection/host-not-found-error"));
var import_host_not_reachable_error = __toModule(require("./connection/host-not-reachable-error"));
var import_invalid_connection_error = __toModule(require("./connection/invalid-connection-error"));
var import_exclusion_constraint_error = __toModule(require("./database/exclusion-constraint-error"));
var import_foreign_key_constraint_error = __toModule(require("./database/foreign-key-constraint-error"));
var import_timeout_error = __toModule(require("./database/timeout-error"));
var import_unknown_constraint_error = __toModule(require("./database/unknown-constraint-error"));
var import_unique_constraint_error = __toModule(require("./validation/unique-constraint-error"));
var import_async_queue = __toModule(require("../dialects/mssql/async-queue"));
//# sourceMappingURL=index.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/index.ts"],
"sourcesContent": ["export { default as BaseError } from './base-error';\n\nexport { default as DatabaseError } from './database-error';\nexport { default as AggregateError } from './aggregate-error';\nexport { default as AssociationError } from './association-error';\nexport { default as BulkRecordError } from './bulk-record-error';\nexport { default as ConnectionError } from './connection-error';\nexport { default as EagerLoadingError } from './eager-loading-error';\nexport { default as EmptyResultError } from './empty-result-error';\nexport { default as InstanceError } from './instance-error';\nexport { default as OptimisticLockError } from './optimistic-lock-error';\nexport { default as QueryError } from './query-error';\nexport { default as SequelizeScopeError } from './sequelize-scope-error';\nexport {\n default as ValidationError,\n ValidationErrorItem,\n ValidationErrorItemOrigin,\n ValidationErrorItemType\n} from './validation-error';\n\nexport { default as AccessDeniedError } from './connection/access-denied-error';\nexport { default as ConnectionAcquireTimeoutError } from './connection/connection-acquire-timeout-error';\nexport { default as ConnectionRefusedError } from './connection/connection-refused-error';\nexport { default as ConnectionTimedOutError } from './connection/connection-timed-out-error';\nexport { default as HostNotFoundError } from './connection/host-not-found-error';\nexport { default as HostNotReachableError } from './connection/host-not-reachable-error';\nexport { default as InvalidConnectionError } from './connection/invalid-connection-error';\n\nexport { default as ExclusionConstraintError } from './database/exclusion-constraint-error';\nexport { default as ForeignKeyConstraintError } from './database/foreign-key-constraint-error';\nexport { default as TimeoutError } from './database/timeout-error';\nexport { default as UnknownConstraintError } from './database/unknown-constraint-error';\n\nexport { default as UniqueConstraintError } from './validation/unique-constraint-error';\n\nexport { AsyncQueueError } from '../dialects/mssql/async-queue';\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAqC;AAErC,4BAAyC;AACzC,6BAA0C;AAC1C,+BAA4C;AAC5C,+BAA2C;AAC3C,8BAA2C;AAC3C,iCAA6C;AAC7C,gCAA4C;AAC5C,4BAAyC;AACzC,mCAA+C;AAC/C,yBAAsC;AACtC,mCAA+C;AAC/C,8BAKO;AAEP,iCAA6C;AAC7C,8CAAyD;AACzD,sCAAkD;AAClD,wCAAmD;AACnD,kCAA6C;AAC7C,sCAAiD;AACjD,sCAAkD;AAElD,wCAAoD;AACpD,0CAAqD;AACrD,2BAAwC;AACxC,sCAAkD;AAElD,qCAAiD;AAEjD,yBAAgC;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => instance_error_default
});
var import_base_error = __toModule(require("./base-error"));
class InstanceError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeInstanceError";
}
}
var instance_error_default = InstanceError;
//# sourceMappingURL=instance-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/instance-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Thrown when a some problem occurred with Instance methods (see message for details)\n */\nclass InstanceError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeInstanceError';\n }\n}\n\nexport default InstanceError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,4BAA4B,0BAAU;AAAA,EACpC,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,yBAAQ;",
"names": []
}
+48
View File
@@ -0,0 +1,48 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => optimistic_lock_error_default
});
var import_base_error = __toModule(require("./base-error"));
class OptimisticLockError extends import_base_error.default {
constructor(options) {
options = options || {};
options.message = options.message || `Attempting to update a stale model instance: ${options.modelName}`;
super(options.message);
__publicField(this, "modelName");
__publicField(this, "values");
__publicField(this, "where");
this.name = "SequelizeOptimisticLockError";
this.modelName = options.modelName;
this.values = options.values;
this.where = options.where;
}
}
var optimistic_lock_error_default = OptimisticLockError;
//# sourceMappingURL=optimistic-lock-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/optimistic-lock-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\ninterface OptimisticLockErrorOptions {\n message?: string;\n\n /** The name of the model on which the update was attempted */\n modelName?: string;\n\n /** The values of the attempted update */\n values?: Record<string, unknown>;\n where?: Record<string, unknown>;\n}\n\n/**\n * Thrown when attempting to update a stale model instance\n */\nclass OptimisticLockError extends BaseError {\n modelName: string | undefined;\n values: Record<string, unknown> | undefined;\n where: Record<string, unknown> | undefined;\n\n constructor(options: OptimisticLockErrorOptions) {\n options = options || {};\n options.message =\n options.message ||\n `Attempting to update a stale model instance: ${options.modelName}`;\n\n super(options.message);\n this.name = 'SequelizeOptimisticLockError';\n this.modelName = options.modelName;\n this.values = options.values;\n this.where = options.where;\n }\n}\n\nexport default OptimisticLockError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAgBtB,kCAAkC,0BAAU;AAAA,EAK1C,YAAY,SAAqC;AAC/C,cAAU,WAAW;AACrB,YAAQ,UACN,QAAQ,WACR,gDAAgD,QAAQ;AAE1D,UAAM,QAAQ;AAVhB;AACA;AACA;AASE,SAAK,OAAO;AACZ,SAAK,YAAY,QAAQ;AACzB,SAAK,SAAS,QAAQ;AACtB,SAAK,QAAQ,QAAQ;AAAA;AAAA;AAIzB,IAAO,gCAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => query_error_default
});
var import_base_error = __toModule(require("./base-error"));
class QueryError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeQueryError";
}
}
var query_error_default = QueryError;
//# sourceMappingURL=query-error.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/query-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Thrown when a query is passed invalid options (see message for details)\n */\nclass QueryError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeQueryError';\n }\n}\n\nexport default QueryError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,yBAAyB,0BAAU;AAAA,EACjC,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,sBAAQ;",
"names": []
}
+35
View File
@@ -0,0 +1,35 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
__export(exports, {
default: () => sequelize_scope_error_default
});
var import_base_error = __toModule(require("./base-error"));
class SequelizeScopeError extends import_base_error.default {
constructor(message) {
super(message);
this.name = "SequelizeScopeError";
}
}
var sequelize_scope_error_default = SequelizeScopeError;
//# sourceMappingURL=sequelize-scope-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/errors/sequelize-scope-error.ts"],
"sourcesContent": ["import BaseError from './base-error';\n\n/**\n * Scope Error. Thrown when the sequelize cannot query the specified scope.\n */\nclass SequelizeScopeError extends BaseError {\n constructor(message: string) {\n super(message);\n this.name = 'SequelizeScopeError';\n }\n}\n\nexport default SequelizeScopeError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,wBAAsB;AAKtB,kCAAkC,0BAAU;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM;AACN,SAAK,OAAO;AAAA;AAAA;AAIhB,IAAO,gCAAQ;",
"names": []
}
+131
View File
@@ -0,0 +1,131 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
ValidationErrorItem: () => ValidationErrorItem,
ValidationErrorItemOrigin: () => ValidationErrorItemOrigin,
ValidationErrorItemType: () => ValidationErrorItemType,
default: () => validation_error_default
});
var import_base_error = __toModule(require("./base-error"));
var ValidationErrorItemType = /* @__PURE__ */ ((ValidationErrorItemType2) => {
ValidationErrorItemType2["notnull violation"] = "CORE";
ValidationErrorItemType2["string violation"] = "CORE";
ValidationErrorItemType2["unique violation"] = "DB";
ValidationErrorItemType2["validation error"] = "FUNCTION";
return ValidationErrorItemType2;
})(ValidationErrorItemType || {});
var ValidationErrorItemOrigin = /* @__PURE__ */ ((ValidationErrorItemOrigin2) => {
ValidationErrorItemOrigin2["CORE"] = "CORE";
ValidationErrorItemOrigin2["DB"] = "DB";
ValidationErrorItemOrigin2["FUNCTION"] = "FUNCTION";
return ValidationErrorItemOrigin2;
})(ValidationErrorItemOrigin || {});
class ValidationErrorItem {
constructor(message, type, path, value, instance, validatorKey, fnName, fnArgs) {
__publicField(this, "message");
__publicField(this, "type");
__publicField(this, "path");
__publicField(this, "value");
__publicField(this, "origin");
__publicField(this, "instance");
__publicField(this, "validatorKey");
__publicField(this, "validatorName");
__publicField(this, "validatorArgs");
this.message = message || "";
this.type = null;
this.path = path || null;
this.value = value !== void 0 ? value : null;
this.origin = null;
this.instance = instance || null;
this.validatorKey = validatorKey || null;
this.validatorName = fnName || null;
this.validatorArgs = fnArgs || [];
if (type) {
if (this.isValidationErrorItemOrigin(type)) {
this.origin = type;
} else {
const lowercaseType = this.normalizeString(type);
const realType = ValidationErrorItemType[lowercaseType];
if (realType && ValidationErrorItemOrigin[realType]) {
this.origin = realType;
this.type = type;
}
}
}
}
isValidationErrorItemOrigin(origin) {
return ValidationErrorItemOrigin[origin] !== void 0;
}
normalizeString(str) {
return str.toLowerCase().trim();
}
getValidatorKey(useTypeAsNS, NSSeparator) {
const useTANS = useTypeAsNS === void 0 || !!useTypeAsNS;
const NSSep = NSSeparator === void 0 ? "." : NSSeparator;
const type = this.origin;
const key = this.validatorKey || this.validatorName;
const useNS = useTANS && type && ValidationErrorItemOrigin[type];
if (useNS && (typeof NSSep !== "string" || !NSSep.length)) {
throw new Error("Invalid namespace separator given, must be a non-empty string");
}
if (!(typeof key === "string" && key.length)) {
return "";
}
return (useNS ? [this.origin, key].join(NSSep) : key).toLowerCase().trim();
}
}
__publicField(ValidationErrorItem, "TypeStringMap", ValidationErrorItemType);
__publicField(ValidationErrorItem, "Origins", ValidationErrorItemOrigin);
class ValidationError extends import_base_error.default {
constructor(message, errors, options = {}) {
super(message);
__publicField(this, "errors");
this.name = "SequelizeValidationError";
this.message = "Validation Error";
this.errors = errors || [];
if (message) {
this.message = message;
} else if (this.errors.length > 0 && this.errors[0].message) {
this.message = this.errors.map((err) => `${err.type || err.origin}: ${err.message}`).join(",\n");
}
if (options.stack) {
this.stack = options.stack;
}
}
get(path) {
return this.errors.reduce((reduced, error) => {
if (error.path === path) {
reduced.push(error);
}
return reduced;
}, []);
}
}
var validation_error_default = ValidationError;
//# sourceMappingURL=validation-error.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,53 @@
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
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 });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
__export(exports, {
default: () => unique_constraint_error_default
});
var import_validation_error = __toModule(require("../validation-error"));
class UniqueConstraintError extends import_validation_error.default {
constructor(options) {
var _a, _b, _c;
options = options != null ? options : {};
options.parent = (_a = options.parent) != null ? _a : { sql: "", name: "", message: "" };
options.message = options.message || options.parent.message || "Validation Error";
options.errors = (_b = options.errors) != null ? _b : [];
super(options.message, options.errors, { stack: options.stack });
__publicField(this, "parent");
__publicField(this, "original");
__publicField(this, "fields");
__publicField(this, "sql");
this.name = "SequelizeUniqueConstraintError";
this.fields = (_c = options.fields) != null ? _c : {};
this.parent = options.parent;
this.original = options.parent;
this.sql = options.parent.sql;
}
}
var unique_constraint_error_default = UniqueConstraintError;
//# sourceMappingURL=unique-constraint-error.js.map
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../../src/errors/validation/unique-constraint-error.ts"],
"sourcesContent": ["import { CommonErrorProperties, ErrorOptions } from '../base-error';\nimport ValidationError, { ValidationErrorItem } from '../validation-error';\n\ninterface UniqueConstraintErrorParent\n extends Error,\n Pick<CommonErrorProperties, 'sql'> {}\n\nexport interface UniqueConstraintErrorOptions extends ErrorOptions {\n parent?: UniqueConstraintErrorParent;\n original?: UniqueConstraintErrorParent;\n errors?: ValidationErrorItem[];\n fields?: Record<string, unknown>;\n message?: string;\n}\n\n/**\n * Thrown when a unique constraint is violated in the database\n */\nclass UniqueConstraintError extends ValidationError implements CommonErrorProperties {\n readonly parent: UniqueConstraintErrorParent;\n readonly original: UniqueConstraintErrorParent;\n readonly fields: Record<string, unknown>;\n readonly sql: string;\n\n constructor(options: UniqueConstraintErrorOptions) {\n options = options ?? {};\n options.parent = options.parent ?? { sql: '', name: '', message: '' };\n options.message =\n options.message || options.parent.message || 'Validation Error';\n options.errors = options.errors ?? [];\n super(options.message, options.errors, { stack: options.stack });\n\n this.name = 'SequelizeUniqueConstraintError';\n this.fields = options.fields ?? {};\n this.parent = options.parent;\n this.original = options.parent;\n this.sql = options.parent.sql;\n }\n}\n\nexport default UniqueConstraintError;\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AACA,8BAAqD;AAiBrD,oCAAoC,gCAAiD;AAAA,EAMnF,YAAY,SAAuC;AAxBrD;AAyBI,cAAU,4BAAW;AACrB,YAAQ,SAAS,cAAQ,WAAR,YAAkB,EAAE,KAAK,IAAI,MAAM,IAAI,SAAS;AACjE,YAAQ,UACN,QAAQ,WAAW,QAAQ,OAAO,WAAW;AAC/C,YAAQ,SAAS,cAAQ,WAAR,YAAkB;AACnC,UAAM,QAAQ,SAAS,QAAQ,QAAQ,EAAE,OAAO,QAAQ;AAXjD;AACA;AACA;AACA;AAUP,SAAK,OAAO;AACZ,SAAK,SAAS,cAAQ,WAAR,YAAkB;AAChC,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ;AACxB,SAAK,MAAM,QAAQ,OAAO;AAAA;AAAA;AAI9B,IAAO,kCAAQ;",
"names": []
}
+4
View File
@@ -0,0 +1,4 @@
var __defProp = Object.defineProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
__markAsModule(exports);
//# sourceMappingURL=falsy.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/generic/falsy.ts"],
"sourcesContent": ["export type Falsy = false | 0 | -0 | 0n | '' | null | undefined | void;\n"],
"mappings": ";;AAAA;",
"names": []
}
+4
View File
@@ -0,0 +1,4 @@
var __defProp = Object.defineProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
__markAsModule(exports);
//# sourceMappingURL=sql-fragment.js.map
+7
View File
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/generic/sql-fragment.ts"],
"sourcesContent": ["import { Falsy } from './falsy';\n\nexport type SQLFragment = string | Falsy | SQLFragment[];\nexport type TruthySQLFragment = string | SQLFragment[];\n"],
"mappings": ";;AAAA;",
"names": []
}
+150
View File
@@ -0,0 +1,150 @@
"use strict";
const _ = require("lodash");
const { logger } = require("./utils/logger");
const debug = logger.debugContext("hooks");
const hookTypes = {
beforeValidate: { params: 2 },
afterValidate: { params: 2 },
validationFailed: { params: 3 },
beforeCreate: { params: 2 },
afterCreate: { params: 2 },
beforeDestroy: { params: 2 },
afterDestroy: { params: 2 },
beforeRestore: { params: 2 },
afterRestore: { params: 2 },
beforeUpdate: { params: 2 },
afterUpdate: { params: 2 },
beforeSave: { params: 2, proxies: ["beforeUpdate", "beforeCreate"] },
afterSave: { params: 2, proxies: ["afterUpdate", "afterCreate"] },
beforeUpsert: { params: 2 },
afterUpsert: { params: 2 },
beforeBulkCreate: { params: 2 },
afterBulkCreate: { params: 2 },
beforeBulkDestroy: { params: 1 },
afterBulkDestroy: { params: 1 },
beforeBulkRestore: { params: 1 },
afterBulkRestore: { params: 1 },
beforeBulkUpdate: { params: 1 },
afterBulkUpdate: { params: 1 },
beforeFind: { params: 1 },
beforeFindAfterExpandIncludeAll: { params: 1 },
beforeFindAfterOptions: { params: 1 },
afterFind: { params: 2 },
beforeCount: { params: 1 },
beforeDefine: { params: 2, sync: true, noModel: true },
afterDefine: { params: 1, sync: true, noModel: true },
beforeInit: { params: 2, sync: true, noModel: true },
afterInit: { params: 1, sync: true, noModel: true },
beforeAssociate: { params: 2, sync: true },
afterAssociate: { params: 2, sync: true },
beforeConnect: { params: 1, noModel: true },
afterConnect: { params: 2, noModel: true },
beforeDisconnect: { params: 1, noModel: true },
afterDisconnect: { params: 1, noModel: true },
beforePoolAcquire: { params: 1, noModel: true },
afterPoolAcquire: { params: 2, noModel: true },
beforeSync: { params: 1 },
afterSync: { params: 1 },
beforeBulkSync: { params: 1 },
afterBulkSync: { params: 1 },
beforeQuery: { params: 2 },
afterQuery: { params: 2 }
};
exports.hooks = hookTypes;
const getProxiedHooks = (hookType) => hookTypes[hookType].proxies ? hookTypes[hookType].proxies.concat(hookType) : [hookType];
function getHooks(hooked, hookType) {
return (hooked.options.hooks || {})[hookType] || [];
}
const Hooks = {
_setupHooks(hooks) {
this.options.hooks = {};
_.map(hooks || {}, (hooksArray, hookName) => {
if (!Array.isArray(hooksArray))
hooksArray = [hooksArray];
hooksArray.forEach((hookFn) => this.addHook(hookName, hookFn));
});
},
async runHooks(hooks, ...hookArgs) {
if (!hooks)
throw new Error("runHooks requires at least 1 argument");
let hookType;
if (typeof hooks === "string") {
hookType = hooks;
hooks = getHooks(this, hookType);
if (this.sequelize) {
hooks = hooks.concat(getHooks(this.sequelize, hookType));
}
}
if (!Array.isArray(hooks)) {
hooks = [hooks];
}
if (hookTypes[hookType] && hookTypes[hookType].sync) {
for (let hook of hooks) {
if (typeof hook === "object") {
hook = hook.fn;
}
debug(`running hook(sync) ${hookType}`);
hook.apply(this, hookArgs);
}
return;
}
for (let hook of hooks) {
if (typeof hook === "object") {
hook = hook.fn;
}
debug(`running hook ${hookType}`);
await hook.apply(this, hookArgs);
}
},
addHook(hookType, name, fn) {
if (typeof name === "function") {
fn = name;
name = null;
}
debug(`adding hook ${hookType}`);
hookType = getProxiedHooks(hookType);
hookType.forEach((type) => {
const hooks = getHooks(this, type);
hooks.push(name ? { name, fn } : fn);
this.options.hooks[type] = hooks;
});
return this;
},
removeHook(hookType, name) {
const isReference = typeof name === "function" ? true : false;
if (!this.hasHook(hookType)) {
return this;
}
debug(`removing hook ${hookType}`);
hookType = getProxiedHooks(hookType);
for (const type of hookType) {
this.options.hooks[type] = this.options.hooks[type].filter((hook) => {
if (isReference && typeof hook === "function") {
return hook !== name;
}
if (!isReference && typeof hook === "object") {
return hook.name !== name;
}
return true;
});
}
return this;
},
hasHook(hookType) {
return this.options.hooks[hookType] && !!this.options.hooks[hookType].length;
}
};
Hooks.hasHooks = Hooks.hasHook;
function applyTo(target, isModel = false) {
_.mixin(target, Hooks);
for (const hook of Object.keys(hookTypes)) {
if (isModel && hookTypes[hook].noModel) {
continue;
}
target[hook] = function(name, callback) {
return this.addHook(hook, name, callback);
};
}
}
exports.applyTo = applyTo;
//# sourceMappingURL=hooks.js.map
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
"use strict";
const IndexHints = module.exports = {
USE: "USE",
FORCE: "FORCE",
IGNORE: "IGNORE"
};
//# sourceMappingURL=index-hints.js.map

Some files were not shown because too many files have changed in this diff Show More