dbgate-api
Version:
Allows run DbGate data-manipulation scripts.
123 lines (111 loc) • 4.83 kB
JavaScript
const path = require('path');
const fs = require('fs-extra');
const executeQuery = require('./executeQuery');
const { connectUtility } = require('../utility/connectUtility');
const requireEngineDriver = require('../utility/requireEngineDriver');
const { getAlterDatabaseScript, DatabaseAnalyser, runCommandOnDriver, adaptDatabaseInfo } = require('dbgate-tools');
const importDbModel = require('../utility/importDbModel');
const jsonLinesReader = require('./jsonLinesReader');
const tableWriter = require('./tableWriter');
const copyStream = require('./copyStream');
/**
* Deploys database model stored in modelFolder (table as yamls) to database
* @param {object} options
* @param {connectionType} options.connection - connection object
* @param {object} options.systemConnection - system connection (result of driver.connect). If not provided, new connection will be created
* @param {object} options.driver - driver object. If not provided, it will be loaded from connection
* @param {string} options.folder - folder with model files (YAML files for tables, SQL files for views, procedures, ...)
* @param {function[]} options.modelTransforms - array of functions for transforming model
*/
async function importDbFromFolder({ connection, systemConnection, driver, folder, modelTransforms }) {
if (!driver) driver = requireEngineDriver(connection);
const dbhan = systemConnection || (await connectUtility(driver, connection, 'read'));
try {
if (driver?.databaseEngineTypes?.includes('sql')) {
const model = await importDbModel(folder);
let modelAdapted = adaptDatabaseInfo(model, driver);
for (const transform of modelTransforms || []) {
modelAdapted = transform(modelAdapted);
}
const modelNoFk = {
...modelAdapted,
tables: modelAdapted.tables.map(table => ({
...table,
foreignKeys: [],
})),
};
// const plan = createAlterDatabasePlan(
// DatabaseAnalyser.createEmptyStructure(),
// driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
// {},
// DatabaseAnalyser.createEmptyStructure(),
// driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
// driver
// );
// const dmp1 = driver.createDumper({ useHardSeparator: true });
// if (driver.dialect.enableAllForeignKeys) {
// dmp1.enableAllForeignKeys(false);
// }
// plan.run(dmp1);
// if (driver.dialect.enableAllForeignKeys) {
// dmp1.enableAllForeignKeys(true);
// }
const { sql } = getAlterDatabaseScript(
DatabaseAnalyser.createEmptyStructure(),
driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
{},
DatabaseAnalyser.createEmptyStructure(),
driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
driver
);
// console.log('CREATING STRUCTURE:', sql);
await executeQuery({ connection, systemConnection: dbhan, driver, sql, logScriptItems: true });
if (driver.dialect.enableAllForeignKeys) {
await runCommandOnDriver(dbhan, driver, dmp => dmp.enableAllForeignKeys(false));
}
for (const table of modelAdapted.tables) {
const fileName = path.join(folder, `${table.pureName}.jsonl`);
if (await fs.exists(fileName)) {
const src = await jsonLinesReader({ fileName });
const dst = await tableWriter({
systemConnection: dbhan,
pureName: table.pureName,
driver,
targetTableStructure: table,
});
await copyStream(src, dst);
}
}
if (driver.dialect.enableAllForeignKeys) {
await runCommandOnDriver(dbhan, driver, dmp => dmp.enableAllForeignKeys(true));
} else if (driver.dialect.createForeignKey) {
const dmp = driver.createDumper();
for (const table of modelAdapted.tables) {
for (const fk of table.foreignKeys) {
dmp.createForeignKey(fk);
}
}
// create foreign keys
await executeQuery({ connection, systemConnection: dbhan, driver, sql: dmp.s, logScriptItems: true });
}
} else if (driver?.databaseEngineTypes?.includes('document')) {
for (const file of fs.readdirSync(folder)) {
if (!file.endsWith('.jsonl')) continue;
const pureName = path.parse(file).name;
const src = await jsonLinesReader({ fileName: path.join(folder, file) });
const dst = await tableWriter({
systemConnection: dbhan,
pureName,
driver,
createIfNotExists: true,
});
await copyStream(src, dst);
}
}
} finally {
if (!systemConnection) {
await driver.close(dbhan);
}
}
}
module.exports = importDbFromFolder;