primer cambio
This commit is contained in:
429
node_modules/sequelize/lib/dialects/db2/query.js
generated
vendored
Normal file
429
node_modules/sequelize/lib/dialects/db2/query.js
generated
vendored
Normal 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
|
||||
Reference in New Issue
Block a user