This commit is contained in:
2025-10-24 17:06:14 -05:00
parent 12d0690b91
commit df8c75603f
11289 changed files with 1209053 additions and 318 deletions

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

View File

@@ -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": []
}

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

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

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": []
}

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

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

View File

@@ -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": []
}

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