refactor - default dbaget engine mvoed to dbgate-tools

This commit is contained in:
Jan Prochazka
2020-11-23 20:49:25 +01:00
parent d3cfc44fd9
commit 88cf6d35ed
16 changed files with 115 additions and 131 deletions

View File

@@ -2,7 +2,7 @@ const uuidv1 = require('uuid/v1');
const connections = require('./connections'); const connections = require('./connections');
const socket = require('../utility/socket'); const socket = require('../utility/socket');
const { fork } = require('child_process'); const { fork } = require('child_process');
const DatabaseAnalyser = require('dbgate-engines/default/DatabaseAnalyser'); const { DatabaseAnalyser } = require('dbgate-tools');
module.exports = { module.exports = {
/** @type {import('dbgate-types').OpenedDatabaseConnection[]} */ /** @type {import('dbgate-types').OpenedDatabaseConnection[]} */

View File

@@ -2,7 +2,7 @@ const fp = require('lodash/fp');
const _ = require('lodash'); const _ = require('lodash');
const sql = require('./sql'); const sql = require('./sql');
const DatabaseAnalyser = require('../default/DatabaseAnalyser'); const { DatabaseAnalyser } = require('dbgate-tools');
const { filter } = require('lodash'); const { filter } = require('lodash');
const { isTypeString, isTypeNumeric } = require('dbgate-tools'); const { isTypeString, isTypeNumeric } = require('dbgate-tools');

View File

@@ -1,4 +1,4 @@
const SqlDumper = require('../default/SqlDumper'); const { SqlDumper } = require('dbgate-tools');
class MsSqlDumper extends SqlDumper { class MsSqlDumper extends SqlDumper {
autoIncrement() { autoIncrement() {

View File

@@ -1,4 +1,4 @@
const createBulkInsertStreamBase = require('../default/createBulkInsertStreamBase'); const { createBulkInsertStreamBase } = require('dbgate-tools');
/** /**
* *

View File

@@ -1,8 +1,8 @@
const _ = require('lodash'); const _ = require('lodash');
const { driverBase } = require('dbgate-tools');
const MsSqlAnalyser = require('./MsSqlAnalyser'); const MsSqlAnalyser = require('./MsSqlAnalyser');
const MsSqlDumper = require('./MsSqlDumper'); const MsSqlDumper = require('./MsSqlDumper');
const createBulkInsertStream = require('./createBulkInsertStream'); const createBulkInsertStream = require('./createBulkInsertStream');
const driverBase = require('../default/driverBase');
/** @type {import('dbgate-types').SqlDialect} */ /** @type {import('dbgate-types').SqlDialect} */
const dialect = { const dialect = {

View File

@@ -2,7 +2,7 @@ const fp = require('lodash/fp');
const _ = require('lodash'); const _ = require('lodash');
const sql = require('./sql'); const sql = require('./sql');
const DatabaseAnalayser = require('../default/DatabaseAnalyser'); const { DatabaseAnalyser } = require('dbgate-tools');
const { isTypeString, isTypeNumeric } = require('dbgate-tools'); const { isTypeString, isTypeNumeric } = require('dbgate-tools');
const { rangeStep } = require('lodash/fp'); const { rangeStep } = require('lodash/fp');
@@ -35,7 +35,7 @@ function objectTypeToField(type) {
return null; return null;
} }
class MySqlAnalyser extends DatabaseAnalayser { class MySqlAnalyser extends DatabaseAnalyser {
constructor(pool, driver) { constructor(pool, driver) {
super(pool, driver); super(pool, driver);
} }
@@ -103,8 +103,8 @@ class MySqlAnalyser extends DatabaseAnalayser {
tables: tables.rows.map((table) => ({ tables: tables.rows.map((table) => ({
...table, ...table,
columns: columns.rows.filter((col) => col.pureName == table.pureName).map(getColumnInfo), columns: columns.rows.filter((col) => col.pureName == table.pureName).map(getColumnInfo),
primaryKey: DatabaseAnalayser.extractPrimaryKeys(table, pkColumns.rows), primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
foreignKeys: DatabaseAnalayser.extractForeignKeys(table, fkColumns.rows), foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
})), })),
views: views.rows.map((view) => ({ views: views.rows.map((view) => ({
...view, ...view,

View File

@@ -1,4 +1,4 @@
const SqlDumper = require('../default/SqlDumper'); const { SqlDumper } = require('dbgate-tools');
class MySqlDumper extends SqlDumper { class MySqlDumper extends SqlDumper {
/** @param type {import('dbgate-types').TransformType} */ /** @param type {import('dbgate-types').TransformType} */

View File

@@ -1,4 +1,4 @@
const driverBase = require('../default/driverBase'); const { driverBase } = require('dbgate-tools');
const MySqlAnalyser = require('./MySqlAnalyser'); const MySqlAnalyser = require('./MySqlAnalyser');
const MySqlDumper = require('./MySqlDumper'); const MySqlDumper = require('./MySqlDumper');
@@ -143,6 +143,12 @@ const driver = {
const { rows } = await this.query(connection, 'show databases'); const { rows } = await this.query(connection, 'show databases');
return rows.map((x) => ({ name: x.Database })); return rows.map((x) => ({ name: x.Database }));
}, },
async writeTable(pool, name, options) {
const { stream } = pool._nativeModules;
// @ts-ignore
return createBulkInsertStreamBase(this, stream, pool, name, options);
},
// createDumper() { // createDumper() {
// return new MySqlDumper(this); // return new MySqlDumper(this);
// }, // },

View File

@@ -2,7 +2,7 @@ const fp = require('lodash/fp');
const _ = require('lodash'); const _ = require('lodash');
const sql = require('./sql'); const sql = require('./sql');
const DatabaseAnalayser = require('../default/DatabaseAnalyser'); const { DatabaseAnalyser } = require('dbgate-tools');
const { isTypeString, isTypeNumeric } = require('dbgate-tools'); const { isTypeString, isTypeNumeric } = require('dbgate-tools');
function normalizeTypeName(dataType) { function normalizeTypeName(dataType) {
@@ -35,7 +35,7 @@ function getColumnInfo({
}; };
} }
class PostgreAnalyser extends DatabaseAnalayser { class PostgreAnalyser extends DatabaseAnalyser {
constructor(pool, driver) { constructor(pool, driver) {
super(pool, driver); super(pool, driver);
} }
@@ -84,8 +84,8 @@ class PostgreAnalyser extends DatabaseAnalayser {
columns: columns.rows columns: columns.rows
.filter((col) => col.pureName == table.pureName && col.schemaName == table.schemaName) .filter((col) => col.pureName == table.pureName && col.schemaName == table.schemaName)
.map(getColumnInfo), .map(getColumnInfo),
primaryKey: DatabaseAnalayser.extractPrimaryKeys(table, pkColumns.rows), primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows),
foreignKeys: DatabaseAnalayser.extractForeignKeys(table, fkColumns.rows), foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows),
})), })),
views: views.rows.map((view) => ({ views: views.rows.map((view) => ({
...view, ...view,

View File

@@ -1,4 +1,4 @@
const SqlDumper = require('../default/SqlDumper'); const { SqlDumper } = require('dbgate-tools');
class PostgreDumper extends SqlDumper { class PostgreDumper extends SqlDumper {
/** @param type {import('dbgate-types').TransformType} */ /** @param type {import('dbgate-types').TransformType} */

View File

@@ -1,5 +1,5 @@
const _ = require('lodash'); const _ = require('lodash');
const driverBase = require('../default/driverBase'); const { driverBase } = require('dbgate-tools');
const PostgreAnalyser = require('./PostgreAnalyser'); const PostgreAnalyser = require('./PostgreAnalyser');
const PostgreDumper = require('./PostgreDumper'); const PostgreDumper = require('./PostgreDumper');
@@ -174,6 +174,11 @@ const driver = {
// createDumper() { // createDumper() {
// return new PostgreDumper(this); // return new PostgreDumper(this);
// }, // },
async writeTable(pool, name, options) {
const { stream } = pool._nativeModules;
// @ts-ignore
return createBulkInsertStreamBase(this, stream, pool, name, options);
},
async listDatabases(client) { async listDatabases(client) {
const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false'); const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false');
return rows; return rows;

View File

@@ -1,21 +1,13 @@
const _ = require('lodash'); import { DatabaseInfo, DatabaseModification, EngineDriver } from 'dbgate-types';
const fp = require('lodash/fp'); import _ from 'lodash';
import fp from 'lodash/fp';
class DatabaseAnalyser { export class DatabaseAnalyser {
/** structure: DatabaseInfo;
* modifications: DatabaseModification[];
* @param {import('dbgate-types').EngineDriver} driver singleObjectFilter: any;
*/
constructor(pool, driver) { constructor(public pool, public driver: EngineDriver) {}
this.pool = pool;
this.driver = driver;
// this.result = DatabaseAnalyser.createEmptyStructure();
/** @type {import('dbgate-types').DatabaseInfo} */
this.structure = null;
/** import('dbgate-types').DatabaseModification[]) */
this.modifications = null;
this.singleObjectFilter = null;
}
async _runAnalysis() { async _runAnalysis() {
return DatabaseAnalyser.createEmptyStructure(); return DatabaseAnalyser.createEmptyStructure();
@@ -80,46 +72,46 @@ class DatabaseAnalyser {
// findObjectById(id) { // findObjectById(id) {
// return this.structure.tables.find((x) => x.objectId == id); // return this.structure.tables.find((x) => x.objectId == id);
// } // }
static createEmptyStructure(): DatabaseInfo {
return {
tables: [],
views: [],
functions: [],
procedures: [],
triggers: [],
schemas: [],
};
}
static byTableFilter(table) {
return (x) => x.pureName == table.pureName && x.schemaName == x.schemaName;
}
static extractPrimaryKeys(table, pkColumns) {
const filtered = pkColumns.filter(DatabaseAnalyser.byTableFilter(table));
if (filtered.length == 0) return undefined;
return {
..._.pick(filtered[0], ['constraintName', 'schemaName', 'pureName']),
constraintType: 'primaryKey',
columns: filtered.map(fp.pick('columnName')),
};
}
static extractForeignKeys(table, fkColumns) {
const grouped = _.groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName');
return _.keys(grouped).map((constraintName) => ({
constraintName,
constraintType: 'foreignKey',
..._.pick(grouped[constraintName][0], [
'constraintName',
'schemaName',
'pureName',
'refSchemaName',
'refTableName',
'updateAction',
'deleteAction',
]),
columns: grouped[constraintName].map(fp.pick(['columnName', 'refColumnName'])),
}));
}
} }
/** @returns {import('dbgate-types').DatabaseInfo} */
DatabaseAnalyser.createEmptyStructure = () => ({
tables: [],
views: [],
functions: [],
procedures: [],
triggers: [],
schemas: [],
});
DatabaseAnalyser.byTableFilter = (table) => (x) => x.pureName == table.pureName && x.schemaName == x.schemaName;
DatabaseAnalyser.extractPrimaryKeys = (table, pkColumns) => {
const filtered = pkColumns.filter(DatabaseAnalyser.byTableFilter(table));
if (filtered.length == 0) return undefined;
return {
..._.pick(filtered[0], ['constraintName', 'schemaName', 'pureName']),
constraintType: 'primaryKey',
columns: filtered.map(fp.pick('columnName')),
};
};
DatabaseAnalyser.extractForeignKeys = (table, fkColumns) => {
const grouped = _.groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName');
return _.keys(grouped).map((constraintName) => ({
constraintName,
constraintType: 'foreignKey',
..._.pick(grouped[constraintName][0], [
'constraintName',
'schemaName',
'pureName',
'refSchemaName',
'refTableName',
'updateAction',
'deleteAction',
]),
columns: grouped[constraintName].map(fp.pick(['columnName', 'refColumnName'])),
}));
};
module.exports = DatabaseAnalyser;

View File

@@ -1,13 +1,24 @@
const _ = require('lodash'); import {
const moment = require('moment'); ColumnInfo,
EngineDriver,
ForeignKeyInfo,
NamedObjectInfo,
SqlDialect,
TableInfo,
TransformType,
} from 'dbgate-types';
import _ from 'lodash';
import moment from 'moment';
class SqlDumper { export class SqlDumper {
/** @param driver {import('dbgate-types').EngineDriver} */ s = '';
constructor(driver) { driver: EngineDriver;
this.s = ''; dialect: SqlDialect;
indentLevel = 0;
constructor(driver: EngineDriver) {
this.driver = driver; this.driver = driver;
this.dialect = driver.dialect; this.dialect = driver.dialect;
this.indentLevel = 0;
} }
endCommand() { endCommand() {
this.putRaw(';\n'); this.putRaw(';\n');
@@ -85,8 +96,7 @@ class SqlDumper {
if (!collection) return; if (!collection) return;
this.putCollection(', ', collection, (item) => this.putFormattedValue(c, item)); this.putCollection(', ', collection, (item) => this.putFormattedValue(c, item));
} }
/** @param format {string} */ put(format: string, ...args) {
put(format, ...args) {
let i = 0; let i = 0;
let argIndex = 0; let argIndex = 0;
const length = format.length; const length = format.length;
@@ -149,10 +159,7 @@ class SqlDumper {
this.put(' ^auto_increment'); this.put(' ^auto_increment');
} }
/** columnDefinition(column: ColumnInfo, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) {
* @param column {import('dbgate-types').ColumnInfo}
*/
columnDefinition(column, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) {
if (column.computedExpression) { if (column.computedExpression) {
this.put('^as %s', column.computedExpression); this.put('^as %s', column.computedExpression);
if (column.isPersisted) this.put(' ^persisted'); if (column.isPersisted) this.put(' ^persisted');
@@ -175,10 +182,7 @@ class SqlDumper {
} }
} }
/** columnDefault(column: ColumnInfo) {
* @param column {import('dbgate-types').ColumnInfo}
*/
columnDefault(column) {
if (column.defaultConstraint != null) { if (column.defaultConstraint != null) {
this.put(' ^constraint %i ^default %s ', column.defaultConstraint, column.defaultValue); this.put(' ^constraint %i ^default %s ', column.defaultConstraint, column.defaultValue);
} else { } else {
@@ -186,13 +190,7 @@ class SqlDumper {
} }
} }
/** putCollection<T>(delimiter: string, collection: T[], lambda: (col: T) => void) {
* @template T
* @param {string} delimiter
* @param {T[]} collection
* @param {(col: T) => void} lambda
*/
putCollection(delimiter, collection, lambda) {
if (!collection) return; if (!collection) return;
let first = true; let first = true;
for (const item of collection) { for (const item of collection) {
@@ -202,8 +200,7 @@ class SqlDumper {
} }
} }
/** @param table {import('dbgate-types').TableInfo} */ createTable(table: TableInfo) {
createTable(table) {
this.put('^create ^table %f ( &>&n', table); this.put('^create ^table %f ( &>&n', table);
this.putCollection(',&n', table.columns, (col) => { this.putCollection(',&n', table.columns, (col) => {
this.put('%i ', col.columnName); this.put('%i ', col.columnName);
@@ -245,8 +242,7 @@ class SqlDumper {
// } // }
} }
/** @param fk {import('dbgate-types').ForeignKeyInfo} */ createForeignKeyFore(fk: ForeignKeyInfo) {
createForeignKeyFore(fk) {
if (fk.constraintName != null) this.put('^constraint %i ', fk.constraintName); if (fk.constraintName != null) this.put('^constraint %i ', fk.constraintName);
this.put( this.put(
'^foreign ^key (%,i) ^references %f (%,i)', '^foreign ^key (%,i) ^references %f (%,i)',
@@ -258,16 +254,9 @@ class SqlDumper {
if (fk.updateAction) this.put(' ^on ^update %k', fk.updateAction); if (fk.updateAction) this.put(' ^on ^update %k', fk.updateAction);
} }
/** @param type {import('dbgate-types').TransformType} */ transform(type: TransformType, dumpExpr) {
transform(type, dumpExpr) {
dumpExpr(); dumpExpr();
} }
/** allowIdentityInsert(table: NamedObjectInfo, allow: boolean) {}
* @param table {import('dbgate-types').NamedObjectInfo}
* @param allow {boolean}
*/
allowIdentityInsert(table, allow) {}
} }
module.exports = SqlDumper;

View File

@@ -1,11 +1,8 @@
const { prepareTableForImport } = require('dbgate-tools'); import { EngineDriver } from 'dbgate-types';
const _ = require('lodash'); import _ from 'lodash';
import { prepareTableForImport } from './tableTransforms';
/** export function createBulkInsertStreamBase(driver, stream, pool, name, options): any {
*
* @param {import('dbgate-types').EngineDriver} driver
*/
function createBulkInsertStreamBase(driver, stream, pool, name, options) {
const fullNameQuoted = name.schemaName const fullNameQuoted = name.schemaName
? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}` ? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}`
: driver.dialect.quoteIdentifier(name.pureName); : driver.dialect.quoteIdentifier(name.pureName);
@@ -94,5 +91,3 @@ function createBulkInsertStreamBase(driver, stream, pool, name, options) {
return writable; return writable;
} }
module.exports = createBulkInsertStreamBase;

View File

@@ -1,6 +1,6 @@
const createBulkInsertStreamBase = require('./createBulkInsertStreamBase'); import { createBulkInsertStreamBase } from './createBulkInsertStreamBase';
const driverBase = { export const driverBase = {
analyserClass: null, analyserClass: null,
dumperClass: null, dumperClass: null,
@@ -24,11 +24,4 @@ const driverBase = {
createDumper() { createDumper() {
return new this.dumperClass(this); return new this.dumperClass(this);
}, },
async writeTable(pool, name, options) {
const { stream, mssql } = pool._nativeModules;
// @ts-ignore
return createBulkInsertStreamBase(this, stream, pool, name, options);
},
}; };
module.exports = driverBase;

View File

@@ -2,3 +2,7 @@ export * from './commonTypeParser';
export * from './nameTools'; export * from './nameTools';
export * from './tableTransforms'; export * from './tableTransforms';
export * from './packageTools'; export * from './packageTools';
export * from './createBulkInsertStreamBase';
export * from './DatabaseAnalyser';
export * from './driverBase';
export * from './SqlDumper';