86 lines
3.2 KiB
JavaScript
86 lines
3.2 KiB
JavaScript
'use strict';
|
|
|
|
const _ = require('lodash');
|
|
|
|
const Utils = require('../../utils');
|
|
const QueryTypes = require('../../query-types');
|
|
const Op = require('../../operators');
|
|
const { QueryInterface } = require('../abstract/query-interface');
|
|
|
|
/**
|
|
* The interface that Sequelize uses to talk with MSSQL database
|
|
*/
|
|
class MSSqlQueryInterface extends QueryInterface {
|
|
/**
|
|
* A wrapper that fixes MSSQL's inability to cleanly remove columns from existing tables if they have a default constraint.
|
|
*
|
|
* @override
|
|
*/
|
|
async removeColumn(tableName, attributeName, options) {
|
|
options = { raw: true, ...options || {} };
|
|
|
|
const findConstraintSql = this.queryGenerator.getDefaultConstraintQuery(tableName, attributeName);
|
|
const [results0] = await this.sequelize.query(findConstraintSql, options);
|
|
if (results0.length) {
|
|
// No default constraint found -- we can cleanly remove the column
|
|
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) {
|
|
// No foreign key constraints found, so we can remove the column
|
|
const dropForeignKeySql = this.queryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name);
|
|
await this.sequelize.query(dropForeignKeySql, options);
|
|
}
|
|
//Check if the current column is a primaryKey
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
async upsert(tableName, insertValues, updateValues, where, options) {
|
|
const model = options.model;
|
|
const wheres = [];
|
|
|
|
options = { ...options };
|
|
|
|
if (!Utils.isWhereEmpty(where)) {
|
|
wheres.push(where);
|
|
}
|
|
|
|
// Lets combine unique keys and indexes into one
|
|
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;
|