load db drivers on demand

This commit is contained in:
Kononnable 2020-03-15 00:41:35 +01:00
parent e0a35280c3
commit c84798e8bf
7 changed files with 120 additions and 63 deletions

View File

@ -13,7 +13,7 @@
"test": "nyc --reporter=lcov ts-node ./node_modules/mocha/bin/_mocha test/**/*.test.ts -- --bail",
"posttest": "eslint ./src/**/*.ts ./test/**/*.ts",
"clean": "rimraf coverage output dist",
"prettier": "prettier --write ./src/*.ts ./src/**/*.ts"
"prettier": "echo Disabled until import type syntax is supported. || prettier --write ./src/*.ts ./src/**/*.ts"
},
"repository": {
"type": "git",

View File

@ -1,4 +1,4 @@
import * as MSSQL from "mssql";
import type * as MSSQL from "mssql";
import { ConnectionOptions } from "typeorm";
import * as TypeormDriver from "typeorm/driver/sqlserver/SqlServerDriver";
import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults";
@ -22,14 +22,27 @@ export default class MssqlDriver extends AbstractDriver {
public readonly standardUser = "sa";
private MSSQL: typeof MSSQL;
private Connection: MSSQL.ConnectionPool;
public constructor() {
super();
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
this.MSSQL = require("mssql");
} catch (error) {
TomgUtils.LogError("", false, error);
throw error;
}
}
public GetAllTablesQuery = async (
schema: string,
dbNames: string,
tableNames: string[]
) => {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
const tableCondition =
tableNames.length > 0
? ` AND NOT TABLE_NAME IN ('${tableNames.join("','")}')`
@ -54,7 +67,7 @@ WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG
schema: string,
dbNames: string
): Promise<Entity[]> {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
const response: {
TABLE_NAME: string;
COLUMN_NAME: string;
@ -253,7 +266,7 @@ WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG
schema: string,
dbNames: string
): Promise<Entity[]> {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
const response: {
TableName: string;
TableSchema: string;
@ -333,7 +346,7 @@ WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG
dbNames: string,
generationOptions: IGenerationOptions
): Promise<Entity[]> {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
const response: {
TableWithForeignKey: string;
FK_PartNo: number;
@ -469,7 +482,7 @@ WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG
};
const promise = new Promise<boolean>((resolve, reject) => {
this.Connection = new MSSQL.ConnectionPool(config, err => {
this.Connection = new this.MSSQL.ConnectionPool(config, err => {
if (!err) {
resolve(true);
} else {
@ -487,22 +500,22 @@ WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG
}
public async CreateDB(dbName: string) {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
await request.query(`CREATE DATABASE ${dbName}; `);
}
public async UseDB(dbName: string) {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
await request.query(`USE ${dbName}; `);
}
public async DropDB(dbName: string) {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
await request.query(`DROP DATABASE ${dbName}; `);
}
public async CheckIfDBExists(dbName: string): Promise<boolean> {
const request = new MSSQL.Request(this.Connection);
const request = new this.MSSQL.Request(this.Connection);
const resp = await request.query(
`SELECT name FROM master.sys.databases WHERE name = N'${dbName}' `
);

View File

@ -1,4 +1,4 @@
import * as MYSQL from "mysql";
import type * as MYSQL from "mysql";
import { ConnectionOptions } from "typeorm";
import * as TypeormDriver from "typeorm/driver/mysql/MysqlDriver";
import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults";
@ -24,8 +24,21 @@ export default class MysqlDriver extends AbstractDriver {
public readonly standardSchema = "";
private MYSQL: typeof MYSQL;
private Connection: MYSQL.Connection;
public constructor() {
super();
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
this.MYSQL = require("mysql");
} catch (error) {
TomgUtils.LogError("", false, error);
throw error;
}
}
public GetAllTablesQuery = async (
schema: string,
dbNames: string,
@ -458,7 +471,7 @@ export default class MysqlDriver extends AbstractDriver {
}
const promise = new Promise<boolean>((resolve, reject) => {
this.Connection = MYSQL.createConnection(config);
this.Connection = this.MYSQL.createConnection(config);
this.Connection.connect(err => {
if (!err) {

View File

@ -1,3 +1,5 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import type * as Oracle from "oracledb"
import * as TypeormDriver from "typeorm/driver/oracle/OracleDriver";
import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults";
import * as TomgUtils from "../Utils";
@ -20,16 +22,16 @@ export default class OracleDriver extends AbstractDriver {
public readonly standardSchema = "";
public Oracle: any;
private Oracle: typeof Oracle;
private Connection: any /* Oracle.IConnection */;
private Connection: Oracle.Connection;
public constructor() {
super();
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
this.Oracle = require("oracledb");
this.Oracle.outFormat = this.Oracle.OBJECT;
this.Oracle.outFormat = (this.Oracle as any).OBJECT;
} catch (error) {
TomgUtils.LogError("", false, error);
throw error;
@ -45,12 +47,11 @@ export default class OracleDriver extends AbstractDriver {
tableNames.length > 0
? ` AND NOT TABLE_NAME IN ('${tableNames.join("','")}')`
: "";
const response: {
TABLE_SCHEMA: string;
const response= (
await this.Connection.execute<{
TABLE_SCHEMA: string;
TABLE_NAME: string;
DB_NAME: string;
}[] = (
await this.Connection.execute(
DB_NAME: string;}>(
`SELECT NULL AS TABLE_SCHEMA, TABLE_NAME, NULL AS DB_NAME FROM all_tables WHERE owner = (select user from dual) ${tableCondition}`
)
).rows!;
@ -58,20 +59,20 @@ export default class OracleDriver extends AbstractDriver {
};
public async GetCoulmnsFromEntity(entities: Entity[]): Promise<Entity[]> {
const response: {
TABLE_NAME: string;
COLUMN_NAME: string;
DATA_DEFAULT: string;
NULLABLE: string;
DATA_TYPE: string;
DATA_LENGTH: number;
DATA_PRECISION: number;
DATA_SCALE: number;
IDENTITY_COLUMN: string; // doesn't exist in old oracle versions (#195)
IS_UNIQUE: number;
}[] = (
const response = (
await this.Connection
.execute(`SELECT utc.*, (select count(*) from USER_CONS_COLUMNS ucc
.execute<{
TABLE_NAME: string;
COLUMN_NAME: string;
DATA_DEFAULT: string;
NULLABLE: string;
DATA_TYPE: string;
DATA_LENGTH: number;
DATA_PRECISION: number;
DATA_SCALE: number;
IDENTITY_COLUMN: string; // doesn't exist in old oracle versions (#195)
IS_UNIQUE: number;
}>(`SELECT utc.*, (select count(*) from USER_CONS_COLUMNS ucc
JOIN USER_CONSTRAINTS uc ON uc.CONSTRAINT_NAME = ucc.CONSTRAINT_NAME and uc.CONSTRAINT_TYPE='U'
where ucc.column_name = utc.COLUMN_NAME AND ucc.table_name = utc.TABLE_NAME) IS_UNIQUE
FROM USER_TAB_COLUMNS utc`)
@ -226,15 +227,15 @@ export default class OracleDriver extends AbstractDriver {
}
public async GetIndexesFromEntity(entities: Entity[]): Promise<Entity[]> {
const response: {
COLUMN_NAME: string;
TABLE_NAME: string;
INDEX_NAME: string;
UNIQUENESS: string;
ISPRIMARYKEY: number;
}[] = (
const response = (
await this.Connection
.execute(`SELECT ind.TABLE_NAME, ind.INDEX_NAME, col.COLUMN_NAME,ind.UNIQUENESS, CASE WHEN uc.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARYKEY
.execute<{
COLUMN_NAME: string;
TABLE_NAME: string;
INDEX_NAME: string;
UNIQUENESS: string;
ISPRIMARYKEY: number;
}>(`SELECT ind.TABLE_NAME, ind.INDEX_NAME, col.COLUMN_NAME,ind.UNIQUENESS, CASE WHEN uc.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END ISPRIMARYKEY
FROM USER_INDEXES ind
JOIN USER_IND_COLUMNS col ON ind.INDEX_NAME=col.INDEX_NAME
LEFT JOIN USER_CONSTRAINTS uc ON uc.INDEX_NAME = ind.INDEX_NAME
@ -274,17 +275,17 @@ export default class OracleDriver extends AbstractDriver {
dbNames: string,
generationOptions: IGenerationOptions
): Promise<Entity[]> {
const response: {
OWNER_TABLE_NAME: string;
OWNER_POSITION: string;
OWNER_COLUMN_NAME: string;
CHILD_TABLE_NAME: string;
CHILD_COLUMN_NAME: string;
DELETE_RULE: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
CONSTRAINT_NAME: string;
}[] = (
const response = (
await this.Connection
.execute(`select owner.TABLE_NAME OWNER_TABLE_NAME,ownCol.POSITION OWNER_POSITION,ownCol.COLUMN_NAME OWNER_COLUMN_NAME,
.execute<{
OWNER_TABLE_NAME: string;
OWNER_POSITION: string;
OWNER_COLUMN_NAME: string;
CHILD_TABLE_NAME: string;
CHILD_COLUMN_NAME: string;
DELETE_RULE: "RESTRICT" | "CASCADE" | "SET NULL" | "NO ACTION";
CONSTRAINT_NAME: string;
}>(`select owner.TABLE_NAME OWNER_TABLE_NAME,ownCol.POSITION OWNER_POSITION,ownCol.COLUMN_NAME OWNER_COLUMN_NAME,
child.TABLE_NAME CHILD_TABLE_NAME ,childCol.COLUMN_NAME CHILD_COLUMN_NAME,
owner.DELETE_RULE,
owner.CONSTRAINT_NAME
@ -345,9 +346,9 @@ export default class OracleDriver extends AbstractDriver {
}
public async ConnectToServer(connectionOptions: IConnectionOptions) {
let config: any;
let config: Oracle.ConnectionAttributes;
if (connectionOptions.user === String(process.env.ORACLE_UsernameSys)) {
config /* Oracle.IConnectionAttributes */ = {
config = {
connectString: `${connectionOptions.host}:${connectionOptions.port}/${connectionOptions.databaseName}`,
externalAuth: connectionOptions.ssl,
password: connectionOptions.password,
@ -355,7 +356,7 @@ export default class OracleDriver extends AbstractDriver {
user: connectionOptions.user
};
} else {
config /* Oracle.IConnectionAttributes */ = {
config = {
connectString: `${connectionOptions.host}:${connectionOptions.port}/${connectionOptions.databaseName}`,
externalAuth: connectionOptions.ssl,
password: connectionOptions.password,
@ -400,10 +401,10 @@ export default class OracleDriver extends AbstractDriver {
}
public async CheckIfDBExists(dbName: string): Promise<boolean> {
const x = await this.Connection.execute(
const {rows} = await this.Connection.execute<any>(
`select count(*) as CNT from dba_users where username='${dbName.toUpperCase()}'`
);
return x.rows[0][0] > 0 || x.rows[0].CNT;
return rows![0][0] > 0 || rows![0].CNT;
}
private static ReturnDefaultValueFunction(

View File

@ -1,4 +1,4 @@
import * as PG from "pg";
import type * as PG from "pg";
import { ConnectionOptions } from "typeorm";
import * as TypeormDriver from "typeorm/driver/postgres/PostgresDriver";
import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults";
@ -22,8 +22,22 @@ export default class PostgresDriver extends AbstractDriver {
public readonly standardSchema = "public";
private PG: typeof PG;
private Connection: PG.Client;
public constructor() {
super();
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
this.PG = require("pg");
} catch (error) {
TomgUtils.LogError("", false, error);
throw error;
}
}
public GetAllTablesQuery = async (
schema: string,
dbNames: string,
@ -599,7 +613,7 @@ export default class PostgresDriver extends AbstractDriver {
}
public async ConnectToServer(connectionOptons: IConnectionOptions) {
this.Connection = new PG.Client({
this.Connection = new this.PG.Client({
database: connectionOptons.databaseName,
host: connectionOptons.host,
password: connectionOptons.password,

View File

@ -1,7 +1,7 @@
import { ConnectionOptions } from "typeorm";
import * as TypeormDriver from "typeorm/driver/sqlite/SqliteDriver";
import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults";
import * as sqliteLib from "sqlite3";
import type * as sqliteLib from "sqlite3";
import * as TomgUtils from "../Utils";
import AbstractDriver from "./AbstractDriver";
import IConnectionOptions from "../IConnectionOptions";
@ -22,14 +22,28 @@ export default class SqliteDriver extends AbstractDriver {
public readonly standardSchema = "";
public sqlite = sqliteLib.verbose();
private sqliteLib:typeof sqliteLib;
public db: sqliteLib.Database;
private sqlite:sqliteLib.sqlite3;
public tablesWithGeneratedPrimaryKey: string[] = new Array<string>();
private db: sqliteLib.Database;
private tablesWithGeneratedPrimaryKey: string[] = new Array<string>();
public GetAllTablesQuery: any;
public constructor() {
super();
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
this.sqliteLib = require("sqlite3");
this.sqlite= this.sqliteLib.verbose()
} catch (error) {
TomgUtils.LogError("", false, error);
throw error;
}
}
public async GetAllTables(
schema: string,
dbNames: string,

View File

@ -1,3 +1,4 @@
// TODO: Enable prettier once import type syntax is supported
import * as Yargs from "yargs";
import { createDriver, createModelFromDatabase } from "./Engine";
import * as TomgUtils from "./Utils";
@ -11,6 +12,7 @@ import IGenerationOptions, {
import fs = require("fs-extra");
import inquirer = require("inquirer");
import path = require("path");
// eslint-disable-next-line @typescript-eslint/no-floating-promises
CliLogic();