naming strategy

This commit is contained in:
Kononnable 2018-06-17 02:34:45 +02:00
parent 893162b881
commit 6b3c0bf9de
22 changed files with 276 additions and 144 deletions

View File

@ -1,39 +1,58 @@
import { NamingStrategy } from "./NamingStrategy";
import { EntityInfo } from "./models/EntityInfo";
import { RelationInfo } from "./models/RelationInfo";
import { DatabaseModel } from "./models/DatabaseModel";
export class DefaultNamingStrategy extends NamingStrategy {
relationName(
ownerEntity: EntityInfo,
referencedEntity: EntityInfo,
isOneToMany: boolean
columnOldName:string,
relation: RelationInfo,
dbModel:DatabaseModel
): string {
let columnName = ownerEntity.EntityName.toLowerCase();
if (columnName.endsWith("Id")) {
columnName = columnName.substring(0, columnName.lastIndexOf("Id"));
let isRelationToMany = relation.isOneToMany || relation.isManyToMany
let ownerEntity = dbModel.entities.filter(v => {
return v.EntityName==relation.ownerTable
})[0]
let referencedEntity = dbModel.entities.filter(v => {
return v.EntityName == relation.relatedTable
})[0]
let columnName = columnOldName[0].toLowerCase()+ columnOldName.substring(1,columnOldName.length);
if ( columnName.endsWith("id")) {
columnName = columnName.substring(0, columnName.lastIndexOf("id"));
}
columnName += isOneToMany ? "s" : "";
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.tsName == columnName;
}).length > 0
) {
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = ownerEntity.EntityName.toLowerCase();
if (columnName.endsWith("Id")) {
columnName = columnName.substring(
0,
columnName.lastIndexOf("Id")
);
if (!isNaN(parseInt(columnName[columnName.length-1]))) {
let num = columnName[columnName.length-1]
columnName = columnName.substring(0, columnName.length - 1)
columnName += (isRelationToMany ? "s" : "")+num.toString();
} else {
columnName += isRelationToMany ? "s" : "";
}
if (relation.relationType!="ManyToMany") {
if (columnOldName!=columnName) {
if (!relation.isOwner) {
if (ownerEntity.Columns.some(v => v.tsName == columnName)) {
columnName = columnName + "_"
for (let i = 2; i <= ownerEntity.Columns.length; i++) {
columnName = columnName.substring(0, columnName.length - 1) + i.toString();
if (ownerEntity.Columns.every(v => v.tsName != columnName)) break;
}
}
} else {
if (referencedEntity.Columns.some(v => v.tsName == columnName)) {
columnName = columnName + "_"
for (let i = 2; i <= referencedEntity.Columns.length; i++) {
columnName = columnName.substring(0, columnName.length - 1) + i.toString();
if (referencedEntity.Columns.every(v => v.tsName != columnName)) break;
}
}
columnName += (isOneToMany ? "s" : "") + i.toString();
if (
referencedEntity.Columns.filter(filterVal => {
return filterVal.tsName == columnName;
}).length == 0
)
break;
}
}
}
return columnName;
}

View File

@ -1,7 +1,8 @@
import { EntityInfo } from "./models/EntityInfo";
import { RelationInfo } from "./models/RelationInfo";
import { DatabaseModel } from "./models/DatabaseModel";
export abstract class NamingStrategy {
abstract relationName(ownerEntity: EntityInfo, referencedEntity: EntityInfo, isOneToMany: boolean): string;
abstract relationName(columnName: string, relation: RelationInfo, dbModel: DatabaseModel): string;
abstract entityName(entityName: string): string;

View File

@ -1,16 +1,120 @@
import { EntityInfo } from "./../models/EntityInfo";
import { DatabaseModel } from "./../models/DatabaseModel";
import * as TomgUtils from "./../Utils";
import { EntityInfo } from "../models/EntityInfo";
import { DatabaseModel } from "../models/DatabaseModel";
import * as TomgUtils from "../Utils";
import { RelationInfo } from "../models/RelationInfo";
import { ColumnInfo } from "../models/ColumnInfo";
import {
WithWidthColumnType,
WithPrecisionColumnType,
WithLengthColumnType
} from "./../../node_modules/typeorm/driver/types/ColumnTypes";
} from "typeorm/driver/types/ColumnTypes";
import { NamingStrategy } from "../NamingStrategy";
export abstract class AbstractDriver {
changeColumnNames(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
entity.Columns.forEach(column => {
let newName = this.namingStrategy.columnName(column.tsName);
entity.Indexes.forEach(index => {
index.columns
.filter(column2 => {
return column2.name == column.tsName;
})
.forEach(column2 => {
column2.name = newName;
});
});
dbModel.entities.forEach(entity2 => {
entity2.Columns.forEach(column2 => {
column2.relations
.filter(relation => {
return (
relation.relatedTable ==
entity.EntityName &&
relation.relatedColumn == column.tsName
);
})
.map(v => {
v.relatedColumn = newName;
});
column2.relations
.filter(relation => {
return (
relation.ownerTable == entity.EntityName &&
relation.ownerColumn == column.tsName
);
})
.map(v => {
v.ownerColumn = newName;
});
});
});
column.tsName = newName;
});
});
}
changeEntityNames(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
let newName = this.namingStrategy.columnName(entity.EntityName);
dbModel.entities.forEach(entity2 => {
entity2.Columns.forEach(column => {
column.relations.forEach(relation => {
if (relation.ownerTable == entity.EntityName)
relation.ownerTable = newName;
if (relation.relatedTable == entity.EntityName)
relation.relatedTable = newName;
});
});
});
entity.EntityName = newName;
});
}
changeRelationNames(dbModel: DatabaseModel) {
dbModel.entities.forEach(entity => {
entity.Columns.forEach(column => {
column.relations.forEach(relation => {
if (true || !relation.isOwner) {
let newName = this.namingStrategy.relationName(
column.tsName,
relation,
dbModel
);
dbModel.entities.forEach(entity2 => {
entity2.Columns.forEach(column2 => {
column2.relations.forEach(relation2 => {
if (
relation2.relatedTable ==
entity.EntityName &&
relation2.ownerColumn == column.tsName
) {
relation2.ownerColumn = newName;
}
if (
relation2.relatedTable ==
entity.EntityName &&
relation2.relatedColumn == column.tsName
) {
relation2.relatedColumn = newName;
}
if (relation.isOwner) {
entity.Indexes.forEach(ind => {
ind.columns.forEach(col => {
if (col.name == column.tsName) {
col.name = newName;
}
});
});
}
});
});
});
column.tsName = newName;
}
});
});
});
}
ColumnTypesWithWidth: WithWidthColumnType[] = [
"tinyint",
"smallint",
@ -99,31 +203,26 @@ export abstract class AbstractDriver {
});
let column1 = new ColumnInfo();
column1.tsName = this.namingStrategy.entityName(
namesOfRelatedTables[1]
);
column1.tsName = namesOfRelatedTables[1];
let col1Rel = new RelationInfo();
col1Rel.relatedTable = namesOfRelatedTables[1];
col1Rel.relatedColumn = this.namingStrategy.entityName(
namesOfRelatedTables[1]
);
col1Rel.relatedColumn = namesOfRelatedTables[1];
col1Rel.relationType = "ManyToMany";
col1Rel.isOwner = true;
col1Rel.ownerColumn = this.namingStrategy.entityName(
namesOfRelatedTables[0]
);
col1Rel.ownerColumn = namesOfRelatedTables[0];
column1.relations.push(col1Rel);
relatedTable1.Columns.push(column1);
let column2 = new ColumnInfo();
column2.tsName = this.namingStrategy.entityName(
namesOfRelatedTables[0]
);
column2.tsName = namesOfRelatedTables[0];
let col2Rel = new RelationInfo();
col2Rel.relatedTable = namesOfRelatedTables[0];
col2Rel.relatedColumn = this.namingStrategy.entityName(
namesOfRelatedTables[1]
);
col2Rel.relatedColumn = namesOfRelatedTables[1];
col2Rel.relationType = "ManyToMany";
col2Rel.isOwner = false;
column2.relations.push(col2Rel);
@ -155,8 +254,16 @@ export abstract class AbstractDriver {
await this.DisconnectFromServer();
this.FindManyToManyRelations(dbModel);
this.FindPrimaryColumnsFromIndexes(dbModel);
this.ApplyNamingStrategy(dbModel);
return dbModel;
}
private ApplyNamingStrategy(dbModel: DatabaseModel) {
this.changeColumnNames(dbModel);
this.changeEntityNames(dbModel);
this.changeRelationNames(dbModel);
}
abstract async ConnectToServer(
database: string,
server: string,
@ -280,11 +387,24 @@ export abstract class AbstractDriver {
? "ManyToOne"
: "OneToOne";
let columnName = this.namingStrategy.relationName(
ownerEntity,
referencedEntity,
isOneToMany
);
let columnName = ownerEntity.EntityName;
if (
referencedEntity.Columns.some(v => v.tsName == columnName)
) {
columnName = columnName + "_";
for (let i = 2; i <= referencedEntity.Columns.length; i++) {
columnName =
columnName.substring(0, columnName.length - 1) +
i.toString();
if (
referencedEntity.Columns.every(
v => v.tsName != columnName
)
)
break;
}
}
ownerRelation.ownerColumn = columnName;
ownerColumn.relations.push(ownerRelation);
if (isOneToMany) {
@ -300,7 +420,7 @@ export abstract class AbstractDriver {
referencedRelation.relatedColumn = ownerColumn.tsName;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.tsName.toLowerCase();
referencedRelation.ownerColumn = relatedColumn.tsName;
referencedRelation.relationType = "OneToMany";
referencedEntity.Columns.push(col);
} else {
@ -316,7 +436,7 @@ export abstract class AbstractDriver {
referencedRelation.relatedColumn = ownerColumn.tsName;
referencedRelation.relatedTable = relationTmp.ownerTable;
referencedRelation.ownerTable = relationTmp.referencedTable;
referencedRelation.ownerColumn = relatedColumn.tsName.toLowerCase();
referencedRelation.ownerColumn = relatedColumn.tsName;
referencedRelation.relationType = "OneToOne";
referencedEntity.Columns.push(col);
}

View File

@ -1,8 +1,8 @@
import { AbstractDriver } from "./AbstractDriver";
import * as MSSQL from "mssql";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import * as TomgUtils from "./../Utils";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
export class MssqlDriver extends AbstractDriver {
GetAllTablesQuery = async (schema: string) => {
@ -53,9 +53,7 @@ export class MssqlDriver extends AbstractDriver {
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.tsName = this.namingStrategy.entityName(
resp.COLUMN_NAME
);
colInfo.tsName = resp.COLUMN_NAME;
colInfo.sqlName = resp.COLUMN_NAME;
colInfo.is_nullable = resp.IS_NULLABLE == "YES";
colInfo.is_generated = resp.IsIdentity == 1;

View File

@ -1,8 +1,8 @@
import { AbstractDriver } from "./AbstractDriver";
import * as MYSQL from "mysql";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import * as TomgUtils from "./../Utils";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
export class MysqlDriver extends AbstractDriver {
readonly EngineName: string = "MySQL";
@ -45,9 +45,7 @@ export class MysqlDriver extends AbstractDriver {
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.tsName = this.namingStrategy.entityName(
resp.COLUMN_NAME
);
colInfo.tsName = resp.COLUMN_NAME;
colInfo.sqlName = resp.COLUMN_NAME;
colInfo.is_nullable = resp.IS_NULLABLE == "YES";
colInfo.is_generated = resp.IsIdentity == 1;

View File

@ -1,7 +1,7 @@
import { AbstractDriver } from "./AbstractDriver";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import * as TomgUtils from "./../Utils";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
export class OracleDriver extends AbstractDriver {
Oracle: any;
@ -55,9 +55,7 @@ export class OracleDriver extends AbstractDriver {
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.tsName = this.namingStrategy.entityName(
resp.COLUMN_NAME
);
colInfo.tsName = resp.COLUMN_NAME;
colInfo.sqlName = resp.COLUMN_NAME;
colInfo.is_nullable = resp.NULLABLE == "Y";
colInfo.is_generated = resp.IDENTITY_COLUMN == "YES";

View File

@ -1,8 +1,8 @@
import { AbstractDriver } from "./AbstractDriver";
import * as PG from "pg";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import * as TomgUtils from "./../Utils";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
export class PostgresDriver extends AbstractDriver {
private Connection: PG.Client;
@ -54,9 +54,7 @@ export class PostgresDriver extends AbstractDriver {
})
.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.tsName = this.namingStrategy.entityName(
resp.column_name
);
colInfo.tsName = resp.column_name;
colInfo.sqlName = resp.column_name;
colInfo.is_nullable = resp.is_nullable == "YES";
colInfo.is_generated = resp.isidentity == "YES";

View File

@ -1,7 +1,7 @@
import { AbstractDriver } from "./AbstractDriver";
import { ColumnInfo } from "./../models/ColumnInfo";
import { EntityInfo } from "./../models/EntityInfo";
import * as TomgUtils from "./../Utils";
import { ColumnInfo } from "../models/ColumnInfo";
import { EntityInfo } from "../models/EntityInfo";
import * as TomgUtils from "../Utils";
export class SqliteDriver extends AbstractDriver {
sqlite = require("sqlite3").verbose();
@ -41,7 +41,7 @@ export class SqliteDriver extends AbstractDriver {
}>(`PRAGMA table_info('${ent.EntityName}');`);
response.forEach(resp => {
let colInfo: ColumnInfo = new ColumnInfo();
colInfo.tsName = this.namingStrategy.entityName(resp.name);
colInfo.tsName = resp.name;
colInfo.sqlName = resp.name;
colInfo.is_nullable = resp.notnull == 0;
colInfo.isPrimary = resp.pk > 0;

View File

@ -24,8 +24,8 @@ import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, Man
})
{{toPropertyName tsName}}:{{ts_type}}{{#is_nullable}} | null{{/is_nullable}};
{{/relations}}{{#relations}}
@{{relationType}}(type=>{{toEntityName relatedTable}}, {{toPropertyName ../tsName}}=>{{toPropertyName ../tsName}}.{{#if isOwner}}{{toPropertyName ownerColumn}},{ {{#../isPrimary}}primary:true,{{/../isPrimary}}{{^../is_nullable}} nullable:false,{{/../is_nullable}}{{#actionOnDelete}}onDelete: '{{.}}',{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{else}}{{toPropertyName relatedColumn}}{{#actionOnDelete}},{ onDelete: '{{.}}' }{{/actionOnDelete}}{{/if}}){{#isOwner}}
{{#if isManyToMany}}@JoinTable(){{else}}@JoinColumn({ name:'{{ ../tsName}}'}){{/if}}{{/isOwner}}
@{{relationType}}(type=>{{toEntityName relatedTable}}, {{toEntityName relatedTable}}=>{{toEntityName relatedTable}}.{{#if isOwner}}{{toPropertyName ownerColumn}},{ {{#../isPrimary}}primary:true,{{/../isPrimary}}{{^../is_nullable}} nullable:false,{{/../is_nullable}}{{#actionOnDelete}}onDelete: '{{.}}',{{/actionOnDelete}}{{#actionOnUpdate}}onUpdate: '{{.}}'{{/actionOnUpdate}} }{{else}}{{toPropertyName relatedColumn}}{{#actionOnDelete}},{ onDelete: '{{.}}' }{{/actionOnDelete}}{{/if}}){{#isOwner}}
{{#if isManyToMany}}@JoinTable(){{else}}@JoinColumn({ name:'{{ ../sqlName}}'}){{/if}}{{/isOwner}}
{{#if (or isOneToMany isManyToMany)}}{{toPropertyName ../tsName}}:{{toLazy (concat (toEntityName relatedTable) "[]")}};
{{else}}{{toPropertyName ../tsName}}:{{toLazy (concat (toEntityName relatedTable) ' | null')}};
{{/if}}{{/relations}}

View File

@ -10,7 +10,7 @@ export class Category {
@Column()
name: string;
@ManyToMany(type => Post, post => post.Category)
Post: Promise<Post[]>;
@ManyToMany(type => Post, post => post.categorys)
posts: Promise<Post[]>;
}

View File

@ -21,10 +21,10 @@ export class Post {
})
author: Promise<Author | null>;
@ManyToMany(type => Category, category => category.Post, {
@ManyToMany(type => Category, category => category.posts, {
// cascade: true
})
@JoinTable()
Category: Promise<Category[]>;
categorys: Promise<Category[]>;
}

View File

@ -1,5 +1,5 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, ManyToMany, JoinColumn, JoinTable } from "typeorm";
import {PostDetails} from "./PostDetails";
import {PostDetail} from "./PostDetail";
import {PostCategory} from "./PostCategory";
import {PostAuthor} from "./PostAuthor";
import {PostInformation} from "./PostInformation";
@ -23,40 +23,40 @@ export class Post {
cascade: true
})
@JoinTable()
PostCategory: PostCategory[];
postCategorys: 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
@ManyToMany(type => PostDetails, details => details.Post, {
@ManyToMany(type => PostDetail, details => details.posts, {
cascade: true
})
@JoinTable()
PostDetails: PostDetails[];
postDetails: PostDetail[];
// 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
@ManyToMany(type => PostImage, image => image.Post, {
@ManyToMany(type => PostImage, image => image.posts, {
cascade: true
})
@JoinTable()
PostImage: PostImage[];
postImages: 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
@ManyToMany(type => PostMetadata, metadata => metadata.Post)
@ManyToMany(type => PostMetadata, metadata => metadata.posts)
@JoinTable()
PostMetadata: PostMetadata[];
postMetadatas: PostMetadata[];
// post has relation with details. full cascades here
@ManyToMany(type => PostInformation, information => information.Post, {
@ManyToMany(type => PostInformation, information => information.posts, {
cascade: true
})
@JoinTable()
PostInformation: PostInformation[];
postInformations: PostInformation[];
// post has relation with details. not cascades here. means cannot be persisted, updated or removed
@ManyToMany(type => PostAuthor, author => author.Post)
@ManyToMany(type => PostAuthor, author => author.posts)
@JoinTable()
PostAuthor: PostAuthor[];
postAuthors: PostAuthor[];
}

View File

@ -10,7 +10,7 @@ export class PostAuthor {
@Column()
name: string;
@ManyToMany(type => Post, post => post.PostAuthor)
Post: Post[];
@ManyToMany(type => Post, post => post.postAuthors)
posts: Post[];
}

View File

@ -1,8 +1,8 @@
import { PrimaryGeneratedColumn, Column, Entity, OneToOne, OneToMany, ManyToOne, ManyToMany, JoinColumn, JoinTable } from "typeorm";
import {Post} from "./Post";
@Entity("PostDetails")
export class PostDetails {
@Entity("PostDetail")
export class PostDetail {
@PrimaryGeneratedColumn()
id: number;
@ -16,7 +16,7 @@ export class PostDetails {
@Column()
metadata: string;
@ManyToMany(type => Post, post => post.PostDetails)
Post: Post[];
@ManyToMany(type => Post, post => post.postDetails)
posts: Post[];
}

View File

@ -10,7 +10,7 @@ export class PostImage {
@Column()
url: string;
@ManyToMany(type => Post, post => post.PostImage)
Post: Post[];
@ManyToMany(type => Post, post => post.postImages)
posts: Post[];
}

View File

@ -10,7 +10,7 @@ export class PostInformation {
@Column()
text: string;
@ManyToMany(type => Post, post => post.PostInformation)
Post: Post[];
@ManyToMany(type => Post, post => post.postInformations)
posts: Post[];
}

View File

@ -10,7 +10,7 @@ export class PostMetadata {
@Column()
description: string;
@ManyToMany(type => Post, post => post.PostMetadata)
Post: Post[];
@ManyToMany(type => Post, post => post.postMetadatas)
posts: Post[];
}

View File

@ -11,8 +11,8 @@ export class Post {
type: string;
// post has relation with details. not cascades here. means cannot be persisted, updated or removed
@ManyToMany(type => PostAuthor, author => author.Post)
@ManyToMany(type => PostAuthor, author => author.posts)
@JoinTable()
PostAuthor: PostAuthor[];
postAuthors: PostAuthor[];
}

View File

@ -15,7 +15,7 @@ export class PostAuthor {
@Column()
name: string;
@ManyToMany(type => Post, post => post.PostAuthor)
Post: Post[];
@ManyToMany(type => Post, post => post.postAuthors)
posts: Post[];
}

View File

@ -4,33 +4,33 @@ import {quests} from "./quests";
@Entity("feedextrainfo")
@Index("feedExtraInfo_FeedOwnerId_idx",["FeedOwnerId",])
@Index("feedExtraInfo_ReaderId_idx",["ReaderId",])
@Index("feedExtraInfo_QuestId_idx",["QuestId",])
@Index("feedExtraInfo_FeedOwnerId_idx",["feedOwnerId",])
@Index("feedExtraInfo_ReaderId_idx",["readerId",])
@Index("feedExtraInfo_QuestId_idx",["questId",])
export class feedextrainfo {
@OneToOne(type=>users, FeedOwnerId=>FeedOwnerId.feedextrainfo,{primary:true, nullable:false, })
@JoinColumn({ name:'FeedOwnerId'})
FeedOwnerId:users;
feedOwnerId:users;
@OneToOne(type=>quests, QuestId=>QuestId.feedextrainfo,{primary:true, nullable:false, })
@JoinColumn({ name:'QuestId'})
QuestId:quests;
questId:quests;
@OneToOne(type=>users, ReaderId=>ReaderId.feedextrainfo2,{primary:true, nullable:false, })
@JoinColumn({ name:'ReaderId'})
ReaderId:users;
readerId:users;
@Column("int",{
@Column("int",{
nullable:false,
name:"MostUpdatedFeedEntryIdUserRead"
})
MostUpdatedFeedEntryIdUserRead:number;
}

View File

@ -5,16 +5,16 @@ import {feedextrainfo} from "./feedextrainfo";
@Entity("quests")
export class quests {
@Column("int",{
@Column("int",{
nullable:false,
primary:true,
name:"QuestId"
})
QuestId:number;
@OneToOne(type=>feedextrainfo, feedextrainfo=>feedextrainfo.QuestId)
@OneToOne(type=>feedextrainfo, feedextrainfo=>feedextrainfo.questId)
feedextrainfo:feedextrainfo;
}

View File

@ -5,21 +5,21 @@ import {feedextrainfo} from "./feedextrainfo";
@Entity("users")
export class users {
@Column("int",{
@Column("int",{
nullable:false,
primary:true,
name:"UserId"
})
UserId:number;
@OneToOne(type=>feedextrainfo, feedextrainfo=>feedextrainfo.FeedOwnerId)
@OneToOne(type=>feedextrainfo, feedextrainfo=>feedextrainfo.feedOwnerId)
feedextrainfo:feedextrainfo;
@OneToOne(type=>feedextrainfo, feedextrainfo2=>feedextrainfo2.ReaderId)
@OneToOne(type=>feedextrainfo, feedextrainfo2=>feedextrainfo2.readerId)
feedextrainfo2:feedextrainfo;
}