typeorm
Version:
Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB databases.
907 lines (906 loc) • 182 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SqlServerQueryRunner = void 0;
var tslib_1 = require("tslib");
var QueryResult_1 = require("../../query-runner/QueryResult");
var QueryFailedError_1 = require("../../error/QueryFailedError");
var QueryRunnerAlreadyReleasedError_1 = require("../../error/QueryRunnerAlreadyReleasedError");
var TransactionAlreadyStartedError_1 = require("../../error/TransactionAlreadyStartedError");
var TransactionNotStartedError_1 = require("../../error/TransactionNotStartedError");
var BaseQueryRunner_1 = require("../../query-runner/BaseQueryRunner");
var Table_1 = require("../../schema-builder/table/Table");
var TableCheck_1 = require("../../schema-builder/table/TableCheck");
var TableColumn_1 = require("../../schema-builder/table/TableColumn");
var TableForeignKey_1 = require("../../schema-builder/table/TableForeignKey");
var TableIndex_1 = require("../../schema-builder/table/TableIndex");
var TableUnique_1 = require("../../schema-builder/table/TableUnique");
var View_1 = require("../../schema-builder/view/View");
var Broadcaster_1 = require("../../subscriber/Broadcaster");
var OrmUtils_1 = require("../../util/OrmUtils");
var Query_1 = require("../Query");
var MssqlParameter_1 = require("./MssqlParameter");
var BroadcasterResult_1 = require("../../subscriber/BroadcasterResult");
var error_1 = require("../../error");
var QueryLock_1 = require("../../query-runner/QueryLock");
/**
* Runs queries on a single SQL Server database connection.
*/
var SqlServerQueryRunner = /** @class */ (function (_super) {
tslib_1.__extends(SqlServerQueryRunner, _super);
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
function SqlServerQueryRunner(driver, mode) {
var _this = _super.call(this) || this;
// -------------------------------------------------------------------------
// Private Properties
// -------------------------------------------------------------------------
_this.lock = new QueryLock_1.QueryLock();
_this.driver = driver;
_this.connection = driver.connection;
_this.broadcaster = new Broadcaster_1.Broadcaster(_this);
_this.mode = mode;
return _this;
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* Creates/uses database connection from the connection pool to perform further operations.
* Returns obtained database connection.
*/
SqlServerQueryRunner.prototype.connect = function () {
return Promise.resolve();
};
/**
* Releases used database connection.
* You cannot use query runner methods once its released.
*/
SqlServerQueryRunner.prototype.release = function () {
this.isReleased = true;
return Promise.resolve();
};
/**
* Starts transaction.
*/
SqlServerQueryRunner.prototype.startTransaction = function (isolationLevel) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var beforeBroadcastResult;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
if (this.isTransactionActive)
throw new TransactionAlreadyStartedError_1.TransactionAlreadyStartedError();
beforeBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastBeforeTransactionStartEvent(beforeBroadcastResult);
if (!(beforeBroadcastResult.promises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(beforeBroadcastResult.promises)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/, new Promise(function (ok, fail) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var pool, transactionCallback, afterBroadcastResult;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
this.isTransactionActive = true;
return [4 /*yield*/, (this.mode === "slave" ? this.driver.obtainSlaveConnection() : this.driver.obtainMasterConnection())];
case 1:
pool = _a.sent();
this.databaseConnection = pool.transaction();
transactionCallback = function (err) {
if (err) {
_this.isTransactionActive = false;
return fail(err);
}
ok();
_this.connection.logger.logQuery("BEGIN TRANSACTION");
if (isolationLevel) {
_this.connection.logger.logQuery("SET TRANSACTION ISOLATION LEVEL " + isolationLevel);
}
};
if (isolationLevel) {
this.databaseConnection.begin(this.convertIsolationLevel(isolationLevel), transactionCallback);
}
else {
this.databaseConnection.begin(transactionCallback);
}
afterBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastAfterTransactionStartEvent(afterBroadcastResult);
if (!(afterBroadcastResult.promises.length > 0)) return [3 /*break*/, 3];
return [4 /*yield*/, Promise.all(afterBroadcastResult.promises)];
case 2:
_a.sent();
_a.label = 3;
case 3: return [2 /*return*/];
}
});
}); })];
}
});
});
};
/**
* Commits transaction.
* Error will be thrown if transaction was not started.
*/
SqlServerQueryRunner.prototype.commitTransaction = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var beforeBroadcastResult;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
if (!this.isTransactionActive)
throw new TransactionNotStartedError_1.TransactionNotStartedError();
beforeBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastBeforeTransactionCommitEvent(beforeBroadcastResult);
if (!(beforeBroadcastResult.promises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(beforeBroadcastResult.promises)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/, new Promise(function (ok, fail) {
_this.databaseConnection.commit(function (err) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var afterBroadcastResult;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (err)
return [2 /*return*/, fail(err)];
this.isTransactionActive = false;
this.databaseConnection = null;
afterBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastAfterTransactionCommitEvent(afterBroadcastResult);
if (!(afterBroadcastResult.promises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(afterBroadcastResult.promises)];
case 1:
_a.sent();
_a.label = 2;
case 2:
ok();
this.connection.logger.logQuery("COMMIT");
return [2 /*return*/];
}
});
}); });
})];
}
});
});
};
/**
* Rollbacks transaction.
* Error will be thrown if transaction was not started.
*/
SqlServerQueryRunner.prototype.rollbackTransaction = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var beforeBroadcastResult;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
if (!this.isTransactionActive)
throw new TransactionNotStartedError_1.TransactionNotStartedError();
beforeBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastBeforeTransactionRollbackEvent(beforeBroadcastResult);
if (!(beforeBroadcastResult.promises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(beforeBroadcastResult.promises)];
case 1:
_a.sent();
_a.label = 2;
case 2: return [2 /*return*/, new Promise(function (ok, fail) {
_this.databaseConnection.rollback(function (err) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var afterBroadcastResult;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (err)
return [2 /*return*/, fail(err)];
this.isTransactionActive = false;
this.databaseConnection = null;
afterBroadcastResult = new BroadcasterResult_1.BroadcasterResult();
this.broadcaster.broadcastAfterTransactionRollbackEvent(afterBroadcastResult);
if (!(afterBroadcastResult.promises.length > 0)) return [3 /*break*/, 2];
return [4 /*yield*/, Promise.all(afterBroadcastResult.promises)];
case 1:
_a.sent();
_a.label = 2;
case 2:
ok();
this.connection.logger.logQuery("ROLLBACK");
return [2 /*return*/];
}
});
}); });
})];
}
});
});
};
/**
* Executes a given SQL query.
*/
SqlServerQueryRunner.prototype.query = function (query, parameters, useStructuredResult) {
if (useStructuredResult === void 0) { useStructuredResult = false; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var release, pool, request_1, queryStartTime_1, raw, result, queryType, err_1;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
return [4 /*yield*/, this.lock.acquire()];
case 1:
release = _a.sent();
_a.label = 2;
case 2:
_a.trys.push([2, 5, 6, 7]);
this.driver.connection.logger.logQuery(query, parameters, this);
return [4 /*yield*/, (this.mode === "slave" ? this.driver.obtainSlaveConnection() : this.driver.obtainMasterConnection())];
case 3:
pool = _a.sent();
request_1 = new this.driver.mssql.Request(this.isTransactionActive ? this.databaseConnection : pool);
if (parameters && parameters.length) {
parameters.forEach(function (parameter, index) {
var parameterName = index.toString();
if (parameter instanceof MssqlParameter_1.MssqlParameter) {
var mssqlParameter = _this.mssqlParameterToNativeParameter(parameter);
if (mssqlParameter) {
request_1.input(parameterName, mssqlParameter, parameter.value);
}
else {
request_1.input(parameterName, parameter.value);
}
}
else {
request_1.input(parameterName, parameter);
}
});
}
queryStartTime_1 = +new Date();
return [4 /*yield*/, new Promise(function (ok, fail) {
request_1.query(query, function (err, raw) {
// log slow queries if maxQueryExecution time is set
var maxQueryExecutionTime = _this.driver.options.maxQueryExecutionTime;
var queryEndTime = +new Date();
var queryExecutionTime = queryEndTime - queryStartTime_1;
if (maxQueryExecutionTime && queryExecutionTime > maxQueryExecutionTime) {
_this.driver.connection.logger.logQuerySlow(queryExecutionTime, query, parameters, _this);
}
if (err) {
fail(new QueryFailedError_1.QueryFailedError(query, parameters, err));
}
ok(raw);
});
})];
case 4:
raw = _a.sent();
result = new QueryResult_1.QueryResult();
if (raw === null || raw === void 0 ? void 0 : raw.hasOwnProperty('recordset')) {
result.records = raw.recordset;
}
if (raw === null || raw === void 0 ? void 0 : raw.hasOwnProperty('rowsAffected')) {
result.affected = raw.rowsAffected[0];
}
queryType = query.slice(0, query.indexOf(" "));
switch (queryType) {
case "DELETE":
// for DELETE query additionally return number of affected rows
result.raw = [raw.recordset, raw.rowsAffected[0]];
break;
default:
result.raw = raw.recordset;
}
if (useStructuredResult) {
return [2 /*return*/, result];
}
else {
return [2 /*return*/, result.raw];
}
return [3 /*break*/, 7];
case 5:
err_1 = _a.sent();
this.driver.connection.logger.logQueryError(err_1, query, parameters, this);
throw err_1;
case 6:
release();
return [7 /*endfinally*/];
case 7: return [2 /*return*/];
}
});
});
};
/**
* Returns raw data stream.
*/
SqlServerQueryRunner.prototype.stream = function (query, parameters, onEnd, onError) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var release, pool, request, PassThrough;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
return [4 /*yield*/, this.lock.acquire()];
case 1:
release = _a.sent();
this.driver.connection.logger.logQuery(query, parameters, this);
return [4 /*yield*/, (this.mode === "slave" ? this.driver.obtainSlaveConnection() : this.driver.obtainMasterConnection())];
case 2:
pool = _a.sent();
request = new this.driver.mssql.Request(this.isTransactionActive ? this.databaseConnection : pool);
request.stream = true;
if (parameters && parameters.length) {
parameters.forEach(function (parameter, index) {
var parameterName = index.toString();
if (parameter instanceof MssqlParameter_1.MssqlParameter) {
request.input(parameterName, _this.mssqlParameterToNativeParameter(parameter), parameter.value);
}
else {
request.input(parameterName, parameter);
}
});
}
request.query(query);
// Any event should release the lock.
request.once("row", release);
request.once("rowsaffected", release);
request.once("done", release);
request.once("error", release);
request.on("error", function (err) {
_this.driver.connection.logger.logQueryError(err, query, parameters, _this);
});
if (onEnd) {
request.on("done", onEnd);
}
if (onError) {
request.on("error", onError);
}
PassThrough = require("stream").PassThrough;
return [2 /*return*/, request.pipe(new PassThrough({ objectMode: true }))];
}
});
});
};
/**
* Returns all available database names including system databases.
*/
SqlServerQueryRunner.prototype.getDatabases = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var results;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.query("EXEC sp_databases")];
case 1:
results = _a.sent();
return [2 /*return*/, results.map(function (result) { return result["DATABASE_NAME"]; })];
}
});
});
};
/**
* Returns all available schema names including system schemas.
* If database parameter specified, returns schemas of that database.
*/
SqlServerQueryRunner.prototype.getSchemas = function (database) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var query, results;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
query = database ? "SELECT * FROM \"" + database + "\".\"sys\".\"schema\"" : "SELECT * FROM \"sys\".\"schemas\"";
return [4 /*yield*/, this.query(query)];
case 1:
results = _a.sent();
return [2 /*return*/, results.map(function (result) { return result["name"]; })];
}
});
});
};
/**
* Checks if database with the given name exist.
*/
SqlServerQueryRunner.prototype.hasDatabase = function (database) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var result, dbId;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.query("SELECT DB_ID('" + database + "') as \"db_id\"")];
case 1:
result = _a.sent();
dbId = result[0]["db_id"];
return [2 /*return*/, !!dbId];
}
});
});
};
/**
* Loads currently using database
*/
SqlServerQueryRunner.prototype.getCurrentDatabase = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var currentDBQuery;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.query("SELECT DB_NAME() AS \"db_name\"")];
case 1:
currentDBQuery = _a.sent();
return [2 /*return*/, currentDBQuery[0]["db_name"]];
}
});
});
};
/**
* Checks if schema with the given name exist.
*/
SqlServerQueryRunner.prototype.hasSchema = function (schema) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var result, schemaId;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.query("SELECT SCHEMA_ID('" + schema + "') as \"schema_id\"")];
case 1:
result = _a.sent();
schemaId = result[0]["schema_id"];
return [2 /*return*/, !!schemaId];
}
});
});
};
/**
* Loads currently using database schema
*/
SqlServerQueryRunner.prototype.getCurrentSchema = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var currentSchemaQuery;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.query("SELECT SCHEMA_NAME() AS \"schema_name\"")];
case 1:
currentSchemaQuery = _a.sent();
return [2 /*return*/, currentSchemaQuery[0]["schema_name"]];
}
});
});
};
/**
* Checks if table with the given name exist in the database.
*/
SqlServerQueryRunner.prototype.hasTable = function (tableOrName) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var parsedTableName, _a, _b, sql, result;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0:
parsedTableName = this.driver.parseTableName(tableOrName);
if (!!parsedTableName.database) return [3 /*break*/, 2];
_a = parsedTableName;
return [4 /*yield*/, this.getCurrentDatabase()];
case 1:
_a.database = _c.sent();
_c.label = 2;
case 2:
if (!!parsedTableName.schema) return [3 /*break*/, 4];
_b = parsedTableName;
return [4 /*yield*/, this.getCurrentSchema()];
case 3:
_b.schema = _c.sent();
_c.label = 4;
case 4:
sql = "SELECT * FROM \"" + parsedTableName.database + "\".\"INFORMATION_SCHEMA\".\"TABLES\" WHERE \"TABLE_NAME\" = '" + parsedTableName.tableName + "' AND \"TABLE_SCHEMA\" = '" + parsedTableName.schema + "'";
return [4 /*yield*/, this.query(sql)];
case 5:
result = _c.sent();
return [2 /*return*/, result.length ? true : false];
}
});
});
};
/**
* Checks if column exist in the table.
*/
SqlServerQueryRunner.prototype.hasColumn = function (tableOrName, columnName) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var parsedTableName, _a, _b, sql, result;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0:
parsedTableName = this.driver.parseTableName(tableOrName);
if (!!parsedTableName.database) return [3 /*break*/, 2];
_a = parsedTableName;
return [4 /*yield*/, this.getCurrentDatabase()];
case 1:
_a.database = _c.sent();
_c.label = 2;
case 2:
if (!!parsedTableName.schema) return [3 /*break*/, 4];
_b = parsedTableName;
return [4 /*yield*/, this.getCurrentSchema()];
case 3:
_b.schema = _c.sent();
_c.label = 4;
case 4:
sql = "SELECT * FROM \"" + parsedTableName.database + "\".\"INFORMATION_SCHEMA\".\"COLUMNS\" WHERE \"TABLE_NAME\" = '" + parsedTableName.tableName + "' AND \"TABLE_SCHEMA\" = '" + parsedTableName.schema + "' AND \"COLUMN_NAME\" = '" + columnName + "'";
return [4 /*yield*/, this.query(sql)];
case 5:
result = _c.sent();
return [2 /*return*/, result.length ? true : false];
}
});
});
};
/**
* Creates a new database.
*/
SqlServerQueryRunner.prototype.createDatabase = function (database, ifNotExist) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var up, down;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
up = ifNotExist ? "IF DB_ID('" + database + "') IS NULL CREATE DATABASE \"" + database + "\"" : "CREATE DATABASE \"" + database + "\"";
down = "DROP DATABASE \"" + database + "\"";
return [4 /*yield*/, this.executeQueries(new Query_1.Query(up), new Query_1.Query(down))];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Drops database.
*/
SqlServerQueryRunner.prototype.dropDatabase = function (database, ifExist) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var up, down;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
up = ifExist ? "IF DB_ID('" + database + "') IS NOT NULL DROP DATABASE \"" + database + "\"" : "DROP DATABASE \"" + database + "\"";
down = "CREATE DATABASE \"" + database + "\"";
return [4 /*yield*/, this.executeQueries(new Query_1.Query(up), new Query_1.Query(down))];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Creates table schema.
* If database name also specified (e.g. 'dbName.schemaName') schema will be created in specified database.
*/
SqlServerQueryRunner.prototype.createSchema = function (schemaPath, ifNotExist) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var upQueries, downQueries, upQuery, dbName, schema, currentDB, upQuery;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
upQueries = [];
downQueries = [];
if (!(schemaPath.indexOf(".") === -1)) return [3 /*break*/, 1];
upQuery = ifNotExist ? "IF SCHEMA_ID('" + schemaPath + "') IS NULL BEGIN EXEC ('CREATE SCHEMA \"" + schemaPath + "\"') END" : "CREATE SCHEMA \"" + schemaPath + "\"";
upQueries.push(new Query_1.Query(upQuery));
downQueries.push(new Query_1.Query("DROP SCHEMA \"" + schemaPath + "\""));
return [3 /*break*/, 3];
case 1:
dbName = schemaPath.split(".")[0];
schema = schemaPath.split(".")[1];
return [4 /*yield*/, this.getCurrentDatabase()];
case 2:
currentDB = _a.sent();
upQueries.push(new Query_1.Query("USE \"" + dbName + "\""));
downQueries.push(new Query_1.Query("USE \"" + currentDB + "\""));
upQuery = ifNotExist ? "IF SCHEMA_ID('" + schema + "') IS NULL BEGIN EXEC ('CREATE SCHEMA \"" + schema + "\"') END" : "CREATE SCHEMA \"" + schema + "\"";
upQueries.push(new Query_1.Query(upQuery));
downQueries.push(new Query_1.Query("DROP SCHEMA \"" + schema + "\""));
upQueries.push(new Query_1.Query("USE \"" + currentDB + "\""));
downQueries.push(new Query_1.Query("USE \"" + dbName + "\""));
_a.label = 3;
case 3: return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 4:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Drops table schema.
* If database name also specified (e.g. 'dbName.schemaName') schema will be dropped in specified database.
*/
SqlServerQueryRunner.prototype.dropSchema = function (schemaPath, ifExist) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var upQueries, downQueries, upQuery, dbName, schema, currentDB, upQuery;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
upQueries = [];
downQueries = [];
if (!(schemaPath.indexOf(".") === -1)) return [3 /*break*/, 1];
upQuery = ifExist ? "IF SCHEMA_ID('" + schemaPath + "') IS NULL BEGIN EXEC ('DROP SCHEMA \"" + schemaPath + "\"') END" : "DROP SCHEMA \"" + schemaPath + "\"";
upQueries.push(new Query_1.Query(upQuery));
downQueries.push(new Query_1.Query("CREATE SCHEMA \"" + schemaPath + "\""));
return [3 /*break*/, 3];
case 1:
dbName = schemaPath.split(".")[0];
schema = schemaPath.split(".")[1];
return [4 /*yield*/, this.getCurrentDatabase()];
case 2:
currentDB = _a.sent();
upQueries.push(new Query_1.Query("USE \"" + dbName + "\""));
downQueries.push(new Query_1.Query("USE \"" + currentDB + "\""));
upQuery = ifExist ? "IF SCHEMA_ID('" + schema + "') IS NULL BEGIN EXEC ('DROP SCHEMA \"" + schema + "\"') END" : "DROP SCHEMA \"" + schema + "\"";
upQueries.push(new Query_1.Query(upQuery));
downQueries.push(new Query_1.Query("CREATE SCHEMA \"" + schema + "\""));
upQueries.push(new Query_1.Query("USE \"" + currentDB + "\""));
downQueries.push(new Query_1.Query("USE \"" + dbName + "\""));
_a.label = 3;
case 3: return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 4:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Creates a new table.
*/
SqlServerQueryRunner.prototype.createTable = function (table, ifNotExist, createForeignKeys, createIndices) {
if (ifNotExist === void 0) { ifNotExist = false; }
if (createForeignKeys === void 0) { createForeignKeys = true; }
if (createIndices === void 0) { createIndices = true; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var isTableExist, upQueries, downQueries;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!ifNotExist) return [3 /*break*/, 2];
return [4 /*yield*/, this.hasTable(table)];
case 1:
isTableExist = _a.sent();
if (isTableExist)
return [2 /*return*/, Promise.resolve()];
_a.label = 2;
case 2:
upQueries = [];
downQueries = [];
upQueries.push(this.createTableSql(table, createForeignKeys));
downQueries.push(this.dropTableSql(table));
// if createForeignKeys is true, we must drop created foreign keys in down query.
// createTable does not need separate method to create foreign keys, because it create fk's in the same query with table creation.
if (createForeignKeys)
table.foreignKeys.forEach(function (foreignKey) { return downQueries.push(_this.dropForeignKeySql(table, foreignKey)); });
if (createIndices) {
table.indices.forEach(function (index) {
// new index may be passed without name. In this case we generate index name manually.
if (!index.name)
index.name = _this.connection.namingStrategy.indexName(table, index.columnNames, index.where);
upQueries.push(_this.createIndexSql(table, index));
downQueries.push(_this.dropIndexSql(table, index));
});
}
return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 3:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* Drops the table.
*/
SqlServerQueryRunner.prototype.dropTable = function (tableOrName, ifExist, dropForeignKeys, dropIndices) {
if (dropForeignKeys === void 0) { dropForeignKeys = true; }
if (dropIndices === void 0) { dropIndices = true; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var isTableExist, createForeignKeys, table, _a, upQueries, downQueries;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!ifExist) return [3 /*break*/, 2];
return [4 /*yield*/, this.hasTable(tableOrName)];
case 1:
isTableExist = _b.sent();
if (!isTableExist)
return [2 /*return*/, Promise.resolve()];
_b.label = 2;
case 2:
createForeignKeys = dropForeignKeys;
if (!(tableOrName instanceof Table_1.Table)) return [3 /*break*/, 3];
_a = tableOrName;
return [3 /*break*/, 5];
case 3: return [4 /*yield*/, this.getCachedTable(tableOrName)];
case 4:
_a = _b.sent();
_b.label = 5;
case 5:
table = _a;
upQueries = [];
downQueries = [];
// It needs because if table does not exist and dropForeignKeys or dropIndices is true, we don't need
// to perform drop queries for foreign keys and indices.
if (dropIndices) {
table.indices.forEach(function (index) {
upQueries.push(_this.dropIndexSql(table, index));
downQueries.push(_this.createIndexSql(table, index));
});
}
// if dropForeignKeys is true, we just drop the table, otherwise we also drop table foreign keys.
// createTable does not need separate method to create foreign keys, because it create fk's in the same query with table creation.
if (dropForeignKeys)
table.foreignKeys.forEach(function (foreignKey) { return upQueries.push(_this.dropForeignKeySql(table, foreignKey)); });
upQueries.push(this.dropTableSql(table));
downQueries.push(this.createTableSql(table, createForeignKeys));
return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 6:
_b.sent();
return [2 /*return*/];
}
});
});
};
/**
* Creates a new view.
*/
SqlServerQueryRunner.prototype.createView = function (view) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var upQueries, downQueries, _a, _b, _c, _d;
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
case 0:
upQueries = [];
downQueries = [];
upQueries.push(this.createViewSql(view));
_b = (_a = upQueries).push;
return [4 /*yield*/, this.insertViewDefinitionSql(view)];
case 1:
_b.apply(_a, [_e.sent()]);
downQueries.push(this.dropViewSql(view));
_d = (_c = downQueries).push;
return [4 /*yield*/, this.deleteViewDefinitionSql(view)];
case 2:
_d.apply(_c, [_e.sent()]);
return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 3:
_e.sent();
return [2 /*return*/];
}
});
});
};
/**
* Drops the view.
*/
SqlServerQueryRunner.prototype.dropView = function (target) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var viewName, view, upQueries, downQueries, _a, _b, _c, _d;
return tslib_1.__generator(this, function (_e) {
switch (_e.label) {
case 0:
viewName = target instanceof View_1.View ? target.name : target;
return [4 /*yield*/, this.getCachedView(viewName)];
case 1:
view = _e.sent();
upQueries = [];
downQueries = [];
_b = (_a = upQueries).push;
return [4 /*yield*/, this.deleteViewDefinitionSql(view)];
case 2:
_b.apply(_a, [_e.sent()]);
upQueries.push(this.dropViewSql(view));
_d = (_c = downQueries).push;
return [4 /*yield*/, this.insertViewDefinitionSql(view)];
case 3:
_d.apply(_c, [_e.sent()]);
downQueries.push(this.createViewSql(view));
return [4 /*yield*/, this.executeQueries(upQueries, downQueries)];
case 4:
_e.sent();
return [2 /*return*/];
}
});
});
};
/**
* Renames a table.
*/
SqlServerQueryRunner.prototype.renameTable = function (oldTableOrName, newTableName) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var upQueries, downQueries, oldTable, _a, newTable, dbName, schemaName, oldTableName, splittedName, currentDB, columnNames, oldPkName, newPkName;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
upQueries = [];
downQueries = [];
if (!(oldTableOrName instanceof Table_1.Table)) return [3 /*break*/, 1];
_a = oldTableOrName;
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, this.getCachedTable(oldTableOrName)];
case 2:
_a = _b.sent();
_b.label = 3;
case 3:
oldTable = _a;
newTable = oldTable.clone();
dbName = undefined;
schemaName = undefined;
oldTableName = oldTable.name;
splittedName = oldTable.name.split(".");
if (splittedName.length === 3) {
dbName = splittedName[0];
oldTableName = splittedName[2];
if (splittedName[1] !== "")
schemaName = splittedName[1];
}
else if (splittedName.length === 2) {
schemaName = splittedName[0];
oldTableName = splittedName[1];
}
newTable.name = this.driver.buildTableName(newTableName, schemaName, dbName);
return [4 /*yield*/, this.getCurrentDatabase()];
case 4:
currentDB = _b.sent();
if (dbName && dbName !== currentDB) {
upQueries.push(new Query_1.Query("USE \"" + dbName + "\""));
downQueries.push(new Query_1.Query("USE \"" + currentDB + "\""));
}
// rename table
upQueries.push(new Query_1.Query("EXEC sp_rename \"" + this.getTablePath(oldTable) + "\", \"" + newTableName + "\""));
downQueries.push(new Query_1.Query("EXEC sp_rename \"" + this.getTablePath(newTable) + "\", \"" + oldTableName + "\""));
// rename primary key constraint
if (newTable.primaryColumns.length > 0) {
columnNames = newTable.primaryColumns.map(function (column) { return column.name; });
oldPkName = this.connection.namingStrategy.primaryKeyName(oldTable, columnNames);
newPkName = this.connection.namingStrategy.primaryKeyName(newTable, columnNames);
// rename primary constraint
upQueries.push(new Query_1.Query("EXEC sp_rename \"" + this.getTablePath(newTable) + "." + oldPkName + "\", \"" + newPkName + "\""));
downQueries.push(new Query_1.Query("EXEC sp_rename \"" + this.getTablePath(newTable) + "." + newPkName + "\", \"" + oldPkName + "\""));
}
// rename unique constraints
newTable.uniques.forEach(function (unique) {
// build new constraint name
var newUniqueName = _this.connection.namingStrategy.uniqueConstraintName(newTable, unique.columnNames);
// build queries
upQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.getTablePath(newTable) + "." + unique.name + "\", \"" + newUniqueName + "\""));
downQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.getTablePath(newTable) + "." + newUniqueName + "\", \"" + unique.name + "\""));
// replace constraint name
unique.name = newUniqueName;
});
// rename index constraints
newTable.indices.forEach(function (index) {
// build new constraint name
var newIndexName = _this.connection.namingStrategy.indexName(newTable, index.columnNames, index.where);
// build queries
upQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.getTablePath(newTable) + "." + index.name + "\", \"" + newIndexName + "\", \"INDEX\""));
downQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.getTablePath(newTable) + "." + newIndexName + "\", \"" + index.name + "\", \"INDEX\""));
// replace constraint name
index.name = newIndexName;
});
// rename foreign key constraints
newTable.foreignKeys.forEach(function (foreignKey) {
// build new constraint name
var newForeignKeyName = _this.connection.namingStrategy.foreignKeyName(newTable, foreignKey.columnNames, _this.getTablePath(foreignKey), foreignKey.referencedColumnNames);
// build queries
upQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.buildForeignKeyName(foreignKey.name, schemaName, dbName) + "\", \"" + newForeignKeyName + "\""));
downQueries.push(new Query_1.Query("EXEC sp_rename \"" + _this.buildForeignKeyName(newForeignKeyName, schemaName, dbName) + "\", \"" + foreignKey.name + "\""));
// replace constraint name
foreignKey.name = newForeignKeyName;
});