diff --git a/src/IConnectionOptions.ts b/src/IConnectionOptions.ts index 8be2079..5aef82d 100644 --- a/src/IConnectionOptions.ts +++ b/src/IConnectionOptions.ts @@ -16,6 +16,7 @@ export default interface IConnectionOptions { | "sqlite"; schemaName: string; ssl: boolean; + skipTables: string[]; } export function getDefaultConnectionOptions(): IConnectionOptions { @@ -27,7 +28,8 @@ export function getDefaultConnectionOptions(): IConnectionOptions { password: "", databaseType: undefined as any, schemaName: "", - ssl: false + ssl: false, + skipTables: [] }; return connectionOptions; } diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index bb6ee21..a086f00 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -69,7 +69,8 @@ export default abstract class AbstractDriver { public abstract GetAllTablesQuery: ( schema: string, - dbNames: string + dbNames: string, + tableNames: string[] ) => Promise< { TABLE_SCHEMA: string; @@ -186,7 +187,8 @@ export default abstract class AbstractDriver { ); dbModel = await this.GetAllTables( sqlEscapedSchema, - connectionOptions.databaseName + connectionOptions.databaseName, + connectionOptions.skipTables ); await this.GetCoulmnsFromEntity( dbModel, @@ -214,9 +216,14 @@ export default abstract class AbstractDriver { public async GetAllTables( schema: string, - dbNames: string + dbNames: string, + tableNames: string[] ): Promise { - const response = await this.GetAllTablesQuery(schema, dbNames); + const response = await this.GetAllTablesQuery( + schema, + dbNames, + tableNames + ); const ret: Entity[] = [] as Entity[]; response.forEach(val => { ret.push({ diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index a541c85..e760810 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -24,8 +24,16 @@ export default class MssqlDriver extends AbstractDriver { private Connection: MSSQL.ConnectionPool; - public GetAllTablesQuery = async (schema: string, dbNames: string) => { + public GetAllTablesQuery = async ( + schema: string, + dbNames: string, + tableNames: string[] + ) => { const request = new MSSQL.Request(this.Connection); + const tableCondition = + tableNames.length > 0 + ? ` AND NOT TABLE_NAME IN ('${tableNames.join("','")}')` + : ""; const response: { TABLE_SCHEMA: string; TABLE_NAME: string; @@ -35,7 +43,7 @@ export default class MssqlDriver extends AbstractDriver { `SELECT TABLE_SCHEMA,TABLE_NAME, table_catalog as "DB_NAME" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA in (${schema}) AND TABLE_CATALOG in (${MssqlDriver.escapeCommaSeparatedList( dbNames - )})` + )}) ${tableCondition}` ) ).recordset; return response; diff --git a/src/drivers/MysqlDriver.ts b/src/drivers/MysqlDriver.ts index b7185fc..f63212c 100644 --- a/src/drivers/MysqlDriver.ts +++ b/src/drivers/MysqlDriver.ts @@ -26,7 +26,15 @@ export default class MysqlDriver extends AbstractDriver { private Connection: MYSQL.Connection; - public GetAllTablesQuery = async (schema: string, dbNames: string) => { + public GetAllTablesQuery = async ( + schema: string, + dbNames: string, + tableNames: string[] + ) => { + const tableCondition = + tableNames.length > 0 + ? ` AND NOT TABLE_NAME IN ('${tableNames.join("','")}')` + : ""; const response = this.ExecQuery<{ TABLE_SCHEMA: string; TABLE_NAME: string; @@ -36,7 +44,7 @@ export default class MysqlDriver extends AbstractDriver { WHERE table_type='BASE TABLE' AND table_schema IN (${MysqlDriver.escapeCommaSeparatedList( dbNames - )})`); + )}) ${tableCondition}`); return response; }; diff --git a/src/drivers/OracleDriver.ts b/src/drivers/OracleDriver.ts index bf045a7..f5f7c04 100644 --- a/src/drivers/OracleDriver.ts +++ b/src/drivers/OracleDriver.ts @@ -36,14 +36,22 @@ export default class OracleDriver extends AbstractDriver { } } - public GetAllTablesQuery = async () => { + public GetAllTablesQuery = async ( + schema: string, + dbNames: string, + tableNames: string[] + ) => { + const tableCondition = + tableNames.length > 0 + ? ` AND NOT TABLE_NAME IN ('${tableNames.join("','")}')` + : ""; const response: { TABLE_SCHEMA: string; TABLE_NAME: string; DB_NAME: string; }[] = ( await this.Connection.execute( - `SELECT NULL AS TABLE_SCHEMA, TABLE_NAME, NULL AS DB_NAME FROM all_tables WHERE owner = (select user from dual)` + `SELECT NULL AS TABLE_SCHEMA, TABLE_NAME, NULL AS DB_NAME FROM all_tables WHERE owner = (select user from dual) ${tableCondition}` ) ).rows!; return response; diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index 4f6f105..2703f59 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -24,14 +24,22 @@ export default class PostgresDriver extends AbstractDriver { private Connection: PG.Client; - public GetAllTablesQuery = async (schema: string) => { + public GetAllTablesQuery = async ( + schema: string, + dbNames: string, + tableNames: string[] + ) => { + const tableCondition = + tableNames.length > 0 + ? ` AND NOT table_name IN ('${tableNames.join("','")}')` + : ""; const response: { TABLE_SCHEMA: string; TABLE_NAME: string; DB_NAME: string; }[] = ( await this.Connection.query( - `SELECT table_schema as "TABLE_SCHEMA",table_name as "TABLE_NAME", table_catalog as "DB_NAME" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema in (${schema}) ` + `SELECT table_schema as "TABLE_SCHEMA",table_name as "TABLE_NAME", table_catalog as "DB_NAME" FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema in (${schema}) ${tableCondition}` ) ).rows; return response; diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index 64ce684..ac99030 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -30,10 +30,18 @@ export default class SqliteDriver extends AbstractDriver { public GetAllTablesQuery: any; - public async GetAllTables(): Promise { + public async GetAllTables( + schema: string, + dbNames: string, + tableNames: string[] + ): Promise { const ret: Entity[] = [] as Entity[]; + const tableCondition = + tableNames.length > 0 + ? ` AND NOT tbl_name IN ('${tableNames.join("','")}')` + : ""; const rows = await this.ExecQuery<{ tbl_name: string; sql: string }>( - `SELECT tbl_name, sql FROM "sqlite_master" WHERE "type" = 'table' AND name NOT LIKE 'sqlite_%'` + `SELECT tbl_name, sql FROM "sqlite_master" WHERE "type" = 'table' AND name NOT LIKE 'sqlite_%' ${tableCondition}` ); rows.forEach(val => { if (val.sql.includes("AUTOINCREMENT")) { diff --git a/src/index.ts b/src/index.ts index e84e68e..b0264fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -243,7 +243,13 @@ function checkYargsParameters(options: options): options { boolean: true, default: !options.generationOptions.pluralizeNames, describe: - "Disable pluralization of OneToMany, ManyToMany relation names." + "Disable pluralization of OneToMany, ManyToMany relation names" + }, + skipTables: { + string: true, + default: options.connectionOptions.skipTables.join(","), + describe: + "Skip schema generation for specific tables. You can pass multiple values separated by comma" }, strictMode: { choices: ["none", "?", "!"], @@ -280,6 +286,7 @@ function checkYargsParameters(options: options): options { options.generationOptions.resultsPath = argv.o; options.generationOptions.pluralizeNames = !argv.disablePluralization; options.generationOptions.strictMode = argv.strictMode as IGenerationOptions["strictMode"]; + options.connectionOptions.skipTables = argv.skipTables.split(","); return options; } @@ -387,6 +394,33 @@ async function useInquirer(options: options): Promise { ]) ).dbName; } + + const ignoreSpecyficTables = ( + await inquirer.prompt([ + { + default: + options.connectionOptions.skipTables.length === 0 + ? "All of them" + : "Ignore specific tables", + message: "Generate schema for tables:", + choices: ["All of them", "Ignore specific tables"], + name: "specyficTables", + type: "list" + } + ]) + ).specyficTables; + if (ignoreSpecyficTables === "Ignore specific tables") { + const { tableNames } = await inquirer.prompt({ + default: options.connectionOptions.skipTables.join(","), + message: "Table names(separated by comma)", + name: "tableNames", + type: "input" + }); + options.connectionOptions.skipTables = tableNames.split(","); + } else { + options.connectionOptions.skipTables = []; + } + options.generationOptions.resultsPath = ( await inquirer.prompt([ { diff --git a/test/drivers/MssqlDriver.test.ts b/test/drivers/MssqlDriver.test.ts index bfa577f..cff8cdc 100644 --- a/test/drivers/MssqlDriver.test.ts +++ b/test/drivers/MssqlDriver.test.ts @@ -47,7 +47,7 @@ describe("MssqlDriver", () => { return response; } }); - const result = await driver.GetAllTables("schema", "db"); + const result = await driver.GetAllTables("schema", "db", []); const expectedResult = [] as Entity[]; const y: Entity = { columns: [], diff --git a/test/integration/runTestsFromPath.test.ts b/test/integration/runTestsFromPath.test.ts index c394a6f..ec5eb24 100644 --- a/test/integration/runTestsFromPath.test.ts +++ b/test/integration/runTestsFromPath.test.ts @@ -320,7 +320,8 @@ async function prepareTestRuns( password: String(process.env.MYSQL_Password), databaseType: "mysql", schemaName: "ignored", - ssl: yn(process.env.MYSQL_SSL, { default: false }) + ssl: yn(process.env.MYSQL_SSL, { default: false }), + skipTables: [] }; break; case "mariadb": @@ -332,7 +333,8 @@ async function prepareTestRuns( password: String(process.env.MARIADB_Password), databaseType: "mariadb", schemaName: "ignored", - ssl: yn(process.env.MARIADB_SSL, { default: false }) + ssl: yn(process.env.MARIADB_SSL, { default: false }), + skipTables: [] }; break; diff --git a/test/modelCustomization/modelCustomization.test.ts b/test/modelCustomization/modelCustomization.test.ts index da60c12..b474300 100644 --- a/test/modelCustomization/modelCustomization.test.ts +++ b/test/modelCustomization/modelCustomization.test.ts @@ -15,6 +15,8 @@ import { compileGeneratedModel } from "../integration/runTestsFromPath.test"; chai.use(chaiSubset); const { expect } = chai; + +// TODO: test for connectionOptions.specyficTables describe("Model customization phase", async () => { const generateSampleData: () => Entity[] = () => [ { diff --git a/test/utils/GeneralTestUtils.ts b/test/utils/GeneralTestUtils.ts index bf2fe82..6821ee6 100644 --- a/test/utils/GeneralTestUtils.ts +++ b/test/utils/GeneralTestUtils.ts @@ -29,7 +29,8 @@ export async function createMSSQLModels( password: String(process.env.MSSQL_Password), databaseType: "mssql", schemaName: "dbo,sch1,sch2", - ssl: yn(process.env.MSSQL_SSL, { default: false }) + ssl: yn(process.env.MSSQL_SSL, { default: false }), + skipTables: [] }; await driver.ConnectToServer(connectionOptions); connectionOptions.databaseName = String(process.env.MSSQL_Database); @@ -80,7 +81,8 @@ export async function createPostgresModels( password: String(process.env.POSTGRES_Password), databaseType: "postgres", schemaName: "public,sch1,sch2", - ssl: yn(process.env.POSTGRES_SSL, { default: false }) + ssl: yn(process.env.POSTGRES_SSL, { default: false }), + skipTables: [] }; await driver.ConnectToServer(connectionOptions); connectionOptions.databaseName = String(process.env.POSTGRES_Database); @@ -130,7 +132,8 @@ export async function createSQLiteModels( password: "", databaseType: "sqlite", schemaName: "", - ssl: false + ssl: false, + skipTables: [] }; const connOpt: ConnectionOptions = { @@ -164,7 +167,8 @@ export async function createMysqlModels( password: String(process.env.MYSQL_Password), databaseType: "mysql", schemaName: "ignored", - ssl: yn(process.env.MYSQL_SSL, { default: false }) + ssl: yn(process.env.MYSQL_SSL, { default: false }), + skipTables: [] }; await driver.ConnectToServer(connectionOptions); @@ -206,7 +210,8 @@ export async function createMariaDBModels( password: String(process.env.MARIADB_Password), databaseType: "mariadb", schemaName: "ignored", - ssl: yn(process.env.MARIADB_SSL, { default: false }) + ssl: yn(process.env.MARIADB_SSL, { default: false }), + skipTables: [] }; await driver.ConnectToServer(connectionOptions); @@ -250,7 +255,8 @@ export async function createOracleDBModels( password: String(process.env.ORACLE_PasswordSys), databaseType: "oracle", schemaName: String(process.env.ORACLE_Username), - ssl: yn(process.env.ORACLE_SSL, { default: false }) + ssl: yn(process.env.ORACLE_SSL, { default: false }), + skipTables: [] }; await driver.ConnectToServer(connectionOptions); connectionOptions.user = String(process.env.ORACLE_Username);