From 38b254548e4ef43749d39062b786644baf7c9b2c Mon Sep 17 00:00:00 2001 From: Kononnable Date: Sun, 2 Apr 2017 00:53:19 +0200 Subject: [PATCH] enumerating all relations(one to many) --- src/Engine.ts | 14 +++++----- src/drivers/AbstractDriver.ts | 15 +++++----- src/drivers/MssqlDriver.ts | 52 +++++++++++++++++++++++++++++++++-- src/models/ColumnInfo.ts | 4 +-- src/models/DatabaseModel.ts | 4 +++ src/models/RelationInfo.ts | 8 ++++++ 6 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 src/models/DatabaseModel.ts create mode 100644 src/models/RelationInfo.ts diff --git a/src/Engine.ts b/src/Engine.ts index e72c01c..ab4edda 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -8,19 +8,19 @@ export class Engine { } public async createModelFromDatabase(): Promise { - let entities = await this.getEntitiesInfo(this.Options.databaseName, this.Options.host, this.Options.port, this.Options.user, this.Options.password); - if (entities.length > 0) { - this.createModelFromMetadata(entities); + let dbModel = await this.getEntitiesInfo(this.Options.databaseName, this.Options.host, this.Options.port, this.Options.user, this.Options.password); + if (dbModel.entities.length > 0) { + this.createModelFromMetadata(dbModel); } else { console.error('Tables not found in selected database. Skipping creation of typeorm model.'); } return true; } - private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string): Promise { - await this.driver.GetDataFromServer(database, server, port, user, password) - return []; + private async getEntitiesInfo(database: string, server: string, port: number, user: string, password: string): Promise { + return await this.driver.GetDataFromServer(database, server, port, user, password) + } - private createModelFromMetadata(entities: EntityInfo[]) { + private createModelFromMetadata(databaseModel: DatabaseModel) { } } diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index 32decb4..29fdf15 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -2,19 +2,20 @@ * AbstractDriver */ export abstract class AbstractDriver { - async GetDataFromServer(database:string,server:string,port:number,user:string,password:string): Promise { + async GetDataFromServer(database:string,server:string,port:number,user:string,password:string): Promise { + let dbModel={}; await this.ConnectToServer(database,server,port,user,password); - let entities = await this.GetAllTables(); - await this.GetCoulmnsFromEntity(entities); - await this.GetIndexesFromEntity(entities); - await this.GetForeignKeysFromEntity(entities); + dbModel.entities = await this.GetAllTables(); + await this.GetCoulmnsFromEntity(dbModel.entities); + await this.GetIndexesFromEntity(dbModel.entities); + dbModel.relations = await this.GetRelations(); await this.DisconnectFromServer(); - return entities; + return dbModel; } abstract async ConnectToServer(database:string,server:string,port:number,user:string,password:string); abstract async GetAllTables(): Promise abstract async GetCoulmnsFromEntity(entity: EntityInfo[]); abstract async GetIndexesFromEntity(entity: EntityInfo[]); - abstract async GetForeignKeysFromEntity(entity: EntityInfo[]); + abstract async GetRelations():Promise; abstract async DisconnectFromServer(); } \ No newline at end of file diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index 1e0b741..d53f3bf 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -90,8 +90,56 @@ ORDER BY }) return entities; } - GetForeignKeysFromEntity(entities: EntityInfo[]) { - throw new Error('Method not implemented.'); + async GetRelations(): Promise { + let request = new MSSQL.Request(this.Connection) + let response: { + TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string, + TableReferenced: string, ForeignKeyColumnReferenced: string, + onDelete: "RESTRICT" | "CASCADE" | "SET NULL", object_id: number + }[] + = await request.query(`select + parentTable.name as TableWithForeignKey, + fkc.constraint_column_id as FK_PartNo, + parentColumn.name as ForeignKeyColumn, + referencedTable.name as TableReferenced, + referencedColumn.name as ForeignKeyColumnReferenced, + fk.delete_referential_action_desc as onDelete, + fk.object_id +from + sys.foreign_keys fk +inner join + sys.foreign_key_columns as fkc on fkc.constraint_object_id=fk.object_id +inner join + sys.tables as parentTable on fkc.parent_object_id = parentTable.object_id +inner join + sys.columns as parentColumn on fkc.parent_object_id = parentColumn.object_id and fkc.parent_column_id = parentColumn.column_id +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 +where + fk.is_disabled=0 and fk.is_ms_shipped=0 +order by + TableWithForeignKey, FK_PartNo`); + let relations: RelationInfo[] = []; + response.forEach((resp) => { + let rels = relations.find((val) => { + return val.object_id == resp.object_id; + }) + if (rels == undefined) { + rels = {}; + rels.ownerColumnsNames = []; + rels.referencedColumnsNames = []; + rels.actionOnDelete = resp.onDelete; + rels.object_id = resp.object_id; + rels.ownerTable = resp.TableWithForeignKey; + rels.referencedTableName = resp.TableReferenced; + relations.push(rels); + } + rels.ownerColumnsNames.push(resp.ForeignKeyColumn); + rels.referencedColumnsNames.push(resp.ForeignKeyColumnReferenced); + }) + return relations; } async DisconnectFromServer() { if (this.Connection) diff --git a/src/models/ColumnInfo.ts b/src/models/ColumnInfo.ts index 2865cd0..aafe1ac 100644 --- a/src/models/ColumnInfo.ts +++ b/src/models/ColumnInfo.ts @@ -6,5 +6,5 @@ interface ColumnInfo { default:string, is_nullable:boolean, data_type:string, - char_max_lenght:number -} \ No newline at end of file + char_max_lenght:number, +} diff --git a/src/models/DatabaseModel.ts b/src/models/DatabaseModel.ts new file mode 100644 index 0000000..5931883 --- /dev/null +++ b/src/models/DatabaseModel.ts @@ -0,0 +1,4 @@ +interface DatabaseModel{ + entities: EntityInfo[], + relations: RelationInfo[] +} \ No newline at end of file diff --git a/src/models/RelationInfo.ts b/src/models/RelationInfo.ts new file mode 100644 index 0000000..edf02fa --- /dev/null +++ b/src/models/RelationInfo.ts @@ -0,0 +1,8 @@ +interface RelationInfo{ + ownerTable:string, + ownerColumnsNames:string[], + referencedTableName:string, + referencedColumnsNames:string[], + actionOnDelete:"RESTRICT"|"CASCADE"|"SET NULL", + object_id:number +} \ No newline at end of file