added relations
This commit is contained in:
parent
0b000042e2
commit
fcf593e3ae
@ -26,7 +26,9 @@ export class Engine {
|
||||
private createModelFromMetadata(databaseModel: DatabaseModel) {
|
||||
let templatePath = path.resolve(__dirname,'entity.mst')
|
||||
let template = fs.readFileSync(templatePath,'UTF-8');
|
||||
//TODO:get results path to argvs, check if dir exists before
|
||||
let resultPath = path.resolve(__dirname,'../results')
|
||||
//TODO:Refactor to new method
|
||||
fs.writeFileSync(path.resolve(resultPath,'tsconfig.json'),`{"compilerOptions": {
|
||||
"lib": ["es5", "es6"],
|
||||
"target": "es6",
|
||||
@ -36,6 +38,7 @@ export class Engine {
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true
|
||||
}}`,{encoding:'UTF-8',flag:'w'});
|
||||
//TODO:Create ormconfig file
|
||||
databaseModel.entities.forEach(element => {
|
||||
let resultFilePath = path.resolve(resultPath,element.EntityName+'.ts');
|
||||
let rendered = Mustache.render(template, element);
|
||||
|
@ -8,16 +8,16 @@ export abstract class AbstractDriver {
|
||||
dbModel.entities = await this.GetAllTables();
|
||||
await this.GetCoulmnsFromEntity(dbModel.entities);
|
||||
await this.GetIndexesFromEntity(dbModel.entities);
|
||||
dbModel.relations = await this.GetRelations();
|
||||
dbModel.entities = await this.GetRelations(dbModel.entities);
|
||||
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[]);
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[]);
|
||||
abstract async GetRelations():Promise<RelationInfo[]>;
|
||||
abstract async GetCoulmnsFromEntity(entities: EntityInfo[]):Promise<EntityInfo[]>;
|
||||
abstract async GetIndexesFromEntity(entities: EntityInfo[]):Promise<EntityInfo[]>;
|
||||
abstract async GetRelations(entities: EntityInfo[]):Promise<EntityInfo[]>;
|
||||
abstract async FindPrimaryColumnsFromIndexes(dbModel:DatabaseModel);
|
||||
abstract async DisconnectFromServer();
|
||||
}
|
@ -32,7 +32,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
})
|
||||
return ret;
|
||||
}
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]) {
|
||||
async GetCoulmnsFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: { TABLE_NAME: string, COLUMN_NAME: string, COLUMN_DEFAULT: string,
|
||||
IS_NULLABLE: string, DATA_TYPE: string, CHARACTER_MAXIMUM_LENGTH: number,
|
||||
@ -114,9 +114,10 @@ export class MssqlDriver extends AbstractDriver {
|
||||
colInfo.numericPrecision=resp.NUMERIC_PRECISION
|
||||
colInfo.numericScale=resp.NUMERIC_SCALE
|
||||
break;
|
||||
// case "xml":
|
||||
// colInfo.ts_type = "number"
|
||||
// break;
|
||||
case "xml":
|
||||
colInfo.ts_type = "string"
|
||||
colInfo.sql_type = "text"
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown column type:" + resp.DATA_TYPE);
|
||||
break;
|
||||
@ -127,7 +128,7 @@ export class MssqlDriver extends AbstractDriver {
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]) {
|
||||
async GetIndexesFromEntity(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: {
|
||||
TableName: string, IndexName: string, ColumnName: string, is_unique: number,
|
||||
@ -181,7 +182,7 @@ ORDER BY
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async GetRelations(): Promise<RelationInfo[]> {
|
||||
async GetRelations(entities: EntityInfo[]): Promise<EntityInfo[]> {
|
||||
let request = new MSSQL.Request(this.Connection)
|
||||
let response: {
|
||||
TableWithForeignKey: string, FK_PartNo: number, ForeignKeyColumn: string,
|
||||
@ -212,25 +213,86 @@ where
|
||||
fk.is_disabled=0 and fk.is_ms_shipped=0
|
||||
order by
|
||||
TableWithForeignKey, FK_PartNo`);
|
||||
let relations: RelationInfo[] = <RelationInfo[]>[];
|
||||
let relationsTemp: RelationTempInfo[] = <RelationTempInfo[]>[];
|
||||
response.forEach((resp) => {
|
||||
let rels = relations.find((val) => {
|
||||
let rels = relationsTemp.find((val) => {
|
||||
return val.object_id == resp.object_id;
|
||||
})
|
||||
if (rels == undefined) {
|
||||
rels = <RelationInfo>{};
|
||||
rels = <RelationTempInfo>{};
|
||||
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.referencedTable = resp.TableReferenced;
|
||||
relationsTemp.push(rels);
|
||||
}
|
||||
rels.ownerColumnsNames.push(resp.ForeignKeyColumn);
|
||||
rels.referencedColumnsNames.push(resp.ForeignKeyColumnReferenced);
|
||||
})
|
||||
return relations;
|
||||
relationsTemp.forEach( (relationTmp)=>{
|
||||
let ownerEntity = entities.find((entitity)=>{
|
||||
return entitity.EntityName==relationTmp.ownerTable;
|
||||
})
|
||||
if (!ownerEntity){
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.ownerTable}.`)
|
||||
return;
|
||||
}
|
||||
let referencedEntity = entities.find((entitity)=>{
|
||||
return entitity.EntityName==relationTmp.referencedTable;
|
||||
})
|
||||
if (!referencedEntity){
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity model ${relationTmp.referencedTable}.`)
|
||||
return;
|
||||
}
|
||||
let ownerColumn = ownerEntity.Columns.find((column)=>{
|
||||
return column.name==relationTmp.ownerColumnsNames[0];
|
||||
})
|
||||
if(!ownerColumn){
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.ownerTable}.${ownerColumn}.`)
|
||||
return;
|
||||
}
|
||||
let relatedColumn = referencedEntity.Columns.find((column)=>{
|
||||
return column.name==relationTmp.referencedColumnsNames[0];
|
||||
})
|
||||
if(!relatedColumn){
|
||||
console.error(`Relation between tables ${relationTmp.ownerTable} and ${relationTmp.referencedTable} didn't found entity column ${relationTmp.referencedTable}.${relatedColumn}.`)
|
||||
return;
|
||||
}
|
||||
let ownColumn:ColumnInfo = ownerColumn;
|
||||
let isOneToMany:boolean;
|
||||
isOneToMany=false;
|
||||
let index = ownerEntity.Indexes.find(
|
||||
(index)=>{
|
||||
return index.isUnique && index.columns.some(col=>{
|
||||
return col.name==ownColumn.name
|
||||
})
|
||||
}
|
||||
)
|
||||
if (!index){
|
||||
isOneToMany=true;
|
||||
}else{
|
||||
isOneToMany=false;
|
||||
}
|
||||
|
||||
ownerColumn.relation=<RelationInfo>{
|
||||
actionOnDelete:relationTmp.actionOnDelete,
|
||||
isOwner:true,
|
||||
relatedColumn:relatedColumn.name,
|
||||
relatedTable:relationTmp.referencedTable,
|
||||
relationType:isOneToMany?"OneToMany":"OneToOne"
|
||||
}
|
||||
relatedColumn.relation=<RelationInfo>{
|
||||
actionOnDelete:relationTmp.actionOnDelete,
|
||||
isOwner:false,
|
||||
relatedColumn:ownerColumn.name,
|
||||
relatedTable:relationTmp.ownerTable,
|
||||
relationType:isOneToMany?"ManyToOne":"OneToOne"
|
||||
}
|
||||
|
||||
})
|
||||
return entities;
|
||||
}
|
||||
async DisconnectFromServer() {
|
||||
if (this.Connection)
|
||||
|
@ -1,4 +1,6 @@
|
||||
import {Index,Entity, PrimaryColumn, Column, OneToMany, ManyToOne, JoinTable} from "typeorm";
|
||||
import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, JoinTable} from "typeorm";
|
||||
{{#Columns}}{{#relation}}import{ {{relatedTable}} } from "./{{relatedTable}}";
|
||||
{{/relation}}{{/Columns}}
|
||||
|
||||
@Entity()
|
||||
{{#Indexes}}{{^isPrimaryKey}}@Index("{{name}}",[{{#columns}}"{{name}}",{{/columns}}]{{#isUnique}},{unique:true}{{/isUnique}})
|
||||
@ -6,7 +8,9 @@ import {Index,Entity, PrimaryColumn, Column, OneToMany, ManyToOne, JoinTable} fr
|
||||
|
||||
{{#Columns}}
|
||||
|
||||
@Column("{{sql_type}}",{ {{#is_nullable}}nullable:true,{{/is_nullable}}{{#char_max_lenght}}length:{{char_max_lenght}},{{/char_max_lenght}}{{#default}}default:{{default}},{{/default}}{{#numericPrecision}}precision:{numericPrecision},{{/numericPrecision}}{{#numericScale}}scale:{{numericScale}},{{/numericScale}}{{#isPrimary}}primary:{{isPrimary}},{{/isPrimary}}})
|
||||
@Column("{{sql_type}}",{ {{#is_nullable}}nullable:true,{{/is_nullable}}{{#char_max_lenght}}length:{{char_max_lenght}},{{/char_max_lenght}}{{#default}}default:{{default}},{{/default}}{{#numericPrecision}}precision:{numericPrecision},{{/numericPrecision}}{{#numericScale}}scale:{{numericScale}},{{/numericScale}}{{#isPrimary}}primary:{{isPrimary}},{{/isPrimary}}}){{#relation}}
|
||||
@{{relationType}}(type=>{{relatedTable}},x=>x.{{relatedColumn}}){{#isOwner}}
|
||||
@JoinTable(){{/isOwner}}{{/relation}}
|
||||
{{name}}:{{ts_type}};
|
||||
{{/Columns}}
|
||||
}
|
@ -11,7 +11,8 @@ interface ColumnInfo {
|
||||
char_max_lenght: number|null,
|
||||
isPrimary:boolean,
|
||||
numericPrecision:number|null,
|
||||
numericScale:number|null
|
||||
numericScale:number|null,
|
||||
relation:RelationInfo
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,8 @@
|
||||
interface DatabaseModel{
|
||||
interface DatabaseModel {
|
||||
entities: EntityInfo[],
|
||||
relations: RelationInfo[]
|
||||
config: {
|
||||
cascadeInsert: boolean,
|
||||
cascadeUpdate: boolean,
|
||||
cascadeRemove: boolean,
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
interface RelationInfo{
|
||||
ownerTable:string,
|
||||
ownerColumnsNames:string[],
|
||||
referencedTableName:string,
|
||||
referencedColumnsNames:string[],
|
||||
interface RelationInfo {
|
||||
isOwner: boolean,
|
||||
relationType: "OneToOne", "OneToMany", "ManyToOne"
|
||||
relatedTable: string,
|
||||
relatedColumn: string,
|
||||
actionOnDelete:"RESTRICT"|"CASCADE"|"SET NULL",
|
||||
object_id:number
|
||||
}
|
8
src/models/RelationTempInfo.ts
Normal file
8
src/models/RelationTempInfo.ts
Normal file
@ -0,0 +1,8 @@
|
||||
interface RelationTempInfo{
|
||||
ownerTable:string,
|
||||
ownerColumnsNames:string[],
|
||||
referencedTable:string,
|
||||
referencedColumnsNames:string[],
|
||||
actionOnDelete:"RESTRICT"|"CASCADE"|"SET NULL",
|
||||
object_id:number
|
||||
}
|
Loading…
Reference in New Issue
Block a user