UNPKG

dbgate-tools

Version:

Auxiliary tools for other DbGate packages.

247 lines (246 loc) 9.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SqlGenerator = void 0; const flatten_1 = __importDefault(require("lodash/flatten")); const uniqBy_1 = __importDefault(require("lodash/uniqBy")); const getLogger_1 = require("./getLogger"); const structureTools_1 = require("./structureTools"); const stringTools_1 = require("./stringTools"); const logger = (0, getLogger_1.getLogger)('sqlGenerator'); class SqlGenerator { constructor(dbinfo, options, objects, dmp, driver, pool) { this.options = options; this.objects = objects; this.dmp = dmp; this.driver = driver; this.pool = pool; this.isTruncated = false; this.isUnhandledException = false; this.handleException = error => { logger.error((0, stringTools_1.extractErrorLogData)(error), 'DBGM-00186 Unhandled error'); this.isUnhandledException = true; }; this.dbinfo = (0, structureTools_1.extendDatabaseInfo)(dbinfo); this.tables = this.extract('tables'); this.views = this.extract('views'); this.matviews = this.extract('matviews'); this.procedures = this.extract('procedures'); this.functions = this.extract('functions'); this.triggers = this.extract('triggers'); this.schedulerEvents = this.extract('schedulerEvents'); } async dump() { try { process.on('uncaughtException', this.handleException); this.dropObjects(this.procedures, 'Procedure'); if (this.checkDumper()) return; this.dropObjects(this.functions, 'Function'); if (this.checkDumper()) return; this.dropObjects(this.views, 'View'); if (this.checkDumper()) return; this.dropObjects(this.matviews, 'Matview'); if (this.checkDumper()) return; this.dropObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; this.dropObjects(this.schedulerEvents, 'SchedulerEvent'); if (this.checkDumper()) return; this.dropTables(); if (this.checkDumper()) return; this.createTables(); if (this.checkDumper()) return; this.truncateTables(); if (this.checkDumper()) return; await this.insertData(); if (this.checkDumper()) return; this.createForeignKeys(); if (this.checkDumper()) return; this.createObjects(this.procedures, 'Procedure'); if (this.checkDumper()) return; this.createObjects(this.functions, 'Function'); if (this.checkDumper()) return; this.createObjects(this.views, 'View'); if (this.checkDumper()) return; this.createObjects(this.matviews, 'Matview'); if (this.checkDumper()) return; this.createObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; this.createObjects(this.schedulerEvents, 'SchedulerEvent'); if (this.checkDumper()) return; } finally { process.off('uncaughtException', this.handleException); } } createForeignKeys() { const fks = []; if (this.options.createForeignKeys) fks.push(...(0, flatten_1.default)(this.tables.map(x => x.foreignKeys || []))); if (this.options.createReferences) fks.push(...(0, flatten_1.default)(this.tables.map(x => x.dependencies || []))); for (const fk of (0, uniqBy_1.default)(fks, 'constraintName')) { this.dmp.createForeignKey(fk); if (this.checkDumper()) return; } } truncateTables() { if (this.options.truncate) { for (const table of this.tables) { this.dmp.truncateTable(table); if (this.checkDumper()) return; } } } createTables() { if (this.options.createTables) { for (const table of this.tables) { this.dmp.createTable({ ...table, foreignKeys: [], dependencies: [], indexes: [], }); if (this.checkDumper()) return; } } if (this.options.createIndexes) { for (const index of (0, flatten_1.default)(this.tables.map(x => x.indexes || []))) { this.dmp.createIndex(index); } } } async insertData() { if (!this.options.insert) return; this.enableConstraints(false); for (const table of this.tables) { await this.insertTableData(table); if (this.checkDumper()) return; } this.enableConstraints(true); } checkDumper() { if (this.dmp.s.length > 4000000) { if (!this.isTruncated) { this.dmp.putRaw('\n'); this.dmp.comment(' *************** SQL is truncated ******************'); this.dmp.putRaw('\n'); } this.isTruncated = true; return true; } return false; } dropObjects(list, name) { if (this.options[`drop${name}s`]) { for (const item of list) { this.dmp[`drop${name}`](item, { testIfExists: this.options[`checkIf${name}Exists`] }); if (this.checkDumper()) return; } } } createObjects(list, name) { if (this.options[`create${name}s`]) { for (const item of list) { this.dmp[`create${name}`](item); if (this.checkDumper()) return; } } } dropTables() { if (this.options.dropReferences) { for (const fk of (0, flatten_1.default)(this.tables.map(x => x.dependencies || []))) { this.dmp.dropForeignKey(fk); } } if (this.options.dropTables) { for (const table of this.tables) { this.dmp.dropTable(table, { testIfExists: this.options.checkIfTableExists }); } } } async insertTableData(table) { const dmpLocal = this.driver.createDumper(); dmpLocal.put('^select * ^from %f', table); const autoinc = table.columns.find(x => x.autoIncrement); if (autoinc && !this.options.skipAutoincrementColumn) { this.dmp.allowIdentityInsert(table, true); } const readable = await this.driver.readQuery(this.pool, dmpLocal.s, table); await this.processReadable(table, readable); if (autoinc && !this.options.skipAutoincrementColumn) { this.dmp.allowIdentityInsert(table, false); } } processReadable(table, readable) { const columnsFiltered = this.options.skipAutoincrementColumn ? table.columns.filter(x => !x.autoIncrement) : table.columns; const columnNames = columnsFiltered.map(x => x.columnName); let isClosed = false; let isHeaderRead = false; return new Promise(resolve => { readable.on('data', chunk => { if (isClosed) return; if (!isHeaderRead) { isHeaderRead = true; return; } if (this.checkDumper()) { isClosed = true; resolve(undefined); readable.destroy(); return; } const columnNamesCopy = this.options.omitNulls ? columnNames.filter(col => chunk[col] != null) : columnNames; this.dmp.put('^insert ^into %f (%,i) ^values (%,v);&n', table, columnNamesCopy, columnNamesCopy.map(col => chunk[col])); }); readable.on('end', () => { resolve(undefined); }); }); } extract(objectTypeField) { var _a, _b; return ((_b = (_a = this.dbinfo[objectTypeField]) === null || _a === void 0 ? void 0 : _a.filter(x => this.objects.find(y => x.pureName == y.pureName && x.schemaName == y.schemaName && y.objectTypeField == objectTypeField))) !== null && _b !== void 0 ? _b : []); } enableConstraints(enabled) { if (this.options.disableConstraints) { if (this.driver.dialect.enableConstraintsPerTable) { for (const table of this.tables) { this.dmp.enableConstraints(table, enabled); } } else { this.dmp.enableConstraints(null, enabled); } } } } exports.SqlGenerator = SqlGenerator;