UNPKG

@microtica/database

Version:

Database tools

120 lines 5.08 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; const Bluebird = require("bluebird"); const _ = require("lodash"); class ColumnProcessor { constructor(columns) { this.columns = columns.slice(0); } get tableName() { return ColumnProcessor.getTableName(this.columns); } get table() { return ColumnProcessor.getTable(this.columns); } get indexName() { return this._indexName || (this._indexName = this.generateIndexName()); } checkIndexColumns() { const firstColumnName = this.tableName; return _.every(_.tail(this.columns), column => column.table._name === firstColumnName); } generateIndexName() { if (!this.checkIndexColumns()) { throw new Error("Can't get index for cross-table columns"); } return this.columns.reduce((result, column) => { return result + "_" + column.name; }, this.tableName); } generateNamedIndexCreationQuery(indexName) { const q = this.table.indexes().create(indexName); return q.on.apply(q, this.columns); } generateIndexCreationQuery() { return this.generateNamedIndexCreationQuery(this.indexName); } generateNamedIndexDropQuery(indexName) { return this.table.indexes().drop(indexName); } generateIndexDropQuery() { return this.generateNamedIndexDropQuery(this.indexName); } static getTable(columns) { return columns[0].table; } static getTableName(columns) { return ColumnProcessor.getTable(columns)._name; } } /** * Generates or drops database indexes. */ class DatabaseIndexGenerator { /** * Creates an instance of DatabaseIndexGenerator. * @param {Transaction} tx the database transaction to use to generate the indexes. * @memberof DatabaseIndexGenerator */ constructor(tx) { this.tx = tx; } getIndexesFromSet(indexSets) { return indexSets[0][0].table.indexes().allWithin(this.tx); // TODO This doesn't work in Jenkins for some reason } executeQueries(queries) { return __awaiter(this, void 0, void 0, function* () { if (queries.length > 0) { yield Bluebird.map(queries, q => q.execWithin(this.tx), { concurrency: 1 }); } }); } /** * Creates a set of indexes. * @param columnSets a list of indexes to create, * each defined by a list of columns to create them on. The columns must all belong to the same table. * @returns * @memberof DatabaseIndexGenerator */ createIndexSets(columnSets) { const byTable = _.groupBy(columnSets, ColumnProcessor.getTableName); return Bluebird.map(Object.keys(byTable), (tableName) => __awaiter(this, void 0, void 0, function* () { const tableSet = byTable[tableName]; const existingIndexes = yield this.getIndexesFromSet(tableSet); return this.executeQueries(_.transform(tableSet, (queries, columns) => { const columnProcessor = new ColumnProcessor(columns); if (!_.some(existingIndexes, index => index.Key_name === columnProcessor.indexName)) { queries.push(columnProcessor.generateIndexCreationQuery()); } }, [])); })); } /** * Drops a set of indexes. * @param columnSets a list of indexes to drop * each defined by a list of columns that they were created on. The columns must all belong to the same table. * @returns * @memberof DatabaseIndexGenerator */ dropIndexSets(columnSets) { const byTable = _.groupBy(columnSets, ColumnProcessor.getTableName); return Bluebird.map(Object.keys(byTable), (tableName) => __awaiter(this, void 0, void 0, function* () { const tableSet = byTable[tableName]; const existingIndexes = yield this.getIndexesFromSet(tableSet); return this.executeQueries(_.transform(tableSet, (queries, columns) => { const columnProcessor = new ColumnProcessor(columns); if (_.some(existingIndexes, index => index.Key_name === columnProcessor.indexName)) { queries.push(columnProcessor.generateIndexDropQuery()); } }, [])); })); } } module.exports = DatabaseIndexGenerator; //# sourceMappingURL=db-index-generator.js.map