better handling of OneToMany/OneToOne relations

This commit is contained in:
Kononnable 2017-06-05 15:33:34 +02:00
parent 694b41cd79
commit d870654fc8
10 changed files with 202 additions and 6 deletions

View File

@ -273,10 +273,10 @@ order by
let ownColumn: ColumnInfo = ownerColumn;
let isOneToMany: boolean;
isOneToMany = false;
let index = referencedEntity.Indexes.find(
let index = ownerEntity.Indexes.find(
(index) => {
return index.isUnique && index.columns.some(col => {
return col.name == relatedColumn!.name
return col.name == ownerColumn!.name
})
}
)
@ -293,11 +293,11 @@ order by
ownerRelation.relatedTable = relationTmp.referencedTable
ownerRelation.ownerTable = relationTmp.ownerTable
ownerRelation.ownerColumn = ownerEntity.EntityName.toLowerCase()
ownerRelation.relationType = isOneToMany ? "OneToMany" : "OneToOne"
ownerRelation.relationType = isOneToMany ? "ManyToOne" : "OneToOne"
ownerColumn.relations.push(ownerRelation)
if (isOneToMany) {
let col = new ColumnInfo()
col.name = ownerEntity.EntityName.toLowerCase() //+ 's'
col.name = ownerEntity.EntityName.toLowerCase() +'s'
let referencedRelation = new RelationInfo();
col.relations.push(referencedRelation)
referencedRelation.actionOnDelete = relationTmp.actionOnDelete
@ -307,7 +307,7 @@ order by
referencedRelation.relatedTable = relationTmp.ownerTable
referencedRelation.ownerTable = relationTmp.referencedTable
referencedRelation.ownerColumn = relatedColumn.name.toLowerCase()
referencedRelation.relationType = "ManyToOne"
referencedRelation.relationType = "OneToMany"
referencedEntity.Columns.push(col)
} else {
let col = new ColumnInfo()

View File

@ -1,4 +1,4 @@
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn} from "typeorm";
import {PrimaryGeneratedColumn, Column, Entity, OneToOne,JoinColumn,Index} from "typeorm";
import {PostDetails} from "./PostDetails";
import {PostCategory} from "./PostCategory";
import {PostAuthor} from "./PostAuthor";
@ -25,6 +25,7 @@ export class Post {
cascadeRemove: true
})
@JoinColumn()
@Index({ unique: true })
category: PostCategory;
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
@ -33,6 +34,7 @@ export class Post {
cascadeInsert: true
})
@JoinColumn()
@Index({ unique: true })
details: PostDetails;
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
@ -41,6 +43,7 @@ export class Post {
cascadeUpdate: true
})
@JoinColumn()
@Index({ unique: true })
image: PostImage;
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
@ -49,6 +52,7 @@ export class Post {
cascadeRemove: true
})
@JoinColumn()
@Index({ unique: true })
metadata: PostMetadata|null;
// post has relation with details. full cascades here
@ -58,11 +62,13 @@ export class Post {
cascadeRemove: true
})
@JoinColumn()
@Index({ unique: true })
information: PostInformation;
// post has relation with details. not cascades here. means cannot be persisted, updated or removed
@OneToOne(type => PostAuthor, author => author.post)
@JoinColumn()
@Index({ unique: true })
author: PostAuthor;
}

View File

@ -0,0 +1,62 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {PostDetails} from "./PostDetails";
import {PostCategory} from "./PostCategory";
import {PostAuthor} from "./PostAuthor";
import {PostInformation} from "./PostInformation";
import {PostImage} from "./PostImage";
import {PostMetadata} from "./PostMetadata";
@Entity("Post")
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
text: string;
// post has relation with category, however inverse relation is not set (category does not have relation with post set)
@ManyToOne(type => PostCategory, {
cascadeInsert: true,
cascadeUpdate: true,
cascadeRemove: true
})
category: PostCategory;
// post has relation with details. cascade inserts here means if new PostDetails instance will be set to this
// relation it will be inserted automatically to the db when you save this Post entity
@ManyToOne(type => PostDetails, details => details.posts, {
cascadeInsert: true
})
details: PostDetails;
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
// it will be inserted automatically to the db when you save this Post entity
@ManyToOne(type => PostImage, image => image.posts, {
cascadeUpdate: true
})
image: PostImage;
// post has relation with details. cascade update here means if new PostDetail instance will be set to this relation
// it will be inserted automatically to the db when you save this Post entity
@ManyToOne(type => PostMetadata, metadata => metadata.posts, {
cascadeRemove: true
})
metadata: PostMetadata|null;
// post has relation with details. full cascades here
@ManyToOne(type => PostInformation, information => information.posts, {
cascadeInsert: true,
cascadeUpdate: true,
cascadeRemove: true
})
information: PostInformation;
// post has relation with details. not cascades here. means cannot be persisted, updated or removed
@ManyToOne(type => PostAuthor, author => author.posts)
author: PostAuthor;
}

View File

@ -0,0 +1,16 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {Post} from "./Post";
@Entity("PostAuthor")
export class PostAuthor {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(type => Post, post => post.author)
posts: Post[];
}

View File

@ -0,0 +1,12 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
@Entity("PostCategory")
export class PostCategory {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}

View File

@ -0,0 +1,31 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {Post} from "./Post";
@Entity("PostDetails")
export class PostDetails {
@PrimaryGeneratedColumn()
id: number;
@Column({
nullable: true
})
authorName: string;
@Column({
nullable: true
})
comment: string;
@Column({
nullable: true
})
metadata: string;
@OneToMany(type => Post, post => post.details, {
cascadeInsert: true,
cascadeUpdate: true
})
posts: Post[];
}

View File

@ -0,0 +1,16 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {Post} from "./Post";
@Entity("PostImage")
export class PostImage {
@PrimaryGeneratedColumn()
id: number;
@Column()
url: string;
@OneToMany(type => Post, post => post.image)
posts: Post[];
}

View File

@ -0,0 +1,18 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {Post} from "./Post";
@Entity("PostInformation")
export class PostInformation {
@PrimaryGeneratedColumn()
id: number;
@Column()
text: string;
@OneToMany(type => Post, post => post.information, {
cascadeUpdate: true,
})
posts: Post[];
}

View File

@ -0,0 +1,16 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, JoinColumn } from "typeorm";
import {Post} from "./Post";
@Entity("PostMetadata")
export class PostMetadata {
@PrimaryGeneratedColumn()
id: number;
@Column()
description: string;
@OneToMany(type => Post, post => post.metadata)
posts: Post[];
}

View File

@ -61,6 +61,15 @@ export class EntityFileToJson {
retVal.entityName = trimmedLine.substring(trimmedLine.indexOf('class') + 5, trimmedLine.lastIndexOf('{')).trim().toLowerCase()
isInClassBody = true;
continue;
} else if (trimmedLine.startsWith('@Index')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
//TODO:Add indicies to comparision model
continue;
}
}
} else {
if (trimmedLine.startsWith('@Column')) {
@ -113,6 +122,7 @@ export class EntityFileToJson {
let column = new EntityColumn()
retVal.columns.push(column)
column.relationType = "ManyToOne"
column.isOwnerOfRelation=true;
continue;
}
} else if (trimmedLine.startsWith('@OneToMany')) {
@ -149,6 +159,15 @@ export class EntityFileToJson {
retVal.columns[retVal.columns.length - 1].isOwnerOfRelation = true;
continue;
}
} else if (trimmedLine.startsWith('@Index')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
//TODO:Add indicies to comparision model
continue;
}
} else if (trimmedLine.split(':').length - 1 > 0) {
retVal.columns[retVal.columns.length - 1].columnName = trimmedLine.split(':')[0].trim();
//TODO:Should check if null only column is nullable?