#8 schemas support for postgres and mssql
This commit is contained in:
parent
54fc6317d5
commit
9205cee926
@ -11,7 +11,7 @@ export class Engine {
|
||||
}
|
||||
|
||||
public async createModelFromDatabase(): Promise<boolean> {
|
||||
let dbModel = await this.getEntitiesInfo(this.Options.databaseName, this.Options.host, this.Options.port, this.Options.user, this.Options.password);
|
||||
let dbModel = await this.getEntitiesInfo(this.Options.databaseName, this.Options.host, this.Options.port, this.Options.user, this.Options.password, this.Options.schemaName);
|
||||
if (dbModel.entities.length > 0) {
|
||||
this.createModelFromMetadata(dbModel);
|
||||
} else {
|
||||
@ -19,8 +19,8 @@ export class Engine {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string): Promise<DatabaseModel> {
|
||||
return await this.driver.GetDataFromServer(database, server, port, user, password)
|
||||
private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string, schemaName:string): Promise<DatabaseModel> {
|
||||
return await this.driver.GetDataFromServer(database, server, port, user, password,schemaName)
|
||||
|
||||
}
|
||||
private createModelFromMetadata(databaseModel: DatabaseModel) {
|
||||
@ -81,5 +81,6 @@ export interface EngineOptions {
|
||||
user: string,
|
||||
password: string,
|
||||
resultsPath: string,
|
||||
databaseType: string
|
||||
databaseType: string,
|
||||
schemaName:string
|
||||
}
|
@ -4,22 +4,22 @@ import { DatabaseModel } from './../models/DatabaseModel'
|
||||
* AbstractDriver
|
||||
*/
|
||||
export abstract class AbstractDriver {
|
||||
async GetDataFromServer(database: string, server: string, port: number, user: string, password: string): Promise<DatabaseModel> {
|
||||
async GetDataFromServer(database: string, server: string, port: number, user: string, password: string, schema:string): Promise<DatabaseModel> {
|
||||
let dbModel = <DatabaseModel>{};
|
||||
await this.ConnectToServer(database, server, port, user, password);
|
||||
dbModel.entities = await this.GetAllTables();
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities);
|
||||
await this.GetIndexesFromEntity(dbModel.entities);
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities);
|
||||
dbModel.entities = await this.GetAllTables(schema);
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities,schema);
|
||||
await this.GetIndexesFromEntity(dbModel.entities,schema);
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities,schema);
|
||||
await this.DisconnectFromServer();
|
||||
this.FindPrimaryColumnsFromIndexes(dbModel)
|
||||
return dbModel;
|
||||
}
|
||||
abstract async ConnectToServer(database: string, server: string, port: number, user: string, password: string);
|
||||
abstract async GetAllTables(): Promise<EntityInfo[]>
|
||||
abstract async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]>;
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]>;
|
||||
abstract async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]>;
|
||||
abstract async GetAllTables(schema:string): Promise<EntityInfo[]>
|
||||
abstract async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]>;
|
||||
abstract async FindPrimaryColumnsFromIndexes(dbModel: DatabaseModel);
|
||||
abstract async DisconnectFromServer();
|
||||
|
||||
|
@ -21,7 +21,7 @@ export class MariaDbDriver extends AbstractDriver {
|
||||
});
|
||||
}
|
||||
|
||||
async GetAllTables(): Promise<EntityInfo[]> {
|
||||
async GetAllTables(schema:string): Promise<EntityInfo[]> {
|
||||
|
||||
let response = await this.ExecQuery<{ TABLE_SCHEMA: string, TABLE_NAME: string }>(`SELECT TABLE_SCHEMA, TABLE_NAME
|
||||
FROM information_schema.tables
|
||||
@ -37,7 +37,7 @@ export class MariaDbDriver extends AbstractDriver {
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
|
||||
IS_NULLABLE: string, DATA_TYPE: string, CHARACTER_MAXIMUM_LENGTH: number,
|
||||
@ -162,7 +162,7 @@ export class MariaDbDriver extends AbstractDriver {
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
is_primary_key: number//, is_descending_key: number//, is_included_column: number
|
||||
@ -200,7 +200,7 @@ export class MariaDbDriver extends AbstractDriver {
|
||||
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
|
||||
TableReferenced: string, ForeignKeyColumnReferenced: string,
|
||||
|
@ -21,10 +21,10 @@ export class MssqlDriver extends AbstractDriver {
|
||||
});
|
||||
}
|
||||
|
||||
async GetAllTables(): Promise<EntityInfo[]> {
|
||||
async GetAllTables(schema:string): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: { TABLE_SCHEMA: string, TABLE_NAME: string }[]
|
||||
= (await request.query("SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'")).recordset;
|
||||
= (await request.query(`SELECT TABLE_SCHEMA,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_SCHEMA='${schema}'`)).recordset;
|
||||
let ret: EntityInfo[] = <EntityInfo[]>[];
|
||||
response.forEach((val) => {
|
||||
let ent: EntityInfo = new EntityInfo();
|
||||
@ -35,7 +35,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: {
|
||||
TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
|
||||
@ -44,7 +44,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
}[]
|
||||
= (await request.query(`SELECT TABLE_NAME,COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,
|
||||
DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,
|
||||
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS`)).recordset;
|
||||
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') IsIdentity FROM INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA='${schema}'`)).recordset;
|
||||
entities.forEach((ent) => {
|
||||
response.filter((filterVal) => {
|
||||
return filterVal.TABLE_NAME == ent.EntityName;
|
||||
@ -154,7 +154,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: {
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
@ -176,8 +176,10 @@ INNER JOIN
|
||||
sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
|
||||
INNER JOIN
|
||||
sys.tables t ON ind.object_id = t.object_id
|
||||
INNER JOIN
|
||||
sys.schemas s on s.schema_id=t.schema_id
|
||||
WHERE
|
||||
t.is_ms_shipped = 0
|
||||
t.is_ms_shipped = 0 and s.name='${schema}'
|
||||
ORDER BY
|
||||
t.name, ind.name, ind.index_id, ic.key_ordinal;`)).recordset;
|
||||
entities.forEach((ent) => {
|
||||
@ -209,7 +211,7 @@ ORDER BY
|
||||
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: {
|
||||
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
|
||||
@ -238,8 +240,10 @@ inner join
|
||||
sys.tables as referencedTable on fkc.referenced_object_id = referencedTable.object_id
|
||||
inner join
|
||||
sys.columns as referencedColumn on fkc.referenced_object_id = referencedColumn.object_id and fkc.referenced_column_id = referencedColumn.column_id
|
||||
inner join
|
||||
sys.schemas as parentSchema on parentSchema.schema_id=parentTable.schema_id
|
||||
where
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0 and parentSchema.name='${schema}'
|
||||
order by
|
||||
TableWithForeignKey, FK_PartNo`)).recordset;
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
|
@ -21,7 +21,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
});
|
||||
}
|
||||
|
||||
async GetAllTables(): Promise<EntityInfo[]> {
|
||||
async GetAllTables(schema:string): Promise<EntityInfo[]> {
|
||||
|
||||
let response = await this.ExecQuery<{ TABLE_SCHEMA: string, TABLE_NAME: string }>(`SELECT TABLE_SCHEMA, TABLE_NAME
|
||||
FROM information_schema.tables
|
||||
@ -37,7 +37,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
|
||||
IS_NULLABLE: string, DATA_TYPE: string, CHARACTER_MAXIMUM_LENGTH: number,
|
||||
@ -162,7 +162,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
is_primary_key: number//, is_descending_key: number//, is_included_column: number
|
||||
@ -200,7 +200,7 @@ export class MysqlDriver extends AbstractDriver {
|
||||
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response = await this.ExecQuery<{
|
||||
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
|
||||
TableReferenced: string, ForeignKeyColumnReferenced: string,
|
||||
|
@ -23,10 +23,10 @@ export class PostgresDriver extends AbstractDriver {
|
||||
});
|
||||
}
|
||||
|
||||
async GetAllTables(): Promise<EntityInfo[]> {
|
||||
async GetAllTables(schema:string): Promise<EntityInfo[]> {
|
||||
|
||||
let response: { table_schema: string, table_name: string }[]
|
||||
= (await this.Connection.query("SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema = 'public' ")).rows;
|
||||
= (await this.Connection.query(`SELECT table_schema,table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND table_schema = '${schema}' `)).rows;
|
||||
|
||||
let ret: EntityInfo[] = <EntityInfo[]>[];
|
||||
response.forEach((val) => {
|
||||
@ -38,7 +38,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response: {
|
||||
table_name: string, column_name: string, column_default: string,
|
||||
is_nullable: string, data_type: string, character_maximum_length: number,
|
||||
@ -48,7 +48,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
data_type,character_maximum_length,numeric_precision,numeric_scale
|
||||
--,COLUMNPROPERTY(object_id(table_name), column_name, 'isidentity') isidentity
|
||||
, case when column_default LIKE 'nextval%' then 'YES' else 'NO' end isidentity
|
||||
FROM INFORMATION_SCHEMA.COLUMNS where table_schema ='public'`)).rows;
|
||||
FROM INFORMATION_SCHEMA.COLUMNS where table_schema ='${schema}'`)).rows;
|
||||
entities.forEach((ent) => {
|
||||
response.filter((filterVal) => {
|
||||
return filterVal.table_name == ent.EntityName;
|
||||
@ -134,7 +134,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetIndexesFromEntity(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response: {
|
||||
tablename: string, indexname: string, columnname: string, is_unique: number,
|
||||
is_primary_key: number//, is_descending_key: number//, is_included_column: number
|
||||
@ -162,7 +162,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
LEFT JOIN pg_class AS i ON ix.indexrelid = i.oid
|
||||
|
||||
WHERE c.relkind = 'r'::char
|
||||
AND n.nspname = 'public' -- Replace with Schema name
|
||||
AND n.nspname = '${schema}'
|
||||
--AND c.relname = 'nodes' -- Replace with table name, or Comment this for get all tables
|
||||
AND f.attnum > 0
|
||||
AND i.oid<>0
|
||||
@ -199,7 +199,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
async GetRelations(entities: EntityInfo[],schema:string): Promise<EntityInfo[]> {
|
||||
let response: {
|
||||
tablewithforeignkey: string, fk_partno: number, foreignkeycolumn: string,
|
||||
tablereferenced: string, foreignkeycolumnreferenced: string,
|
||||
@ -231,6 +231,7 @@ export class PostgresDriver extends AbstractDriver {
|
||||
con1.contype = 'f'::"char"
|
||||
AND cl_1.relnamespace = ns.oid
|
||||
AND con1.conrelid = cl_1.oid
|
||||
and nspname='${schema}'
|
||||
) con,
|
||||
pg_attribute att,
|
||||
pg_class cl,
|
||||
|
11
src/index.ts
11
src/index.ts
@ -46,19 +46,26 @@ var argv = Yargs
|
||||
describe: 'Where to place generated models.',
|
||||
default: path.resolve(process.cwd(), 'output')
|
||||
})
|
||||
.option('s', {
|
||||
alias: 'schema',
|
||||
describe: 'Schema name to create model from. Only for mssql and postgres.'
|
||||
})
|
||||
.argv;
|
||||
|
||||
|
||||
var driver: AbstractDriver;
|
||||
var standardPort: number;
|
||||
var standardSchema: string = '';
|
||||
switch (argv.e) {
|
||||
case 'mssql':
|
||||
driver = new MssqlDriver();
|
||||
standardPort = 1433;
|
||||
standardSchema = 'dbo';
|
||||
break;
|
||||
case 'postgres':
|
||||
driver = new PostgresDriver();
|
||||
standardPort = 5432;
|
||||
standardSchema = 'public';
|
||||
break;
|
||||
case 'mysql':
|
||||
driver = new MysqlDriver();
|
||||
@ -74,6 +81,7 @@ switch (argv.e) {
|
||||
throw new Error('Database engine not recognized.');
|
||||
}
|
||||
|
||||
|
||||
let engine = new Engine(
|
||||
driver, {
|
||||
host: argv.h,
|
||||
@ -82,7 +90,8 @@ let engine = new Engine(
|
||||
user: argv.u,
|
||||
password: argv.x,
|
||||
databaseType: argv.e,
|
||||
resultsPath: argv.o
|
||||
resultsPath: argv.o,
|
||||
schemaName: argv.s || standardSchema
|
||||
});
|
||||
|
||||
console.log(`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`);
|
||||
|
@ -57,7 +57,7 @@ describe('MssqlDriver', function () {
|
||||
}
|
||||
}
|
||||
)
|
||||
let result = await driver.GetAllTables()
|
||||
let result = await driver.GetAllTables('schema')
|
||||
let expectedResult = <EntityInfo[]>[];
|
||||
let y = new EntityInfo();
|
||||
y.EntityName = 'name'
|
||||
@ -105,7 +105,7 @@ describe('MssqlDriver', function () {
|
||||
ts_type: 'number',
|
||||
relations: <RelationInfo[]>[]
|
||||
})
|
||||
let result = await driver.GetCoulmnsFromEntity(entities);
|
||||
let result = await driver.GetCoulmnsFromEntity(entities,'schema');
|
||||
expect(result).to.be.deep.equal(expected)
|
||||
})
|
||||
it('should find primary indexes')
|
||||
|
@ -139,7 +139,8 @@ async function createMSSQLModels(filesOrgPath: string, resultsPath: string): Pro
|
||||
user: String(process.env.MSSQL_Username),
|
||||
password: String(process.env.MSSQL_Password),
|
||||
databaseType: 'mssql',
|
||||
resultsPath: resultsPath
|
||||
resultsPath: resultsPath,
|
||||
schemaName:'dbo'
|
||||
});
|
||||
|
||||
|
||||
@ -180,7 +181,8 @@ async function createPostgresModels(filesOrgPath: string, resultsPath: string):
|
||||
user: String(process.env.POSTGRES_Username),
|
||||
password: String(process.env.POSTGRES_Password),
|
||||
databaseType: 'postgres',
|
||||
resultsPath: resultsPath
|
||||
resultsPath: resultsPath,
|
||||
schemaName:'public'
|
||||
});
|
||||
|
||||
|
||||
@ -222,7 +224,8 @@ async function createMysqlModels(filesOrgPath: string, resultsPath: string): Pro
|
||||
user: String(process.env.MYSQL_Username),
|
||||
password: String(process.env.MYSQL_Password),
|
||||
databaseType: 'mysql',
|
||||
resultsPath: resultsPath
|
||||
resultsPath: resultsPath,
|
||||
schemaName:'ignored'
|
||||
});
|
||||
|
||||
|
||||
@ -264,7 +267,8 @@ async function createMariaDBModels(filesOrgPath: string, resultsPath: string): P
|
||||
user: String(process.env.MARIADB_Username),
|
||||
password: String(process.env.MARIADB_Password),
|
||||
databaseType: 'mariadb',
|
||||
resultsPath: resultsPath
|
||||
resultsPath: resultsPath,
|
||||
schemaName:'ignored'
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user