mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 21:26:00 +00:00
dbmodel commandline tool
This commit is contained in:
30
packages/api/src/shell/generateModelSql.js
Normal file
30
packages/api/src/shell/generateModelSql.js
Normal file
@@ -0,0 +1,30 @@
|
||||
const requireEngineDriver = require('../utility/requireEngineDriver');
|
||||
const {
|
||||
extendDatabaseInfo,
|
||||
databaseInfoFromYamlModel,
|
||||
getAlterDatabaseScript,
|
||||
DatabaseAnalyser,
|
||||
} = require('dbgate-tools');
|
||||
const importDbModel = require('../utility/importDbModel');
|
||||
const fs = require('fs');
|
||||
|
||||
async function generateModelSql({ engine, driver, modelFolder, loadedDbModel, outputFile }) {
|
||||
if (!driver) driver = requireEngineDriver(engine);
|
||||
|
||||
const dbInfo = extendDatabaseInfo(
|
||||
loadedDbModel ? databaseInfoFromYamlModel(loadedDbModel) : await importDbModel(modelFolder)
|
||||
);
|
||||
|
||||
const { sql } = getAlterDatabaseScript(
|
||||
DatabaseAnalyser.createEmptyStructure(),
|
||||
dbInfo,
|
||||
{},
|
||||
DatabaseAnalyser.createEmptyStructure(),
|
||||
dbInfo,
|
||||
driver
|
||||
);
|
||||
|
||||
fs.writeFileSync(outputFile, sql);
|
||||
}
|
||||
|
||||
module.exports = generateModelSql;
|
||||
@@ -24,6 +24,7 @@ const initializeApiEnvironment = require('./initializeApiEnvironment');
|
||||
const dumpDatabase = require('./dumpDatabase');
|
||||
const importDatabase = require('./importDatabase');
|
||||
const loadDatabase = require('./loadDatabase');
|
||||
const generateModelSql = require('./generateModelSql');
|
||||
|
||||
const dbgateApi = {
|
||||
queryReader,
|
||||
@@ -51,6 +52,7 @@ const dbgateApi = {
|
||||
dumpDatabase,
|
||||
importDatabase,
|
||||
loadDatabase,
|
||||
generateModelSql,
|
||||
};
|
||||
|
||||
requirePlugin.initializeDbgateApi(dbgateApi);
|
||||
|
||||
@@ -43,41 +43,15 @@ Model is stored as a collection of files:
|
||||
|
||||
```sh
|
||||
# load from existing database
|
||||
dbmodel load -s localhost -u USERNAME -p PASSWORD -d DATABASE -c mssql OUTPUT_FOLDER
|
||||
dbmodel load -s localhost -u USERNAME -p PASSWORD -d DATABASE -e mssql@dbgate-plugin-mssql OUTPUT_FOLDER
|
||||
|
||||
# deploy project to database
|
||||
dbmodel deploy -s localhost -u USERNAME -p PASSWORD -d DATABASE -c mssql PROJECT_FOLDER
|
||||
dbmodel deploy -s localhost -u USERNAME -p PASSWORD -d DATABASE -e mssql@dbgate-plugin-mssql PROJECT_FOLDER
|
||||
|
||||
# build SQL script from project
|
||||
dbmodel build -c mssql PROJECT_FOLDER OUTPUT_FILE.sql
|
||||
dbmodel build -e mssql@dbgate-plugin-mssql PROJECT_FOLDER OUTPUT_FILE.sql
|
||||
```
|
||||
|
||||
## JavaScript interface
|
||||
|
||||
```javascript
|
||||
const dbmodel = require('dbmodel');
|
||||
|
||||
await dbmodel.deploy({
|
||||
client: 'mssql',
|
||||
connection: {
|
||||
server: '127.0.0.1',
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: 'Chinook_Model',
|
||||
},
|
||||
hooks: [dbmodel.hooks.autoIndexForeignKeys], // this hook adds indexes to all foreign keys
|
||||
projectDir: 'model',
|
||||
})
|
||||
```
|
||||
|
||||
list of dbmodel exported functions:
|
||||
* build - builds SQL script
|
||||
* deploy - deploys model to database
|
||||
* dump - dumps loaded model into directory
|
||||
* load - loads model from database
|
||||
* read - reads model from directory
|
||||
* connect - creates database connection defined in options
|
||||
|
||||
## Table yaml file documentation
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -10,8 +10,21 @@ global.PLUGINS_DIR = process.env.DEVMODE
|
||||
global.IS_NPM_DIST = true;
|
||||
|
||||
const program = require('commander');
|
||||
const dbmodel = require('../lib');
|
||||
const dbgateApi = require('dbgate-api');
|
||||
const { createLogger } = require('pinomin');
|
||||
|
||||
const logger = createLogger('dbmodel');
|
||||
|
||||
async function runAndExit(promise) {
|
||||
try {
|
||||
await promise;
|
||||
logger.info('Success');
|
||||
process.exit();
|
||||
} catch (err) {
|
||||
logger.error({ err }, 'Processing failed');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
program
|
||||
.option('-s, --server <server>', 'server host')
|
||||
@@ -26,14 +39,15 @@ program
|
||||
.requiredOption('-e, --engine <engine>', 'engine name, eg. mysql@dbgate-plugin-mysql');
|
||||
|
||||
program
|
||||
.command('deploy <projectDir>')
|
||||
.command('deploy <modelFolder>')
|
||||
.description('Deploys model to database')
|
||||
.action(projectDir => {
|
||||
const { engine, server, user, password, database } = program;
|
||||
const hooks = [];
|
||||
if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
|
||||
dbmodel.runAndExit(
|
||||
dbmodel.deploy({
|
||||
.action(modelFolder => {
|
||||
const { engine, server, user, password, database } = program.opts();
|
||||
// const hooks = [];
|
||||
// if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
|
||||
|
||||
runAndExit(
|
||||
dbgateApi.deployDb({
|
||||
connection: {
|
||||
engine,
|
||||
server,
|
||||
@@ -41,12 +55,25 @@ program
|
||||
password,
|
||||
database,
|
||||
},
|
||||
hooks,
|
||||
projectDir,
|
||||
modelFolder,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
// runAndExit(
|
||||
// dbmodel.deploy({
|
||||
// connection: {
|
||||
// engine,
|
||||
// server,
|
||||
// user,
|
||||
// password,
|
||||
// database,
|
||||
// },
|
||||
// hooks,
|
||||
// projectDir,
|
||||
// })
|
||||
// );
|
||||
|
||||
program
|
||||
.command('load <outputDir>')
|
||||
.description('Loads model from database')
|
||||
@@ -57,7 +84,7 @@ program
|
||||
// : null;
|
||||
// const hooks = [];
|
||||
|
||||
dbmodel.runAndExit(
|
||||
runAndExit(
|
||||
dbgateApi.loadDatabase({
|
||||
connection: {
|
||||
engine,
|
||||
@@ -72,17 +99,18 @@ program
|
||||
});
|
||||
|
||||
program
|
||||
.command('build <projectDir> <outputFile>')
|
||||
.command('build <modelFolder> <outputFile>')
|
||||
.description('Builds single SQL script from project')
|
||||
.action((projectDir, outputFile) => {
|
||||
const { client } = program;
|
||||
const hooks = [];
|
||||
dbmodel.runAndExit(
|
||||
dbmodel.build({
|
||||
client,
|
||||
hooks,
|
||||
projectDir,
|
||||
.action((modelFolder, outputFile) => {
|
||||
const { engine } = program.opts();
|
||||
// const hooks = [];
|
||||
runAndExit(
|
||||
dbgateApi.generateModelSql({
|
||||
// client,
|
||||
// hooks,
|
||||
modelFolder,
|
||||
outputFile,
|
||||
engine,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
const load = require('./load');
|
||||
// const connect = require('./connect');
|
||||
// const dump = require('./dump');
|
||||
// const deploy = require('./deploy');
|
||||
// const build = require('./build');
|
||||
// const efmodel = require('./efmodel');
|
||||
|
||||
// const hooks = require('./hooks');
|
||||
const runAndExit = require('./runAndExit');
|
||||
|
||||
module.exports = {
|
||||
load,
|
||||
// connect,
|
||||
// dump,
|
||||
// deploy,
|
||||
// hooks,
|
||||
// build,
|
||||
// efmodel,
|
||||
runAndExit,
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
const _ = require('lodash');
|
||||
const dbgateApi = require('dbgate-api');
|
||||
|
||||
async function load({ connection, outputDir }) {
|
||||
await dbgateApi.loadDatabase(connection, outputDir);
|
||||
|
||||
// await connect(options);
|
||||
// const { client } = options;
|
||||
// const loadFunc = require(`./clients/${client}/load`);
|
||||
// options.databaseStructure = await loadFunc(options);
|
||||
// if (options.loadDataCondition) {
|
||||
// const { tables } = options.databaseStructure;
|
||||
// for (const tableName of _.keys(tables)) {
|
||||
// const table = tables[tableName];
|
||||
// if (!options.loadDataCondition(table)) continue;
|
||||
// const data = await query(options, `SELECT * FROM [${tableName}]`);
|
||||
// table.data = data;
|
||||
// }
|
||||
// }
|
||||
// return options;
|
||||
}
|
||||
|
||||
module.exports = load;
|
||||
@@ -1,16 +0,0 @@
|
||||
const { createLogger } = require('pinomin');
|
||||
|
||||
const logger = createLogger('runAndExit');
|
||||
|
||||
async function runAndExit(promise) {
|
||||
try {
|
||||
await promise;
|
||||
logger.info('Success');
|
||||
process.exit();
|
||||
} catch (err) {
|
||||
logger.error({ err }, 'Processing failed');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = runAndExit;
|
||||
@@ -19,7 +19,9 @@
|
||||
],
|
||||
"scripts": {
|
||||
"dbmodel": "node ./bin/dbmodel.js",
|
||||
"dbmodel:load": "cross-env DEVMODE=1 node ./bin/dbmodel.js load testdata/db -e postgres@dbgate-plugin-postgres -s localhost -u postgres -p Pwd2020Db -d zradlo"
|
||||
"dbmodel:load": "cross-env DEVMODE=1 node ./bin/dbmodel.js load testdata/db -e postgres@dbgate-plugin-postgres -s localhost -u postgres -p Pwd2020Db -d zradlo",
|
||||
"dbmodel:deploy": "cross-env DEVMODE=1 node ./bin/dbmodel.js deploy testdata/db -e postgres@dbgate-plugin-postgres -s localhost -u postgres -p Pwd2020Db -d deployed",
|
||||
"dbmodel:build": "cross-env DEVMODE=1 node ./bin/dbmodel.js build testdata/db testdata/db.sql -e postgres@dbgate-plugin-postgres "
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^10.0.0",
|
||||
|
||||
76
packages/dbmodel/testdata/db.sql
vendored
Normal file
76
packages/dbmodel/testdata/db.sql
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE "language" (
|
||||
"language_id" CHARACTER(31) NOT NULL,
|
||||
"name" VARCHAR(255) NULL,
|
||||
PRIMARY KEY ("language_id")
|
||||
);
|
||||
CREATE TABLE "preparation_step" (
|
||||
"preparation_step_id" SERIAL,
|
||||
"recipe_id" INTEGER NULL,
|
||||
"description" VARCHAR NULL,
|
||||
"duration" INTERVAL NULL,
|
||||
"step_order" SMALLINT NULL,
|
||||
"language_id" CHARACTER(31) NULL,
|
||||
PRIMARY KEY ("preparation_step_id")
|
||||
);
|
||||
CREATE TABLE "recipe" (
|
||||
"recipe_id" SERIAL,
|
||||
"name" VARCHAR(1000) NOT NULL,
|
||||
"is_public" BOOLEAN NULL,
|
||||
"user_id" INTEGER NULL,
|
||||
"source_url" VARCHAR(1000) NULL,
|
||||
"cook_duration" INTERVAL NULL,
|
||||
"servings" SMALLINT NULL,
|
||||
"language_id" CHARACTER(31) NULL,
|
||||
"deleted_date" TIMESTAMP NULL,
|
||||
PRIMARY KEY ("recipe_id")
|
||||
);
|
||||
CREATE TABLE "recipe_has_ingredient" (
|
||||
"recipe_id" INTEGER NOT NULL,
|
||||
"recipe_ingredient_id" INTEGER NOT NULL,
|
||||
"unit_id" INTEGER NULL,
|
||||
"unit" VARCHAR(100) NULL,
|
||||
"name" VARCHAR(1000) NULL,
|
||||
"amount" REAL NULL,
|
||||
PRIMARY KEY ("recipe_id", "recipe_ingredient_id")
|
||||
);
|
||||
CREATE TABLE "recipe_photo" (
|
||||
"recipe_photo_id" SERIAL,
|
||||
"path" VARCHAR NULL,
|
||||
"name" VARCHAR(255) NULL,
|
||||
"recipe_id" INTEGER NULL,
|
||||
"user_id" INTEGER NULL,
|
||||
"created_on" TIMESTAMP NULL,
|
||||
PRIMARY KEY ("recipe_photo_id")
|
||||
);
|
||||
CREATE TABLE "shop" (
|
||||
"shop_id" SERIAL,
|
||||
"name" VARCHAR(255) NULL,
|
||||
"url" VARCHAR NULL,
|
||||
"logo_path" VARCHAR NULL,
|
||||
PRIMARY KEY ("shop_id")
|
||||
);
|
||||
CREATE TABLE "unit" (
|
||||
"unit_id" SERIAL,
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"user_id" INTEGER NULL,
|
||||
PRIMARY KEY ("unit_id")
|
||||
);
|
||||
CREATE TABLE "user" (
|
||||
"user_id" SERIAL,
|
||||
"name" VARCHAR(255) NULL,
|
||||
"email" VARCHAR(255) NULL,
|
||||
"password_hash" VARCHAR NULL,
|
||||
"last_logged_on" TIMESTAMP NULL,
|
||||
"user_settings_id" INTEGER NULL,
|
||||
PRIMARY KEY ("user_id")
|
||||
);
|
||||
ALTER TABLE "preparation_step" ADD FOREIGN KEY ("recipe_id") REFERENCES "recipe" ("recipe_id");
|
||||
ALTER TABLE "preparation_step" ADD FOREIGN KEY ("language_id") REFERENCES "language" ("language_id");
|
||||
ALTER TABLE "recipe" ADD FOREIGN KEY ("user_id") REFERENCES "user" ("user_id");
|
||||
ALTER TABLE "recipe" ADD FOREIGN KEY ("language_id") REFERENCES "language" ("language_id");
|
||||
ALTER TABLE "recipe_has_ingredient" ADD FOREIGN KEY ("recipe_id") REFERENCES "recipe" ("recipe_id");
|
||||
ALTER TABLE "recipe_has_ingredient" ADD FOREIGN KEY ("unit_id") REFERENCES "unit" ("unit_id");
|
||||
ALTER TABLE "recipe_photo" ADD FOREIGN KEY ("recipe_id") REFERENCES "recipe" ("recipe_id");
|
||||
ALTER TABLE "recipe_photo" ADD FOREIGN KEY ("user_id") REFERENCES "user" ("user_id");
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user