mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
Merge pull request #337 from typeorm/query-builder-refactoring
refactored query builder - refactored JOIN part
This commit is contained in:
commit
be7244a025
@ -18,6 +18,14 @@ each for its own `findOne*` or `find*` methods
|
||||
* table decorators were not removed in the release, however they will be removed in next. Be sure to replace them before that.
|
||||
* `QueryBuilder#setFirstResult` has been renamed to `QueryBuilder#skip`
|
||||
* `QueryBuilder#setMaxResults` has been renamed to `QueryBuilder#take`
|
||||
* renamed `entityManager` to `manager` in `Connection`, `AbstractRepository` and event objects
|
||||
* renamed `persist` to `save` in `EntityManager` and `Repository` objects
|
||||
* `@AbstractEntity` is deprecated. Now there is no need to mark class with a decorator, it can extend any class with columns
|
||||
* `SpecificRepository` is deprecated for now
|
||||
* `transaction` method has been removed from `Repository`. Use `EntityManager#transaction` method instead
|
||||
* custom repositories do not support container anymore
|
||||
* added ActiveRecord support (by extending EntityModel) class
|
||||
|
||||
|
||||
### NEW FEATURES
|
||||
|
||||
|
||||
@ -362,7 +362,7 @@ createConnection(/*...*/).then(connection => {
|
||||
photo.views = 1;
|
||||
photo.isPublished = true;
|
||||
|
||||
connection.entityManager
|
||||
connection.manager
|
||||
.persist(photo)
|
||||
.then(photo => {
|
||||
console.log("Photo has been saved");
|
||||
@ -388,7 +388,7 @@ createConnection(/*...*/).then(async connection => {
|
||||
photo.views = 1;
|
||||
photo.isPublished = true;
|
||||
|
||||
await connection.entityManager.persist(photo);
|
||||
await connection.manager.persist(photo);
|
||||
console.log("Photo has been saved");
|
||||
|
||||
}).catch(error => console.log(error));
|
||||
@ -405,7 +405,7 @@ import {Photo} from "./entity/Photo";
|
||||
createConnection(/*...*/).then(async connection => {
|
||||
|
||||
/*...*/
|
||||
let savedPhotos = await connection.entityManager.find(Photo);
|
||||
let savedPhotos = await connection.manager.find(Photo);
|
||||
console.log("All photos from the db: ", savedPhotos);
|
||||
|
||||
}).catch(error => console.log(error));
|
||||
|
||||
@ -424,7 +424,7 @@ createConnection(/*...*/).then(connection => {
|
||||
photo.views = 1;
|
||||
photo.isPublished = true;
|
||||
|
||||
connection.entityManager
|
||||
connection.manager
|
||||
.persist(photo)
|
||||
.then(photo => {
|
||||
console.log("Photo has been saved");
|
||||
@ -450,7 +450,7 @@ createConnection(/*...*/).then(async connection => {
|
||||
photo.views = 1;
|
||||
photo.isPublished = true;
|
||||
|
||||
await connection.entityManager.persist(photo);
|
||||
await connection.manager.persist(photo);
|
||||
console.log("Photo has been saved");
|
||||
|
||||
}).catch(error => console.log(error));
|
||||
@ -470,7 +470,7 @@ import {Photo} from "./entity/Photo";
|
||||
createConnection(/*...*/).then(async connection => {
|
||||
|
||||
/*...*/
|
||||
let savedPhotos = await connection.entityManager.find(Photo);
|
||||
let savedPhotos = await connection.manager.find(Photo);
|
||||
console.log("All photos from the db: ", savedPhotos);
|
||||
|
||||
}).catch(error => console.log(error));
|
||||
|
||||
48
package.json
48
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "typeorm",
|
||||
"private": true,
|
||||
"version": "0.1.0-alpha.1",
|
||||
"description": "Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases.",
|
||||
"version": "0.1.0-alpha.3",
|
||||
"description": "Data-Mapper ORM for TypeScript, ES7, ES6, ES5. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL, MongoDB databases.",
|
||||
"license": "MIT",
|
||||
"readmeFilename": "README.md",
|
||||
"author": {
|
||||
@ -36,13 +36,13 @@
|
||||
"websql-orm"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chai": "^3.4.35",
|
||||
"@types/chai-as-promised": "0.0.29",
|
||||
"@types/mocha": "^2.2.39",
|
||||
"@types/chai": "^3.5.2",
|
||||
"@types/chai-as-promised": "0.0.30",
|
||||
"@types/mocha": "^2.2.41",
|
||||
"@types/mongodb": "^2.1.41",
|
||||
"@types/node": "^7.0.5",
|
||||
"@types/node": "^7.0.16",
|
||||
"@types/promises-a-plus": "0.0.27",
|
||||
"@types/sinon": "^1.16.35",
|
||||
"@types/sinon": "^2.2.0",
|
||||
"chai": "^3.4.1",
|
||||
"chai-as-promised": "^6.0.0",
|
||||
"del": "^2.2.2",
|
||||
@ -52,33 +52,33 @@
|
||||
"gulp-mocha": "^3.0.1",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-replace": "^0.5.4",
|
||||
"gulp-shell": "^0.6.1",
|
||||
"gulp-sourcemaps": "^2.4.1",
|
||||
"gulp-tslint": "^7.1.0",
|
||||
"gulp-typescript": "^3.1.5",
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulpclass": "0.1.1",
|
||||
"mocha": "^3.2.0",
|
||||
"mongodb": "^2.2.24",
|
||||
"gulp-shell": "^0.6.3",
|
||||
"gulp-sourcemaps": "^2.6.0",
|
||||
"gulp-tslint": "^8.0.0",
|
||||
"gulp-typescript": "^3.1.6",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"gulpclass": "^0.1.2",
|
||||
"mocha": "^2.5.3",
|
||||
"mongodb": "^2.2.26",
|
||||
"mssql": "^3.3.0",
|
||||
"mysql": "^2.12.0",
|
||||
"mysql2": "^1.2.0",
|
||||
"pg": "^6.1.2",
|
||||
"remap-istanbul": "^0.9.1",
|
||||
"sinon": "^1.17.7",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"pg": "^6.1.5",
|
||||
"remap-istanbul": "^0.9.5",
|
||||
"sinon": "^2.2.0",
|
||||
"sinon-chai": "^2.10.0",
|
||||
"sqlite3": "^3.1.8",
|
||||
"ts-node": "^2.1.0",
|
||||
"tslint": "^4.4.2",
|
||||
"ts-node": "^3.0.3",
|
||||
"tslint": "^5.2.0",
|
||||
"tslint-stylish": "^2.1.0",
|
||||
"typescript": "^2.2.1"
|
||||
"typescript": "^2.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"app-root-path": "^2.0.1",
|
||||
"glob": "^7.1.1",
|
||||
"reflect-metadata": "^0.1.9",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"yargonaut": "^1.1.2",
|
||||
"yargs": "^6.6.0"
|
||||
"yargs": "^8.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/.bin/gulp tests"
|
||||
|
||||
@ -43,7 +43,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved: ", post))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ createConnection(options).then(connection => {
|
||||
post.images.push(image);
|
||||
post.categories = [category1, category2];
|
||||
|
||||
postRepository.persist(post).then(result => {
|
||||
postRepository.save(post).then(result => {
|
||||
|
||||
/*const qb = postRepository.createQueryBuilder("post")
|
||||
.leftJoinAndSelect("post.details", "details")
|
||||
|
||||
@ -44,11 +44,11 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(EverythingEntity);
|
||||
|
||||
postRepository
|
||||
.persist(entity)
|
||||
.save(entity)
|
||||
.then(entity => {
|
||||
console.log("EverythingEntity has been saved. Lets insert a new one to update it later");
|
||||
delete entity.id;
|
||||
return postRepository.persist(entity);
|
||||
return postRepository.save(entity);
|
||||
})
|
||||
.then(entity => {
|
||||
console.log("Second entity has been inserted. Lets update it");
|
||||
@ -72,13 +72,13 @@ createConnection(options).then(connection => {
|
||||
entity.jsonColumn = [{ olleh: "hello" }, { dlrow: "world" }];
|
||||
entity.alsoJson = { olleh: "hello", dlrow: "world" };
|
||||
|
||||
return postRepository.persist(entity);
|
||||
return postRepository.save(entity);
|
||||
})
|
||||
.then(entity => {
|
||||
console.log("Entity has been updated. Persist once again to make find and remove then");
|
||||
|
||||
delete entity.id;
|
||||
return postRepository.persist(entity);
|
||||
return postRepository.save(entity);
|
||||
})
|
||||
.then(entity => {
|
||||
return postRepository.findOneById(entity.id);
|
||||
|
||||
@ -27,7 +27,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved"))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
|
||||
@ -6,12 +6,12 @@ import {snakeCase} from "../../../src/util/StringUtils";
|
||||
@NamingStrategy("custom_strategy")
|
||||
export class CustomNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(className: string, customName: string): string {
|
||||
return customName ? customName : snakeCase(className);
|
||||
tableName(targetName: string, userSpecifiedName: string): string {
|
||||
return userSpecifiedName ? userSpecifiedName : snakeCase(targetName);
|
||||
}
|
||||
|
||||
columnName(propertyName: string, customName: string): string {
|
||||
return customName ? customName : snakeCase(propertyName);
|
||||
columnName(propertyName: string, customName: string, embeddedPrefixes: string[]): string {
|
||||
return snakeCase(embeddedPrefixes.concat(customName ? customName : propertyName).join("_"));
|
||||
}
|
||||
|
||||
columnNameCustomized(customName: string): string {
|
||||
|
||||
@ -62,14 +62,14 @@ createConnection(options).then(connection => {
|
||||
let blogRepository = connection.getRepository(Blog);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("post is loaded: ", loadedPost);
|
||||
return blogRepository.persist(blog);
|
||||
return blogRepository.save(blog);
|
||||
})
|
||||
.then(blog => {
|
||||
console.log("Blog has been saved");
|
||||
@ -77,7 +77,7 @@ createConnection(options).then(connection => {
|
||||
})
|
||||
.then(loadedBlog => {
|
||||
console.log("blog is loaded: ", loadedBlog);
|
||||
return blogRepository.persist(blog);
|
||||
return blogRepository.save(blog);
|
||||
})
|
||||
.catch(error => console.log("Cannot save. Error: ", error.stack ? error.stack : error));
|
||||
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
import {Column} from "../../../src/index";
|
||||
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
|
||||
import {BasePost} from "./BasePost";
|
||||
import {PostAuthor} from "./PostAuthor";
|
||||
import {ManyToOne} from "../../../src/decorator/relations/ManyToOne";
|
||||
import {PrimaryColumn} from "../../../src/decorator/columns/PrimaryColumn";
|
||||
|
||||
@AbstractEntity()
|
||||
export class BaseObject extends BasePost {
|
||||
|
||||
@PrimaryColumn("double", { generated: true })
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column} from "../../../src/index";
|
||||
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
|
||||
|
||||
@AbstractEntity()
|
||||
export class BasePost {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
|
||||
@ -29,7 +29,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved"))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved"));
|
||||
|
||||
}, error => console.log("Cannot connect: ", error));
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import {PrimaryGeneratedColumn, Column} from "../../../src/index";
|
||||
import {Index} from "../../../src/decorator/Index";
|
||||
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
|
||||
|
||||
@AbstractEntity()
|
||||
@Index("my_index_with_id_and_text", ["id", "text"])
|
||||
export class BasePost {
|
||||
|
||||
|
||||
@ -28,12 +28,12 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log(`Post has been saved: `, post);
|
||||
console.log(`Post's version is ${post.version}. Lets change post's text and update it:`);
|
||||
post.title = "updating title";
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
|
||||
}).then(post => {
|
||||
console.log(`Post has been updated. Post's version is ${post.version}`);
|
||||
|
||||
@ -37,7 +37,7 @@ createConnection(options).then(connection => {
|
||||
// same as: post.author = Promise.resolve(author);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved. Lets save post from inverse side.");
|
||||
console.log(post);
|
||||
@ -47,14 +47,14 @@ createConnection(options).then(connection => {
|
||||
secondPost.title = "About second post";
|
||||
author.posts = Promise.resolve([secondPost]);
|
||||
|
||||
return authorRepository.persist(author);
|
||||
return authorRepository.save(author);
|
||||
})
|
||||
.then((author: any) => { // temporary
|
||||
console.log("Author with a new post has been saved. Lets try to update post in the author");
|
||||
|
||||
return author.posts!.then((posts: any) => { // temporary
|
||||
posts![0]!.title = "should be updated second post";
|
||||
return authorRepository.persist(author!);
|
||||
return authorRepository.save(author!);
|
||||
});
|
||||
})
|
||||
.then(updatedAuthor => {
|
||||
@ -67,7 +67,7 @@ createConnection(options).then(connection => {
|
||||
console.log("Now lets delete a post");
|
||||
posts[0].author = Promise.resolve(null);
|
||||
posts[1].author = Promise.resolve(null);
|
||||
return postRepository.persist(posts[0]);
|
||||
return postRepository.save(posts[0]);
|
||||
})
|
||||
.then(posts => {
|
||||
console.log("Two post's author has been removed.");
|
||||
@ -87,7 +87,7 @@ createConnection(options).then(connection => {
|
||||
category2
|
||||
]);
|
||||
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
})
|
||||
.then(posts => {
|
||||
console.log("Post has been saved with its categories. ");
|
||||
@ -100,7 +100,7 @@ createConnection(options).then(connection => {
|
||||
return posts[0].categories.then((categories: any) => { // temporary
|
||||
categories!.splice(0, 1);
|
||||
// console.log(posts[0]);
|
||||
return postRepository.persist(posts[0]);
|
||||
return postRepository.save(posts[0]);
|
||||
});
|
||||
})
|
||||
.then(posts => {
|
||||
|
||||
@ -49,7 +49,7 @@ createConnection(options).then(connection => {
|
||||
post.categories = [category1, category2];
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved.");
|
||||
console.log(post);
|
||||
|
||||
@ -39,7 +39,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved. Lets try to find this post using query builder: ");
|
||||
return postRepository
|
||||
|
||||
@ -23,7 +23,7 @@ const options: ConnectionOptions = {
|
||||
|
||||
createConnection(options).then(connection => {
|
||||
|
||||
let entityManager = connection.entityManager;
|
||||
let entityManager = connection.manager;
|
||||
|
||||
let postRepository = connection.getRepository(Post);
|
||||
let authorRepository = connection.getRepository(Author);
|
||||
@ -46,12 +46,12 @@ createConnection(options).then(connection => {
|
||||
post.categories = [category1, category2];
|
||||
|
||||
Promise.all<any>([
|
||||
authorRepository.persist(author),
|
||||
categoryRepository.persist(category1),
|
||||
categoryRepository.persist(category2),
|
||||
authorRepository.save(author),
|
||||
categoryRepository.save(category1),
|
||||
categoryRepository.save(category2),
|
||||
])
|
||||
.then(() => {
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
})
|
||||
.then(() => {
|
||||
console.log("Everything has been saved.");
|
||||
|
||||
@ -41,7 +41,7 @@ createConnection(options).then(connection => {
|
||||
post.categories = [category1, category2];
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved. Lets load it now.");
|
||||
return postRepository.find({
|
||||
|
||||
@ -42,7 +42,7 @@ createConnection(options).then(connection => {
|
||||
category1.childCategories = [childCategory1, childCategory2];
|
||||
|
||||
return categoryRepository
|
||||
.persist(category1)
|
||||
.save(category1)
|
||||
.then(category => {
|
||||
console.log("Categories has been saved. Lets now load it and all its descendants:");
|
||||
return categoryRepository.findDescendants(category1);
|
||||
|
||||
@ -44,7 +44,7 @@ createConnection(options).then(connection => {
|
||||
author2.name = "Bakhrom";
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
return postRepository
|
||||
.createQueryBuilder("post")
|
||||
@ -63,7 +63,7 @@ createConnection(options).then(connection => {
|
||||
|
||||
post.author = author2;
|
||||
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
})
|
||||
.then(updatedPost => {
|
||||
return postRepository
|
||||
@ -80,7 +80,7 @@ createConnection(options).then(connection => {
|
||||
console.log("updating with: ", author);
|
||||
loadedPost!.title = "Umed's post";
|
||||
loadedPost!.author = author;
|
||||
return postRepository.persist(loadedPost!);
|
||||
return postRepository.save(loadedPost!);
|
||||
})
|
||||
.then(updatedPost => {
|
||||
return postRepository
|
||||
@ -94,7 +94,7 @@ createConnection(options).then(connection => {
|
||||
console.log(loadedPost);
|
||||
console.log("Now lets remove post's author:");
|
||||
post.author = null;
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
})
|
||||
.then(updatedPost => {
|
||||
return postRepository
|
||||
@ -108,7 +108,7 @@ createConnection(options).then(connection => {
|
||||
console.log(loadedPost);
|
||||
console.log("Finally bakhrom's post:");
|
||||
post.author = author2;
|
||||
return postRepository.persist(post);
|
||||
return postRepository.save(post);
|
||||
})
|
||||
.then(updatedPost => {
|
||||
return postRepository
|
||||
|
||||
@ -39,7 +39,7 @@ createConnection(options).then(connection => {
|
||||
};
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(result => {
|
||||
console.log(result);
|
||||
})
|
||||
|
||||
@ -29,7 +29,7 @@ createConnection(options).then(connection => {
|
||||
if (!author) {
|
||||
author = new Author();
|
||||
author.name = "Umed";
|
||||
return authorRepository.persist(author).then(savedAuthor => {
|
||||
return authorRepository.save(author).then(savedAuthor => {
|
||||
return authorRepository.findOneById(1);
|
||||
});
|
||||
}
|
||||
@ -41,7 +41,7 @@ createConnection(options).then(connection => {
|
||||
post = new Post();
|
||||
post.title = "Hello post";
|
||||
post.text = "This is post contents";
|
||||
return postRepository.persist(post).then(savedPost => {
|
||||
return postRepository.save(post).then(savedPost => {
|
||||
return postRepository.findOneById(1);
|
||||
});
|
||||
}
|
||||
@ -52,7 +52,7 @@ createConnection(options).then(connection => {
|
||||
.then(results => {
|
||||
const [author, post] = results;
|
||||
author.posts = [post];
|
||||
return authorRepository.persist(author);
|
||||
return authorRepository.save(author);
|
||||
})
|
||||
.then(savedAuthor => {
|
||||
console.log("Author has been saved: ", savedAuthor);
|
||||
|
||||
@ -34,7 +34,7 @@ createConnection(options).then(connection => {
|
||||
question.counters.metadata = "#question #question-counter";
|
||||
|
||||
questionRepository
|
||||
.persist(question)
|
||||
.save(question)
|
||||
.then(savedQuestion => {
|
||||
console.log("question has been saved: ", savedQuestion);
|
||||
|
||||
@ -47,7 +47,7 @@ createConnection(options).then(connection => {
|
||||
loadedQuestion!.counters.commentCount = 7;
|
||||
loadedQuestion!.counters.metadata = "#updated question";
|
||||
|
||||
return questionRepository.persist(loadedQuestion!);
|
||||
return questionRepository.save(loadedQuestion!);
|
||||
})
|
||||
.then(updatedQuestion => {
|
||||
console.log("question has been updated: ", updatedQuestion);
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import {Column} from "../../../src/index";
|
||||
import {EmbeddableEntity} from "../../../src/decorator/entity/EmbeddableEntity";
|
||||
|
||||
@EmbeddableEntity()
|
||||
export class Counters {
|
||||
|
||||
@Column()
|
||||
|
||||
@ -29,7 +29,7 @@ createConnection(options).then(async connection => {
|
||||
post.text = "this is test post!";
|
||||
|
||||
console.log("saving the post: ");
|
||||
await postRepository.persist(post);
|
||||
await postRepository.save(post);
|
||||
console.log("Post has been saved: ", post);
|
||||
|
||||
console.log("now loading the post: ");
|
||||
|
||||
@ -38,7 +38,7 @@ createConnection(options).then(async connection => {
|
||||
employee.salary = 200000;
|
||||
|
||||
console.log("saving the employee: ");
|
||||
await employeeRepository.persist(employee);
|
||||
await employeeRepository.save(employee);
|
||||
console.log("employee has been saved: ", employee);
|
||||
|
||||
console.log("now loading the employee: ");
|
||||
@ -55,7 +55,7 @@ createConnection(options).then(async connection => {
|
||||
homesitter.numberOfKids = 5;
|
||||
|
||||
console.log("saving the homesitter: ");
|
||||
await homesitterRepository.persist(homesitter);
|
||||
await homesitterRepository.save(homesitter);
|
||||
console.log("homesitter has been saved: ", homesitter);
|
||||
|
||||
console.log("now loading the homesitter: ");
|
||||
@ -72,7 +72,7 @@ createConnection(options).then(async connection => {
|
||||
student.faculty = "computer science";
|
||||
|
||||
console.log("saving the student: ");
|
||||
await studentRepository.persist(student);
|
||||
await studentRepository.save(student);
|
||||
console.log("student has been saved: ", student);
|
||||
|
||||
console.log("now loading the student: ");
|
||||
|
||||
@ -38,13 +38,13 @@ createConnection(options).then(async connection => {
|
||||
employee.salary = 300000;
|
||||
|
||||
console.log("saving the employee: ");
|
||||
await employeeRepository.persist(employee);
|
||||
await employeeRepository.save(employee);
|
||||
console.log("employee has been saved: ", employee);
|
||||
|
||||
console.log("updating the employee: ");
|
||||
employee.firstName = "zuma";
|
||||
employee.lastName += "a";
|
||||
await employeeRepository.persist(employee);
|
||||
await employeeRepository.save(employee);
|
||||
console.log("employee has been updated: ", employee);
|
||||
|
||||
console.log("now loading the employee: ");
|
||||
@ -52,7 +52,7 @@ createConnection(options).then(async connection => {
|
||||
console.log("loaded employee: ", loadedEmployee);
|
||||
|
||||
loadedEmployee.firstName = "dima";
|
||||
await employeeRepository.persist(loadedEmployee);
|
||||
await employeeRepository.save(loadedEmployee);
|
||||
|
||||
const allEmployees = await employeeRepository.findAndCount();
|
||||
console.log("all employees: ", allEmployees);
|
||||
|
||||
@ -44,7 +44,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved"))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ createConnection(options).then(async connection => {
|
||||
]);
|
||||
|
||||
console.log("saving posts");
|
||||
await postRepository.persist([post1, post2, post3, post4]);
|
||||
await postRepository.save([post1, post2, post3, post4]);
|
||||
|
||||
console.log("loading the post. pay attention on order: ");
|
||||
const allPosts = await postRepository.find();
|
||||
|
||||
@ -39,7 +39,7 @@ createConnection(options).then(async connection => {
|
||||
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
await postRepository.persist(post);
|
||||
await postRepository.save(post);
|
||||
console.log("Post has been saved");
|
||||
|
||||
}).catch(error => console.log("Error: ", error));
|
||||
|
||||
@ -33,7 +33,7 @@ createConnection(options).then(async connection => {
|
||||
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
await postRepository.persist(post);
|
||||
await postRepository.save(post);
|
||||
console.log("Database schema was created and data has been inserted into the database.");
|
||||
|
||||
// close connection now
|
||||
|
||||
@ -5,6 +5,8 @@ import {Author} from "./entity/Author";
|
||||
import {MigrationExecutor} from "../../src/migration/MigrationExecutor";
|
||||
import {PostRepository} from "./repository/PostRepository";
|
||||
import {AuthorRepository} from "./repository/AuthorRepository";
|
||||
import {UserRepository} from "./repository/UserRepository";
|
||||
import {User} from "./entity/User";
|
||||
|
||||
const options: ConnectionOptions = {
|
||||
driver: {
|
||||
@ -19,28 +21,12 @@ const options: ConnectionOptions = {
|
||||
logging: {
|
||||
logQueries: true,
|
||||
},
|
||||
entities: [Post, Author],
|
||||
entities: [Post, Author, User],
|
||||
};
|
||||
|
||||
createConnection(options).then(async connection => {
|
||||
|
||||
const post = connection
|
||||
.getCustomRepository(PostRepository)
|
||||
.create();
|
||||
|
||||
post.title = "Hello Repositories!";
|
||||
|
||||
await connection
|
||||
.entityManager
|
||||
.getCustomRepository(PostRepository)
|
||||
.persist(post);
|
||||
|
||||
const loadedPost = await connection
|
||||
.entityManager
|
||||
.getCustomRepository(PostRepository)
|
||||
.findMyPost();
|
||||
|
||||
console.log("Post persisted! Loaded post: ", loadedPost);
|
||||
// first type of custom repository
|
||||
|
||||
const author = await connection
|
||||
.getCustomRepository(AuthorRepository)
|
||||
@ -52,4 +38,33 @@ createConnection(options).then(async connection => {
|
||||
|
||||
console.log("Author persisted! Loaded author: ", loadedAuthor);
|
||||
|
||||
// second type of custom repository
|
||||
|
||||
const post = connection
|
||||
.getCustomRepository(PostRepository)
|
||||
.create();
|
||||
|
||||
post.title = "Hello Repositories!";
|
||||
|
||||
await connection
|
||||
.manager
|
||||
.getCustomRepository(PostRepository)
|
||||
.save(post);
|
||||
|
||||
const loadedPost = await connection
|
||||
.manager
|
||||
.getCustomRepository(PostRepository)
|
||||
.findMyPost();
|
||||
|
||||
console.log("Post persisted! Loaded post: ", loadedPost);
|
||||
|
||||
// third type of custom repository
|
||||
|
||||
const userRepository = connection.manager.getCustomRepository(UserRepository);
|
||||
await userRepository.createAndSave("Umed", "Khudoiberdiev");
|
||||
const loadedUser = await userRepository.findByName("Umed", "Khudoiberdiev");
|
||||
|
||||
console.log("User loaded: ", loadedUser);
|
||||
|
||||
|
||||
}).catch(error => console.log("Error: ", error));
|
||||
|
||||
15
sample/sample33-custom-repository/entity/User.ts
Normal file
15
sample/sample33-custom-repository/entity/User.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import {PrimaryGeneratedColumn, Column, Entity} from "../../../src/index";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
firstName: string;
|
||||
|
||||
@Column()
|
||||
lastName: string;
|
||||
|
||||
}
|
||||
@ -3,7 +3,7 @@ import {AbstractRepository} from "../../../src/repository/AbstractRepository";
|
||||
import {Author} from "../entity/Author";
|
||||
|
||||
/**
|
||||
* Second type of custom repository - extends abstract repository (also can not extend anything).
|
||||
* First type of custom repository - extends abstract repository.
|
||||
*/
|
||||
@EntityRepository(Author)
|
||||
export class AuthorRepository extends AbstractRepository<Author> {
|
||||
@ -13,7 +13,7 @@ export class AuthorRepository extends AbstractRepository<Author> {
|
||||
author.firstName = firstName;
|
||||
author.lastName = lastName;
|
||||
|
||||
return this.entityManager.persist(author);
|
||||
return this.manager.save(author);
|
||||
}
|
||||
|
||||
findMyAuthor() {
|
||||
|
||||
@ -3,7 +3,7 @@ import {Post} from "../entity/Post";
|
||||
import {EntityRepository} from "../../../src/decorator/EntityRepository";
|
||||
|
||||
/**
|
||||
* First type of custom repository - extends standard repository.
|
||||
* Second type of custom repository - extends standard repository.
|
||||
*/
|
||||
@EntityRepository(Post)
|
||||
export class PostRepository extends Repository<Post> {
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
import {EntityRepository} from "../../../src/decorator/EntityRepository";
|
||||
import {EntityManager} from "../../../src/entity-manager/EntityManager";
|
||||
import {User} from "../entity/User";
|
||||
|
||||
/**
|
||||
* Third type of custom repository - extends nothing and accepts entity manager as a first constructor parameter.
|
||||
*/
|
||||
@EntityRepository()
|
||||
export class UserRepository {
|
||||
|
||||
constructor(private entityManager: EntityManager) {
|
||||
}
|
||||
|
||||
async createAndSave(firstName: string, lastName: string) {
|
||||
const user = await this.entityManager.create(User, { firstName, lastName });
|
||||
return this.entityManager.save(user);
|
||||
}
|
||||
|
||||
async findByName(firstName: string, lastName: string) {
|
||||
return this.entityManager.createQueryBuilder(User, "user")
|
||||
.where("user.firstName = :firstName AND user.lastName = :lastName")
|
||||
.setParameters({ firstName, lastName })
|
||||
.getOne();
|
||||
}
|
||||
|
||||
}
|
||||
@ -23,7 +23,7 @@ createConnection(options).then(async connection => {
|
||||
post.title = "hello";
|
||||
post.likesCount = 100;
|
||||
|
||||
await connection.getRepository(Post).persist(post);
|
||||
await connection.getRepository(Post).save(post);
|
||||
console.log("Post has been saved: ", post);
|
||||
|
||||
const loadedPost = await connection.getRepository(Post).findOne({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Column, Entity} from "../../../src/index";
|
||||
import {ObjectIdColumn} from "../../../src/decorator/columns/ObjectIdColumn";
|
||||
import {ObjectID} from "mongodb";
|
||||
import {ObjectID} from "../../../src/driver/mongodb/typings";
|
||||
|
||||
@Entity("sample34_post")
|
||||
export class Post {
|
||||
|
||||
@ -34,7 +34,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => console.log("Post has been saved"))
|
||||
.catch(error => console.log("Cannot save. Error: ", error));
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findOneById(post.id);
|
||||
@ -60,7 +60,7 @@ createConnection(options).then(connection => {
|
||||
console.log("load finished. Now lets update entity");
|
||||
loadedPost!.text = "post updated";
|
||||
loadedPost!.author.name = "Bakha";
|
||||
return postRepository.persist(loadedPost!);
|
||||
return postRepository.save(loadedPost!);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("---------------------------");
|
||||
|
||||
@ -54,14 +54,14 @@ createConnection(options).then(connection => {
|
||||
let blogRepository = connection.getRepository(Blog);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
return postRepository.findOneById(post.id);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("post is loaded: ", loadedPost);
|
||||
return blogRepository.persist(blog);
|
||||
return blogRepository.save(blog);
|
||||
})
|
||||
.then(blog => {
|
||||
console.log("Blog has been saved");
|
||||
@ -69,7 +69,7 @@ createConnection(options).then(connection => {
|
||||
})
|
||||
.then(loadedBlog => {
|
||||
console.log("blog is loaded: ", loadedBlog);
|
||||
return blogRepository.persist(blog);
|
||||
return blogRepository.save(blog);
|
||||
})
|
||||
.catch(error => console.log("Cannot save. Error: ", error.stack ? error.stack : error));
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
import {PrimaryGeneratedColumn, Column} from "../../../src/index";
|
||||
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
|
||||
|
||||
@AbstractEntity()
|
||||
export class BasePost {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
|
||||
@ -49,7 +49,7 @@ createConnection(options).then(connection => {
|
||||
.skip(5)
|
||||
.take(10);
|
||||
|
||||
Promise.all(posts.map(post => postRepository.persist(post)))
|
||||
Promise.all(posts.map(post => postRepository.save(post)))
|
||||
.then(savedPosts => {
|
||||
console.log("Posts has been saved. Lets try to load some posts");
|
||||
return qb.getMany();
|
||||
|
||||
@ -27,7 +27,7 @@ createConnection(options).then(connection => {
|
||||
mainCategory.manyCategories.push(category1);
|
||||
mainCategory.oneManyCategory = category1;
|
||||
|
||||
categoryRepository.persist(mainCategory)
|
||||
categoryRepository.save(mainCategory)
|
||||
.then(savedCategory => {
|
||||
console.log("saved category: ", savedCategory);
|
||||
})
|
||||
|
||||
@ -37,7 +37,7 @@ createConnection(options).then(connection => {
|
||||
let postRepository = connection.getRepository(Post);
|
||||
|
||||
postRepository
|
||||
.persist(post)
|
||||
.save(post)
|
||||
.then(post => {
|
||||
console.log("Post has been saved");
|
||||
console.log("---------------------------");
|
||||
@ -59,7 +59,7 @@ createConnection(options).then(connection => {
|
||||
console.log("---------------------------");
|
||||
loadedPost!.text = "post updated";
|
||||
loadedPost!.author.name = "Bakha";
|
||||
return postRepository.persist(loadedPost!);
|
||||
return postRepository.save(loadedPost!);
|
||||
})
|
||||
.then(loadedPost => {
|
||||
console.log("update finished. Now lets remove entity");
|
||||
|
||||
@ -3,10 +3,9 @@ import {Repository} from "../repository/Repository";
|
||||
import {EntitySubscriberInterface} from "../subscriber/EntitySubscriberInterface";
|
||||
import {RepositoryNotFoundError} from "./error/RepositoryNotFoundError";
|
||||
import {ObjectType} from "../common/ObjectType";
|
||||
import {EntityListenerMetadata} from "../metadata/EntityListenerMetadata";
|
||||
import {EntityManager} from "../entity-manager/EntityManager";
|
||||
import {importClassesFromDirectories, importJsonsFromDirectories} from "../util/DirectoryExportedClassesLoader";
|
||||
import {getMetadataArgsStorage, getFromContainer} from "../index";
|
||||
import {getFromContainer, getMetadataArgsStorage} from "../index";
|
||||
import {EntityMetadataBuilder} from "../metadata-builder/EntityMetadataBuilder";
|
||||
import {DefaultNamingStrategy} from "../naming-strategy/DefaultNamingStrategy";
|
||||
import {CannotImportAlreadyConnectedError} from "./error/CannotImportAlreadyConnectedError";
|
||||
@ -39,6 +38,8 @@ import {CustomRepositoryCannotInheritRepositoryError} from "../repository/error/
|
||||
import {MongoRepository} from "../repository/MongoRepository";
|
||||
import {MongoDriver} from "../driver/mongodb/MongoDriver";
|
||||
import {MongoEntityManager} from "../entity-manager/MongoEntityManager";
|
||||
import {EntitySchemaTransformer} from "../entity-schema/EntitySchemaTransformer";
|
||||
import {EntityMetadataValidator} from "../metadata-builder/EntityMetadataValidator";
|
||||
|
||||
/**
|
||||
* Connection is a single database connection to a specific database of a database management system.
|
||||
@ -82,7 +83,7 @@ export class Connection {
|
||||
/**
|
||||
* Gets EntityManager of this connection.
|
||||
*/
|
||||
private readonly _entityManager: EntityManager;
|
||||
readonly manager: EntityManager;
|
||||
|
||||
/**
|
||||
* Stores all registered repositories.
|
||||
@ -94,11 +95,6 @@ export class Connection {
|
||||
*/
|
||||
private readonly entityRepositories: Object[] = [];
|
||||
|
||||
/**
|
||||
* Entity listeners that are registered for this connection.
|
||||
*/
|
||||
private readonly entityListeners: EntityListenerMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Entity subscribers that are registered for this connection.
|
||||
*/
|
||||
@ -147,7 +143,7 @@ export class Connection {
|
||||
this.name = name;
|
||||
this.driver = driver;
|
||||
this.logger = logger;
|
||||
this._entityManager = this.createEntityManager();
|
||||
this.manager = this.createEntityManager();
|
||||
this.broadcaster = this.createBroadcaster();
|
||||
}
|
||||
|
||||
@ -164,12 +160,11 @@ export class Connection {
|
||||
|
||||
/**
|
||||
* Gets entity manager that allows to perform repository operations with any entity in this connection.
|
||||
*
|
||||
* @deprecated use manager instead.
|
||||
*/
|
||||
get entityManager(): EntityManager {
|
||||
// if (!this.isConnected)
|
||||
// throw new CannotGetEntityManagerNotConnectedError(this.name);
|
||||
|
||||
return this._entityManager;
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,10 +172,10 @@ export class Connection {
|
||||
* with any entity in this connection.
|
||||
*/
|
||||
get mongoEntityManager(): MongoEntityManager {
|
||||
if (!(this._entityManager instanceof MongoEntityManager))
|
||||
if (!(this.manager instanceof MongoEntityManager))
|
||||
throw new Error(`MongoEntityManager is only available for MongoDB databases.`);
|
||||
|
||||
return this._entityManager as MongoEntityManager;
|
||||
return this.manager as MongoEntityManager;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -572,67 +567,7 @@ export class Connection {
|
||||
* Gets custom entity repository marked with @EntityRepository decorator.
|
||||
*/
|
||||
getCustomRepository<T>(customRepository: ObjectType<T>): T {
|
||||
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
|
||||
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
|
||||
});
|
||||
if (!entityRepositoryMetadataArgs)
|
||||
throw new CustomRepositoryNotFoundError(customRepository);
|
||||
|
||||
let entityRepositoryInstance: any = this.entityRepositories.find(entityRepository => entityRepository.constructor === customRepository);
|
||||
if (!entityRepositoryInstance) {
|
||||
if (entityRepositoryMetadataArgs.useContainer) {
|
||||
entityRepositoryInstance = getFromContainer(entityRepositoryMetadataArgs.target);
|
||||
|
||||
// if we get custom entity repository from container then there is a risk that it already was used
|
||||
// in some different connection. If it was used there then we check it and throw an exception
|
||||
// because we cant override its connection there again
|
||||
|
||||
if (entityRepositoryInstance instanceof AbstractRepository || entityRepositoryInstance instanceof Repository) {
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
if ((entityRepositoryInstance as any)["connection"] && (entityRepositoryInstance as any)["connection"] !== this)
|
||||
throw new CustomRepositoryReusedError(customRepository);
|
||||
}
|
||||
|
||||
} else {
|
||||
entityRepositoryInstance = new (entityRepositoryMetadataArgs.target as any)();
|
||||
}
|
||||
|
||||
if (entityRepositoryInstance instanceof AbstractRepository) {
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
if (!(entityRepositoryInstance as any)["connection"])
|
||||
(entityRepositoryInstance as any)["connection"] = this;
|
||||
}
|
||||
if (entityRepositoryInstance instanceof Repository) {
|
||||
if (!entityRepositoryMetadataArgs.entity)
|
||||
throw new CustomRepositoryCannotInheritRepositoryError(customRepository);
|
||||
|
||||
// NOTE: dynamic access to protected properties. We need this to prevent unwanted properties in those classes to be exposed,
|
||||
// however we need these properties for internal work of the class
|
||||
(entityRepositoryInstance as any)["connection"] = this;
|
||||
(entityRepositoryInstance as any)["metadata"] = this.getMetadata(entityRepositoryMetadataArgs.entity);
|
||||
}
|
||||
|
||||
// register entity repository
|
||||
this.entityRepositories.push(entityRepositoryInstance);
|
||||
}
|
||||
|
||||
return entityRepositoryInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets custom repository's managed entity.
|
||||
* If given custom repository does not manage any entity then undefined will be returned.
|
||||
*/
|
||||
getCustomRepositoryTarget<T>(customRepository: any): Function|string|undefined {
|
||||
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.toArray().find(repository => {
|
||||
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
|
||||
});
|
||||
if (!entityRepositoryMetadataArgs)
|
||||
throw new CustomRepositoryNotFoundError(customRepository);
|
||||
|
||||
return entityRepositoryMetadataArgs.entity;
|
||||
return this.manager.getCustomRepository(customRepository);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -660,40 +595,30 @@ export class Connection {
|
||||
/**
|
||||
* Builds all registered metadatas.
|
||||
*/
|
||||
protected buildMetadatas() {
|
||||
public buildMetadatas() {
|
||||
|
||||
this.entitySubscribers.length = 0;
|
||||
this.entityListeners.length = 0;
|
||||
this.repositoryAggregators.length = 0;
|
||||
this.entityMetadatas.length = 0;
|
||||
|
||||
const namingStrategy = this.createNamingStrategy();
|
||||
this.driver.namingStrategy = namingStrategy;
|
||||
const lazyRelationsWrapper = this.createLazyRelationsWrapper();
|
||||
this.driver.namingStrategy = this.createNamingStrategy(); // todo: why they are in the driver
|
||||
this.driver.lazyRelationsWrapper = this.createLazyRelationsWrapper(); // todo: why they are in the driver
|
||||
const entityMetadataValidator = new EntityMetadataValidator();
|
||||
|
||||
// take imported event subscribers
|
||||
if (this.subscriberClasses && this.subscriberClasses.length && !PlatformTools.getEnvVariable("SKIP_SUBSCRIBERS_LOADING")) {
|
||||
getMetadataArgsStorage()
|
||||
.entitySubscribers
|
||||
.filterByTargets(this.subscriberClasses)
|
||||
.toArray()
|
||||
.filterSubscribers(this.subscriberClasses)
|
||||
.map(metadata => getFromContainer(metadata.target))
|
||||
.forEach(subscriber => this.entitySubscribers.push(subscriber));
|
||||
}
|
||||
|
||||
// take imported entity listeners
|
||||
if (this.entityClasses && this.entityClasses.length) {
|
||||
getMetadataArgsStorage()
|
||||
.entityListeners
|
||||
.filterByTargets(this.entityClasses)
|
||||
.toArray()
|
||||
.forEach(metadata => this.entityListeners.push(new EntityListenerMetadata(metadata)));
|
||||
}
|
||||
|
||||
// build entity metadatas from metadata args storage (collected from decorators)
|
||||
if (this.entityClasses && this.entityClasses.length) {
|
||||
getFromContainer(EntityMetadataBuilder)
|
||||
.buildFromMetadataArgsStorage(this.driver, lazyRelationsWrapper, namingStrategy, this.entityClasses)
|
||||
// build entity metadatas from metadata args storage (collected from decorators)
|
||||
new EntityMetadataBuilder(this, getMetadataArgsStorage())
|
||||
.build(this.entityClasses)
|
||||
.forEach(metadata => {
|
||||
this.entityMetadatas.push(metadata);
|
||||
this.repositoryAggregators.push(new RepositoryAggregator(this, metadata));
|
||||
@ -702,13 +627,16 @@ export class Connection {
|
||||
|
||||
// build entity metadatas from given entity schemas
|
||||
if (this.entitySchemas && this.entitySchemas.length) {
|
||||
getFromContainer(EntityMetadataBuilder)
|
||||
.buildFromSchemas(this.driver, lazyRelationsWrapper, namingStrategy, this.entitySchemas)
|
||||
const metadataArgsStorage = getFromContainer(EntitySchemaTransformer).transform(this.entitySchemas);
|
||||
new EntityMetadataBuilder(this, metadataArgsStorage)
|
||||
.build()
|
||||
.forEach(metadata => {
|
||||
this.entityMetadatas.push(metadata);
|
||||
this.repositoryAggregators.push(new RepositoryAggregator(this, metadata));
|
||||
});
|
||||
}
|
||||
|
||||
entityMetadataValidator.validateMany(this.entityMetadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -722,9 +650,7 @@ export class Connection {
|
||||
|
||||
// try to find used naming strategy in the list of loaded naming strategies
|
||||
const namingMetadata = getMetadataArgsStorage()
|
||||
.namingStrategies
|
||||
.filterByTargets(this.namingStrategyClasses)
|
||||
.toArray()
|
||||
.filterNamingStrategies(this.namingStrategyClasses)
|
||||
.find(strategy => {
|
||||
if (typeof this.usedNamingStrategy === "string") {
|
||||
return strategy.name === this.usedNamingStrategy;
|
||||
@ -755,7 +681,7 @@ export class Connection {
|
||||
* Creates a new entity broadcaster using in this connection.
|
||||
*/
|
||||
protected createBroadcaster() {
|
||||
return new Broadcaster(this, this.entitySubscribers, this.entityListeners);
|
||||
return new Broadcaster(this, this.entitySubscribers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -359,7 +359,8 @@ export class ConnectionManager {
|
||||
* If path is not given, then ormconfig.json file will be searched near node_modules directory.
|
||||
*/
|
||||
protected async createFromConfigAndConnectToAll(path?: string): Promise<Connection[]> {
|
||||
const optionsArray: ConnectionOptions[] = PlatformTools.load(path || (PlatformTools.load("app-root-path").path + "/ormconfig.json"));
|
||||
let optionsArray: ConnectionOptions[] = PlatformTools.load(path || (PlatformTools.load("app-root-path").path + "/ormconfig.json"));
|
||||
if (!(optionsArray instanceof Array)) optionsArray = [optionsArray]; // cast options to array if ormconfig contains a single connection options object
|
||||
if (!optionsArray)
|
||||
throw new Error(`Configuration ${path || "ormconfig.json"} was not found. Add connection configuration inside ormconfig.json file.`);
|
||||
|
||||
@ -377,7 +378,8 @@ export class ConnectionManager {
|
||||
* If path is not given, then ormconfig.json file will be searched near node_modules directory.
|
||||
*/
|
||||
protected async createFromConfigAndConnect(connectionName: string, path?: string): Promise<Connection> {
|
||||
const optionsArray: ConnectionOptions[] = PlatformTools.load(path || (PlatformTools.load("app-root-path").path + "/ormconfig.json"));
|
||||
let optionsArray: ConnectionOptions[] = PlatformTools.load(path || (PlatformTools.load("app-root-path").path + "/ormconfig.json"));
|
||||
if (!(optionsArray instanceof Array)) optionsArray = [optionsArray]; // cast options to array if ormconfig contains a single connection options object
|
||||
if (!optionsArray)
|
||||
throw new Error(`Configuration ${path || "ormconfig.json"} was not found. Add connection configuration inside ormconfig.json file.`);
|
||||
|
||||
|
||||
@ -11,6 +11,6 @@ export function DiscriminatorValue(value: any): Function {
|
||||
target: target,
|
||||
value: value
|
||||
};
|
||||
getMetadataArgsStorage().discriminatorValues.add(args);
|
||||
getMetadataArgsStorage().discriminatorValues.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -6,8 +6,10 @@ import {EmbeddedMetadataArgs} from "../metadata-args/EmbeddedMetadataArgs";
|
||||
* Property in entity can be marked as Embedded, and on persist all columns from the embedded are mapped to the
|
||||
* single table of the entity where Embedded is used. And on hydration all columns which supposed to be in the
|
||||
* embedded will be mapped to it from the single table.
|
||||
*
|
||||
* Array option works only in monogodb.
|
||||
*/
|
||||
export function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>, options?: { prefix?: string, array?: boolean }) {
|
||||
export function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>, options?: { prefix?: string|boolean, array?: boolean }) {
|
||||
return function (object: Object, propertyName: string) {
|
||||
|
||||
const reflectMetadataType = Reflect && (Reflect as any).getMetadata ? (Reflect as any).getMetadata("design:type", object, propertyName) : undefined;
|
||||
@ -20,6 +22,6 @@ export function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>, options
|
||||
prefix: options && options.prefix !== undefined ? options.prefix : undefined,
|
||||
type: typeFunction
|
||||
};
|
||||
getMetadataArgsStorage().embeddeds.add(args);
|
||||
getMetadataArgsStorage().embeddeds.push(args);
|
||||
};
|
||||
}
|
||||
@ -6,29 +6,12 @@ import {EntityRepositoryMetadataArgs} from "../metadata-args/EntityRepositoryMet
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(entity?: Function, options?: { useContainer?: boolean }): Function;
|
||||
|
||||
/**
|
||||
* Used to declare a class as a custom repository.
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(options?: { useContainer?: boolean }): Function;
|
||||
|
||||
/**
|
||||
* Used to declare a class as a custom repository.
|
||||
* Custom repository can either manage some specific entity, either just be generic.
|
||||
* Custom repository can extend AbstractRepository or regular Repository or TreeRepository.
|
||||
*/
|
||||
export function EntityRepository(entityOrOptions?: Function|{ useContainer?: boolean }, maybeOptions?: { useContainer?: boolean }): Function {
|
||||
const entity = entityOrOptions instanceof Function ? entityOrOptions as Function : undefined;
|
||||
const options = entityOrOptions instanceof Function ? maybeOptions : entityOrOptions as { useContainer?: boolean };
|
||||
export function EntityRepository(entity?: Function): Function {
|
||||
return function (target: Function) {
|
||||
const args: EntityRepositoryMetadataArgs = {
|
||||
target: target,
|
||||
entity: entity,
|
||||
useContainer: !!(options && options.useContainer)
|
||||
};
|
||||
getMetadataArgsStorage().entityRepositories.add(args);
|
||||
getMetadataArgsStorage().entityRepositories.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export function Index(nameOrFieldsOrOptions: string|string[]|((object: any) => a
|
||||
const fields = typeof nameOrFieldsOrOptions === "string" ? <((object?: any) => (any[]|{ [key: string]: number }))|string[]> maybeFieldsOrOptions : nameOrFieldsOrOptions as string[];
|
||||
let options = (typeof nameOrFieldsOrOptions === "object" && !Array.isArray(nameOrFieldsOrOptions)) ? nameOrFieldsOrOptions as IndexOptions : maybeOptions;
|
||||
if (!options)
|
||||
options = (typeof maybeFieldsOrOptions === "object" && !Array.isArray(maybeFieldsOrOptions)) ? nameOrFieldsOrOptions as IndexOptions : maybeOptions;
|
||||
options = (typeof maybeFieldsOrOptions === "object" && !Array.isArray(maybeFieldsOrOptions)) ? maybeFieldsOrOptions as IndexOptions : maybeOptions;
|
||||
|
||||
return function (clsOrObject: Function|Object, propertyName?: string) {
|
||||
const args: IndexMetadataArgs = {
|
||||
@ -51,6 +51,6 @@ export function Index(nameOrFieldsOrOptions: string|string[]|((object: any) => a
|
||||
columns: propertyName ? [propertyName] : fields,
|
||||
unique: options && options.unique ? true : false
|
||||
};
|
||||
getMetadataArgsStorage().indices.add(args);
|
||||
getMetadataArgsStorage().indices.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -14,6 +14,6 @@ export function NamingStrategy(name?: string): Function {
|
||||
target: target,
|
||||
name: strategyName
|
||||
};
|
||||
getMetadataArgsStorage().namingStrategies.add(args);
|
||||
getMetadataArgsStorage().namingStrategies.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -76,6 +76,6 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
|
||||
mode: "regular",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -27,6 +27,6 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
|
||||
mode: "createDate",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ export function DiscriminatorColumn(discriminatorOptions: { name: string, type:
|
||||
propertyName: discriminatorOptions.name,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,6 @@ export function ObjectIdColumn<T>(options?: ColumnOptions): Function {
|
||||
mode: "objectId",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
|
||||
mode: "regular",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ export function PrimaryGeneratedColumn(options?: ColumnOptions): Function {
|
||||
if (!options) options = {} as ColumnOptions;
|
||||
|
||||
// check if there is no type in column options then set the int type - by default for auto generated column
|
||||
if (!options.type)
|
||||
options = Object.assign({type: "int"} as ColumnOptions, options);
|
||||
|
||||
// check if column is not nullable, because we cannot allow a primary key to be nullable
|
||||
@ -37,7 +36,7 @@ export function PrimaryGeneratedColumn(options?: ColumnOptions): Function {
|
||||
mode: "regular",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
|
||||
mode: "updateDate",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ export function VersionColumn(options?: ColumnOptions): Function {
|
||||
mode: "version",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@ import {TableMetadataArgs} from "../../metadata-args/TableMetadataArgs";
|
||||
/**
|
||||
* Abstract entity is a class that contains columns and relations for all entities that will inherit this entity.
|
||||
* Database table for the abstract entity is not created.
|
||||
*
|
||||
* @deprecated don't use it anymore. Now entity can extend any class with columns, no need to mark it with this decorator
|
||||
*/
|
||||
export function AbstractEntity() {
|
||||
return function (target: Function) {
|
||||
@ -12,6 +14,6 @@ export function AbstractEntity() {
|
||||
name: undefined,
|
||||
type: "abstract"
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
@ -14,6 +14,6 @@ export function ClassEntityChild(tableName?: string, options?: EntityOptions) {
|
||||
orderBy: options && options.orderBy ? options.orderBy : undefined,
|
||||
skipSchemaSync: !!(options && options.skipSchemaSync === true)
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
@ -14,6 +14,6 @@ export function ClosureEntity(name?: string, options?: EntityOptions) {
|
||||
orderBy: options && options.orderBy ? options.orderBy : undefined,
|
||||
skipSchemaSync: !!(options && options.skipSchemaSync === true)
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@ import {TableMetadataArgs} from "../../metadata-args/TableMetadataArgs";
|
||||
|
||||
/**
|
||||
* This decorator is used on the entities that must be embedded into another entities.
|
||||
*
|
||||
* @deprecated don't use it anymore. Now entity can embed any class with columns, no need to mark it with this decorator
|
||||
*/
|
||||
export function EmbeddableEntity(): Function {
|
||||
return function (target: Function) {
|
||||
@ -11,6 +13,6 @@ export function EmbeddableEntity(): Function {
|
||||
type: "embeddable",
|
||||
orderBy: undefined
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -16,6 +16,6 @@ export function Entity(name?: string, options?: EntityOptions) {
|
||||
engine: options && options.engine ? options.engine : undefined,
|
||||
skipSchemaSync: !!(options && options.skipSchemaSync === true)
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -12,6 +12,6 @@ export function SingleEntityChild() {
|
||||
type: "single-table-child",
|
||||
orderBy: undefined
|
||||
};
|
||||
getMetadataArgsStorage().tables.add(args);
|
||||
getMetadataArgsStorage().tables.push(args);
|
||||
};
|
||||
}
|
||||
@ -10,6 +10,6 @@ export function TableInheritance(type: "single-table"|"class-table") {
|
||||
target: target,
|
||||
type: type
|
||||
};
|
||||
getMetadataArgsStorage().inheritances.add(args);
|
||||
getMetadataArgsStorage().inheritances.push(args);
|
||||
};
|
||||
}
|
||||
@ -13,6 +13,6 @@ export function AfterInsert() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.AFTER_INSERT
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function AfterLoad() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.AFTER_LOAD
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function AfterRemove() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.AFTER_REMOVE
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function AfterUpdate() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.AFTER_UPDATE
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function BeforeInsert() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.BEFORE_INSERT
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function BeforeRemove() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.BEFORE_REMOVE
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -12,6 +12,6 @@ export function BeforeUpdate() {
|
||||
propertyName: propertyName,
|
||||
type: EventListenerTypes.BEFORE_UPDATE
|
||||
};
|
||||
getMetadataArgsStorage().entityListeners.add(args);
|
||||
getMetadataArgsStorage().entityListeners.push(args);
|
||||
};
|
||||
}
|
||||
@ -10,6 +10,6 @@ export function EventSubscriber() {
|
||||
const args: EntitySubscriberMetadataArgs = {
|
||||
target: target
|
||||
};
|
||||
getMetadataArgsStorage().entitySubscribers.add(args);
|
||||
getMetadataArgsStorage().entitySubscribers.push(args);
|
||||
};
|
||||
}
|
||||
@ -8,36 +8,36 @@ export interface ColumnOptions {
|
||||
/**
|
||||
* Column type. Must be one of the value from the ColumnTypes class.
|
||||
*/
|
||||
readonly type?: ColumnType;
|
||||
type?: ColumnType;
|
||||
|
||||
/**
|
||||
* Column name in the database.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Column type's length. Used only on some column types.
|
||||
* For example type = "string" and length = "100" means that ORM will create a column with type varchar(100).
|
||||
*/
|
||||
readonly length?: string|number;
|
||||
length?: string|number;
|
||||
|
||||
/**
|
||||
* Indicates if this column is PRIMARY.
|
||||
* Same can be achieved if @PrimaryColumn decorator will be used.
|
||||
*/
|
||||
readonly primary?: boolean;
|
||||
primary?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies if this column will use auto increment (sequence, generated identity).
|
||||
* Note that only one column in entity can be marked as generated, and it must be a primary column.
|
||||
* (todo: create validation logic for this condition)
|
||||
*/
|
||||
readonly generated?: boolean;
|
||||
generated?: boolean; // |"uuid"|"sequence";
|
||||
|
||||
/**
|
||||
* Specifies if column's value must be unique or not.
|
||||
*/
|
||||
readonly unique?: boolean;
|
||||
unique?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's value can be set to NULL.
|
||||
@ -47,43 +47,43 @@ export interface ColumnOptions {
|
||||
/**
|
||||
* Column comment.
|
||||
*/
|
||||
readonly comment?: string;
|
||||
comment?: string;
|
||||
|
||||
/**
|
||||
* Default database value.
|
||||
*/
|
||||
readonly default?: any;
|
||||
default?: any;
|
||||
|
||||
/**
|
||||
* The precision for a decimal (exact numeric) column (applies only for decimal column), which is the maximum
|
||||
* number of digits that are stored for the values.
|
||||
*/
|
||||
readonly precision?: number;
|
||||
precision?: number;
|
||||
|
||||
/**
|
||||
* The scale for a decimal (exact numeric) column (applies only for decimal column), which represents the number
|
||||
* of digits to the right of the decimal point and must not be greater than precision.
|
||||
*/
|
||||
readonly scale?: number;
|
||||
scale?: number;
|
||||
|
||||
/**
|
||||
* Indicates if this date column will contain a timezone.
|
||||
* Used only for date-typed column types.
|
||||
* Note that timezone option is not supported by all databases (only postgres for now).
|
||||
*/
|
||||
readonly timezone?: boolean;
|
||||
timezone?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if date object must be stored in given date's timezone.
|
||||
* By default date is saved in UTC timezone.
|
||||
* Works only with "datetime" columns.
|
||||
*/
|
||||
readonly localTimezone?: boolean;
|
||||
localTimezone?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if column's type will be set as a fixed-length data type.
|
||||
* Works only with "string" columns.
|
||||
*/
|
||||
readonly fixedLength?: boolean;
|
||||
fixedLength?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ export interface EntityOptions {
|
||||
/**
|
||||
* Specifies a default order by used for queries from this table when no explicit order by is specified.
|
||||
*/
|
||||
readonly orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
orderBy?: OrderByCondition|((object: any) => OrderByCondition|any);
|
||||
|
||||
/**
|
||||
* Table's database engine type (like "InnoDB", "MyISAM", etc).
|
||||
@ -16,11 +16,11 @@ export interface EntityOptions {
|
||||
* If you update this value and table is already created, it will not change table's engine type.
|
||||
* Note that not all databases support this option.
|
||||
*/
|
||||
readonly engine?: string;
|
||||
engine?: string;
|
||||
|
||||
/**
|
||||
* Specifies if this table will be skipped during schema synchronization.
|
||||
*/
|
||||
readonly skipSchemaSync?: boolean;
|
||||
skipSchemaSync?: boolean;
|
||||
|
||||
}
|
||||
|
||||
@ -6,13 +6,13 @@ export interface IndexOptions {
|
||||
/**
|
||||
* Indicates if this composite index must be unique or not.
|
||||
*/
|
||||
readonly unique?: boolean;
|
||||
unique?: boolean;
|
||||
|
||||
/**
|
||||
* If true, the index only references documents with the specified field.
|
||||
* These indexes use less space but behave differently in some situations (particularly sorts).
|
||||
* This option is only supported for mongodb database.
|
||||
*/
|
||||
readonly sparse?: boolean;
|
||||
sparse?: boolean;
|
||||
|
||||
}
|
||||
@ -6,11 +6,11 @@ export interface JoinColumnOptions {
|
||||
/**
|
||||
* Name of the column.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Name of the column in the entity to which this column is referenced.
|
||||
*/
|
||||
readonly referencedColumnName?: string;
|
||||
referencedColumnName?: string; // TODO rename to referencedColumn
|
||||
|
||||
}
|
||||
24
src/decorator/options/JoinTableMuplipleColumnsOptions.ts
Normal file
24
src/decorator/options/JoinTableMuplipleColumnsOptions.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import {JoinColumnOptions} from "./JoinColumnOptions";
|
||||
|
||||
/**
|
||||
* Describes all relation's options.
|
||||
*/
|
||||
export interface JoinTableMultipleColumnsOptions {
|
||||
|
||||
/**
|
||||
* Name of the table that will be created to store values of the both tables (join table).
|
||||
* By default is auto generated.
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* First column of the join table.
|
||||
*/
|
||||
joinColumns?: JoinColumnOptions[];
|
||||
|
||||
/**
|
||||
* Second (inverse) column of the join table.
|
||||
*/
|
||||
inverseJoinColumns?: JoinColumnOptions[];
|
||||
|
||||
}
|
||||
@ -9,16 +9,16 @@ export interface JoinTableOptions {
|
||||
* Name of the table that will be created to store values of the both tables (join table).
|
||||
* By default is auto generated.
|
||||
*/
|
||||
readonly name?: string;
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* First column of the join table.
|
||||
*/
|
||||
readonly joinColumn?: JoinColumnOptions;
|
||||
joinColumn?: JoinColumnOptions;
|
||||
|
||||
/**
|
||||
* Second (inverse) column of the join table.
|
||||
*/
|
||||
readonly inverseJoinColumn?: JoinColumnOptions;
|
||||
inverseJoinColumn?: JoinColumnOptions;
|
||||
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import {OnDeleteType} from "../../metadata/ForeignKeyMetadata";
|
||||
import {OnDeleteType} from "../../metadata/types/OnDeleteType";
|
||||
|
||||
// todo: add ON_UPDATE
|
||||
|
||||
@ -11,43 +11,43 @@ export interface RelationOptions {
|
||||
* If set to true then it means that related object can be allowed to be inserted / updated / removed to the db.
|
||||
* This is option a shortcut if you would like to set cascadeInsert, cascadeUpdate and cascadeRemove to true.
|
||||
*/
|
||||
readonly cascadeAll?: boolean;
|
||||
cascadeAll?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be inserted to the db.
|
||||
*/
|
||||
readonly cascadeInsert?: boolean;
|
||||
cascadeInsert?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be updated in the db.
|
||||
*/
|
||||
readonly cascadeUpdate?: boolean;
|
||||
cascadeUpdate?: boolean;
|
||||
|
||||
/**
|
||||
* If set to true then it means that related object can be allowed to be remove from the db.
|
||||
*/
|
||||
readonly cascadeRemove?: boolean;
|
||||
cascadeRemove?: boolean;
|
||||
|
||||
/**
|
||||
* Indicates if relation column value can be nullable or not.
|
||||
*/
|
||||
readonly nullable?: boolean;
|
||||
nullable?: boolean;
|
||||
|
||||
/**
|
||||
* Database cascade action on delete.
|
||||
*/
|
||||
readonly onDelete?: OnDeleteType;
|
||||
onDelete?: OnDeleteType;
|
||||
|
||||
/**
|
||||
* Indicates if this relation will be a primary key.
|
||||
* Can be used only for many-to-one and owner one-to-one relations.
|
||||
*/
|
||||
readonly primary?: boolean;
|
||||
primary?: boolean;
|
||||
|
||||
/**
|
||||
* Set this relation to be lazy. Note: lazy relations are promises. When you call them they return promise
|
||||
* which resolve relation result then. If your property's type is Promise then this relation is set to lazy automatically.
|
||||
*/
|
||||
readonly lazy?: boolean;
|
||||
lazy?: boolean;
|
||||
|
||||
}
|
||||
@ -7,16 +7,39 @@ import {JoinColumnMetadataArgs} from "../../metadata-args/JoinColumnMetadataArgs
|
||||
* It also can be used on both one-to-one and many-to-one relations to specify custom column name
|
||||
* or custom referenced column.
|
||||
*/
|
||||
export function JoinColumn(options?: JoinColumnOptions): Function {
|
||||
export function JoinColumn(): Function;
|
||||
|
||||
/**
|
||||
* JoinColumn decorator used on one-to-one relations to specify owner side of relationship.
|
||||
* It also can be used on both one-to-one and many-to-one relations to specify custom column name
|
||||
* or custom referenced column.
|
||||
*/
|
||||
export function JoinColumn(options: JoinColumnOptions): Function;
|
||||
|
||||
/**
|
||||
* JoinColumn decorator used on one-to-one relations to specify owner side of relationship.
|
||||
* It also can be used on both one-to-one and many-to-one relations to specify custom column name
|
||||
* or custom referenced column.
|
||||
*/
|
||||
export function JoinColumn(options: JoinColumnOptions[]): Function;
|
||||
|
||||
/**
|
||||
* JoinColumn decorator used on one-to-one relations to specify owner side of relationship.
|
||||
* It also can be used on both one-to-one and many-to-one relations to specify custom column name
|
||||
* or custom referenced column.
|
||||
*/
|
||||
export function JoinColumn(optionsOrOptionsArray?: JoinColumnOptions|JoinColumnOptions[]): Function {
|
||||
return function (object: Object, propertyName: string) {
|
||||
options = options || {} as JoinColumnOptions;
|
||||
const args: JoinColumnMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
name: options.name,
|
||||
referencedColumnName: options.referencedColumnName
|
||||
};
|
||||
getMetadataArgsStorage().joinColumns.add(args);
|
||||
const options = optionsOrOptionsArray instanceof Array ? optionsOrOptionsArray : [optionsOrOptionsArray || {}];
|
||||
options.forEach(options => {
|
||||
const args: JoinColumnMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
name: options.name,
|
||||
referencedColumnName: options.referencedColumnName
|
||||
};
|
||||
getMetadataArgsStorage().joinColumns.push(args);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +1,41 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {JoinTableOptions} from "../options/JoinTableOptions";
|
||||
import {JoinTableMetadataArgs} from "../../metadata-args/JoinTableMetadataArgs";
|
||||
import {JoinTableMultipleColumnsOptions} from "../options/JoinTableMuplipleColumnsOptions";
|
||||
|
||||
/**
|
||||
* JoinTable decorator is used in many-to-many relationship to specify owner side of relationship.
|
||||
* Its also used to set a custom junction table's name, column names and referenced columns.
|
||||
*/
|
||||
export function JoinTable(options?: JoinTableOptions): Function {
|
||||
export function JoinTable(): Function;
|
||||
|
||||
/**
|
||||
* JoinTable decorator is used in many-to-many relationship to specify owner side of relationship.
|
||||
* Its also used to set a custom junction table's name, column names and referenced columns.
|
||||
*/
|
||||
export function JoinTable(options: JoinTableOptions): Function;
|
||||
|
||||
/**
|
||||
* JoinTable decorator is used in many-to-many relationship to specify owner side of relationship.
|
||||
* Its also used to set a custom junction table's name, column names and referenced columns.
|
||||
*/
|
||||
export function JoinTable(options: JoinTableMultipleColumnsOptions): Function;
|
||||
|
||||
/**
|
||||
* JoinTable decorator is used in many-to-many relationship to specify owner side of relationship.
|
||||
* Its also used to set a custom junction table's name, column names and referenced columns.
|
||||
*/
|
||||
export function JoinTable(options?: JoinTableOptions|JoinTableMultipleColumnsOptions): Function {
|
||||
return function (object: Object, propertyName: string) {
|
||||
options = options || {} as JoinTableOptions;
|
||||
options = options || {} as JoinTableOptions|JoinTableMultipleColumnsOptions;
|
||||
const args: JoinTableMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
name: options.name,
|
||||
joinColumn: options.joinColumn,
|
||||
inverseJoinColumn: options.inverseJoinColumn
|
||||
joinColumns: (options && (options as JoinTableOptions).joinColumn ? [(options as JoinTableOptions).joinColumn!] : (options as JoinTableMultipleColumnsOptions).joinColumns) as any,
|
||||
inverseJoinColumns: (options && (options as JoinTableOptions).inverseJoinColumn ? [(options as JoinTableOptions).inverseJoinColumn!] : (options as JoinTableMultipleColumnsOptions).inverseJoinColumns) as any,
|
||||
};
|
||||
getMetadataArgsStorage().joinTables.add(args);
|
||||
getMetadataArgsStorage().joinTables.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {ObjectType} from "../../common/ObjectType";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
@ -50,13 +49,13 @@ export function ManyToMany<T>(typeFunction: (type?: any) => ObjectType<T>,
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
relationType: RelationTypes.MANY_TO_MANY,
|
||||
relationType: "many-to-many",
|
||||
isLazy: isLazy,
|
||||
type: typeFunction,
|
||||
inverseSideProperty: inverseSideProperty,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {ObjectType} from "../../common/ObjectType";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
@ -50,12 +49,12 @@ export function ManyToOne<T>(typeFunction: (type?: any) => ObjectType<T>,
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
relationType: RelationTypes.MANY_TO_ONE,
|
||||
relationType: "many-to-one",
|
||||
isLazy: isLazy,
|
||||
type: typeFunction,
|
||||
inverseSideProperty: inverseSideProperty,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {ObjectType} from "../../common/ObjectType";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
@ -27,12 +26,12 @@ export function OneToMany<T>(typeFunction: (type?: any) => ObjectType<T>, invers
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
isLazy: isLazy,
|
||||
relationType: RelationTypes.ONE_TO_MANY,
|
||||
relationType: "one-to-many",
|
||||
type: typeFunction,
|
||||
inverseSideProperty: inverseSide,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {ObjectType} from "../../common/ObjectType";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
@ -48,11 +47,11 @@ export function OneToOne<T>(typeFunction: (type?: any) => ObjectType<T>,
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
isLazy: isLazy,
|
||||
relationType: RelationTypes.ONE_TO_ONE,
|
||||
relationType: "one-to-one",
|
||||
type: typeFunction,
|
||||
inverseSideProperty: inverseSideProperty,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
@ -1,22 +1,20 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {RelationCountMetadataArgs} from "../../metadata-args/RelationCountMetadataArgs";
|
||||
import {QueryBuilder} from "../../query-builder/QueryBuilder";
|
||||
|
||||
/**
|
||||
* Holds a number of children in the closure table of the column.
|
||||
*/
|
||||
export function RelationCount<T>(relation: string|((object: T) => any)): Function {
|
||||
export function RelationCount<T>(relation: string|((object: T) => any), alias?: string, queryBuilderFactory?: (qb: QueryBuilder<any>) => QueryBuilder<any>): Function {
|
||||
return function (object: Object, propertyName: string) {
|
||||
|
||||
// todo: need to check if property type is number?
|
||||
// const reflectedType = ColumnTypes.typeToString((Reflect as any).getMetadata("design:type", object, propertyName));
|
||||
|
||||
// create and register a new column metadata
|
||||
const args: RelationCountMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relation: relation
|
||||
relation: relation,
|
||||
alias: alias,
|
||||
queryBuilderFactory: queryBuilderFactory
|
||||
};
|
||||
getMetadataArgsStorage().relationCounts.add(args);
|
||||
getMetadataArgsStorage().relationCounts.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {RelationIdMetadataArgs} from "../../metadata-args/RelationIdMetadataArgs";
|
||||
import {QueryBuilder} from "../../query-builder/QueryBuilder";
|
||||
|
||||
/**
|
||||
* Special decorator used to extract relation id into separate entity property.
|
||||
*/
|
||||
export function RelationId<T>(relation: string|((object: T) => any)): Function {
|
||||
export function RelationId<T>(relation: string|((object: T) => any), alias?: string, queryBuilderFactory?: (qb: QueryBuilder<any>) => QueryBuilder<any>): Function {
|
||||
return function (object: Object, propertyName: string) {
|
||||
const args: RelationIdMetadataArgs = {
|
||||
target: object.constructor,
|
||||
propertyName: propertyName,
|
||||
relation: relation
|
||||
relation: relation,
|
||||
alias: alias,
|
||||
queryBuilderFactory: queryBuilderFactory
|
||||
};
|
||||
getMetadataArgsStorage().relationIds.add(args);
|
||||
getMetadataArgsStorage().relationIds.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {getMetadataArgsStorage, getConnection} from "../../index";
|
||||
import {getConnection, getMetadataArgsStorage} from "../../index";
|
||||
|
||||
/**
|
||||
* Wraps some method into the transaction.
|
||||
@ -17,14 +17,12 @@ export function Transaction(connectionName: string = "default"): Function {
|
||||
// override method descriptor with proxy method
|
||||
descriptor.value = function(...args: any[]) {
|
||||
return getConnection(connectionName)
|
||||
.entityManager
|
||||
.manager
|
||||
.transaction(entityManager => {
|
||||
|
||||
// gets all @TransactionEntityManager() decorator usages for this method
|
||||
const indices = getMetadataArgsStorage()
|
||||
.transactionEntityManagers
|
||||
.filterByTarget(target.constructor)
|
||||
.toArray()
|
||||
.filterTransactionEntityManagers(target.constructor)
|
||||
.filter(transactionEntityManager => transactionEntityManager.methodName === methodName)
|
||||
.map(transactionEntityManager => transactionEntityManager.index);
|
||||
|
||||
|
||||
@ -11,6 +11,6 @@ export function TransactionEntityManager(): Function {
|
||||
methodName: methodName,
|
||||
index: index,
|
||||
};
|
||||
getMetadataArgsStorage().transactionEntityManagers.add(args);
|
||||
getMetadataArgsStorage().transactionEntityManagers.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
|
||||
/**
|
||||
@ -25,11 +24,11 @@ export function TreeChildren(options?: { cascadeInsert?: boolean, cascadeUpdate?
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
isLazy: isLazy,
|
||||
relationType: RelationTypes.ONE_TO_MANY,
|
||||
relationType: "one-to-many",
|
||||
type: () => object.constructor,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ export function TreeLevelColumn(): Function {
|
||||
mode: "treeLevel",
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().columns.add(args);
|
||||
getMetadataArgsStorage().columns.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import {getMetadataArgsStorage} from "../../index";
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {RelationTypes} from "../../metadata/types/RelationTypes";
|
||||
import {RelationMetadataArgs} from "../../metadata-args/RelationMetadataArgs";
|
||||
|
||||
/**
|
||||
@ -24,11 +23,11 @@ export function TreeParent(options?: { cascadeInsert?: boolean, cascadeUpdate?:
|
||||
propertyName: propertyName,
|
||||
// propertyType: reflectedType,
|
||||
isLazy: isLazy,
|
||||
relationType: RelationTypes.MANY_TO_ONE,
|
||||
relationType: "many-to-one",
|
||||
type: () => object.constructor,
|
||||
options: options
|
||||
};
|
||||
getMetadataArgsStorage().relations.add(args);
|
||||
getMetadataArgsStorage().relations.push(args);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import {QueryRunner} from "../query-runner/QueryRunner";
|
||||
import {ColumnMetadata} from "../metadata/ColumnMetadata";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {LazyRelationsWrapper} from "../lazy-loading/LazyRelationsWrapper";
|
||||
|
||||
/**
|
||||
* Driver organizes TypeORM communication with specific database management system.
|
||||
@ -14,6 +15,11 @@ export interface Driver {
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver options contains connectivity options used to connection to the database.
|
||||
*/
|
||||
|
||||
@ -47,7 +47,7 @@ export interface DriverOptions {
|
||||
* Schema name. By default is "public" (used only in Postgres databases).
|
||||
*/
|
||||
readonly schemaName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* Connection SID (used for Oracle databases).
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user