mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added entity schemas sample draft
This commit is contained in:
parent
0055a381d1
commit
d4cc792b95
47
sample/sample24-schemas/app.ts
Normal file
47
sample/sample24-schemas/app.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import {createConnection, CreateConnectionOptions} from "../../src/typeorm";
|
||||
import {Post} from "./entity/Post";
|
||||
|
||||
// NOTE: this example is not working yet, only concepts of how this feature must work described here
|
||||
|
||||
const options: CreateConnectionOptions = {
|
||||
driver: "mysql",
|
||||
connection: {
|
||||
host: "192.168.99.100",
|
||||
port: 3306,
|
||||
username: "root",
|
||||
password: "admin",
|
||||
database: "test",
|
||||
autoSchemaCreate: true
|
||||
},
|
||||
// entitySchemaDirectories: [__dirname + "/schemas"],
|
||||
entitySchemas: [
|
||||
require("./schemas/post.json"),
|
||||
require("./schemas/post-details.json"),
|
||||
require("./schemas/category.json"),
|
||||
require("./schemas/image.json")
|
||||
]
|
||||
};
|
||||
|
||||
createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository<Post>("post");
|
||||
|
||||
let post: Post = {
|
||||
title: "Hello post",
|
||||
text: "I am virtual post!",
|
||||
details: {
|
||||
metadata: "#post,#virtual",
|
||||
comment: "it all about a post"
|
||||
},
|
||||
images: [],
|
||||
secondaryImages: [],
|
||||
categories: []
|
||||
};
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
})
|
||||
.catch(error => console.log(error.stack ? error.stack : error));
|
||||
|
||||
}).catch(error => console.log(error.stack ? error.stack : error));
|
||||
9
sample/sample24-schemas/entity/Category.ts
Normal file
9
sample/sample24-schemas/entity/Category.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import {Post} from "./Post";
|
||||
|
||||
export interface Category {
|
||||
|
||||
id?: number;
|
||||
description: string;
|
||||
posts?: Post[];
|
||||
|
||||
}
|
||||
11
sample/sample24-schemas/entity/Image.ts
Normal file
11
sample/sample24-schemas/entity/Image.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import {Post} from "./Post";
|
||||
|
||||
export interface Image {
|
||||
|
||||
id?: number;
|
||||
name: string;
|
||||
url: string;
|
||||
post?: Post;
|
||||
secondaryPost?: Post;
|
||||
|
||||
}
|
||||
15
sample/sample24-schemas/entity/Post.ts
Normal file
15
sample/sample24-schemas/entity/Post.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import {Image} from "./Image";
|
||||
import {Category} from "./Category";
|
||||
import {PostDetails} from "./PostDetails";
|
||||
|
||||
export interface Post {
|
||||
|
||||
id?: number;
|
||||
title: string;
|
||||
text: string;
|
||||
details?: PostDetails;
|
||||
images?: Image[];
|
||||
secondaryImages?: Image[];
|
||||
categories?: Category[];
|
||||
|
||||
}
|
||||
10
sample/sample24-schemas/entity/PostDetails.ts
Normal file
10
sample/sample24-schemas/entity/PostDetails.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {Post} from "./Post";
|
||||
|
||||
export interface PostDetails {
|
||||
|
||||
id?: number;
|
||||
metadata: string;
|
||||
comment: string;
|
||||
post?: Post;
|
||||
|
||||
}
|
||||
39
sample/sample24-schemas/schemas/Image.json
Normal file
39
sample/sample24-schemas/schemas/Image.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "Image",
|
||||
"table": {
|
||||
"name": "sample24_image"
|
||||
},
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "int",
|
||||
"primary": true,
|
||||
"generated": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"post": {
|
||||
"target": "Post",
|
||||
"type": "many-to-one",
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true,
|
||||
"inverseSide": "images"
|
||||
},
|
||||
"secondaryImages": {
|
||||
"target": "Post",
|
||||
"type": "many-to-one",
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true,
|
||||
"inverseSide": "secondaryImages"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
sample/sample24-schemas/schemas/category.json
Normal file
27
sample/sample24-schemas/schemas/category.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "Category",
|
||||
"table": {
|
||||
"name": "sample24_category"
|
||||
},
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "int",
|
||||
"primary": true,
|
||||
"generated": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"posts": {
|
||||
"target": "Post",
|
||||
"type": "many-to-many",
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true,
|
||||
"inverseSide": "categories"
|
||||
}
|
||||
}
|
||||
}
|
||||
29
sample/sample24-schemas/schemas/post-details.json
Normal file
29
sample/sample24-schemas/schemas/post-details.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "PostDetails",
|
||||
"table": {
|
||||
"name": "sample24_post_details"
|
||||
},
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "int",
|
||||
"primary": true,
|
||||
"generated": true
|
||||
},
|
||||
"comment": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
},
|
||||
"metadata": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"post": {
|
||||
"target": "Post",
|
||||
"type": "one-to-one",
|
||||
"owner": false,
|
||||
"inverseSide": "postDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
54
sample/sample24-schemas/schemas/post.json
Normal file
54
sample/sample24-schemas/schemas/post.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "Post",
|
||||
"table": {
|
||||
"name": "sample24_post"
|
||||
},
|
||||
"columns": {
|
||||
"id": {
|
||||
"type": "int",
|
||||
"primary": true,
|
||||
"generated": true
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
},
|
||||
"text": {
|
||||
"type": "string",
|
||||
"nullable": false
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"details": {
|
||||
"target": "PostDetails",
|
||||
"type": "one-to-one",
|
||||
"owner": true,
|
||||
"inverseSide": "post",
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true
|
||||
},
|
||||
"images": {
|
||||
"target": "Image",
|
||||
"type": "one-to-many",
|
||||
"inverseSide": "post",
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true
|
||||
},
|
||||
"secondaryImages": {
|
||||
"target": "Image",
|
||||
"type": "one-to-many",
|
||||
"inverseSide": "secondaryPost"
|
||||
},
|
||||
"categories": {
|
||||
"target": "Category",
|
||||
"type": "many-to-many",
|
||||
"owner": true,
|
||||
"cascadeInsert": true,
|
||||
"cascadeUpdate": true,
|
||||
"cascadeRemove": true,
|
||||
"inverseSide": "posts"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,11 @@ export interface CreateConnectionOptions {
|
||||
*/
|
||||
namingStrategies?: Function[];
|
||||
|
||||
/**
|
||||
* Entity schemas to be loaded for the new connection.
|
||||
*/
|
||||
entitySchemas?: any[];
|
||||
|
||||
/**
|
||||
* List of directories from where entities will be loaded.
|
||||
*/
|
||||
@ -49,4 +54,9 @@ export interface CreateConnectionOptions {
|
||||
* List of directories from where naming strategies will be loaded.
|
||||
*/
|
||||
namingStrategyDirectories?: string[];
|
||||
|
||||
/**
|
||||
* List of directories from where entity schemas will be loaded.
|
||||
*/
|
||||
entitySchemaDirectories?: string[];
|
||||
}
|
||||
@ -243,30 +243,63 @@ export class Connection {
|
||||
/**
|
||||
* Gets repository for the given entity class.
|
||||
*/
|
||||
getRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): Repository<Entity> {
|
||||
getRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): Repository<Entity>;
|
||||
// getRepository<Entity>(entityClass: Function): Repository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity name.
|
||||
*/
|
||||
getRepository<Entity>(entityClass: string): Repository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity class or name.
|
||||
*/
|
||||
getRepository<Entity>(entityClassOrName: ConstructorFunction<Entity>|Function|string): Repository<Entity> {
|
||||
if (!this.isConnected)
|
||||
throw new NoConnectionForRepositoryError(this.name);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClass);
|
||||
let metadata: EntityMetadata;
|
||||
if (typeof entityClassOrName === "string") {
|
||||
metadata = this.entityMetadatas.findByName(entityClassOrName);
|
||||
} else {
|
||||
metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
}
|
||||
|
||||
const repoMeta = this.repositoryAndMetadatas.find(repoMeta => repoMeta.metadata === metadata);
|
||||
if (!repoMeta)
|
||||
throw new RepositoryNotFoundError(this.name, entityClass);
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
|
||||
return repoMeta.repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tree repository for the given entity class.
|
||||
* Gets repository for the given entity class.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): TreeRepository<Entity> {
|
||||
const repository = this.getRepository(entityClass);
|
||||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): TreeRepository<Entity>;
|
||||
// getTreeRepository<Entity>(entityClass: Function): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity name.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClass: string): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity class or name.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClassOrName: ConstructorFunction<Entity>|Function|string): TreeRepository<Entity> {
|
||||
if (!this.isConnected)
|
||||
throw new NoConnectionForRepositoryError(this.name);
|
||||
|
||||
const metadata = this.entityMetadatas.findByTarget(entityClass);
|
||||
let metadata: EntityMetadata;
|
||||
if (typeof entityClassOrName === "string") {
|
||||
metadata = this.entityMetadatas.findByName(entityClassOrName);
|
||||
} else {
|
||||
metadata = this.entityMetadatas.findByTarget(entityClassOrName);
|
||||
}
|
||||
|
||||
const repoMeta = this.repositoryAndMetadatas.find(repoMeta => repoMeta.metadata === metadata);
|
||||
if (!repoMeta)
|
||||
throw new RepositoryNotFoundError(this.name, entityClass);
|
||||
throw new RepositoryNotFoundError(this.name, entityClassOrName);
|
||||
if (!repoMeta.metadata.table.isClosure)
|
||||
throw new Error(`Cannot get a tree repository. ${repoMeta.metadata.name} is not a tree table. Try to use @ClosureTable decorator instead of @Table.`);
|
||||
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
export class RepositoryNotFoundError extends Error {
|
||||
name = "RepositoryNotFoundError";
|
||||
|
||||
constructor(connectionName: string, entityClass: Function) {
|
||||
constructor(connectionName: string, entityClass: Function|string) {
|
||||
super();
|
||||
const targetName = (<any> entityClass).name ? (<any> entityClass).name : entityClass;
|
||||
const targetName = typeof entityClass === "function" && (<any> entityClass).name ? (<any> entityClass).name : entityClass;
|
||||
this.message = `No repository for "${targetName}" was found. Looks like this entity is not registered in ` +
|
||||
`current "${connectionName}" connection?`;
|
||||
}
|
||||
|
||||
@ -24,17 +24,47 @@ export class EntityManager {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets repository of the given entity.
|
||||
* Gets repository for the given entity class.
|
||||
*/
|
||||
getRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): Repository<Entity> {
|
||||
return this.connection.getRepository(entityClass);
|
||||
getRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): Repository<Entity>;
|
||||
// getRepository<Entity>(entityClass: Function): Repository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity name.
|
||||
*/
|
||||
getRepository<Entity>(entityClass: string): Repository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity class or name.
|
||||
*/
|
||||
getRepository<Entity>(entityClassOrName: ConstructorFunction<Entity>|Function|string): Repository<Entity> {
|
||||
if (typeof entityClassOrName === "string") {
|
||||
return this.connection.getRepository<Entity>(entityClassOrName);
|
||||
} else {
|
||||
return this.connection.getRepository(<ConstructorFunction<Entity>|Function> entityClassOrName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a tree repository of the given entity.
|
||||
* Gets repository for the given entity class.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): TreeRepository<Entity> {
|
||||
return this.connection.getTreeRepository(entityClass);
|
||||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity>|Function): TreeRepository<Entity>;
|
||||
// getTreeRepository<Entity>(entityClass: Function): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity name.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClass: string): TreeRepository<Entity>;
|
||||
|
||||
/**
|
||||
* Gets repository for the given entity class or name.
|
||||
*/
|
||||
getTreeRepository<Entity>(entityClassOrName: ConstructorFunction<Entity>|Function|string): TreeRepository<Entity> {
|
||||
if (typeof entityClassOrName === "string") {
|
||||
return this.connection.getTreeRepository<Entity>(entityClassOrName);
|
||||
} else {
|
||||
return this.connection.getTreeRepository(<ConstructorFunction<Entity>|Function> entityClassOrName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -21,5 +21,13 @@ export class EntityMetadataCollection extends Array<EntityMetadata> {
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
findByName(name: string) {
|
||||
const metadata = this.find(metadata => metadata.name === name);
|
||||
if (!metadata)
|
||||
throw new EntityMetadataNotFound(name);
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,9 +4,9 @@
|
||||
export class EntityMetadataNotFound extends Error {
|
||||
name = "EntityMetadataNotFound";
|
||||
|
||||
constructor(target: Function) {
|
||||
constructor(target: Function|string) {
|
||||
super();
|
||||
const targetName = (<any> target).name ? (<any> target).name : target;
|
||||
const targetName = typeof target === "function" && (<any> target).name ? (<any> target).name : target;
|
||||
this.message = `No metadata for "${targetName}" was found.`;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user