better handling of OneToMany/OneToOne relations
This commit is contained in:
parent
694b41cd79
commit
d870654fc8
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
}
|
62
test/integration/examples/sample3-many-to-one/entity/Post.ts
Normal file
62
test/integration/examples/sample3-many-to-one/entity/Post.ts
Normal 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;
|
||||
|
||||
}
|
@ -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[];
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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[];
|
||||
|
||||
}
|
@ -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[];
|
||||
|
||||
}
|
@ -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[];
|
||||
|
||||
}
|
@ -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[];
|
||||
|
||||
}
|
@ -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?
|
||||
|
Loading…
Reference in New Issue
Block a user