UNPKG

typeorm

Version:

Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, MongoDB databases.

799 lines • 59.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var Table_1 = require("./table/Table"); var TableColumn_1 = require("./table/TableColumn"); var TableForeignKey_1 = require("./table/TableForeignKey"); var TableIndex_1 = require("./table/TableIndex"); var PromiseUtils_1 = require("../util/PromiseUtils"); var TableUtils_1 = require("./util/TableUtils"); var MysqlDriver_1 = require("../driver/mysql/MysqlDriver"); var TableUnique_1 = require("./table/TableUnique"); var TableCheck_1 = require("./table/TableCheck"); /** * Creates complete tables schemas in the database based on the entity metadatas. * * Steps how schema is being built: * 1. load list of all tables with complete column and keys information from the db * 2. drop all (old) foreign keys that exist in the table, but does not exist in the metadata * 3. create new tables that does not exist in the db, but exist in the metadata * 4. drop all columns exist (left old) in the db table, but does not exist in the metadata * 5. add columns from metadata which does not exist in the table * 6. update all exist columns which metadata has changed * 7. update primary keys - update old and create new primary key from changed columns * 8. create foreign keys which does not exist in the table yet * 9. create indices which are missing in db yet, and drops indices which exist in the db, but does not exist in the metadata anymore */ var RdbmsSchemaBuilder = /** @class */ (function () { // ------------------------------------------------------------------------- // Constructor // ------------------------------------------------------------------------- function RdbmsSchemaBuilder(connection) { this.connection = connection; } // ------------------------------------------------------------------------- // Public Methods // ------------------------------------------------------------------------- /** * Creates complete schemas for the given entity metadatas. */ RdbmsSchemaBuilder.prototype.build = function () { return __awaiter(this, void 0, void 0, function () { var tablePaths, error_1, rollbackError_1; return __generator(this, function (_a) { switch (_a.label) { case 0: this.queryRunner = this.connection.createQueryRunner("master"); return [4 /*yield*/, this.queryRunner.startTransaction()]; case 1: _a.sent(); _a.label = 2; case 2: _a.trys.push([2, 8, 13, 15]); tablePaths = this.entityToSyncMetadatas.map(function (metadata) { return metadata.tablePath; }); return [4 /*yield*/, this.queryRunner.getTables(tablePaths)]; case 3: _a.sent(); return [4 /*yield*/, this.executeSchemaSyncOperationsInProperOrder()]; case 4: _a.sent(); if (!this.connection.queryResultCache) return [3 /*break*/, 6]; return [4 /*yield*/, this.connection.queryResultCache.synchronize(this.queryRunner)]; case 5: _a.sent(); _a.label = 6; case 6: return [4 /*yield*/, this.queryRunner.commitTransaction()]; case 7: _a.sent(); return [3 /*break*/, 15]; case 8: error_1 = _a.sent(); _a.label = 9; case 9: _a.trys.push([9, 11, , 12]); return [4 /*yield*/, this.queryRunner.rollbackTransaction()]; case 10: _a.sent(); return [3 /*break*/, 12]; case 11: rollbackError_1 = _a.sent(); return [3 /*break*/, 12]; case 12: throw error_1; case 13: return [4 /*yield*/, this.queryRunner.release()]; case 14: _a.sent(); return [7 /*endfinally*/]; case 15: return [2 /*return*/]; } }); }); }; /** * Returns sql queries to be executed by schema builder. */ RdbmsSchemaBuilder.prototype.log = function () { return __awaiter(this, void 0, void 0, function () { var tablePaths; return __generator(this, function (_a) { switch (_a.label) { case 0: this.queryRunner = this.connection.createQueryRunner("master"); _a.label = 1; case 1: _a.trys.push([1, , 6, 8]); tablePaths = this.entityToSyncMetadatas.map(function (metadata) { return metadata.tablePath; }); return [4 /*yield*/, this.queryRunner.getTables(tablePaths)]; case 2: _a.sent(); this.queryRunner.enableSqlMemory(); return [4 /*yield*/, this.executeSchemaSyncOperationsInProperOrder()]; case 3: _a.sent(); if (!this.connection.queryResultCache) return [3 /*break*/, 5]; return [4 /*yield*/, this.connection.queryResultCache.synchronize(this.queryRunner)]; case 4: _a.sent(); _a.label = 5; case 5: return [2 /*return*/, this.queryRunner.getMemorySql()]; case 6: // its important to disable this mode despite the fact we are release query builder // because there exist drivers which reuse same query runner. Also its important to disable // sql memory after call of getMemorySql() method because last one flushes sql memory. this.queryRunner.disableSqlMemory(); return [4 /*yield*/, this.queryRunner.release()]; case 7: _a.sent(); return [7 /*endfinally*/]; case 8: return [2 /*return*/]; } }); }); }; Object.defineProperty(RdbmsSchemaBuilder.prototype, "entityToSyncMetadatas", { // ------------------------------------------------------------------------- // Protected Methods // ------------------------------------------------------------------------- /** * Returns only entities that should be synced in the database. */ get: function () { return this.connection.entityMetadatas.filter(function (metadata) { return metadata.synchronize && metadata.tableType !== "entity-child"; }); }, enumerable: true, configurable: true }); /** * Executes schema sync operations in a proper order. * Order of operations matter here. */ RdbmsSchemaBuilder.prototype.executeSchemaSyncOperationsInProperOrder = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.dropOldForeignKeys()]; case 1: _a.sent(); return [4 /*yield*/, this.dropOldIndices()]; case 2: _a.sent(); return [4 /*yield*/, this.dropOldChecks()]; case 3: _a.sent(); return [4 /*yield*/, this.dropCompositeUniqueConstraints()]; case 4: _a.sent(); // await this.renameTables(); return [4 /*yield*/, this.renameColumns()]; case 5: // await this.renameTables(); _a.sent(); return [4 /*yield*/, this.createNewTables()]; case 6: _a.sent(); return [4 /*yield*/, this.dropRemovedColumns()]; case 7: _a.sent(); return [4 /*yield*/, this.addNewColumns()]; case 8: _a.sent(); return [4 /*yield*/, this.updatePrimaryKeys()]; case 9: _a.sent(); return [4 /*yield*/, this.updateExistColumns()]; case 10: _a.sent(); return [4 /*yield*/, this.createNewIndices()]; case 11: _a.sent(); return [4 /*yield*/, this.createNewChecks()]; case 12: _a.sent(); return [4 /*yield*/, this.createCompositeUniqueConstraints()]; case 13: _a.sent(); return [4 /*yield*/, this.createForeignKeys()]; case 14: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Drops all (old) foreign keys that exist in the tables, but do not exist in the entity metadata. */ RdbmsSchemaBuilder.prototype.dropOldForeignKeys = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, tableForeignKeysToDrop; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; tableForeignKeysToDrop = table.foreignKeys.filter(function (tableForeignKey) { var metadataFK = metadata.foreignKeys.find(function (metadataForeignKey) { return metadataForeignKey.name === tableForeignKey.name; }); return !metadataFK || metadataFK.onDelete && metadataFK.onDelete !== tableForeignKey.onDelete || metadataFK.onUpdate && metadataFK.onUpdate !== tableForeignKey.onUpdate; }); if (tableForeignKeysToDrop.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("dropping old foreign keys of " + table.name + ": " + tableForeignKeysToDrop.map(function (dbForeignKey) { return dbForeignKey.name; }).join(", ")); // drop foreign keys from the database return [4 /*yield*/, this.queryRunner.dropForeignKeys(table, tableForeignKeysToDrop)]; case 1: // drop foreign keys from the database _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Rename tables */ RdbmsSchemaBuilder.prototype.renameTables = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Renames columns. * Works if only one column per table was changed. * Changes only column name. If something besides name was changed, these changes will be ignored. */ RdbmsSchemaBuilder.prototype.renameColumns = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var _this = this; var table, renamedMetadataColumns, renamedTableColumns, renamedColumn; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; if (metadata.columns.length !== table.columns.length) return [2 /*return*/]; renamedMetadataColumns = metadata.columns.filter(function (column) { return !table.columns.find(function (tableColumn) { return tableColumn.name === column.databaseName && tableColumn.type === _this.connection.driver.normalizeType(column) && tableColumn.isNullable === column.isNullable && tableColumn.isUnique === _this.connection.driver.normalizeIsUnique(column); }); }); if (renamedMetadataColumns.length === 0 || renamedMetadataColumns.length > 1) return [2 /*return*/]; renamedTableColumns = table.columns.filter(function (tableColumn) { return !metadata.columns.find(function (column) { return column.databaseName === tableColumn.name && _this.connection.driver.normalizeType(column) === tableColumn.type && column.isNullable === tableColumn.isNullable && _this.connection.driver.normalizeIsUnique(column) === tableColumn.isUnique; }); }); if (renamedTableColumns.length === 0 || renamedTableColumns.length > 1) return [2 /*return*/]; renamedColumn = renamedTableColumns[0].clone(); renamedColumn.name = renamedMetadataColumns[0].databaseName; this.connection.logger.logSchemaBuild("renaming column \"" + renamedTableColumns[0].name + "\" in to \"" + renamedColumn.name + "\""); return [4 /*yield*/, this.queryRunner.renameColumn(table, renamedTableColumns[0], renamedColumn)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; RdbmsSchemaBuilder.prototype.dropOldIndices = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var _this = this; var table, dropQueries; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; dropQueries = table.indices .filter(function (tableIndex) { var indexMetadata = metadata.indices.find(function (index) { return index.name === tableIndex.name; }); if (indexMetadata) { if (indexMetadata.synchronize === false) return false; if (indexMetadata.isUnique !== tableIndex.isUnique) return true; if (indexMetadata.isSpatial !== tableIndex.isSpatial) return true; if (indexMetadata.isFulltext !== tableIndex.isFulltext) return true; if (indexMetadata.columns.length !== tableIndex.columnNames.length) return true; return !indexMetadata.columns.every(function (column) { return tableIndex.columnNames.indexOf(column.databaseName) !== -1; }); } return true; }) .map(function (tableIndex) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: this.connection.logger.logSchemaBuild("dropping an index: \"" + tableIndex.name + "\" from table " + table.name); return [4 /*yield*/, this.queryRunner.dropIndex(table, tableIndex)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }); return [4 /*yield*/, Promise.all(dropQueries)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; RdbmsSchemaBuilder.prototype.dropOldChecks = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: // Mysql does not support check constraints if (this.connection.driver instanceof MysqlDriver_1.MysqlDriver) return [2 /*return*/]; return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, oldChecks; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; oldChecks = table.checks.filter(function (tableCheck) { return !metadata.checks.find(function (checkMetadata) { return checkMetadata.name === tableCheck.name; }); }); if (oldChecks.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("dropping old check constraint: " + oldChecks.map(function (check) { return "\"" + check.name + "\""; }).join(", ") + " from table \"" + table.name + "\""); return [4 /*yield*/, this.queryRunner.dropCheckConstraints(table, oldChecks)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; RdbmsSchemaBuilder.prototype.dropCompositeUniqueConstraints = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, compositeUniques; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; compositeUniques = table.uniques.filter(function (tableUnique) { return tableUnique.columnNames.length > 1 && !metadata.uniques.find(function (uniqueMetadata) { return uniqueMetadata.name === tableUnique.name; }); }); if (compositeUniques.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("dropping old unique constraint: " + compositeUniques.map(function (unique) { return "\"" + unique.name + "\""; }).join(", ") + " from table \"" + table.name + "\""); return [4 /*yield*/, this.queryRunner.dropUniqueConstraints(table, compositeUniques)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Creates tables that do not exist in the database yet. * New tables are created without foreign and primary keys. * Primary key only can be created in conclusion with auto generated column. */ RdbmsSchemaBuilder.prototype.createNewTables = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var _this = this; var existTable, table; return __generator(this, function (_a) { switch (_a.label) { case 0: existTable = this.queryRunner.loadedTables.find(function (table) { var database = metadata.database && metadata.database !== _this.connection.driver.database ? metadata.database : undefined; var schema = metadata.schema || _this.connection.driver.options.schema; var fullTableName = _this.connection.driver.buildTableName(metadata.tableName, schema, database); return table.name === fullTableName; }); if (existTable) return [2 /*return*/]; this.connection.logger.logSchemaBuild("creating a new table: " + metadata.tablePath); table = Table_1.Table.create(metadata, this.connection.driver); return [4 /*yield*/, this.queryRunner.createTable(table, false, false)]; case 1: _a.sent(); this.queryRunner.loadedTables.push(table); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Drops all columns that exist in the table, but does not exist in the metadata (left old). * We drop their keys too, since it should be safe. */ RdbmsSchemaBuilder.prototype.dropRemovedColumns = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, droppedTableColumns; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; droppedTableColumns = table.columns.filter(function (tableColumn) { return !metadata.columns.find(function (columnMetadata) { return columnMetadata.databaseName === tableColumn.name; }); }); if (droppedTableColumns.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("columns dropped in " + table.name + ": " + droppedTableColumns.map(function (column) { return column.name; }).join(", ")); // drop columns from the database return [4 /*yield*/, this.queryRunner.dropColumns(table, droppedTableColumns)]; case 1: // drop columns from the database _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Adds columns from metadata which does not exist in the table. * Columns are created without keys. */ RdbmsSchemaBuilder.prototype.addNewColumns = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, newColumnMetadatas, newTableColumnOptions, newTableColumns; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; newColumnMetadatas = metadata.columns.filter(function (columnMetadata) { return !table.columns.find(function (tableColumn) { return tableColumn.name === columnMetadata.databaseName; }); }); if (newColumnMetadatas.length === 0) return [2 /*return*/]; newTableColumnOptions = this.metadataColumnsToTableColumnOptions(newColumnMetadatas); newTableColumns = newTableColumnOptions.map(function (option) { return new TableColumn_1.TableColumn(option); }); if (newTableColumns.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("new columns added: " + newColumnMetadatas.map(function (column) { return column.databaseName; }).join(", ")); return [4 /*yield*/, this.queryRunner.addColumns(table, newTableColumns)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Updates composite primary keys. */ RdbmsSchemaBuilder.prototype.updatePrimaryKeys = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var _this = this; var table, primaryMetadataColumns, primaryTableColumns, changedPrimaryColumns; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; primaryMetadataColumns = metadata.columns.filter(function (column) { return column.isPrimary; }); primaryTableColumns = table.columns.filter(function (column) { return column.isPrimary; }); if (!(primaryTableColumns.length !== primaryMetadataColumns.length && primaryMetadataColumns.length > 1)) return [3 /*break*/, 2]; changedPrimaryColumns = primaryMetadataColumns.map(function (primaryMetadataColumn) { return new TableColumn_1.TableColumn(TableUtils_1.TableUtils.createTableColumnOptions(primaryMetadataColumn, _this.connection.driver)); }); return [4 /*yield*/, this.queryRunner.updatePrimaryKeys(table, changedPrimaryColumns)]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Update all exist columns which metadata has changed. * Still don't create keys. Also we don't touch foreign keys of the changed columns. */ RdbmsSchemaBuilder.prototype.updateExistColumns = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var _this = this; var table, changedColumns, newAndOldTableColumns; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; changedColumns = this.connection.driver.findChangedColumns(table.columns, metadata.columns); if (changedColumns.length === 0) return [2 /*return*/]; // drop all foreign keys that point to this column return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(changedColumns, function (changedColumn) { return _this.dropColumnReferencedForeignKeys(metadata.tablePath, changedColumn.databaseName); })]; case 1: // drop all foreign keys that point to this column _a.sent(); // drop all composite indices related to this column return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(changedColumns, function (changedColumn) { return _this.dropColumnCompositeIndices(metadata.tablePath, changedColumn.databaseName); })]; case 2: // drop all composite indices related to this column _a.sent(); if (!!(this.connection.driver instanceof MysqlDriver_1.MysqlDriver)) return [3 /*break*/, 4]; return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(changedColumns, function (changedColumn) { return _this.dropColumnCompositeUniques(metadata.tablePath, changedColumn.databaseName); })]; case 3: _a.sent(); _a.label = 4; case 4: newAndOldTableColumns = changedColumns.map(function (changedColumn) { var oldTableColumn = table.columns.find(function (column) { return column.name === changedColumn.databaseName; }); var newTableColumnOptions = TableUtils_1.TableUtils.createTableColumnOptions(changedColumn, _this.connection.driver); var newTableColumn = new TableColumn_1.TableColumn(newTableColumnOptions); return { oldColumn: oldTableColumn, newColumn: newTableColumn }; }); if (newAndOldTableColumns.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("columns changed in \"" + table.name + "\". updating: " + changedColumns.map(function (column) { return column.databaseName; }).join(", ")); return [4 /*yield*/, this.queryRunner.changeColumns(table, newAndOldTableColumns)]; case 5: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Creates composite indices which are missing in db yet. */ RdbmsSchemaBuilder.prototype.createNewIndices = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, newIndices; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; newIndices = metadata.indices .filter(function (indexMetadata) { return !table.indices.find(function (tableIndex) { return tableIndex.name === indexMetadata.name; }) && indexMetadata.synchronize === true; }) .map(function (indexMetadata) { return TableIndex_1.TableIndex.create(indexMetadata); }); if (newIndices.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("adding new indices " + newIndices.map(function (index) { return "\"" + index.name + "\""; }).join(", ") + " in table \"" + table.name + "\""); return [4 /*yield*/, this.queryRunner.createIndices(table, newIndices)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; RdbmsSchemaBuilder.prototype.createNewChecks = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: // Mysql does not support check constraints if (this.connection.driver instanceof MysqlDriver_1.MysqlDriver) return [2 /*return*/]; return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, newChecks; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; newChecks = metadata.checks .filter(function (checkMetadata) { return !table.checks.find(function (tableCheck) { return tableCheck.name === checkMetadata.name; }); }) .map(function (checkMetadata) { return TableCheck_1.TableCheck.create(checkMetadata); }); if (newChecks.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("adding new check constraints: " + newChecks.map(function (index) { return "\"" + index.name + "\""; }).join(", ") + " in table \"" + table.name + "\""); return [4 /*yield*/, this.queryRunner.createCheckConstraints(table, newChecks)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Creates composite uniques which are missing in db yet. */ RdbmsSchemaBuilder.prototype.createCompositeUniqueConstraints = function () { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, PromiseUtils_1.PromiseUtils.runInSequence(this.entityToSyncMetadatas, function (metadata) { return __awaiter(_this, void 0, void 0, function () { var table, compositeUniques; return __generator(this, function (_a) { switch (_a.label) { case 0: table = this.queryRunner.loadedTables.find(function (table) { return table.name === metadata.tablePath; }); if (!table) return [2 /*return*/]; compositeUniques = metadata.uniques .filter(function (uniqueMetadata) { return uniqueMetadata.columns.length > 1 && !table.uniques.find(function (tableUnique) { return tableUnique.name === uniqueMetadata.name; }); }) .map(function (uniqueMetadata) { return TableUnique_1.TableUnique.create(uniqueMetadata); }); if (compositeUniques.length === 0) return [2 /*return*/]; this.connection.logger.logSchemaBuild("adding new unique constraints: " + compositeUniques.map(func