Merge branch 'master' into issue-512-fix

This commit is contained in:
Umed Khudoiberdiev 2017-06-07 15:06:47 +05:00 committed by GitHub
commit 24a5d4e614
579 changed files with 34505 additions and 7844 deletions

View File

@ -18,6 +18,15 @@ 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
* controller / subscriber / migrations from options tsconfig now appended with a project root directory
### NEW FEATURES

View File

@ -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));

View File

@ -30,7 +30,8 @@ Share this library with friends on Twitter and everywhere else you can.
If you notice bug or have something not working please report an issue, we'll try to fix it as soon as possible.
More documentation and features expected to be soon. Feel free to contribute.
> For the latest release changes see [changelog](./CHANGELOG.md).
> Important note: if you want latest stable version install `npm i typeorm@0.0.11`. You can find 0.0.11 version [README here](https://github.com/typeorm/typeorm/tree/0.0.x-version).
> If you want the latest development version simply install `npm i typeorm`. For the latest development release changes see [changelog](./CHANGELOG.md).
TypeORM is an [Object Relational Mapper](1) (ORM) for Node.js written in
TypeScript that can be used with TypeScript or JavaScript (ES5, ES6, ES7).
@ -62,6 +63,10 @@ TypeORM is highly influenced by other ORMs, such as [Hibernate](http://hibernate
1. Install module:
`npm install typeorm --save`
Important note: if you want latest stable version install `npm i typeorm@0.0.11`
If you want the latest development version simply install `npm i typeorm`. For the latest development release changes see [changelog](./CHANGELOG.md).
2. You need to install `reflect-metadata` shim:
@ -424,7 +429,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 +455,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 +475,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));

View File

@ -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"

View File

@ -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));

View File

@ -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")

View File

@ -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);

View File

@ -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));

View File

@ -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 {

View File

@ -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));

View File

@ -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 })

View File

@ -1,7 +1,5 @@
import {PrimaryGeneratedColumn, Column} from "../../../src/index";
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
@AbstractEntity()
export class BasePost {
@PrimaryGeneratedColumn()

View File

@ -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));

View File

@ -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));

View File

@ -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 {

View File

@ -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}`);

View File

@ -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 => {

View File

@ -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);

View File

@ -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

View File

@ -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.");

View File

@ -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({

View File

@ -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);

View File

@ -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

View File

@ -39,7 +39,7 @@ createConnection(options).then(connection => {
};
postRepository
.persist(post)
.save(post)
.then(result => {
console.log(result);
})

View File

@ -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);

View File

@ -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);

View File

@ -1,7 +1,5 @@
import {Column} from "../../../src/index";
import {EmbeddableEntity} from "../../../src/decorator/entity/EmbeddableEntity";
@EmbeddableEntity()
export class Counters {
@Column()

View File

@ -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: ");

View File

@ -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: ");

View File

@ -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);

View File

@ -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));

View File

@ -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();

View File

@ -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));

View File

@ -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

View File

@ -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));

View 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;
}

View File

@ -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() {

View File

@ -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> {

View File

@ -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();
}
}

View File

@ -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({

View File

@ -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 {

View File

@ -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));

View File

@ -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("---------------------------");

View File

@ -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));

View File

@ -1,7 +1,5 @@
import {PrimaryGeneratedColumn, Column} from "../../../src/index";
import {AbstractEntity} from "../../../src/decorator/entity/AbstractEntity";
@AbstractEntity()
export class BasePost {
@PrimaryGeneratedColumn()

View File

@ -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();

View File

@ -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);
})

View File

@ -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");

View File

@ -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);
}
/**

View File

@ -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,18 +378,53 @@ 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.`);
const environmentLessOptions = optionsArray.filter(options => (options.name || "default") === connectionName);
const options = environmentLessOptions.filter(options => !options.environment || options.environment === PlatformTools.getEnvVariable("NODE_ENV")); // skip connection creation if environment is set in the options, and its not equal to the value in the NODE_ENV variable
const options = environmentLessOptions.find(options => !options.environment || options.environment === PlatformTools.getEnvVariable("NODE_ENV")); // skip connection creation if environment is set in the options, and its not equal to the value in the NODE_ENV variable
if (!options.length)
if (!options)
throw new Error(`Connection "${connectionName}" ${PlatformTools.getEnvVariable("NODE_ENV") ? "for the environment " + PlatformTools.getEnvVariable("NODE_ENV") + " " : ""}was not found in the json configuration file.` +
(environmentLessOptions.length ? ` However there are such configurations for other environments: ${environmentLessOptions.map(options => options.environment).join(", ")}.` : ""));
return this.createAndConnectByConnectionOptions(options[0]);
// normalize directory paths
if (options.entities) {
options.entities = (options.entities as any[]).map(entity => {
if (typeof entity === "string" || entity.substr(0, 1) !== "/")
return PlatformTools.load("app-root-path").path + "/" + entity;
return entity;
});
}
if (options.subscribers) {
options.subscribers = (options.subscribers as any[]).map(subscriber => {
if (typeof subscriber === "string" || subscriber.substr(0, 1) !== "/")
return PlatformTools.load("app-root-path").path + "/" + subscriber;
return subscriber;
});
}
if (options.migrations) {
options.migrations = (options.migrations as any[]).map(migration => {
if (typeof migration === "string" || migration.substr(0, 1) !== "/")
return PlatformTools.load("app-root-path").path + "/" + migration;
return migration;
});
}
if (options.namingStrategies) {
options.namingStrategies = (options.namingStrategies as any[]).map(namingStrategy => {
if (typeof namingStrategy === "string" || namingStrategy.substr(0, 1) !== "/")
return PlatformTools.load("app-root-path").path + "/" + namingStrategy;
return namingStrategy;
});
}
return this.createAndConnectByConnectionOptions(options);
}
/**

View File

@ -12,65 +12,65 @@ export interface ConnectionOptions {
/**
* Database options of this connection.
*/
readonly driver: DriverOptions;
driver: DriverOptions;
/**
* Connection name. If connection name is not given then it will be called "default".
* Different connections must have different names.
*/
readonly name?: string;
name?: string;
/**
* Name of the naming strategy or target class of the naming strategy to be used for this connection.
*/
readonly usedNamingStrategy?: string|Function;
usedNamingStrategy?: string|Function;
/**
* Entities to be loaded for this connection.
* Accepts both entity classes and directories where from entities need to be loaded.
* Directories support glob patterns.
*/
readonly entities?: Function[]|string[];
entities?: Function[]|string[];
/**
* Subscribers to be loaded for this connection.
* Accepts both subscriber classes and directories where from subscribers need to be loaded.
* Directories support glob patterns.
*/
readonly subscribers?: Function[]|string[];
subscribers?: Function[]|string[];
/**
* Naming strategies to be loaded for this connection.
* Accepts both naming strategy classes and directories where from naming strategies need to be loaded.
* Directories support glob patterns.
*/
readonly namingStrategies?: Function[]|string[];
namingStrategies?: Function[]|string[];
/**
* Entity schemas to be loaded for this connection.
* Accepts both entity schema classes and directories where from entity schemas need to be loaded.
* Directories support glob patterns.
*/
readonly entitySchemas?: EntitySchema[]|string[];
entitySchemas?: EntitySchema[]|string[];
/**
* Migrations to be loaded for this connection.
* Accepts both migration classes and directories where from migrations need to be loaded.
* Directories support glob patterns.
*/
readonly migrations?: Function[]|string[];
migrations?: Function[]|string[];
/**
* Logging options.
*/
readonly logging?: LoggerOptions;
logging?: LoggerOptions;
/**
* Drops the schema each time connection is being established.
* Be careful with this option and don't use this in production - otherwise you'll loose all production data.
* This option is useful during debug and development.
*/
readonly dropSchemaOnConnection?: boolean;
dropSchemaOnConnection?: boolean;
/**
* Indicates if database schema should be auto created on every application launch.
@ -83,7 +83,7 @@ export interface ConnectionOptions {
*
* todo: rename it simply to synchronize: boolean ?
*/
readonly autoSchemaSync?: boolean;
autoSchemaSync?: boolean;
/**
* Indicates if migrations should be auto run on every application launch.
@ -91,7 +91,7 @@ export interface ConnectionOptions {
*
* todo: rename it simply to runMigrations: boolean ?
*/
readonly autoMigrationsRun?: boolean;
autoMigrationsRun?: boolean;
/**
* Environment in which connection will run.
@ -100,27 +100,27 @@ export interface ConnectionOptions {
* then this connection will be created. On any other NODE_ENV value it will be skipped.
* This option is specific to the configuration in the ormconfig.json file.
*/
readonly environment?: string;
environment?: string;
/**
* CLI settings.
*/
readonly cli?: {
cli?: {
/**
* Directory where entities should be created by default.
*/
readonly entitiesDir?: string;
entitiesDir?: string;
/**
* Directory where migrations should be created by default.
*/
readonly migrationsDir?: string;
migrationsDir?: string;
/**
* Directory where subscribers should be created by default.
*/
readonly subscribersDir?: string;
subscribersDir?: string;
};

View File

@ -11,6 +11,6 @@ export function DiscriminatorValue(value: any): Function {
target: target,
value: value
};
getMetadataArgsStorage().discriminatorValues.add(args);
getMetadataArgsStorage().discriminatorValues.push(args);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -14,6 +14,6 @@ export function NamingStrategy(name?: string): Function {
target: target,
name: strategyName
};
getMetadataArgsStorage().namingStrategies.add(args);
getMetadataArgsStorage().namingStrategies.push(args);
};
}

View File

@ -76,6 +76,6 @@ export function Column(typeOrOptions?: ColumnType|ColumnOptions, options?: Colum
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -27,6 +27,6 @@ export function CreateDateColumn(options?: ColumnOptions): Function {
mode: "createDate",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -24,7 +24,7 @@ export function DiscriminatorColumn(discriminatorOptions: { name: string, type:
propertyName: discriminatorOptions.name,
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -23,6 +23,6 @@ export function ObjectIdColumn<T>(options?: ColumnOptions): Function {
mode: "objectId",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -68,7 +68,7 @@ export function PrimaryColumn(typeOrOptions?: ColumnType|ColumnOptions, options?
mode: "regular",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -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);
};
}

View File

@ -26,7 +26,7 @@ export function UpdateDateColumn(options?: ColumnOptions): Function {
mode: "updateDate",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -29,7 +29,7 @@ export function VersionColumn(options?: ColumnOptions): Function {
mode: "version",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -12,6 +12,6 @@ export function SingleEntityChild() {
type: "single-table-child",
orderBy: undefined
};
getMetadataArgsStorage().tables.add(args);
getMetadataArgsStorage().tables.push(args);
};
}

View File

@ -10,6 +10,6 @@ export function TableInheritance(type: "single-table"|"class-table") {
target: target,
type: type
};
getMetadataArgsStorage().inheritances.add(args);
getMetadataArgsStorage().inheritances.push(args);
};
}

View File

@ -13,6 +13,6 @@ export function AfterInsert() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_INSERT
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterLoad() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_LOAD
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterRemove() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_REMOVE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function AfterUpdate() {
propertyName: propertyName,
type: EventListenerTypes.AFTER_UPDATE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeInsert() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_INSERT
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeRemove() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_REMOVE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -12,6 +12,6 @@ export function BeforeUpdate() {
propertyName: propertyName,
type: EventListenerTypes.BEFORE_UPDATE
};
getMetadataArgsStorage().entityListeners.add(args);
getMetadataArgsStorage().entityListeners.push(args);
};
}

View File

@ -10,6 +10,6 @@ export function EventSubscriber() {
const args: EntitySubscriberMetadataArgs = {
target: target
};
getMetadataArgsStorage().entitySubscribers.add(args);
getMetadataArgsStorage().entitySubscribers.push(args);
};
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}

View 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[];
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
});
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);

View File

@ -11,6 +11,6 @@ export function TransactionEntityManager(): Function {
methodName: methodName,
index: index,
};
getMetadataArgsStorage().transactionEntityManagers.add(args);
getMetadataArgsStorage().transactionEntityManagers.push(args);
};
}

View File

@ -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);
};
}

View File

@ -22,7 +22,7 @@ export function TreeLevelColumn(): Function {
mode: "treeLevel",
options: options
};
getMetadataArgsStorage().columns.add(args);
getMetadataArgsStorage().columns.push(args);
};
}

View File

@ -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);
};
}

View File

@ -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.
*/

Some files were not shown because too many files have changed in this diff Show More