mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 22:36:01 +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 dumpDatabase = require('./dumpDatabase');
|
||||||
const importDatabase = require('./importDatabase');
|
const importDatabase = require('./importDatabase');
|
||||||
const loadDatabase = require('./loadDatabase');
|
const loadDatabase = require('./loadDatabase');
|
||||||
|
const generateModelSql = require('./generateModelSql');
|
||||||
|
|
||||||
const dbgateApi = {
|
const dbgateApi = {
|
||||||
queryReader,
|
queryReader,
|
||||||
@@ -51,6 +52,7 @@ const dbgateApi = {
|
|||||||
dumpDatabase,
|
dumpDatabase,
|
||||||
importDatabase,
|
importDatabase,
|
||||||
loadDatabase,
|
loadDatabase,
|
||||||
|
generateModelSql,
|
||||||
};
|
};
|
||||||
|
|
||||||
requirePlugin.initializeDbgateApi(dbgateApi);
|
requirePlugin.initializeDbgateApi(dbgateApi);
|
||||||
|
|||||||
@@ -43,41 +43,15 @@ Model is stored as a collection of files:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
# load from existing database
|
# 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
|
# 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
|
# 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
|
## Table yaml file documentation
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|||||||
@@ -10,8 +10,21 @@ global.PLUGINS_DIR = process.env.DEVMODE
|
|||||||
global.IS_NPM_DIST = true;
|
global.IS_NPM_DIST = true;
|
||||||
|
|
||||||
const program = require('commander');
|
const program = require('commander');
|
||||||
const dbmodel = require('../lib');
|
|
||||||
const dbgateApi = require('dbgate-api');
|
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
|
program
|
||||||
.option('-s, --server <server>', 'server host')
|
.option('-s, --server <server>', 'server host')
|
||||||
@@ -26,14 +39,15 @@ program
|
|||||||
.requiredOption('-e, --engine <engine>', 'engine name, eg. mysql@dbgate-plugin-mysql');
|
.requiredOption('-e, --engine <engine>', 'engine name, eg. mysql@dbgate-plugin-mysql');
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('deploy <projectDir>')
|
.command('deploy <modelFolder>')
|
||||||
.description('Deploys model to database')
|
.description('Deploys model to database')
|
||||||
.action(projectDir => {
|
.action(modelFolder => {
|
||||||
const { engine, server, user, password, database } = program;
|
const { engine, server, user, password, database } = program.opts();
|
||||||
const hooks = [];
|
// const hooks = [];
|
||||||
if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
|
// if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
|
||||||
dbmodel.runAndExit(
|
|
||||||
dbmodel.deploy({
|
runAndExit(
|
||||||
|
dbgateApi.deployDb({
|
||||||
connection: {
|
connection: {
|
||||||
engine,
|
engine,
|
||||||
server,
|
server,
|
||||||
@@ -41,12 +55,25 @@ program
|
|||||||
password,
|
password,
|
||||||
database,
|
database,
|
||||||
},
|
},
|
||||||
hooks,
|
modelFolder,
|
||||||
projectDir,
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// runAndExit(
|
||||||
|
// dbmodel.deploy({
|
||||||
|
// connection: {
|
||||||
|
// engine,
|
||||||
|
// server,
|
||||||
|
// user,
|
||||||
|
// password,
|
||||||
|
// database,
|
||||||
|
// },
|
||||||
|
// hooks,
|
||||||
|
// projectDir,
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('load <outputDir>')
|
.command('load <outputDir>')
|
||||||
.description('Loads model from database')
|
.description('Loads model from database')
|
||||||
@@ -57,7 +84,7 @@ program
|
|||||||
// : null;
|
// : null;
|
||||||
// const hooks = [];
|
// const hooks = [];
|
||||||
|
|
||||||
dbmodel.runAndExit(
|
runAndExit(
|
||||||
dbgateApi.loadDatabase({
|
dbgateApi.loadDatabase({
|
||||||
connection: {
|
connection: {
|
||||||
engine,
|
engine,
|
||||||
@@ -72,17 +99,18 @@ program
|
|||||||
});
|
});
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('build <projectDir> <outputFile>')
|
.command('build <modelFolder> <outputFile>')
|
||||||
.description('Builds single SQL script from project')
|
.description('Builds single SQL script from project')
|
||||||
.action((projectDir, outputFile) => {
|
.action((modelFolder, outputFile) => {
|
||||||
const { client } = program;
|
const { engine } = program.opts();
|
||||||
const hooks = [];
|
// const hooks = [];
|
||||||
dbmodel.runAndExit(
|
runAndExit(
|
||||||
dbmodel.build({
|
dbgateApi.generateModelSql({
|
||||||
client,
|
// client,
|
||||||
hooks,
|
// hooks,
|
||||||
projectDir,
|
modelFolder,
|
||||||
outputFile,
|
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": {
|
"scripts": {
|
||||||
"dbmodel": "node ./bin/dbmodel.js",
|
"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": {
|
"dependencies": {
|
||||||
"commander": "^10.0.0",
|
"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