mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-27 07:56:28 +00:00
export model - filter by schema
This commit is contained in:
@@ -49,7 +49,6 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"line-reader": "^0.4.0",
|
"line-reader": "^0.4.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mkdirp": "^3.0.1",
|
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"node-cron": "^2.0.3",
|
"node-cron": "^2.0.3",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const {
|
|||||||
modelCompareDbDiffOptions,
|
modelCompareDbDiffOptions,
|
||||||
getLogger,
|
getLogger,
|
||||||
extractErrorLogData,
|
extractErrorLogData,
|
||||||
|
filterStructureBySchema,
|
||||||
} = require('dbgate-tools');
|
} = require('dbgate-tools');
|
||||||
const { html, parse } = require('diff2html');
|
const { html, parse } = require('diff2html');
|
||||||
const { handleProcessCommunication } = require('../utility/processComm');
|
const { handleProcessCommunication } = require('../utility/processComm');
|
||||||
@@ -448,7 +449,8 @@ module.exports = {
|
|||||||
: outputFolder;
|
: outputFolder;
|
||||||
|
|
||||||
const model = await this.structure({ conid, database });
|
const model = await this.structure({ conid, database });
|
||||||
await exportDbModel(extendDatabaseInfo(model), realFolder);
|
const filteredModel = schema ? filterStructureBySchema(model, schema) : model;
|
||||||
|
await exportDbModel(extendDatabaseInfo(filteredModel), realFolder);
|
||||||
|
|
||||||
if (outputFolder.startsWith('archive:')) {
|
if (outputFolder.startsWith('archive:')) {
|
||||||
socket.emitChanged(`archive-files-changed`, { folder: outputFolder.substring('archive:'.length) });
|
socket.emitChanged(`archive-files-changed`, { folder: outputFolder.substring('archive:'.length) });
|
||||||
@@ -457,14 +459,15 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
exportModelSql_meta: true,
|
exportModelSql_meta: true,
|
||||||
async exportModelSql({ conid, database, outputFolder, outputFile }, req) {
|
async exportModelSql({ conid, database, outputFolder, outputFile, schema }, req) {
|
||||||
testConnectionPermission(conid, req);
|
testConnectionPermission(conid, req);
|
||||||
|
|
||||||
const connection = await connections.getCore({ conid });
|
const connection = await connections.getCore({ conid });
|
||||||
const driver = requireEngineDriver(connection);
|
const driver = requireEngineDriver(connection);
|
||||||
|
|
||||||
const model = await this.structure({ conid, database });
|
const model = await this.structure({ conid, database });
|
||||||
await exportDbModelSql(extendDatabaseInfo(model), driver, outputFolder, outputFile);
|
const filteredModel = schema ? filterStructureBySchema(model, schema) : model;
|
||||||
|
await exportDbModelSql(extendDatabaseInfo(filteredModel), driver, outputFolder, outputFile);
|
||||||
|
|
||||||
return { status: 'ok' };
|
return { status: 'ok' };
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const yaml = require('js-yaml');
|
const { getSchemasUsedByStructure } = require('dbgate-tools');
|
||||||
const { mkdirp } = require('mkdirp');
|
|
||||||
|
|
||||||
async function exportDbModelSql(dbModel, driver, outputDir, outputFile) {
|
async function exportDbModelSql(dbModel, driver, outputDir, outputFile) {
|
||||||
const { tables, views, procedures, functions, triggers, matviews } = dbModel;
|
const { tables, views, procedures, functions, triggers, matviews } = dbModel;
|
||||||
|
|
||||||
|
const usedSchemas = getSchemasUsedByStructure(dbModel);
|
||||||
|
const useSchemaDir = usedSchemas.length > 1;
|
||||||
|
|
||||||
|
const createdDirs = new Set();
|
||||||
|
async function ensureDir(dir) {
|
||||||
|
if (!createdDirs.has(dir)) {
|
||||||
|
await fs.mkdir(dir, { recursive: true });
|
||||||
|
createdDirs.add(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function writeLists(writeList) {
|
async function writeLists(writeList) {
|
||||||
await writeList(views, 'views');
|
await writeList(views, 'views');
|
||||||
await writeList(procedures, 'procedures');
|
await writeList(procedures, 'procedures');
|
||||||
@@ -39,25 +49,29 @@ async function exportDbModelSql(dbModel, driver, outputDir, outputFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (outputDir) {
|
if (outputDir) {
|
||||||
await mkdirp(path.join(outputDir, 'tables'));
|
|
||||||
for (const table of tables || []) {
|
for (const table of tables || []) {
|
||||||
|
const tablesDir = useSchemaDir
|
||||||
|
? path.join(outputDir, table.schemaName ?? 'default', 'tables')
|
||||||
|
: path.join(outputDir, 'tables');
|
||||||
|
await ensureDir(tablesDir);
|
||||||
const dmp = driver.createDumper();
|
const dmp = driver.createDumper();
|
||||||
dmp.createTable({
|
dmp.createTable({
|
||||||
...table,
|
...table,
|
||||||
foreignKeys: [],
|
foreignKeys: [],
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
});
|
});
|
||||||
await fs.writeFile(path.join(outputDir, 'tables', `${table.pureName}.sql`), dmp.s);
|
await fs.writeFile(path.join(tablesDir, `${table.pureName}.sql`), dmp.s);
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeLists(async (list, folder) => {
|
await writeLists(async (list, folder) => {
|
||||||
if (list.length > 0) {
|
|
||||||
await mkdirp(path.join(outputDir, folder));
|
|
||||||
}
|
|
||||||
for (const obj of list || []) {
|
for (const obj of list || []) {
|
||||||
|
const objdir = useSchemaDir
|
||||||
|
? path.join(outputDir, obj.schemaName ?? 'default', folder)
|
||||||
|
: path.join(outputDir, folder);
|
||||||
|
await ensureDir(objdir);
|
||||||
const dmp = driver.createDumper();
|
const dmp = driver.createDumper();
|
||||||
dmp.createSqlObject(obj);
|
dmp.createSqlObject(obj);
|
||||||
await fs.writeFile(path.join(outputDir, folder, `${obj.pureName}.sql`), dmp.s);
|
await fs.writeFile(path.join(objdir, `${obj.pureName}.sql`), dmp.s);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { DatabaseInfo, TableInfo, ApplicationDefinition, ViewInfo, CollectionInfo } from 'dbgate-types';
|
import type { DatabaseInfo, TableInfo, ApplicationDefinition, ViewInfo, CollectionInfo } from 'dbgate-types';
|
||||||
import _flatten from 'lodash/flatten';
|
import _flatten from 'lodash/flatten';
|
||||||
|
import _uniq from 'lodash/uniq';
|
||||||
|
|
||||||
export function addTableDependencies(db: DatabaseInfo): DatabaseInfo {
|
export function addTableDependencies(db: DatabaseInfo): DatabaseInfo {
|
||||||
if (!db.tables) {
|
if (!db.tables) {
|
||||||
@@ -142,3 +143,28 @@ export function isViewInfo(obj: { objectTypeField?: string }): obj is ViewInfo {
|
|||||||
export function isCollectionInfo(obj: { objectTypeField?: string }): obj is CollectionInfo {
|
export function isCollectionInfo(obj: { objectTypeField?: string }): obj is CollectionInfo {
|
||||||
return obj.objectTypeField == 'collections';
|
return obj.objectTypeField == 'collections';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function filterStructureBySchema(db: DatabaseInfo, schema: string) {
|
||||||
|
return {
|
||||||
|
...db,
|
||||||
|
tables: (db.tables || []).filter(x => x.schemaName == schema),
|
||||||
|
views: (db.views || []).filter(x => x.schemaName == schema),
|
||||||
|
collections: (db.collections || []).filter(x => x.schemaName == schema),
|
||||||
|
matviews: (db.matviews || []).filter(x => x.schemaName == schema),
|
||||||
|
procedures: (db.procedures || []).filter(x => x.schemaName == schema),
|
||||||
|
functions: (db.functions || []).filter(x => x.schemaName == schema),
|
||||||
|
triggers: (db.triggers || []).filter(x => x.schemaName == schema),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSchemasUsedByStructure(db: DatabaseInfo) {
|
||||||
|
return _uniq([
|
||||||
|
...(db.tables || []).map(x => x.schemaName),
|
||||||
|
...(db.views || []).map(x => x.schemaName),
|
||||||
|
...(db.collections || []).map(x => x.schemaName),
|
||||||
|
...(db.matviews || []).map(x => x.schemaName),
|
||||||
|
...(db.procedures || []).map(x => x.schemaName),
|
||||||
|
...(db.functions || []).map(x => x.schemaName),
|
||||||
|
...(db.triggers || []).map(x => x.schemaName),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|||||||
1
packages/types/dbinfo.d.ts
vendored
1
packages/types/dbinfo.d.ts
vendored
@@ -3,7 +3,6 @@ export interface NamedObjectInfo {
|
|||||||
schemaName?: string;
|
schemaName?: string;
|
||||||
contentHash?: string;
|
contentHash?: string;
|
||||||
engine?: string;
|
engine?: string;
|
||||||
undropPureName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColumnReference {
|
export interface ColumnReference {
|
||||||
|
|||||||
@@ -8390,11 +8390,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
mkdirp@^3.0.1:
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50"
|
|
||||||
integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==
|
|
||||||
|
|
||||||
moment@^2.24.0, moment@^2.29.2:
|
moment@^2.24.0, moment@^2.29.2:
|
||||||
version "2.30.1"
|
version "2.30.1"
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
||||||
|
|||||||
Reference in New Issue
Block a user