added relations

This commit is contained in:
Kononnable 2017-04-23 23:41:49 +02:00
parent 0b000042e2
commit fcf593e3ae
8 changed files with 108 additions and 27 deletions

View File

@ -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);

View File

@ -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();
}

View File

@ -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)

View File

@ -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}}
}

View File

@ -11,7 +11,8 @@ interface ColumnInfo {
char_max_lenght: number|null,
isPrimary:boolean,
numericPrecision:number|null,
numericScale:number|null
numericScale:number|null,
relation:RelationInfo
}

View File

@ -1,4 +1,8 @@
interface DatabaseModel{
interface DatabaseModel {
entities: EntityInfo[],
relations: RelationInfo[]
config: {
cascadeInsert: boolean,
cascadeUpdate: boolean,
cascadeRemove: boolean,
}
}

View File

@ -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
}

View File

@ -0,0 +1,8 @@
interface RelationTempInfo{
ownerTable:string,
ownerColumnsNames:string[],
referencedTable:string,
referencedColumnsNames:string[],
actionOnDelete:"RESTRICT"|"CASCADE"|"SET NULL",
object_id:number
}