refactored entity metadata and repositories - switched delegation process

This commit is contained in:
Umed Khudoiberdiev 2017-05-19 18:46:23 +05:00
parent bababca2c0
commit 3baa57be3e
81 changed files with 1086 additions and 1268 deletions

View File

@ -18,9 +18,13 @@ 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` object
* 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
### 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

@ -425,7 +425,7 @@ createConnection(/*...*/).then(connection => {
photo.views = 1;
photo.isPublished = true;
connection.entityManager
connection.manager
.persist(photo)
.then(photo => {
console.log("Photo has been saved");
@ -451,7 +451,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));
@ -471,7 +471,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

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

View File

@ -31,12 +31,12 @@ createConnection(options).then(async connection => {
post.title = "Hello Repositories!";
await connection
.entityManager
.manager
.getCustomRepository(PostRepository)
.save(post);
const loadedPost = await connection
.entityManager
.manager
.getCustomRepository(PostRepository)
.findMyPost();

View File

@ -13,7 +13,7 @@ export class AuthorRepository extends AbstractRepository<Author> {
author.firstName = firstName;
author.lastName = lastName;
return this.entityManager.save(author);
return this.manager.save(author);
}
findMyAuthor() {

View File

@ -575,29 +575,13 @@ export class Connection {
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)();
}
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 as any)["manager"])
(entityRepositoryInstance as any)["manager"] = this.manager;
}
if (entityRepositoryInstance instanceof Repository) {
if (!entityRepositoryMetadataArgs.entity)
@ -605,7 +589,7 @@ export class Connection {
// 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)["manager"] = this.manager;
(entityRepositoryInstance as any)["metadata"] = this.getMetadata(entityRepositoryMetadataArgs.entity);
}
@ -616,19 +600,6 @@ export class Connection {
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.find(repository => {
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
});
if (!entityRepositoryMetadataArgs)
throw new CustomRepositoryNotFoundError(customRepository);
return entityRepositoryMetadataArgs.entity;
}
// -------------------------------------------------------------------------
// Protected Methods

View File

@ -6,28 +6,11 @@ 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.push(args);
};

View File

@ -17,7 +17,7 @@ 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

View File

@ -1,306 +0,0 @@
import {Connection} from "../connection/Connection";
import {QueryBuilder} from "../query-builder/QueryBuilder";
import {Repository} from "../repository/Repository";
import {ObjectType} from "../common/ObjectType";
import {TreeRepository} from "../repository/TreeRepository";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
import {RepositoryAggregator} from "../repository/RepositoryAggregator";
import {RepositoryNotTreeError} from "../connection/error/RepositoryNotTreeError";
import {NoNeedToReleaseEntityManagerError} from "./error/NoNeedToReleaseEntityManagerError";
import {QueryRunnerProviderAlreadyReleasedError} from "../query-runner/error/QueryRunnerProviderAlreadyReleasedError";
import {SpecificRepository} from "../repository/SpecificRepository";
import {MongoRepository} from "../repository/MongoRepository";
import {DeepPartial} from "../common/DeepPartial";
/**
* Common functions shared between different entity manager types.
*/
export abstract class BaseEntityManager {
// -------------------------------------------------------------------------
// Private Properties
// -------------------------------------------------------------------------
/**
* Stores all registered repositories.
* Used when custom queryRunnerProvider is provided.
*/
private readonly repositoryAggregators: RepositoryAggregator[] = [];
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
/**
* @param connection Connection to be used in this entity manager
* @param queryRunnerProvider Custom query runner to be used for operations in this entity manager
*/
constructor(protected connection: Connection,
protected queryRunnerProvider?: QueryRunnerProvider) {
}
// -------------------------------------------------------------------------
// Public Methods
// -------------------------------------------------------------------------
/**
* Gets repository for the given entity class.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getRepository<Entity>(entityClass: ObjectType<Entity>): Repository<Entity>;
/**
* Gets repository for the given entity name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getRepository<Entity>(entityName: string): Repository<Entity>;
/**
* Gets repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): Repository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName as any).repository;
return this.connection.getRepository<Entity>(entityClassOrName as any);
}
/**
* Gets tree repository for the given entity class.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getTreeRepository<Entity>(entityClass: ObjectType<Entity>): TreeRepository<Entity>;
/**
* Gets tree repository for the given entity name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getTreeRepository<Entity>(entityName: string): TreeRepository<Entity>;
/**
* Gets tree repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getTreeRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): TreeRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider) {
const treeRepository = this.obtainRepositoryAggregator(entityClassOrName).treeRepository;
if (!treeRepository)
throw new RepositoryNotTreeError(entityClassOrName);
return treeRepository;
}
return this.connection.getTreeRepository<Entity>(entityClassOrName as any);
}
/**
* Gets mongodb repository for the given entity class.
*/
getMongoRepository<Entity>(entityClass: ObjectType<Entity>): MongoRepository<Entity>;
/**
* Gets mongodb repository for the given entity name.
*/
getMongoRepository<Entity>(entityName: string): MongoRepository<Entity>;
/**
* Gets mongodb repository for the given entity class or name.
*/
getMongoRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): MongoRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName as any).repository as MongoRepository<Entity>;
return this.connection.getMongoRepository<Entity>(entityClassOrName as any);
}
/**
* Gets specific repository for the given entity class.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityClass: ObjectType<Entity>): SpecificRepository<Entity>;
/**
* Gets specific repository for the given entity name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityName: string): SpecificRepository<Entity>;
/**
* Gets specific repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): SpecificRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName).specificRepository;
return this.connection.getSpecificRepository<Entity>(entityClassOrName as any);
}
/**
* Gets custom entity repository marked with @EntityRepository decorator.
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
return this.connection.getCustomRepository<T>(customRepository);
}
/**
* Checks if entity has an id.
*/
hasId(entity: any): boolean;
/**
* Checks if entity of given schema name has an id.
*/
hasId(target: string, entity: any): boolean;
/**
* Checks if entity has an id by its Function type or schema name.
*/
hasId(targetOrEntity: any|string, maybeEntity?: any): boolean {
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor;
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity;
return this.getRepository(target as any).hasId(entity);
}
/**
* Gets entity mixed id.
*/
getId(entity: any): any;
/**
* Gets entity mixed id.
*/
getId(target: string, entity: any): any;
/**
* Gets entity mixed id.
*/
getId(targetOrEntity: any|string, maybeEntity?: any): any {
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor;
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity;
return this.getRepository(target as any).getId(entity);
}
/**
* Creates a new query builder that can be used to build an sql query.
*/
createQueryBuilder<Entity>(entityClass: ObjectType<Entity>|Function|string, alias: string): QueryBuilder<Entity> {
return this.getRepository(entityClass as any).createQueryBuilder(alias);
}
/**
* Creates a new entity instance.
*/
create<Entity>(entityClass: ObjectType<Entity>): Entity;
/**
* Creates a new entity instance and copies all entity properties from this object into a new entity.
* Note that it copies only properties that present in entity schema.
*/
create<Entity>(entityClass: ObjectType<Entity>, plainObject: DeepPartial<Entity>): Entity;
/**
* Creates a new entities and copies all entity properties from given objects into their new entities.
* Note that it copies only properties that present in entity schema.
*/
create<Entity>(entityClass: ObjectType<Entity>, plainObjects: DeepPartial<Entity>[]): Entity[];
/**
* Creates a new entity instance or instances.
* Can copy properties from the given object into new entities.
*/
create<Entity>(entityClass: ObjectType<Entity>, plainObjectOrObjects?: DeepPartial<Entity>|DeepPartial<Entity>[]): Entity|Entity[] {
if (plainObjectOrObjects instanceof Array) {
return this.getRepository(entityClass).create(plainObjectOrObjects);
} else if (plainObjectOrObjects) {
return this.getRepository(entityClass).create(plainObjectOrObjects);
} else {
return this.getRepository(entityClass).create();
}
}
/**
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then
* it loads it (and everything related to it), replaces all values with the new ones from the given object
* and returns this new entity. This new entity is actually a loaded from the db entity with all properties
* replaced from the new object.
*/
preload<Entity>(entityClass: ObjectType<Entity>, object: DeepPartial<Entity>): Promise<Entity> {
return this.getRepository(entityClass).preload(object);
}
/**
* Merges two entities into one new entity.
*/
merge<Entity>(entityClass: ObjectType<Entity>, mergeIntoEntity: Entity, ...objects: DeepPartial<Entity>[]): Entity { // todo: throw exception ie tntity manager is released
return <Entity> this.getRepository(entityClass).merge(mergeIntoEntity, ...objects);
}
/**
* Releases all resources used by entity manager.
* This is used when entity manager is created with a single query runner,
* and this single query runner needs to be released after job with entity manager is done.
*/
async release(): Promise<void> {
if (!this.queryRunnerProvider)
throw new NoNeedToReleaseEntityManagerError();
return this.queryRunnerProvider.releaseReused();
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* Gets, or if does not exist yet, creates and returns a repository aggregator for a particular entity target.
*/
protected obtainRepositoryAggregator<Entity>(entityClassOrName: ObjectType<Entity>|string): RepositoryAggregator {
if (this.queryRunnerProvider && this.queryRunnerProvider.isReleased)
throw new QueryRunnerProviderAlreadyReleasedError();
const metadata = this.connection.getMetadata(entityClassOrName);
let repositoryAggregator = this.repositoryAggregators.find(repositoryAggregate => repositoryAggregate.metadata === metadata);
if (!repositoryAggregator) {
repositoryAggregator = new RepositoryAggregator(
this.connection,
this.connection.getMetadata(entityClassOrName as any),
this.queryRunnerProvider
);
this.repositoryAggregators.push(repositoryAggregator); // todo: check isnt memory leak here?
}
return repositoryAggregator;
}
}

View File

@ -1,7 +1,6 @@
import {Connection} from "../connection/Connection";
import {FindManyOptions} from "../find-options/FindManyOptions";
import {ObjectType} from "../common/ObjectType";
import {BaseEntityManager} from "./BaseEntityManager";
import {QueryRunnerProviderAlreadyReleasedError} from "../query-runner/error/QueryRunnerProviderAlreadyReleasedError";
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
import {ObjectLiteral} from "../common/ObjectLiteral";
@ -9,12 +8,25 @@ import {FindOneOptions} from "../find-options/FindOneOptions";
import {DeepPartial} from "../common/DeepPartial";
import {RemoveOptions} from "../repository/RemoveOptions";
import {SaveOptions} from "../repository/SaveOptions";
import {RepositoryAggregator} from "../repository/RepositoryAggregator";
import {NoNeedToReleaseEntityManagerError} from "./error/NoNeedToReleaseEntityManagerError";
import {SpecificRepository} from "../repository/SpecificRepository";
import {MongoRepository} from "../repository/MongoRepository";
import {TreeRepository} from "../repository/TreeRepository";
import {Repository} from "../repository/Repository";
import {RepositoryNotTreeError} from "../connection/error/RepositoryNotTreeError";
import {QueryBuilder} from "../query-builder/QueryBuilder";
import {FindOptionsUtils} from "../find-options/FindOptionsUtils";
import {SubjectBuilder} from "../persistence/SubjectBuilder";
import {SubjectOperationExecutor} from "../persistence/SubjectOperationExecutor";
import {PlainObjectToNewEntityTransformer} from "../query-builder/transformer/PlainObjectToNewEntityTransformer";
import {PlainObjectToDatabaseEntityTransformer} from "../query-builder/transformer/PlainObjectToDatabaseEntityTransformer";
/**
* Entity manager supposed to work with any entity, automatically find its repository and call its methods,
* whatever entity type are you passing.
*/
export class EntityManager extends BaseEntityManager {
export class EntityManager {
// -------------------------------------------------------------------------
// Private properties
@ -26,12 +38,22 @@ export class EntityManager extends BaseEntityManager {
*/
private data: ObjectLiteral = {};
/**
* Stores all registered repositories.
* Used when custom queryRunnerProvider is provided.
*/
private readonly repositoryAggregators: RepositoryAggregator[] = [];
// -------------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------------
constructor(connection: Connection, queryRunnerProvider?: QueryRunnerProvider) {
super(connection, queryRunnerProvider);
/**
* @param connection Connection to be used in this entity manager
* @param queryRunnerProvider Custom query runner to be used for operations in this entity manager
*/
constructor(public connection: Connection,
protected queryRunnerProvider?: QueryRunnerProvider) {
}
// -------------------------------------------------------------------------
@ -52,6 +74,115 @@ export class EntityManager extends BaseEntityManager {
this.data[key] = value;
}
/**
* Checks if entity has an id.
*/
hasId(entity: any): boolean;
/**
* Checks if entity of given schema name has an id.
*/
hasId(target: Function|string, entity: any): boolean;
/**
* Checks if entity has an id by its Function type or schema name.
*/
hasId(targetOrEntity: any|Function|string, maybeEntity?: any): boolean {
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor;
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity;
const metadata = this.connection.getMetadata(target);
return metadata.hasId(entity);
}
/**
* Gets entity mixed id.
*/
getId(entity: any): any;
/**
* Gets entity mixed id.
*/
getId(target: Function|string, entity: any): any;
/**
* Gets entity mixed id.
*/
getId(targetOrEntity: any|Function|string, maybeEntity?: any): any {
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor;
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity;
const metadata = this.connection.getMetadata(target);
return metadata.getEntityIdMixedMap(entity);
}
/**
* Creates a new query builder that can be used to build an sql query.
*/
createQueryBuilder<Entity>(entityClass: ObjectType<Entity>|Function|string, alias: string, queryRunnerProvider?: QueryRunnerProvider): QueryBuilder<Entity> {
const metadata = this.connection.getMetadata(entityClass);
return new QueryBuilder(this.connection, queryRunnerProvider || this.queryRunnerProvider)
.select(alias)
.from(metadata.target, alias);
}
/**
* Creates a new entity instance.
*/
create<Entity>(entityClass: ObjectType<Entity>): Entity;
/**
* Creates a new entity instance and copies all entity properties from this object into a new entity.
* Note that it copies only properties that present in entity schema.
*/
create<Entity>(entityClass: ObjectType<Entity>|string, plainObject: DeepPartial<Entity>): Entity;
/**
* Creates a new entities and copies all entity properties from given objects into their new entities.
* Note that it copies only properties that present in entity schema.
*/
create<Entity>(entityClass: ObjectType<Entity>|string, plainObjects: DeepPartial<Entity>[]): Entity[];
/**
* Creates a new entity instance or instances.
* Can copy properties from the given object into new entities.
*/
create<Entity>(entityClass: ObjectType<Entity>|string, plainObjectOrObjects?: DeepPartial<Entity>|DeepPartial<Entity>[]): Entity|Entity[] {
const metadata = this.connection.getMetadata(entityClass);
if (!plainObjectOrObjects)
return metadata.create();
if (plainObjectOrObjects instanceof Array)
return plainObjectOrObjects.map(plainEntityLike => this.create(entityClass, plainEntityLike));
return this.merge(entityClass, metadata.create(), plainObjectOrObjects);
}
/**
* Merges two entities into one new entity.
*/
merge<Entity>(entityClass: ObjectType<Entity>|string, mergeIntoEntity: Entity, ...entityLikes: DeepPartial<Entity>[]): Entity { // todo: throw exception ie tntity manager is released
const metadata = this.connection.getMetadata(entityClass);
const plainObjectToEntityTransformer = new PlainObjectToNewEntityTransformer();
entityLikes.forEach(object => plainObjectToEntityTransformer.transform(mergeIntoEntity, object, metadata));
return mergeIntoEntity;
}
/**
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then
* it loads it (and everything related to it), replaces all values with the new ones from the given object
* and returns this new entity. This new entity is actually a loaded from the db entity with all properties
* replaced from the new object.
*/
async preload<Entity>(entityClass: ObjectType<Entity>|string, entityLike: DeepPartial<Entity>): Promise<Entity|undefined> {
const metadata = this.connection.getMetadata(entityClass);
const plainObjectToDatabaseEntityTransformer = new PlainObjectToDatabaseEntityTransformer(this.connection.manager);
const transformedEntity = await plainObjectToDatabaseEntityTransformer.transform(entityLike, metadata);
if (transformedEntity)
return this.merge(entityClass, transformedEntity as Entity, entityLike);
return undefined;
}
/**
* Persists (saves) all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
@ -62,13 +193,7 @@ export class EntityManager extends BaseEntityManager {
* Persists (saves) all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/
save<Entity>(targetOrEntity: Function, entity: Entity, options?: SaveOptions): Promise<Entity>;
/**
* Persists (saves) all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/
save<Entity>(targetOrEntity: string, entity: Entity, options?: SaveOptions): Promise<Entity>;
save<Entity>(targetOrEntity: Function|string, entity: Entity, options?: SaveOptions): Promise<Entity>;
/**
* Persists (saves) all given entities in the database.
@ -80,36 +205,30 @@ export class EntityManager extends BaseEntityManager {
* Persists (saves) all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/
save<Entity>(targetOrEntity: Function, entities: Entity[], options?: SaveOptions): Promise<Entity[]>;
/**
* Persists (saves) all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/
save<Entity>(targetOrEntity: string, entities: Entity[], options?: SaveOptions): Promise<Entity[]>;
save<Entity>(targetOrEntity: Function|string, entities: Entity[], options?: SaveOptions): Promise<Entity[]>;
/**
* Persists (saves) a given entity in the database.
*/
save<Entity>(targetOrEntity: (Entity|Entity[])|Function|string, maybeEntity?: Entity|Entity[], options?: SaveOptions): Promise<Entity|Entity[]> {
const target = arguments.length === 2 ? maybeEntity as Entity|Entity[] : targetOrEntity as Function|string;
const entity = arguments.length === 2 ? maybeEntity as Entity|Entity[] : targetOrEntity as Entity|Entity[];
return Promise.resolve().then(() => { // we MUST call "fake" resolve here to make sure all properties of lazily loaded properties are resolved.
if (typeof target === "string") {
return this.getRepository<Entity|Entity[]>(target).save(entity, options);
} else {
// todo: throw exception if constructor in target is not set
if (target instanceof Array) {
if (target.length === 0)
return Promise.resolve(target);
save<Entity>(targetOrEntity: (Entity|Entity[])|Function|string, maybeEntityOrOptions?: Entity|Entity[], maybeOptions?: SaveOptions): Promise<Entity|Entity[]> {
return Promise.all(target.map((t, i) => {
return this.getRepository<Entity>(t.constructor).save((entity as Entity[])[i], options);
}));
} else {
return this.getRepository<Entity>(target.constructor).save(entity as Entity, options);
}
const target = (arguments.length > 1 && (targetOrEntity instanceof Function || typeof targetOrEntity === "string")) ? targetOrEntity as Function|string : undefined;
const entity: Entity|Entity[] = target ? maybeEntityOrOptions as Entity|Entity[] : targetOrEntity as Entity|Entity[];
const options = target ? maybeOptions : maybeEntityOrOptions as SaveOptions;
return Promise.resolve().then(async () => { // we MUST call "fake" resolve here to make sure all properties of lazily loaded properties are resolved.
// todo: throw exception if constructor in target is not set
if (entity instanceof Array) {
await Promise.all(entity.map(e => {
const finalTarget = target ? target : e.constructor;
return this.saveOne(finalTarget, e, options) as any;
}));
} else {
const finalTarget = target ? target : entity.constructor;
await this.saveOne(finalTarget, entity as Entity, options);
}
return entity;
});
}
@ -159,27 +278,35 @@ export class EntityManager extends BaseEntityManager {
/**
* Updates entity partially. Entity can be found by a given conditions.
*/
async update<Entity>(target: Function|string, conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
async update<Entity>(target: ObjectType<Entity>|string, conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
/**
* Updates entity partially. Entity can be found by a given find options.
*/
async update<Entity>(target: Function|string, findOptions: FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
async update<Entity>(target: ObjectType<Entity>|string, findOptions: FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
/**
* Updates entity partially. Entity can be found by a given conditions.
*/
async update<Entity>(target: Function|string, conditionsOrFindOptions: Partial<Entity>|FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
return this.getRepository<Entity|Entity[]>(target as any)
.update(conditionsOrFindOptions as any, partialEntity, options);
async update<Entity>(target: ObjectType<Entity>|string, conditionsOrFindOptions: Partial<Entity>|FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
const entity = await this.findOne(target, conditionsOrFindOptions as any); // this is temporary, in the future can be refactored to perform better
if (!entity)
throw new Error(`Cannot find entity to update by a given criteria`);
Object.assign(entity, partialEntity);
await this.save(entity, options);
}
/**
* Updates entity partially. Entity will be found by a given id.
*/
async updateById<Entity>(target: Function|string, id: any, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
return this.getRepository<Entity|Entity[]>(target as any)
.updateById(id, partialEntity, options);
async updateById<Entity>(target: ObjectType<Entity>|string, id: any, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
const entity = await this.findOneById(target, id as any); // this is temporary, in the future can be refactored to perform better
if (!entity)
throw new Error(`Cannot find entity to update by a id`);
Object.assign(entity, partialEntity);
await this.save(entity, options);
}
/**
@ -190,12 +317,7 @@ export class EntityManager extends BaseEntityManager {
/**
* Removes a given entity from the database.
*/
remove<Entity>(targetOrEntity: Function, entity: Entity, options?: RemoveOptions): Promise<Entity>;
/**
* Removes a given entity from the database.
*/
remove<Entity>(targetOrEntity: string, entity: Entity, options?: RemoveOptions): Promise<Entity>;
remove<Entity>(targetOrEntity: ObjectType<Entity>|string, entity: Entity, options?: RemoveOptions): Promise<Entity>;
/**
* Removes a given entity from the database.
@ -205,72 +327,80 @@ export class EntityManager extends BaseEntityManager {
/**
* Removes a given entity from the database.
*/
remove<Entity>(targetOrEntity: Function, entity: Entity[], options?: RemoveOptions): Promise<Entity[]>;
remove<Entity>(targetOrEntity: ObjectType<Entity>|string, entity: Entity[], options?: RemoveOptions): Promise<Entity[]>;
/**
* Removes a given entity from the database.
*/
remove<Entity>(targetOrEntity: string, entity: Entity[], options?: RemoveOptions): Promise<Entity[]>;
remove<Entity>(targetOrEntity: (Entity|Entity[])|Function|string, maybeEntityOrOptions?: Entity|Entity[], maybeOptions?: RemoveOptions): Promise<Entity|Entity[]> {
/**
* Removes a given entity from the database.
*/
remove<Entity>(targetOrEntity: (Entity|Entity[])|Function|string, maybeEntity?: Entity|Entity[], options?: RemoveOptions): Promise<Entity|Entity[]> {
const target = arguments.length === 2 ? maybeEntity as Entity|Entity[] : targetOrEntity as Function|string;
const entity = arguments.length === 2 ? maybeEntity as Entity|Entity[] : targetOrEntity as Entity|Entity[];
if (typeof target === "string") {
return this.getRepository<Entity|Entity[]>(target).remove(entity, options);
} else {
const target = (arguments.length > 1 && (targetOrEntity instanceof Function || typeof targetOrEntity === "string")) ? targetOrEntity as Function|string : undefined;
const entity: Entity|Entity[] = target ? maybeEntityOrOptions as Entity|Entity[] : targetOrEntity as Entity|Entity[];
const options = target ? maybeOptions : maybeEntityOrOptions as RemoveOptions;
return Promise.resolve().then(async () => { // we MUST call "fake" resolve here to make sure all properties of lazily loaded properties are resolved.
// todo: throw exception if constructor in target is not set
if (target instanceof Array) {
return Promise.all(target.map((t, i) => {
return this.getRepository<Entity>(t.constructor).remove((entity as Entity[])[i], options);
if (entity instanceof Array) {
await Promise.all(entity.map(e => {
const finalTarget = target ? target : e.constructor;
return this.removeOne(finalTarget, e, options) as any;
}));
} else {
return this.getRepository<Entity>(target.constructor).remove(entity as Entity, options);
const finalTarget = target ? target : entity.constructor;
await this.removeOne(finalTarget, entity as Entity, options);
}
}
return entity;
});
}
/**
* Removes entity by a given entity id.
*/
async removeById(targetOrEntity: Function|string, id: any, options?: RemoveOptions): Promise<void> {
return this.getRepository(targetOrEntity as any).removeById(id, options);
async removeById<Entity>(targetOrEntity: ObjectType<Entity>|string, id: any, options?: RemoveOptions): Promise<void> {
const entity = await this.findOneById<any>(targetOrEntity, id); // this is temporary, in the future can be refactored to perform better
if (!entity)
throw new Error(`Cannot find entity to remove by a given id`);
await this.remove(entity, options);
}
/**
* Counts entities that match given options.
*/
count<Entity>(entityClass: ObjectType<Entity>, options?: FindManyOptions<Entity>): Promise<number>;
count<Entity>(entityClass: ObjectType<Entity>|string, options?: FindManyOptions<Entity>): Promise<number>;
/**
* Counts entities that match given conditions.
*/
count<Entity>(entityClass: ObjectType<Entity>, conditions?: Partial<Entity>): Promise<number>;
count<Entity>(entityClass: ObjectType<Entity>|string, conditions?: Partial<Entity>): Promise<number>;
/**
* Counts entities that match given find options or conditions.
*/
count<Entity>(entityClass: ObjectType<Entity>, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<number> {
return this.getRepository(entityClass).count(optionsOrConditions as ObjectLiteral);
count<Entity>(entityClass: ObjectType<Entity>|string, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<number> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || metadata.name);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getCount();
}
/**
* Finds entities that match given options.
*/
find<Entity>(entityClass: ObjectType<Entity>, options?: FindManyOptions<Entity>): Promise<Entity[]>;
find<Entity>(entityClass: ObjectType<Entity>|string, options?: FindManyOptions<Entity>): Promise<Entity[]>;
/**
* Finds entities that match given conditions.
*/
find<Entity>(entityClass: ObjectType<Entity>, conditions?: Partial<Entity>): Promise<Entity[]>;
find<Entity>(entityClass: ObjectType<Entity>|string, conditions?: Partial<Entity>): Promise<Entity[]>;
/**
* Finds entities that match given find options or conditions.
*/
find<Entity>(entityClass: ObjectType<Entity>, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<Entity[]> {
return this.getRepository(entityClass).find(optionsOrConditions as ObjectLiteral);
find<Entity>(entityClass: ObjectType<Entity>|string, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<Entity[]> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || metadata.name);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getMany();
}
/**
@ -278,79 +408,107 @@ export class EntityManager extends BaseEntityManager {
* Also counts all entities that match given conditions,
* but ignores pagination settings (from and take options).
*/
findAndCount<Entity>(entityClass: ObjectType<Entity>, options?: FindManyOptions<Entity>): Promise<[Entity[], number]>;
findAndCount<Entity>(entityClass: ObjectType<Entity>|string, options?: FindManyOptions<Entity>): Promise<[Entity[], number]>;
/**
* Finds entities that match given conditions.
* Also counts all entities that match given conditions,
* but ignores pagination settings (from and take options).
*/
findAndCount<Entity>(entityClass: ObjectType<Entity>, conditions?: Partial<Entity>): Promise<[Entity[], number]>;
findAndCount<Entity>(entityClass: ObjectType<Entity>|string, conditions?: Partial<Entity>): Promise<[Entity[], number]>;
/**
* Finds entities that match given find options and conditions.
* Also counts all entities that match given conditions,
* but ignores pagination settings (from and take options).
*/
findAndCount<Entity>(entityClass: ObjectType<Entity>, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<[Entity[], number]> {
return this.getRepository(entityClass).findAndCount(optionsOrConditions as ObjectLiteral);
findAndCount<Entity>(entityClass: ObjectType<Entity>|string, optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<[Entity[], number]> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || metadata.name);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getManyAndCount();
}
/**
* Finds entities with ids.
* Optionally find options can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>|string, ids: any[], options?: FindManyOptions<Entity>): Promise<Entity[]>;
/**
* Finds entities with ids.
* Optionally conditions can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>|string, ids: any[], conditions?: Partial<Entity>): Promise<Entity[]>;
/**
* Finds entities with ids.
* Optionally find options or conditions can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>|string, ids: any[], optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<Entity[]> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || metadata.name);
FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions);
ids = ids.map(id => {
if (!metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
return metadata.createEntityIdMap([id]);
}
return id;
});
qb.andWhereInIds(ids);
return qb.getMany();
}
/**
* Finds first entity that matches given find options.
*/
findOne<Entity>(entityClass: ObjectType<Entity>, options?: FindOneOptions<Entity>): Promise<Entity|undefined>;
findOne<Entity>(entityClass: ObjectType<Entity>|string, options?: FindOneOptions<Entity>): Promise<Entity|undefined>;
/**
* Finds first entity that matches given conditions.
*/
findOne<Entity>(entityClass: ObjectType<Entity>, conditions?: Partial<Entity>): Promise<Entity|undefined>;
findOne<Entity>(entityClass: ObjectType<Entity>|string, conditions?: Partial<Entity>): Promise<Entity|undefined>;
/**
* Finds first entity that matches given conditions.
*/
findOne<Entity>(entityClass: ObjectType<Entity>, optionsOrConditions?: FindOneOptions<Entity>|Partial<Entity>): Promise<Entity|undefined> {
return this.getRepository(entityClass).findOne(optionsOrConditions as ObjectLiteral);
}
/**
* Finds entities with ids.
* Optionally find options can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>, ids: any[], options?: FindManyOptions<Entity>): Promise<Entity[]>;
/**
* Finds entities with ids.
* Optionally conditions can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>, ids: any[], conditions?: Partial<Entity>): Promise<Entity[]>;
/**
* Finds entities with ids.
* Optionally find options or conditions can be applied.
*/
findByIds<Entity>(entityClass: ObjectType<Entity>, ids: any[], optionsOrConditions?: FindManyOptions<Entity>|Partial<Entity>): Promise<Entity[]> {
return this.getRepository(entityClass).findByIds(ids, optionsOrConditions as ObjectLiteral);
findOne<Entity>(entityClass: ObjectType<Entity>|string, optionsOrConditions?: FindOneOptions<Entity>|Partial<Entity>): Promise<Entity|undefined> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || metadata.name);
return FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getOne();
}
/**
* Finds entity with given id.
* Optionally find options can be applied.
*/
findOneById<Entity>(entityClass: ObjectType<Entity>, id: any, options?: FindOneOptions<Entity>): Promise<Entity|undefined>;
findOneById<Entity>(entityClass: ObjectType<Entity>|string, id: any, options?: FindOneOptions<Entity>): Promise<Entity|undefined>;
/**
* Finds entity with given id.
* Optionally conditions can be applied.
*/
findOneById<Entity>(entityClass: ObjectType<Entity>, id: any, conditions?: Partial<Entity>): Promise<Entity|undefined>;
findOneById<Entity>(entityClass: ObjectType<Entity>|string, id: any, conditions?: Partial<Entity>): Promise<Entity|undefined>;
/**
* Finds entity with given id.
* Optionally find options or conditions can be applied.
*/
findOneById<Entity>(entityClass: ObjectType<Entity>, id: any, optionsOrConditions?: FindOneOptions<Entity>|Partial<Entity>): Promise<Entity|undefined> {
return this.getRepository(entityClass).findOneById(id, optionsOrConditions as ObjectLiteral);
findOneById<Entity>(entityClass: ObjectType<Entity>|string, id: any, optionsOrConditions?: FindOneOptions<Entity>|Partial<Entity>): Promise<Entity|undefined> {
const metadata = this.connection.getMetadata(entityClass);
const qb = this.createQueryBuilder(entityClass, FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || metadata.name);
if (metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
// const columnNames = this.metadata.getEntityIdMap({ });
throw new Error(`You have multiple primary keys in your entity, to use findOneById with multiple primary keys please provide ` +
`complete object with all entity ids, like this: { firstKey: value, secondKey: value }`);
}
FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions);
if (!metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
id = metadata.createEntityIdMap([id]);
}
qb.andWhereInIds([id]);
return qb.getOne();
}
/**
@ -403,8 +561,191 @@ export class EntityManager extends BaseEntityManager {
/**
* Clears all the data from the given table (truncates/drops it).
*/
clear<Entity>(entityClass: ObjectType<Entity>): Promise<void> {
return this.getRepository(entityClass).clear();
async clear<Entity>(entityClass: ObjectType<Entity>|string): Promise<void> {
const metadata = this.connection.getMetadata(entityClass);
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver);
const queryRunner = await queryRunnerProvider.provide();
try {
return await queryRunner.truncate(metadata.tableName); // await is needed here because we are using finally
} finally {
await queryRunnerProvider.release(queryRunner);
}
}
/**
* Gets repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): Repository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName as any).repository;
return this.connection.getRepository<Entity>(entityClassOrName as any);
}
/**
* Gets tree repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getTreeRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): TreeRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider) {
const treeRepository = this.obtainRepositoryAggregator(entityClassOrName).treeRepository;
if (!treeRepository)
throw new RepositoryNotTreeError(entityClassOrName);
return treeRepository;
}
return this.connection.getTreeRepository<Entity>(entityClassOrName as any);
}
/**
* Gets mongodb repository for the given entity class.
*/
getMongoRepository<Entity>(entityClass: ObjectType<Entity>): MongoRepository<Entity>;
/**
* Gets mongodb repository for the given entity name.
*/
getMongoRepository<Entity>(entityName: string): MongoRepository<Entity>;
/**
* Gets mongodb repository for the given entity class or name.
*/
getMongoRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): MongoRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName as any).repository as MongoRepository<Entity>;
return this.connection.getMongoRepository<Entity>(entityClassOrName as any);
}
/**
* Gets specific repository for the given entity class.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityClass: ObjectType<Entity>): SpecificRepository<Entity>;
/**
* Gets specific repository for the given entity name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityName: string): SpecificRepository<Entity>;
/**
* Gets specific repository for the given entity class or name.
* If single database connection mode is used, then repository is obtained from the
* repository aggregator, where each repository is individually created for this entity manager.
* When single database connection is not used, repository is being obtained from the connection.
*/
getSpecificRepository<Entity>(entityClassOrName: ObjectType<Entity>|string): SpecificRepository<Entity> {
// if single db connection is used then create its own repository with reused query runner
if (this.queryRunnerProvider)
return this.obtainRepositoryAggregator(entityClassOrName).specificRepository;
return this.connection.getSpecificRepository<Entity>(entityClassOrName as any);
}
/**
* Gets custom entity repository marked with @EntityRepository decorator.
*/
getCustomRepository<T>(customRepository: ObjectType<T>): T {
return this.connection.getCustomRepository<T>(customRepository);
}
/**
* Releases all resources used by entity manager.
* This is used when entity manager is created with a single query runner,
* and this single query runner needs to be released after job with entity manager is done.
*/
async release(): Promise<void> {
if (!this.queryRunnerProvider)
throw new NoNeedToReleaseEntityManagerError();
return this.queryRunnerProvider.releaseReused();
}
// -------------------------------------------------------------------------
// Protected Methods
// -------------------------------------------------------------------------
/**
* Performs a save operation for a single entity.
*/
protected async saveOne(target: Function|string, entity: any, options?: SaveOptions): Promise<void> {
const metadata = this.connection.getMetadata(target);
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
try {
const transactionEntityManager = this.connection.createEntityManagerWithSingleDatabaseConnection(queryRunnerProvider);
// transactionEntityManager.data =
const databaseEntityLoader = new SubjectBuilder(this.connection, queryRunnerProvider);
await databaseEntityLoader.persist(entity, metadata);
const executor = new SubjectOperationExecutor(this.connection, transactionEntityManager, queryRunnerProvider);
await executor.execute(databaseEntityLoader.operateSubjects);
} finally {
if (!this.queryRunnerProvider) // release it only if its created by this method
await queryRunnerProvider.releaseReused();
}
}
/**
* Performs a remove operation for a single entity.
*/
protected async removeOne(target: Function|string, entity: any, options?: RemoveOptions): Promise<void> {
const metadata = this.connection.getMetadata(target);
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
try {
const transactionEntityManager = this.connection.createEntityManagerWithSingleDatabaseConnection(queryRunnerProvider);
const databaseEntityLoader = new SubjectBuilder(this.connection, queryRunnerProvider);
await databaseEntityLoader.remove(entity, metadata);
const executor = new SubjectOperationExecutor(this.connection, transactionEntityManager, queryRunnerProvider);
await executor.execute(databaseEntityLoader.operateSubjects);
} finally {
if (!this.queryRunnerProvider) // release it only if its created by this method
await queryRunnerProvider.releaseReused();
}
}
/**
* Gets, or if does not exist yet, creates and returns a repository aggregator for a particular entity target.
*/
protected obtainRepositoryAggregator<Entity>(entityClassOrName: ObjectType<Entity>|string): RepositoryAggregator {
if (this.queryRunnerProvider && this.queryRunnerProvider.isReleased)
throw new QueryRunnerProviderAlreadyReleasedError();
const metadata = this.connection.getMetadata(entityClassOrName);
let repositoryAggregator = this.repositoryAggregators.find(repositoryAggregate => repositoryAggregate.metadata === metadata);
if (!repositoryAggregator) {
repositoryAggregator = new RepositoryAggregator(
this.connection,
this.connection.getMetadata(entityClassOrName as any),
this.queryRunnerProvider
);
this.repositoryAggregators.push(repositoryAggregator); // todo: check isnt memory leak here?
}
return repositoryAggregator;
}
}

View File

@ -249,7 +249,7 @@ export function getConnection(connectionName: string = "default"): Connection {
* If connection name wasn't specified, then "default" connection will be retrieved.
*/
export function getEntityManager(connectionName: string = "default"): EntityManager {
return getConnectionManager().get(connectionName).entityManager;
return getConnectionManager().get(connectionName).manager;
}
/**

View File

@ -13,10 +13,4 @@ export interface EntityRepositoryMetadataArgs {
*/
readonly entity?: Function|string;
/**
* Indicates if entity repository will be retrieved from the service container.
* Note: this may cause problems if you are sharing entity repositories between using multiple connections.
*/
readonly useContainer: boolean;
}

View File

@ -236,10 +236,10 @@ export class EntityMetadataBuilder {
entityMetadata.propertiesMap = entityMetadata.createPropertiesMap();
entityMetadata.relationIds.forEach(relationId => relationId.build());
// entityMetadata.relationCounts.forEach(relationCount => relationCount.build());
entityMetadata.relationCounts.forEach(relationCount => relationCount.build());
entityMetadata.embeddeds.forEach(embedded => {
embedded.relationIdsFromTree.forEach(relationId => relationId.build());
// embedded.relationCountsFromTree.forEach(relationCount => relationCount.build());
embedded.relationCountsFromTree.forEach(relationCount => relationCount.build());
});
}

View File

@ -1,12 +1,12 @@
import {Connection} from "../connection/Connection";
import {QueryBuilder} from "../query-builder/QueryBuilder";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {EntityManager} from "../entity-manager/EntityManager";
import {Repository} from "./Repository";
import {TreeRepository} from "./TreeRepository";
import {SpecificRepository} from "./SpecificRepository";
import {ObjectType} from "../common/ObjectType";
import {CustomRepositoryDoesNotHaveEntityError} from "./error/CustomRepositoryDoesNotHaveEntityError";
import {getMetadataArgsStorage} from "../index";
import {CustomRepositoryNotFoundError} from "./error/CustomRepositoryNotFoundError";
/**
* Provides abstract class for custom repositories that do not inherit from original orm Repository.
@ -22,31 +22,24 @@ export class AbstractRepository<Entity extends ObjectLiteral> {
// -------------------------------------------------------------------------
/**
* Connection used by this repository.
* Gets entity manager that allows to perform repository operations with any entity.
*/
protected connection: Connection;
protected manager: EntityManager;
// -------------------------------------------------------------------------
// Protected Accessors
// -------------------------------------------------------------------------
/**
* Gets entity manager that allows to perform repository operations with any entity.
*/
protected get entityManager(): EntityManager {
return this.connection.entityManager;
}
/**
* Gets the original ORM repository for the entity that is managed by this repository.
* If current repository does not manage any entity, then exception will be thrown.
*/
protected get repository(): Repository<Entity> {
const target = this.connection.getCustomRepositoryTarget(this as any);
const target = this.getCustomRepositoryTarget(this as any);
if (!target)
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
return this.connection.getRepository<Entity>(target);
return this.manager.getRepository<Entity>(target);
}
/**
@ -54,23 +47,11 @@ export class AbstractRepository<Entity extends ObjectLiteral> {
* If current repository does not manage any entity, then exception will be thrown.
*/
protected get treeRepository(): TreeRepository<Entity> {
const target = this.connection.getCustomRepositoryTarget(this as any);
const target = this.getCustomRepositoryTarget(this as any);
if (!target)
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
return this.connection.getTreeRepository<Entity>(target);
}
/**
* Gets the original ORM specific repository for the entity that is managed by this repository.
* If current repository does not manage any entity, then exception will be thrown.
*/
protected get specificRepository(): SpecificRepository<Entity> {
const target = this.connection.getCustomRepositoryTarget(this as any);
if (!target)
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
return this.connection.getSpecificRepository<Entity>(target);
return this.manager.getTreeRepository<Entity>(target);
}
// -------------------------------------------------------------------------
@ -82,11 +63,11 @@ export class AbstractRepository<Entity extends ObjectLiteral> {
* If current repository does not manage any entity, then exception will be thrown.
*/
protected createQueryBuilder(alias: string): QueryBuilder<Entity> {
const target = this.connection.getCustomRepositoryTarget(this.constructor);
const target = this.getCustomRepositoryTarget(this.constructor);
if (!target)
throw new CustomRepositoryDoesNotHaveEntityError(this.constructor);
return this.connection.getRepository(target).createQueryBuilder(alias);
return this.manager.getRepository(target).createQueryBuilder(alias);
}
/**
@ -100,21 +81,32 @@ export class AbstractRepository<Entity extends ObjectLiteral> {
* Gets the original ORM repository for the given entity class.
*/
protected getRepositoryFor<T>(entity: ObjectType<T>): Repository<T> {
return this.entityManager.getRepository(entity);
return this.manager.getRepository(entity);
}
/**
* Gets the original ORM tree repository for the given entity class.
*/
protected getTreeRepositoryFor<T>(entity: ObjectType<T>): TreeRepository<T> {
return this.entityManager.getTreeRepository(entity);
return this.manager.getTreeRepository(entity);
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
/**
* Gets the original ORM specific repository for the given entity class.
* Gets custom repository's managed entity.
* If given custom repository does not manage any entity then undefined will be returned.
*/
protected getSpecificRepositoryFor<T>(entity: ObjectType<T>): SpecificRepository<T> {
return this.entityManager.getSpecificRepository(entity);
private getCustomRepositoryTarget<T>(customRepository: any): Function|string|undefined {
const entityRepositoryMetadataArgs = getMetadataArgsStorage().entityRepositories.find(repository => {
return repository.target === (customRepository instanceof Function ? customRepository : (customRepository as any).constructor);
});
if (!entityRepositoryMetadataArgs)
throw new CustomRepositoryNotFoundError(customRepository);
return entityRepositoryMetadataArgs.entity;
}
}

View File

@ -466,7 +466,7 @@ export class MongoRepository<Entity extends ObjectLiteral> extends Repository<En
// todo: extra these methods into separate class
protected get queryRunner(): MongoQueryRunner {
return (this.connection.driver as MongoDriver).queryRunner;
return (this.manager.connection.driver as MongoDriver).queryRunner;
}
protected convertFindManyOptionsOrConditionsToMongodbQuery(optionsOrConditions: FindOneOptions<Entity>|Partial<Entity>|undefined): ObjectLiteral|undefined {

View File

@ -1,18 +1,13 @@
import {Connection} from "../connection/Connection";
import {EntityMetadata} from "../metadata/EntityMetadata";
import {QueryBuilder} from "../query-builder/QueryBuilder";
import {PlainObjectToNewEntityTransformer} from "../query-builder/transformer/PlainObjectToNewEntityTransformer";
import {PlainObjectToDatabaseEntityTransformer} from "../query-builder/transformer/PlainObjectToDatabaseEntityTransformer";
import {FindManyOptions} from "../find-options/FindManyOptions";
import {FindOptionsUtils} from "../find-options/FindOptionsUtils";
import {ObjectLiteral} from "../common/ObjectLiteral";
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
import {SubjectOperationExecutor} from "../persistence/SubjectOperationExecutor";
import {SubjectBuilder} from "../persistence/SubjectBuilder";
import {FindOneOptions} from "../find-options/FindOneOptions";
import {DeepPartial} from "../common/DeepPartial";
import {SaveOptions} from "./SaveOptions";
import {RemoveOptions} from "./RemoveOptions";
import {EntityManager} from "../entity-manager/EntityManager";
/**
* Repository is supposed to work with your entity objects. Find entities, insert, update, delete, etc.
@ -26,7 +21,7 @@ export class Repository<Entity extends ObjectLiteral> {
/**
* Connection used by this repository.
*/
protected connection: Connection;
protected manager: EntityManager;
/**
* Entity metadata of the entity current repository manages.
@ -56,23 +51,21 @@ export class Repository<Entity extends ObjectLiteral> {
* If entity composite compose ids, it will check them all.
*/
hasId(entity: Entity): boolean {
return this.metadata.hasId(entity);
return this.manager.hasId(this.metadata.target, entity);
}
/**
* Gets entity mixed id.
*/
getId(entity: Entity): any {
return this.metadata.getEntityIdMixedMap(entity);
return this.manager.getId(this.metadata.target, entity);
}
/**
* Creates a new query builder that can be used to build a sql query.
*/
createQueryBuilder(alias: string, queryRunnerProvider?: QueryRunnerProvider): QueryBuilder<Entity> {
return new QueryBuilder(this.connection, queryRunnerProvider || this.queryRunnerProvider)
.select(alias)
.from(this.metadata.target, alias);
return this.manager.createQueryBuilder(this.metadata.target, alias, queryRunnerProvider);
}
/**
@ -97,23 +90,14 @@ export class Repository<Entity extends ObjectLiteral> {
* Can copy properties from the given object into new entities.
*/
create(plainEntityLikeOrPlainEntityLikes?: DeepPartial<Entity>|DeepPartial<Entity>[]): Entity|Entity[] {
if (!plainEntityLikeOrPlainEntityLikes)
return this.metadata.create();
if (plainEntityLikeOrPlainEntityLikes instanceof Array)
return plainEntityLikeOrPlainEntityLikes.map(plainEntityLike => this.create(plainEntityLike));
return this.merge(this.metadata.create(), plainEntityLikeOrPlainEntityLikes);
return this.manager.create<any>(this.metadata.target, plainEntityLikeOrPlainEntityLikes as any);
}
/**
* Merges multiple entities (or entity-like objects) into a given entity.
*/
merge(mergeIntoEntity: Entity, ...entityLikes: DeepPartial<Entity>[]): Entity {
const plainObjectToEntityTransformer = new PlainObjectToNewEntityTransformer();
entityLikes.forEach(object => plainObjectToEntityTransformer.transform(mergeIntoEntity, object, this.metadata));
return mergeIntoEntity;
return this.manager.merge(this.metadata.target, mergeIntoEntity, ...entityLikes);
}
/**
@ -126,13 +110,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Returns undefined if entity with given id was not found.
*/
async preload(entityLike: DeepPartial<Entity>): Promise<Entity|undefined> {
// todo: right now sending this.connection.entityManager is not correct because its out of query runner of this repository
const plainObjectToDatabaseEntityTransformer = new PlainObjectToDatabaseEntityTransformer(this.connection.entityManager);
const transformedEntity = await plainObjectToDatabaseEntityTransformer.transform(entityLike, this.metadata);
if (transformedEntity)
return this.merge(transformedEntity as Entity, entityLike);
return undefined;
return this.manager.preload(this.metadata.target, entityLike);
}
/**
@ -151,32 +129,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Saves one or many given entities.
*/
async save(entityOrEntities: Entity|Entity[], options?: SaveOptions): Promise<Entity|Entity[]> {
// if for some reason non empty entity was passed then return it back without having to do anything
if (!entityOrEntities)
return entityOrEntities;
// if multiple entities given then go throw all of them and save them
if (entityOrEntities instanceof Array)
return Promise.all(entityOrEntities.map(entity => this.save(entity)));
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
try {
const transactionEntityManager = this.connection.createEntityManagerWithSingleDatabaseConnection(queryRunnerProvider);
// transactionEntityManager.data =
const databaseEntityLoader = new SubjectBuilder(this.connection, queryRunnerProvider);
await databaseEntityLoader.persist(entityOrEntities, this.metadata);
const executor = new SubjectOperationExecutor(this.connection, transactionEntityManager, queryRunnerProvider);
await executor.execute(databaseEntityLoader.operateSubjects);
return entityOrEntities;
} finally {
if (!this.queryRunnerProvider) // release it only if its created by this method
await queryRunnerProvider.releaseReused();
}
return this.manager.save(this.metadata.target, entityOrEntities as any, options);
}
/**
@ -224,12 +177,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Updates entity partially. Entity will be found by a given id.
*/
async updateById(id: any, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
const entity = await this.findOneById(id as any); // this is temporary, in the future can be refactored to perform better
if (!entity)
throw new Error(`Cannot find entity to update by a id`);
Object.assign(entity, partialEntity);
await this.save(entity, options);
return this.manager.updateById(this.metadata.target, id, partialEntity, options);
}
/**
@ -246,42 +194,14 @@ export class Repository<Entity extends ObjectLiteral> {
* Removes one or many given entities.
*/
async remove(entityOrEntities: Entity|Entity[], options?: RemoveOptions): Promise<Entity|Entity[]> {
// if for some reason non empty entity was passed then return it back without having to do anything
if (!entityOrEntities)
return entityOrEntities;
// if multiple entities given then go throw all of them and save them
if (entityOrEntities instanceof Array)
return Promise.all(entityOrEntities.map(entity => this.remove(entity)));
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
try {
const transactionEntityManager = this.connection.createEntityManagerWithSingleDatabaseConnection(queryRunnerProvider);
const databaseEntityLoader = new SubjectBuilder(this.connection, queryRunnerProvider);
await databaseEntityLoader.remove(entityOrEntities, this.metadata);
const executor = new SubjectOperationExecutor(this.connection, transactionEntityManager, queryRunnerProvider);
await executor.execute(databaseEntityLoader.operateSubjects);
return entityOrEntities;
} finally {
if (!this.queryRunnerProvider) // release it only if its created by this method
await queryRunnerProvider.releaseReused();
}
return this.manager.remove(this.metadata.target, entityOrEntities as any, options);
}
/**
* Removes entity by a given entity id.
*/
async removeById(id: any, options?: RemoveOptions): Promise<void> {
const entity = await this.findOneById(id); // this is temporary, in the future can be refactored to perform better
if (!entity)
throw new Error(`Cannot find entity to remove by a given id`);
await this.remove(entity, options);
return this.manager.removeById(this.metadata.target, id, options);
}
/**
@ -298,8 +218,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Counts entities that match given find options or conditions.
*/
count(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<number> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getCount();
return this.manager.count(this.metadata.target, optionsOrConditions as any);
}
/**
@ -316,8 +235,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Finds entities that match given find options or conditions.
*/
find(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<Entity[]> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getMany();
return this.manager.find(this.metadata.target, optionsOrConditions as any);
}
/**
@ -340,8 +258,7 @@ export class Repository<Entity extends ObjectLiteral> {
* but ignores pagination settings (from and take options).
*/
findAndCount(optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<[ Entity[], number ]> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
return FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getManyAndCount();
return this.manager.findAndCount(this.metadata.target, optionsOrConditions as any);
}
/**
@ -361,17 +278,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Optionally find options can be applied.
*/
findByIds(ids: any[], optionsOrConditions?: FindManyOptions<Entity>|DeepPartial<Entity>): Promise<Entity[]> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindManyOptionsAlias(optionsOrConditions) || this.metadata.tableName);
FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions);
ids = ids.map(id => {
if (!this.metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
return this.metadata.createEntityIdMap([id]);
}
return id;
});
qb.andWhereInIds(ids);
return qb.getMany();
return this.manager.findByIds(this.metadata.target, optionsOrConditions as any);
}
/**
@ -388,8 +295,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Finds first entity that matches given conditions.
*/
findOne(optionsOrConditions?: FindOneOptions<Entity>|DeepPartial<Entity>): Promise<Entity|undefined> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.tableName);
return FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions).getOne();
return this.manager.findOne(this.metadata.target, optionsOrConditions as any);
}
/**
@ -409,19 +315,7 @@ export class Repository<Entity extends ObjectLiteral> {
* Optionally find options or conditions can be applied.
*/
findOneById(id: any, optionsOrConditions?: FindOneOptions<Entity>|DeepPartial<Entity>): Promise<Entity|undefined> {
const qb = this.createQueryBuilder(FindOptionsUtils.extractFindOneOptionsAlias(optionsOrConditions) || this.metadata.tableName);
if (this.metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
// const columnNames = this.metadata.getEntityIdMap({ });
throw new Error(`You have multiple primary keys in your entity, to use findOneById with multiple primary keys please provide ` +
`complete object with all entity ids, like this: { firstKey: value, secondKey: value }`);
}
FindOptionsUtils.applyFindOneOptionsOrConditionsToQueryBuilder(qb, optionsOrConditions);
if (!this.metadata.hasMultiplePrimaryKeys && !(id instanceof Object)) {
id = this.metadata.createEntityIdMap([id]);
}
qb.andWhereInIds([id]);
return qb.getOne();
return this.manager.findOneById(this.metadata.target, id, optionsOrConditions as any);
}
/**
@ -429,70 +323,14 @@ export class Repository<Entity extends ObjectLiteral> {
* Raw query execution is supported only by relational databases (MongoDB is not supported).
*/
async query(query: string, parameters?: any[]): Promise<any> {
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver);
const queryRunner = await queryRunnerProvider.provide();
try {
return await queryRunner.query(query, parameters); // await is needed here because we are using finally
} finally {
await queryRunnerProvider.release(queryRunner);
}
}
/**
* Wraps given function execution (and all operations made there) in a transaction.
* All database operations must be executed using provided repository.
*
* Most important, you should execute all your database operations using provided repository instance,
* all other operations would not be included in the transaction.
* If you want to execute transaction and persist multiple different entity types, then
* use EntityManager.transaction method instead.
*
* Transactions are supported only by relational databases (MongoDB is not supported).
*
* @deprecated use entity manager's transaction method instead.
*/
async transaction(runInTransaction: (repository: Repository<Entity>) => Promise<any>|any): Promise<any> {
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver, true);
const queryRunner = await queryRunnerProvider.provide();
// 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
const transactionRepository = new Repository<any>();
(transactionRepository as any)["connection"] = this.connection;
(transactionRepository as any)["metadata"] = this.metadata;
(transactionRepository as any)["queryRunnerProvider"] = queryRunnerProvider;
// todo: same code in the repository factory. probably better to use repository factory here too
try {
await queryRunner.beginTransaction();
const result = await runInTransaction(transactionRepository);
await queryRunner.commitTransaction();
return result;
} catch (err) {
await queryRunner.rollbackTransaction();
throw err;
} finally {
await queryRunnerProvider.release(queryRunner);
if (!this.queryRunnerProvider) // if we used a new query runner provider then release it
await queryRunnerProvider.releaseReused();
}
return this.manager.query(query, parameters);
}
/**
* Clears all the data from the given table/collection (truncates/drops it).
*/
async clear(): Promise<void> {
const queryRunnerProvider = this.queryRunnerProvider || new QueryRunnerProvider(this.connection.driver);
const queryRunner = await queryRunnerProvider.provide();
try {
return await queryRunner.truncate(this.metadata.tableName); // await is needed here because we are using finally
} finally {
await queryRunnerProvider.release(queryRunner);
}
return this.manager.clear(this.metadata.target);
}
}

View File

@ -46,9 +46,9 @@ export class RepositoryAggregator {
const factory = getFromContainer(RepositoryFactory);
if (metadata.isClosure) {
this.repository = this.treeRepository = factory.createTreeRepository(connection, metadata, queryRunnerProvider);
this.repository = this.treeRepository = factory.createTreeRepository(connection.manager, metadata, queryRunnerProvider);
} else {
this.repository = factory.createRepository(connection, metadata, queryRunnerProvider);
this.repository = factory.createRepository(connection.manager, metadata, queryRunnerProvider);
}
this.specificRepository = factory.createSpecificRepository(connection, metadata, queryRunnerProvider);

View File

@ -6,6 +6,7 @@ import {SpecificRepository} from "./SpecificRepository";
import {QueryRunnerProvider} from "../query-runner/QueryRunnerProvider";
import {MongoDriver} from "../driver/mongodb/MongoDriver";
import {MongoRepository} from "./MongoRepository";
import {EntityManager} from "../entity-manager/EntityManager";
/**
* Factory used to create different types of repositories.
@ -19,17 +20,17 @@ export class RepositoryFactory {
/**
* Creates a regular repository.
*/
createRepository(connection: Connection, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): Repository<any> {
createRepository(manager: EntityManager, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): Repository<any> {
// 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
let repository: Repository<any>;
if (connection.driver instanceof MongoDriver) {
if (manager.connection.driver instanceof MongoDriver) {
repository = new MongoRepository();
} else {
repository = new Repository<any>();
}
(repository as any)["connection"] = connection;
(repository as any)["manager"] = manager;
(repository as any)["metadata"] = metadata;
(repository as any)["queryRunnerProvider"] = queryRunnerProvider;
return repository;
@ -38,12 +39,12 @@ export class RepositoryFactory {
/**
* Creates a tree repository.
*/
createTreeRepository(connection: Connection, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): TreeRepository<any> {
createTreeRepository(manager: EntityManager, metadata: EntityMetadata, queryRunnerProvider?: QueryRunnerProvider): TreeRepository<any> {
// 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
const repository = new TreeRepository<any>();
(repository as any)["connection"] = connection;
(repository as any)["manager"] = manager;
(repository as any)["metadata"] = metadata;
(repository as any)["queryRunnerProvider"] = queryRunnerProvider;
return repository;

View File

@ -44,8 +44,8 @@ export class TreeRepository<Entity> extends Repository<Entity> {
createDescendantsQueryBuilder(alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity> {
// create shortcuts for better readability
const escapeAlias = (alias: string) => this.connection.driver.escapeAliasName(alias);
const escapeColumn = (column: string) => this.connection.driver.escapeColumnName(column);
const escapeAlias = (alias: string) => this.manager.connection.driver.escapeAliasName(alias);
const escapeColumn = (column: string) => this.manager.connection.driver.escapeColumnName(column);
const joinCondition = `${escapeAlias(alias)}.${escapeColumn(this.metadata.primaryColumns[0].databaseName)}=${escapeAlias(closureTableAlias)}.${escapeColumn("descendant")}`;
return this.createQueryBuilder(alias)
@ -92,8 +92,8 @@ export class TreeRepository<Entity> extends Repository<Entity> {
createAncestorsQueryBuilder(alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity> {
// create shortcuts for better readability
const escapeAlias = (alias: string) => this.connection.driver.escapeAliasName(alias);
const escapeColumn = (column: string) => this.connection.driver.escapeColumnName(column);
const escapeAlias = (alias: string) => this.manager.connection.driver.escapeAliasName(alias);
const escapeColumn = (column: string) => this.manager.connection.driver.escapeColumnName(column);
const joinCondition = `${escapeAlias(alias)}.${escapeColumn(this.metadata.primaryColumns[0].databaseName)}=${escapeAlias(closureTableAlias)}.${escapeColumn("ancestor")}`;
return this.createQueryBuilder(alias)

View File

@ -51,7 +51,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastBeforeInsertEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
async broadcastBeforeInsertEvent(manager: EntityManager, subject: Subject): Promise<void> {
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_INSERT && listener.isAllowed(subject.entity))
@ -60,7 +60,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.beforeInsert)
.map(subscriber => subscriber.beforeInsert!({
entityManager: entityManager,
manager: manager,
entity: subject.entity
}));
@ -73,7 +73,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastBeforeUpdateEvent(entityManager: EntityManager, subject: Subject): Promise<void> { // todo: send relations too?
async broadcastBeforeUpdateEvent(manager: EntityManager, subject: Subject): Promise<void> { // todo: send relations too?
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_UPDATE && listener.isAllowed(subject.entity))
@ -82,7 +82,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.beforeUpdate)
.map(subscriber => subscriber.beforeUpdate!({
entityManager: entityManager,
manager: manager,
entity: subject.entity,
databaseEntity: subject.databaseEntity,
updatedColumns: subject.diffColumns,
@ -98,7 +98,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastBeforeRemoveEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
async broadcastBeforeRemoveEvent(manager: EntityManager, subject: Subject): Promise<void> {
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.BEFORE_REMOVE && listener.isAllowed(subject.entity))
@ -107,7 +107,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.beforeRemove)
.map(subscriber => subscriber.beforeRemove!({
entityManager: entityManager,
manager: manager,
entity: subject.hasEntity ? subject.entity : undefined,
databaseEntity: subject.databaseEntity,
entityId: subject.metadata.getEntityIdMixedMap(subject.databaseEntity)
@ -122,7 +122,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastAfterInsertEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
async broadcastAfterInsertEvent(manager: EntityManager, subject: Subject): Promise<void> {
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_INSERT && listener.isAllowed(subject.entity))
@ -131,7 +131,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.afterInsert)
.map(subscriber => subscriber.afterInsert!({
entityManager: entityManager,
manager: manager,
entity: subject.entity
}));
@ -144,7 +144,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastAfterUpdateEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
async broadcastAfterUpdateEvent(manager: EntityManager, subject: Subject): Promise<void> {
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_UPDATE && listener.isAllowed(subject.entity))
@ -153,7 +153,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.afterUpdate)
.map(subscriber => subscriber.afterUpdate!({
entityManager: entityManager,
manager: manager,
entity: subject.entity,
databaseEntity: subject.databaseEntity,
updatedColumns: subject.diffColumns,
@ -169,7 +169,7 @@ export class Broadcaster {
* All subscribers and entity listeners who listened to this event will be executed at this point.
* Subscribers and entity listeners can return promises, it will wait until they are resolved.
*/
async broadcastAfterRemoveEvent(entityManager: EntityManager, subject: Subject): Promise<void> {
async broadcastAfterRemoveEvent(manager: EntityManager, subject: Subject): Promise<void> {
const listeners = subject.metadata.listeners
.filter(listener => listener.type === EventListenerTypes.AFTER_REMOVE && listener.isAllowed(subject.entity))
@ -178,7 +178,7 @@ export class Broadcaster {
const subscribers = this.subscriberMetadatas
.filter(subscriber => this.isAllowedSubscriber(subscriber, subject.entityTarget!) && subscriber.afterRemove)
.map(subscriber => subscriber.afterRemove!({
entityManager: entityManager,
manager: manager,
entity: subject.hasEntity ? subject.entity : undefined,
databaseEntity: subject.databaseEntity,
entityId: subject.metadata.getEntityIdMixedMap(subject.databaseEntity)

View File

@ -9,7 +9,7 @@ export interface InsertEvent<Entity> {
* Entity managed with connection used for original event.
* All database operations in the subscribed event listener should be performed using this entity manager instance.
*/
entityManager: EntityManager;
manager: EntityManager;
/**
* Inserting event.

View File

@ -9,7 +9,7 @@ export interface RemoveEvent<Entity> {
* Entity managed with connection used for original event.
* All database operations in the subscribed event listener should be performed using this entity manager instance.
*/
entityManager: EntityManager;
manager: EntityManager;
/**
* Entity that is being removed.

View File

@ -11,7 +11,7 @@ export interface UpdateEvent<Entity> {
* Entity managed with connection used for original event.
* All database operations in the subscribed event listener should be performed using this entity manager instance.
*/
entityManager: EntityManager;
manager: EntityManager;
/**
* Updating entity.

View File

@ -25,10 +25,10 @@ describe.skip("cascades > should insert by cascades from both sides (#57)", () =
const post1 = new Post();
post1.title = "Hello Post #1";
post1.details = details;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
innerJoinAndSelect: {

View File

@ -123,12 +123,12 @@ describe("ConnectionManager", () => {
// create connection, save post and close connection
let connection = await connectionManager.createAndConnect(options);
const post = new Post(1, "Hello post");
await connection.entityManager.save(post);
await connection.manager.save(post);
await connection.close();
// recreate connection and find previously saved post
connection = await connectionManager.createAndConnect(options);
const loadedPost = (await connection.entityManager.findOneById(Post, 1))!;
const loadedPost = (await connection.manager.findOneById(Post, 1))!;
loadedPost.should.be.instanceof(Post);
loadedPost.should.be.eql({ id: 1, title: "Hello post" });
await connection.close();
@ -146,12 +146,12 @@ describe("ConnectionManager", () => {
// create connection, save post and close connection
let connection = await connectionManager.createAndConnect(options);
const post = new Post(1, "Hello post");
await connection.entityManager.save(post);
await connection.manager.save(post);
await connection.close();
// recreate connection and find previously saved post
connection = await connectionManager.createAndConnect(options);
const loadedPost = await connection.entityManager.findOneById(Post, 1);
const loadedPost = await connection.manager.findOneById(Post, 1);
expect(loadedPost).to.be.undefined;
await connection.close();
});
@ -168,12 +168,12 @@ describe("ConnectionManager", () => {
// create connection, save post and close connection
let connection = await connectionManager.createAndConnect(options);
const post = new Post(1, "Hello post");
await connection.entityManager.persist(post);
await connection.manager.persist(post);
await connection.close();
// recreate connection and find previously saved post
connection = await connectionManager.createAndConnect(options);
const loadedPost = await connection.entityManager.findOneById(Post, 1);
const loadedPost = await connection.manager.findOneById(Post, 1);
expect(loadedPost).to.be.undefined;
await connection.close();
@ -191,12 +191,12 @@ describe("ConnectionManager", () => {
// create connection, save post and close connection
let connection = await connectionManager.createAndConnect(options);
const post = new Post(1, "Hello post");
await connection.entityManager.persist(post);
await connection.manager.persist(post);
await connection.close();
// recreate connection and find previously saved post
connection = await connectionManager.createAndConnect(options);
const loadedPost = await connection.entityManager.findOneById(Post, 1);
const loadedPost = await connection.manager.findOneById(Post, 1);
expect(loadedPost).to.be.undefined;
await connection.close();
});*/

View File

@ -47,7 +47,7 @@ describe("Connection", () => {
});
it.skip("entity manager and reactive entity manager should not be accessible", () => {
expect(() => connection.entityManager).to.throw(CannotGetEntityManagerNotConnectedError);
expect(() => connection.manager).to.throw(CannotGetEntityManagerNotConnectedError);
// expect(() => connection.reactiveEntityManager).to.throw(CannotGetEntityManagerNotConnectedError);
});
@ -118,7 +118,7 @@ describe("Connection", () => {
}));
it("entity manager and reactive entity manager should be accessible", () => connections.forEach(connection => {
expect(connection.entityManager).to.be.instanceOf(EntityManager);
expect(connection.manager).to.be.instanceOf(EntityManager);
// expect(connection.reactiveEntityManager).to.be.instanceOf(ReactiveEntityManager);
}));

View File

@ -24,42 +24,42 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.getMany();
expect(loadedPosts![0].categoryCount).to.be.equal(3);
expect(loadedPosts![1].categoryCount).to.be.equal(2);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.id = :id", { id: 1 })
.getOne();
@ -71,43 +71,43 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Audi";
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Airbus";
await connection.entityManager.save(post4);
await connection.manager.save(post4);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.setOffset(0)
.setLimit(2)
@ -122,50 +122,50 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const image1 = new Image();
image1.isRemoved = true;
image1.name = "image #1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image #2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image #3";
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const category1 = new Category();
category1.name = "cars";
category1.isRemoved = true;
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
category4.images = [image3];
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.addOrderBy("post.id, categories.id")
@ -180,7 +180,7 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
expect(loadedPosts![1].categoryCount).to.be.equal(2);
expect(loadedPosts![1].categories[0].imageCount).to.be.equal(1);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id = :id", { id: 1 })
@ -197,27 +197,27 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1, category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.addOrderBy("post.id, categories.id")
@ -231,7 +231,7 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
expect(loadedPosts![1].categories[0].postCount).to.be.equal(2);
expect(loadedPosts![1].categories[1].postCount).to.be.equal(2);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id = :id", { id: 1 })
@ -248,45 +248,45 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.getMany();
expect(loadedCategories![0].postCount).to.be.equal(3);
expect(loadedCategories![1].postCount).to.be.equal(2);
let loadedCategory = await connection.entityManager
let loadedCategory = await connection.manager
.createQueryBuilder(Category, "category")
.where("category.id = :id", { id: 1 })
.getOne();
@ -298,46 +298,46 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "BMW";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "Boeing";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.setOffset(0)
.setLimit(2)
@ -351,40 +351,40 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post1 = new Post();
post1.title = "about BMW";
post1.isRemoved = true;
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.isRemoved = true;
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.getMany();
@ -392,7 +392,7 @@ describe("query builder > relation-count-decorator-many-to-many > many-to-many",
expect(loadedCategories![0].removedPostCount).to.be.equal(2);
expect(loadedCategories![1].postCount).to.be.equal(2);
let loadedCategory = await connection.entityManager
let loadedCategory = await connection.manager
.createQueryBuilder(Category, "category")
.where("category.id = :id", { id: 1 })
.getOne();

View File

@ -25,42 +25,42 @@ describe("decorators > relation-count-decorator > one-to-many", () => {
const image1 = new Image();
image1.isRemoved = true;
image1.name = "image #1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image #2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image #3";
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const category1 = new Category();
category1.name = "cars";
category1.isRemoved = true;
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "airplanes";
category3.images = [image3];
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.addOrderBy("post.id, categories.id")
@ -74,7 +74,7 @@ describe("decorators > relation-count-decorator > one-to-many", () => {
expect(loadedPosts![1].categoryCount).to.be.equal(1);
expect(loadedPosts![1].categories[0].imageCount).to.be.equal(1);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id = :id", { id: 1 })

View File

@ -19,23 +19,23 @@ describe.skip("entity manager > custom data", () => {
it("should set data into entity manager and retrieve it successfully", () => Promise.all(connections.map(async connection => {
const user = { name: "Dima" };
connection.entityManager.setData("user", user);
expect(connection.entityManager.getData("user")).to.be.not.empty;
connection.entityManager.getData("user").should.be.equal(user);
connection.manager.setData("user", user);
expect(connection.manager.getData("user")).to.be.not.empty;
connection.manager.getData("user").should.be.equal(user);
})));
it("change in subscriber should update data set in entity manager", () => Promise.all(connections.map(async connection => {
const user = { name: "Dima" };
connection.entityManager.setData("user", user);
connection.manager.setData("user", user);
const post = new Post();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
expect(connection.entityManager.getData("user")).to.be.not.empty;
connection.entityManager.getData("user").should.be.eql({ name: "Updated Dima" });
expect(connection.manager.getData("user")).to.be.not.empty;
connection.manager.getData("user").should.be.eql({ name: "Updated Dima" });
})));

View File

@ -9,7 +9,7 @@ export class PostSubscriber implements EntitySubscriberInterface<any> {
* Called before entity insertion.
*/
beforeInsert(event: InsertEvent<any>) {
const user = event.entityManager.getData("user");
const user = event.manager.getData("user");
user.name = "Updated Dima";
}

View File

@ -20,7 +20,7 @@ describe("indices > basic unique index test", () => {
const customer = new Customer();
customer.nameEnglish = "Umed";
customer.nameHebrew = "Uma";
await connection.entityManager.save(customer);
await connection.manager.save(customer);
})));
});

View File

@ -158,7 +158,7 @@ describe("lazy-relations", () => {
fakePost.text = "post #" + i;
fakePosts.push(fakePost);
}
await connection.entityManager.save(fakePosts);
await connection.manager.save(fakePosts);
const fakeCategories: Category[] = [];
for (let i = 0; i < 8; i++) {
@ -166,7 +166,7 @@ describe("lazy-relations", () => {
fakeCategory.name = "category #" + i;
fakeCategories.push(fakeCategory);
}
await connection.entityManager.save(fakeCategories);
await connection.manager.save(fakeCategories);
const category = new Category();
category.name = "category of great post";
@ -176,10 +176,10 @@ describe("lazy-relations", () => {
post.text = "post with great category and great text";
post.category = Promise.resolve(category);
await connection.entityManager.save(category);
await connection.entityManager.save(post);
await connection.manager.save(category);
await connection.manager.save(post);
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "post with great category" } });
const loadedPost = await connection.manager.findOne(Post, { where: { title: "post with great category" } });
const loadedCategory = await loadedPost!.category;
loadedCategory.name.should.be.equal("category of great post");
@ -195,7 +195,7 @@ describe("lazy-relations", () => {
fakePost.text = "post #" + i;
fakePosts.push(fakePost);
}
await connection.entityManager.save(fakePosts);
await connection.manager.save(fakePosts);
const fakeCategories: Category[] = [];
for (let i = 0; i < 30; i++) {
@ -203,7 +203,7 @@ describe("lazy-relations", () => {
fakeCategory.name = "category #" + i;
fakeCategories.push(fakeCategory);
}
await connection.entityManager.save(fakeCategories);
await connection.manager.save(fakeCategories);
const category = new Category();
category.name = "category of great post";
@ -213,10 +213,10 @@ describe("lazy-relations", () => {
post.text = "post with great category and great text";
post.twoSideCategory = Promise.resolve(category);
await connection.entityManager.save(category);
await connection.entityManager.save(post);
await connection.manager.save(category);
await connection.manager.save(post);
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "post with great category" } });
const loadedPost = await connection.manager.findOne(Post, { where: { title: "post with great category" } });
const loadedCategory = await loadedPost!.twoSideCategory;
loadedCategory.name.should.be.equal("category of great post");
@ -232,7 +232,7 @@ describe("lazy-relations", () => {
fakePost.text = "post #" + i;
fakePosts.push(fakePost);
}
await connection.entityManager.save(fakePosts);
await connection.manager.save(fakePosts);
const fakeCategories: Category[] = [];
for (let i = 0; i < 30; i++) {
@ -240,19 +240,19 @@ describe("lazy-relations", () => {
fakeCategory.name = "category #" + i;
fakeCategories.push(fakeCategory);
}
await connection.entityManager.save(fakeCategories);
await connection.manager.save(fakeCategories);
const category = new Category();
category.name = "category of great post";
await connection.entityManager.save(category);
await connection.manager.save(category);
const post = new Post();
post.title = "post with great category";
post.text = "post with great category and great text";
post.twoSideCategory = Promise.resolve(category);
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "category of great post" } });
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "category of great post" } });
const loadedPost = await loadedCategory!.twoSidePosts2;
loadedPost[0].title.should.be.equal("post with great category");
@ -268,7 +268,7 @@ describe("lazy-relations", () => {
fakePost.text = "post #" + i;
fakePosts.push(fakePost);
}
await connection.entityManager.save(fakePosts);
await connection.manager.save(fakePosts);
const fakeCategories: Category[] = [];
for (let i = 0; i < 30; i++) {
@ -276,19 +276,19 @@ describe("lazy-relations", () => {
fakeCategory.name = "category #" + i;
fakeCategories.push(fakeCategory);
}
await connection.entityManager.save(fakeCategories);
await connection.manager.save(fakeCategories);
const category = new Category();
category.name = "category of great post";
await connection.entityManager.save(category);
await connection.manager.save(category);
const post = new Post();
post.title = "post with great category";
post.text = "post with great category and great text";
post.oneCategory = Promise.resolve(category);
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "post with great category" } });
const loadedPost = await connection.manager.findOne(Post, { where: { title: "post with great category" } });
const loadedCategory = await loadedPost!.oneCategory;
loadedCategory.name.should.be.equal("category of great post");
@ -304,7 +304,7 @@ describe("lazy-relations", () => {
fakePost.text = "post #" + i;
fakePosts.push(fakePost);
}
await connection.entityManager.save(fakePosts);
await connection.manager.save(fakePosts);
const fakeCategories: Category[] = [];
for (let i = 0; i < 30; i++) {
@ -312,19 +312,19 @@ describe("lazy-relations", () => {
fakeCategory.name = "category #" + i;
fakeCategories.push(fakeCategory);
}
await connection.entityManager.save(fakeCategories);
await connection.manager.save(fakeCategories);
const category = new Category();
category.name = "category of great post";
await connection.entityManager.save(category);
await connection.manager.save(category);
const post = new Post();
post.title = "post with great category";
post.text = "post with great category and great text";
post.oneCategory = Promise.resolve(category);
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "category of great post" } });
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "category of great post" } });
const loadedPost = await loadedCategory!.onePost;
loadedPost.title.should.be.equal("post with great category");
})));

View File

@ -20,7 +20,7 @@ describe.skip("mongodb > MongoRepository", () => {
})));
it("entity manager should return mongo repository when requested", () => Promise.all(connections.map(async connection => {
const postRepository = connection.entityManager.getMongoRepository(Post);
const postRepository = connection.manager.getMongoRepository(Post);
postRepository.should.be.instanceOf(MongoRepository);
})));

View File

@ -77,7 +77,7 @@ describe.skip("mongodb > basic repository actions", () => {
const postRepository = connection.getRepository(Post);
expect(() => postRepository.createQueryBuilder("post")).to.throw(Error);
expect(() => postRepository.query("SELECT * FROM POSTS")).to.throw(Error);
expect(() => postRepository.transaction(() => {})).to.throw(Error);
// expect(() => postRepository.transaction(() => {})).to.throw(Error);
})));
it("should return persisted objects using find* methods", () => Promise.all(connections.map(async connection => {

View File

@ -51,7 +51,7 @@ describe("persistence > cascade operations", () => {
// post1.category = category1;
// post1.category.photos = [photo1, photo2];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
console.log("********************************************************");
console.log("updating: ", post1);
@ -59,19 +59,19 @@ describe("persistence > cascade operations", () => {
post1.title = "updated post #1";
post1.oneCategory.name = "updated category";
await connection.entityManager.save(post1);
await connection.manager.save(post1);
console.log("********************************************************");
console.log("removing: ", post1);
console.log("********************************************************");
await connection.entityManager.remove(post1);
await connection.manager.remove(post1);
// await connection.entityManager.persist(post1);
// await connection.manager.persist(post1);
console.log("********************************************************");
/*const posts = await connection.entityManager
/*const posts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.category", "category")
// .innerJoinAndSelect("post.photos", "photos")
@ -84,25 +84,25 @@ describe("persistence > cascade operations", () => {
// posts[0].category = null; // todo: uncomment to check remove
console.log("removing post's category: ", posts[0]);
await connection.entityManager.persist(posts[0]);*/
await connection.manager.persist(posts[0]);*/
/* await connection.entityManager.persist([photo1, photo2]);
/* await connection.manager.persist([photo1, photo2]);
post1.photos = [photo1];
await connection.entityManager.persist(post1);
await connection.manager.persist(post1);
console.log("********************************************************");
console.log("********************************************************");
post1.photos = [photo1, photo2];
await connection.entityManager.persist(post1);
await connection.manager.persist(post1);
console.log("********************************************************");
console.log("********************************************************");
post1.title = "Updated Post";
await connection.entityManager.persist(post1);*/
await connection.manager.persist(post1);*/
})));
@ -116,7 +116,7 @@ describe("persistence > cascade operations", () => {
post1.title = "Hello Post #1";
post1.category = category1;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
// create second category and post and save them
const category2 = new Category();
@ -126,10 +126,10 @@ describe("persistence > cascade operations", () => {
post2.title = "Hello Post #2";
post2.category = category2;
await connection.entityManager.save(post2);
await connection.manager.save(post2);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
innerJoinAndSelect: {
@ -168,7 +168,7 @@ describe("persistence > cascade operations", () => {
category1.name = "Category saved by cascades #1";
category1.posts = [post1];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
// create first post and category and save them
const post2 = new Post();
@ -178,10 +178,10 @@ describe("persistence > cascade operations", () => {
category2.name = "Category saved by cascades #2";
category2.posts = [post2];
await connection.entityManager.save(category2);
await connection.manager.save(category2);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
innerJoinAndSelect: {

View File

@ -27,14 +27,14 @@ describe("persistence > cascade operations with custom name", () => {
category1.name = "Category saved by cascades #1";
category1.posts = [post1];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
category1.posts = [];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
leftJoinAndSelect: {

View File

@ -40,12 +40,12 @@ describe.skip("persistence > insert operations", () => {
// post1.category = category1;
// post1.category.photos = [photo1, photo2];
await connection.entityManager.save(post1);
await connection.entityManager.save(category1);
await connection.manager.save(post1);
await connection.manager.save(category1);
console.log("********************************************************");
/*const posts = await connection.entityManager
/*const posts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.category", "category")
// .innerJoinAndSelect("post.photos", "photos")
@ -58,25 +58,25 @@ describe.skip("persistence > insert operations", () => {
// posts[0].category = null; // todo: uncomment to check remove
console.log("removing post's category: ", posts[0]);
await connection.entityManager.persist(posts[0]);*/
await connection.manager.persist(posts[0]);*/
/* await connection.entityManager.persist([photo1, photo2]);
/* await connection.manager.persist([photo1, photo2]);
post1.photos = [photo1];
await connection.entityManager.persist(post1);
await connection.manager.persist(post1);
console.log("********************************************************");
console.log("********************************************************");
post1.photos = [photo1, photo2];
await connection.entityManager.persist(post1);
await connection.manager.persist(post1);
console.log("********************************************************");
console.log("********************************************************");
post1.title = "Updated Post";
await connection.entityManager.persist(post1);*/
await connection.manager.persist(post1);*/
})));

View File

@ -21,13 +21,13 @@ describe("persistence > insert > update-relation-columns-after-insertion", () =>
// create category
const category1 = new Category();
category1.name = "Category saved by cascades #1";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
// create post
const post1 = new Post();
post1.title = "Hello Post #1";
post1.category = category1;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
// todo: HERE FOR CALCULATIONS WE NEED TO CALCULATE OVERALL NUMBER OF QUERIES TO PREVENT EXTRA QUERIES

View File

@ -23,7 +23,7 @@ describe("persistence > multi primary keys", () => {
post1.firstId = 1;
post1.secondId = 2;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
// create first category and post and save them
const category1 = new Category();
@ -31,10 +31,10 @@ describe("persistence > multi primary keys", () => {
category1.name = "Category saved by cascades #1";
category1.posts = [post1];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
innerJoinAndSelect: {

View File

@ -23,7 +23,7 @@ describe("persistence > multi primary keys", () => {
post1.firstId = 1;
post1.secondId = 2;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
post1.should.be.eql({
firstId: 1,
@ -37,10 +37,10 @@ describe("persistence > multi primary keys", () => {
category1.name = "Category saved by cascades #1";
category1.posts = [post1];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
// now check
const posts = await connection.entityManager.find(Post, {
const posts = await connection.manager.find(Post, {
join: {
alias: "post",
innerJoinAndSelect: {

View File

@ -36,10 +36,10 @@ describe("persistence > order of persistence execution operations", () => {
post1.title = "Hello Post #1";
post1.category = category1;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
// now check
/*const posts = await connection.entityManager.find(Post, {
/*const posts = await connection.manager.find(Post, {
alias: "post",
innerJoinAndSelect: {
category: "post.category"

View File

@ -28,51 +28,51 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image3";
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "airplanes";
category3.images = [image3];
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2];
post1.tag = tag;
post1.author = user;
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.tag", "tag")
.leftJoinAndSelect("post.author", "author")
@ -95,7 +95,7 @@ describe("query builder > joins", () => {
expect(loadedPosts![1].categories[0].images.length).to.be.equal(1);
expect(loadedPosts![1].categories[0].images[0].id).to.be.equal(3);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.tag", "tag")
.leftJoinAndSelect("post.author", "author")
@ -127,27 +127,27 @@ describe("query builder > joins", () => {
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.categories = [category1, category2];
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories", "categories.id = :categoryId")
.leftJoinAndSelect("categories.images", "images", "images.id = :imageId")
@ -168,14 +168,14 @@ describe("query builder > joins", () => {
const category = new Category();
category.name = "cars";
await connection.entityManager.save(category);
await connection.manager.save(category);
const post = new Post();
post.title = "about BMW";
post.categories = [category];
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedRawPost = await connection.entityManager
const loadedRawPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post_categories_category", "categoriesJunction", "categoriesJunction.postId = post.id")
.leftJoinAndSelect(Category, "categories", "categories.id = categoriesJunction.categoryId")
@ -194,37 +194,37 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.categories = [category1, category2];
post.tag = tag;
post.author = user;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.tag", "tag")
.innerJoinAndSelect("post.author", "author")
@ -248,27 +248,27 @@ describe("query builder > joins", () => {
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.categories = [category1, category2];
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.categories", "categories", "categories.id = :categoryId")
.innerJoinAndSelect("categories.images", "images", "images.id = :imageId")
@ -289,9 +289,9 @@ describe("query builder > joins", () => {
const post = new Post();
post.title = "about BMW";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.tag", "tag")
.where("post.id = :id", { id: post.id })
@ -309,35 +309,35 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.tag = tag;
post.author = user;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapOne("post.tag", Tag, "tag", "tag.id = :tagId")
.leftJoinAndMapOne("post.author", User, "user", "user.id = :userId")
@ -363,35 +363,35 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.tag = tag;
post.author = user;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapOne("post.tag", "tag", "tag", "tag.id = :tagId")
.leftJoinAndMapOne("post.author", "user", "user", "user.id = :userId")
@ -417,21 +417,21 @@ describe("query builder > joins", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "bmw";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post = new Post();
post.title = "about BMW";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapMany("post.categories", Category, "categories", "categories.id IN (:categoryIds)")
.leftJoinAndMapMany("post.subcategories", Category, "subcategories", "subcategories.id IN (:subcategoryIds)")
@ -450,55 +450,55 @@ describe("query builder > joins", () => {
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image3";
image3.isRemoved = true;
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const image4 = new Image();
image4.name = "image4";
image4.isRemoved = true;
await connection.entityManager.save(image4);
await connection.manager.save(image4);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2, image3, image4];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
category2.images = [image1, image2, image3, image4];
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "bmw";
category3.isRemoved = true;
category3.images = [image1, image3];
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "citroen";
category4.isRemoved = true;
category4.images = [image2, image4];
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const post = new Post();
post.title = "about BMW";
post.categories = [category1, category2, category3];
await connection.entityManager.save(post);
await connection.manager.save(post);
const post2 = new Post();
post2.title = "about Citroen";
post2.categories = [category1, category4];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapMany("post.removedCategories", "post.categories", "removedCategories", "removedCategories.isRemoved = :isRemoved")
.leftJoinAndMapMany("removedCategories.removedImages", "removedCategories.images", "removedImages", "removedImages.isRemoved = :isRemoved")
@ -528,7 +528,7 @@ describe("query builder > joins", () => {
expect(loadedPosts![1].subcategories.length).to.be.equal(1);
expect(loadedPosts![1].subcategories[0].titleImage.id).to.be.equal(1);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapMany("post.removedCategories", "post.categories", "removedCategories", "removedCategories.isRemoved = :isRemoved")
.leftJoinAndMapMany("removedCategories.removedImages", "removedCategories.images", "removedImages", "removedImages.isRemoved = :isRemoved")
@ -559,35 +559,35 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.tag = tag;
post.author = user;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapOne("post.tag", Tag, "tag", "tag.id = :tagId")
.innerJoinAndMapOne("post.author", User, "user", "user.id = :userId")
@ -613,35 +613,35 @@ describe("query builder > joins", () => {
const user = new User();
user.name = "Alex Messer";
await connection.entityManager.save(user);
await connection.manager.save(user);
const tag = new Tag();
tag.name = "audi";
await connection.entityManager.save(tag);
await connection.manager.save(tag);
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post = new Post();
post.title = "about BMW";
post.tag = tag;
post.author = user;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapOne("post.tag", "tag", "tag", "tag.id = :tagId")
.innerJoinAndMapOne("post.author", "user", "user", "user.id = :userId")
@ -667,21 +667,21 @@ describe("query builder > joins", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "bmw";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post = new Post();
post.title = "about BMW";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapMany("post.categories", Category, "categories", "categories.id IN (:categoryIds)")
.innerJoinAndMapMany("post.subcategories", Category, "subcategories", "subcategories.id IN (:subcategoryIds)")
@ -700,55 +700,55 @@ describe("query builder > joins", () => {
const image1 = new Image();
image1.name = "image1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image3";
image3.isRemoved = true;
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const image4 = new Image();
image4.name = "image4";
image4.isRemoved = true;
await connection.entityManager.save(image4);
await connection.manager.save(image4);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2, image3, image4];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "germany";
category2.images = [image1, image2, image3, image4];
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "bmw";
category3.isRemoved = true;
category3.images = [image1, image3];
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "citroen";
category4.isRemoved = true;
category4.images = [image2, image4];
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const post = new Post();
post.title = "about BMW";
post.categories = [category1, category2, category3];
await connection.entityManager.save(post);
await connection.manager.save(post);
const post2 = new Post();
post2.title = "about Citroen";
post2.categories = [category1, category4];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndMapMany("post.removedCategories", "post.categories", "removedCategories", "removedCategories.isRemoved = :isRemoved")
.leftJoinAndMapMany("removedCategories.removedImages", "removedCategories.images", "removedImages", "removedImages.isRemoved = :isRemoved")
@ -778,7 +778,7 @@ describe("query builder > joins", () => {
expect(loadedPosts![1].subcategories.length).to.be.equal(1);
expect(loadedPosts![1].subcategories[0].titleImage.id).to.be.equal(1);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapMany("post.removedCategories", "post.categories", "removedCategories", "removedCategories.isRemoved = :isRemoved")
.innerJoinAndMapMany("removedCategories.removedImages", "removedCategories.images", "removedImages", "removedImages.isRemoved = :isRemoved")
@ -805,9 +805,9 @@ describe("query builder > joins", () => {
const post = new Post();
post.title = "about BMW";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost1 = await connection.entityManager
const loadedPost1 = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapOne("post.author", User, "user", "user.id = :userId")
.where("post.id = :id", { id: 1 })
@ -816,7 +816,7 @@ describe("query builder > joins", () => {
expect(loadedPost1!).to.be.empty;
const loadedPost2 = await connection.entityManager
const loadedPost2 = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndMapMany("post.categories", Category, "categories", "categories.id = :categoryId")
.where("post.id = :id", { id: 1 })

View File

@ -32,7 +32,7 @@ describe("query builder > locking", () => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return;
const sql = connection.entityManager.createQueryBuilder(PostWithVersion, "post")
const sql = connection.manager.createQueryBuilder(PostWithVersion, "post")
.where("post.id = :id", { id: 1 })
.getSql();
@ -52,12 +52,12 @@ describe("query builder > locking", () => {
return;
return Promise.all([
connection.entityManager.createQueryBuilder(PostWithVersion, "post")
connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_read")
.where("post.id = :id", { id: 1 })
.getOne().should.be.rejectedWith(PessimisticLockTransactionRequiredError),
connection.entityManager.createQueryBuilder(PostWithVersion, "post")
connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_write")
.where("post.id = :id", { id: 1 })
.getOne().should.be.rejectedWith(PessimisticLockTransactionRequiredError)
@ -68,7 +68,7 @@ describe("query builder > locking", () => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return;
return connection.entityManager.transaction(entityManager => {
return connection.manager.transaction(entityManager => {
return Promise.all([
entityManager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_read")
@ -87,7 +87,7 @@ describe("query builder > locking", () => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return;
const sql = connection.entityManager.createQueryBuilder(PostWithVersion, "post")
const sql = connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_read")
.where("post.id = :id", { id: 1 })
.getSql();
@ -107,7 +107,7 @@ describe("query builder > locking", () => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return;
const sql = connection.entityManager.createQueryBuilder(PostWithVersion, "post")
const sql = connection.manager.createQueryBuilder(PostWithVersion, "post")
.where("post.id = :id", { id: 1 })
.getSql();
@ -123,7 +123,7 @@ describe("query builder > locking", () => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return;
const sql = connection.entityManager.createQueryBuilder(PostWithVersion, "post")
const sql = connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_write")
.where("post.id = :id", { id: 1 })
.getSql();
@ -139,35 +139,35 @@ describe("query builder > locking", () => {
it("should throw error if optimistic lock used with getMany method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.getMany().should.be.rejectedWith(OptimisticLockCanNotBeUsedError);
})));
it("should throw error if optimistic lock used with getCount method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.getCount().should.be.rejectedWith(OptimisticLockCanNotBeUsedError);
})));
it("should throw error if optimistic lock used with getManyAndCount method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.getManyAndCount().should.be.rejectedWith(OptimisticLockCanNotBeUsedError);
})));
it("should throw error if optimistic lock used with getRawMany method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.getRawMany().should.be.rejectedWith(OptimisticLockCanNotBeUsedError);
})));
it("should throw error if optimistic lock used with getRawOne method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.where("post.id = :id", { id: 1 })
.getRawOne().should.be.rejectedWith(OptimisticLockCanNotBeUsedError);
@ -175,7 +175,7 @@ describe("query builder > locking", () => {
it("should not throw error if optimistic lock used with getOne method", () => Promise.all(connections.map(async connection => {
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.where("post.id = :id", { id: 1 })
.getOne().should.not.be.rejected;
@ -185,9 +185,9 @@ describe("query builder > locking", () => {
const post = new PostWithoutVersionAndUpdateDate();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return connection.entityManager.createQueryBuilder(PostWithoutVersionAndUpdateDate, "post")
return connection.manager.createQueryBuilder(PostWithoutVersionAndUpdateDate, "post")
.setLock("optimistic", 1)
.where("post.id = :id", { id: 1 })
.getOne().should.be.rejectedWith(NoVersionOrUpdateDateColumnError);
@ -197,9 +197,9 @@ describe("query builder > locking", () => {
const post = new PostWithVersion();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 2)
.where("post.id = :id", { id: 1 })
.getOne().should.be.rejectedWith(OptimisticLockVersionMismatchError);
@ -209,9 +209,9 @@ describe("query builder > locking", () => {
const post = new PostWithVersion();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return connection.entityManager.createQueryBuilder(PostWithVersion, "post")
return connection.manager.createQueryBuilder(PostWithVersion, "post")
.setLock("optimistic", 1)
.where("post.id = :id", { id: 1 })
.getOne().should.not.be.rejected;
@ -221,9 +221,9 @@ describe("query builder > locking", () => {
const post = new PostWithUpdateDate();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return connection.entityManager.createQueryBuilder(PostWithUpdateDate, "post")
return connection.manager.createQueryBuilder(PostWithUpdateDate, "post")
.setLock("optimistic", new Date(2017, 1, 1))
.where("post.id = :id", { id: 1 })
.getOne().should.be.rejectedWith(OptimisticLockVersionMismatchError);
@ -233,9 +233,9 @@ describe("query builder > locking", () => {
const post = new PostWithUpdateDate();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return connection.entityManager.createQueryBuilder(PostWithUpdateDate, "post")
return connection.manager.createQueryBuilder(PostWithUpdateDate, "post")
.setLock("optimistic", post.updateDate)
.where("post.id = :id", { id: 1 })
.getOne().should.not.be.rejected;
@ -245,15 +245,15 @@ describe("query builder > locking", () => {
const post = new PostWithVersionAndUpdatedDate();
post.title = "New post";
await connection.entityManager.save(post);
await connection.manager.save(post);
return Promise.all([
connection.entityManager.createQueryBuilder(PostWithVersionAndUpdatedDate, "post")
connection.manager.createQueryBuilder(PostWithVersionAndUpdatedDate, "post")
.setLock("optimistic", post.updateDate)
.where("post.id = :id", { id: 1 })
.getOne().should.not.be.rejected,
connection.entityManager.createQueryBuilder(PostWithVersionAndUpdatedDate, "post")
connection.manager.createQueryBuilder(PostWithVersionAndUpdatedDate, "post")
.setLock("optimistic", 1)
.where("post.id = :id", { id: 1 })
.getOne().should.not.be.rejected
@ -262,7 +262,7 @@ describe("query builder > locking", () => {
it("should throw error if pessimistic locking not supported by given driver", () => Promise.all(connections.map(async connection => {
if (connection.driver instanceof SqliteDriver || connection.driver instanceof OracleDriver)
return connection.entityManager.transaction(entityManager => {
return connection.manager.transaction(entityManager => {
return Promise.all([
entityManager.createQueryBuilder(PostWithVersion, "post")
.setLock("pessimistic_read")

View File

@ -24,35 +24,35 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.getMany();
@ -60,7 +60,7 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
expect(loadedPosts![0].categoryCount).to.be.equal(3);
expect(loadedPosts![1].categoryCount).to.be.equal(2);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.where("post.id = :id", { id: 1 })
@ -73,43 +73,43 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Audi";
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Airbus";
await connection.entityManager.save(post4);
await connection.manager.save(post4);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.setOffset(0)
@ -125,50 +125,50 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const image1 = new Image();
image1.isRemoved = true;
image1.name = "image #1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image #2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image #3";
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const category1 = new Category();
category1.name = "cars";
category1.isRemoved = true;
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "airplanes";
category4.images = [image3];
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const category5 = new Category();
category5.name = "Boeing";
await connection.entityManager.save(category5);
await connection.manager.save(category5);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category4, category5];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -187,7 +187,7 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
expect(loadedPosts![1].categoryCount).to.be.equal(2);
expect(loadedPosts![1].categories[0].imageCount).to.be.equal(1);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -208,27 +208,27 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "Germany";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2, category3];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1, category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
let loadedPosts = await connection.entityManager
let loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -244,7 +244,7 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
expect(loadedPosts![1].categories[0].postCount).to.be.equal(2);
expect(loadedPosts![1].categories[1].postCount).to.be.equal(2);
let loadedPost = await connection.entityManager
let loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -263,38 +263,38 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationCountAndMap("category.postCount", "category.posts")
.getMany();
@ -302,7 +302,7 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
expect(loadedCategories![0].postCount).to.be.equal(3);
expect(loadedCategories![1].postCount).to.be.equal(2);
let loadedCategory = await connection.entityManager
let loadedCategory = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationCountAndMap("category.postCount", "category.posts")
.where("category.id = :id", { id: 1 })
@ -315,46 +315,46 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "BMW";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const category4 = new Category();
category4.name = "Boeing";
await connection.entityManager.save(category4);
await connection.manager.save(category4);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationCountAndMap("category.postCount", "category.posts")
.setOffset(0)
@ -369,40 +369,40 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "airplanes";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const post1 = new Post();
post1.title = "about BMW";
post1.isRemoved = true;
post1.categories = [category1];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Audi";
post2.isRemoved = true;
post2.categories = [category1];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const post3 = new Post();
post3.title = "about Mercedes";
post3.categories = [category1];
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const post4 = new Post();
post4.title = "about Boeing";
post4.categories = [category2];
await connection.entityManager.save(post4);
await connection.manager.save(post4);
const post5 = new Post();
post5.title = "about Airbus";
post5.categories = [category2];
await connection.entityManager.save(post5);
await connection.manager.save(post5);
let loadedCategories = await connection.entityManager
let loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationCountAndMap("category.postCount", "category.posts")
.loadRelationCountAndMap("category.removedPostCount", "category.posts", "removedPosts", qb => qb.andWhere("removedPosts.isRemoved = :isRemoved", { isRemoved: true }))
@ -412,7 +412,7 @@ describe("query builder > load-relation-count-and-map > many-to-many", () => {
expect(loadedCategories![0].removedPostCount).to.be.equal(2);
expect(loadedCategories![1].postCount).to.be.equal(2);
let loadedCategory = await connection.entityManager
let loadedCategory = await connection.manager
.createQueryBuilder(Category, "category")
.loadRelationCountAndMap("category.postCount", "category.posts")
.loadRelationCountAndMap("category.removedPostCount", "category.posts", "removedPosts", qb => qb.andWhere("removedPosts.isRemoved = :isRemoved", { isRemoved: true }))

View File

@ -24,27 +24,27 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
const category1 = new Category();
category1.name = "cars";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "airplanes";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.getMany();
@ -52,7 +52,7 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
expect(loadedPosts[0]!.categoryCount).to.be.equal(2);
expect(loadedPosts[1]!.categoryCount).to.be.equal(1);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.where("post.id = :id", { id: 1 })
@ -65,41 +65,41 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
const image1 = new Image();
image1.name = "image #1";
await connection.entityManager.save(image1);
await connection.manager.save(image1);
const image2 = new Image();
image2.name = "image #2";
await connection.entityManager.save(image2);
await connection.manager.save(image2);
const image3 = new Image();
image3.name = "image #3";
await connection.entityManager.save(image3);
await connection.manager.save(image3);
const category1 = new Category();
category1.name = "cars";
category1.images = [image1, image2];
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "airplanes";
category3.images = [image3];
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -113,7 +113,7 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
expect(loadedPosts[1]!.categoryCount).to.be.equal(1);
expect(loadedPosts[1]!.categories[0].imageCount).to.be.equal(1);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
@ -132,27 +132,27 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
const category1 = new Category();
category1.name = "cars";
category1.isRemoved = true;
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "BMW";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const category3 = new Category();
category3.name = "airplanes";
await connection.entityManager.save(category3);
await connection.manager.save(category3);
const post1 = new Post();
post1.title = "about BMW";
post1.categories = [category1, category2];
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const post2 = new Post();
post2.title = "about Boeing";
post2.categories = [category3];
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.loadRelationCountAndMap("post.removedCategoryCount", "post.categories", "removedCategories", qb => qb.andWhere("removedCategories.isRemoved = :isRemoved", { isRemoved: true }))
@ -162,7 +162,7 @@ describe("query builder > load-relation-count-and-map > one-to-many", () => {
expect(loadedPosts[0]!.removedCategoryCount).to.be.equal(1);
expect(loadedPosts[1]!.categoryCount).to.be.equal(1);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.loadRelationCountAndMap("post.categoryCount", "post.categories")
.loadRelationCountAndMap("post.removedCategoryCount", "post.categories", "removedCategories", qb => qb.andWhere("removedCategories.isRemoved = :isRemoved", { isRemoved: true }))

View File

@ -16,7 +16,7 @@ describe("query builder > select", () => {
after(() => closeTestingConnections(connections));
it("should append all entity mapped columns from main selection to select statement", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.disableEscaping()
.getSql();
@ -30,7 +30,7 @@ describe("query builder > select", () => {
})));
it("should append all entity mapped columns from both main selection and join selections to select statement", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.leftJoinAndSelect("category", "category")
.disableEscaping()
.getSql();
@ -49,7 +49,7 @@ describe("query builder > select", () => {
})));
it("should append entity mapped columns from both main alias and join aliases to select statement", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.select("post.id")
.addSelect("category.name")
.leftJoin("category", "category")
@ -62,7 +62,7 @@ describe("query builder > select", () => {
})));
it("should append entity mapped columns to select statement, if they passed as array", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.select(["post.id", "post.title"])
.disableEscaping()
.getSql();
@ -71,7 +71,7 @@ describe("query builder > select", () => {
})));
it("should append raw sql to select statement", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.select("COUNT(*) as cnt")
.disableEscaping()
.getSql();
@ -80,7 +80,7 @@ describe("query builder > select", () => {
})));
it("should append raw sql and entity mapped column to select statement", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.select(["COUNT(*) as cnt", "post.title"])
.disableEscaping()
.getSql();
@ -89,7 +89,7 @@ describe("query builder > select", () => {
})));
it("should not create alias for selection, which is not entity mapped column", () => Promise.all(connections.map(async connection => {
const sql = connection.entityManager.createQueryBuilder(Post, "post")
const sql = connection.manager.createQueryBuilder(Post, "post")
.select("post.name")
.disableEscaping()
.getSql();

View File

@ -385,7 +385,7 @@ describe("repository > basic methods", () => {
});
describe.skip("transaction", function() {
/*describe.skip("transaction", function() {
it("executed queries must success", () => Promise.all(connections.map(async connection => {
const repository = connection.getRepository(Blog);
@ -456,6 +456,6 @@ describe("repository > basic methods", () => {
blogs.length.should.be.equal(1);
})));
});
});*/
});

View File

@ -23,19 +23,19 @@ describe("repository > clear method", () => {
const post = new Post();
post.id = i;
post.title = "post #" + i;
promises.push(connection.entityManager.save(post));
promises.push(connection.manager.save(post));
}
await Promise.all(promises);
// check if they all are saved
const loadedPosts = await connection.entityManager.find(Post);
const loadedPosts = await connection.manager.find(Post);
loadedPosts.should.be.instanceOf(Array);
loadedPosts.length.should.be.equal(100);
await connection.getRepository(Post).clear();
// check find method
const loadedPostsAfterClear = await connection.entityManager.find(Post);
const loadedPostsAfterClear = await connection.manager.find(Post);
loadedPostsAfterClear.should.be.instanceOf(Array);
loadedPostsAfterClear.length.should.be.equal(0);
})));
@ -48,19 +48,19 @@ describe("repository > clear method", () => {
const post = new Post();
post.id = i;
post.title = "post #" + i;
promises.push(connection.entityManager.save(post));
promises.push(connection.manager.save(post));
}
await Promise.all(promises);
// check if they all are saved
const loadedPosts = await connection.entityManager.find(Post);
const loadedPosts = await connection.manager.find(Post);
loadedPosts.should.be.instanceOf(Array);
loadedPosts.length.should.be.equal(100);
await connection.entityManager.clear(Post);
await connection.manager.clear(Post);
// check find method
const loadedPostsAfterClear = await connection.entityManager.find(Post);
const loadedPostsAfterClear = await connection.manager.find(Post);
loadedPostsAfterClear.should.be.instanceOf(Array);
loadedPostsAfterClear.length.should.be.equal(0);
})));

View File

@ -33,11 +33,11 @@ describe("transaction > method wrapped into transaction decorator", () => {
await controller.save.apply(controller, [post, category]);
// controller should have saved both post and category successfully
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "successfully saved post" } });
const loadedPost = await connection.manager.findOne(Post, { where: { title: "successfully saved post" } });
expect(loadedPost).not.to.be.empty;
loadedPost!.should.be.eql(post);
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "successfully saved category" } });
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "successfully saved category" } });
expect(loadedCategory).not.to.be.empty;
loadedCategory!.should.be.eql(category);
@ -59,10 +59,10 @@ describe("transaction > method wrapped into transaction decorator", () => {
}
expect(throwError).not.to.be.empty;
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "successfully saved post" }});
const loadedPost = await connection.manager.findOne(Post, { where: { title: "successfully saved post" }});
expect(loadedPost).to.be.empty;
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "successfully saved category" }});
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "successfully saved category" }});
expect(loadedCategory).to.be.empty;
})));
@ -83,10 +83,10 @@ describe("transaction > method wrapped into transaction decorator", () => {
}
expect(throwError).not.to.be.empty;
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "successfully saved post" }});
const loadedPost = await connection.manager.findOne(Post, { where: { title: "successfully saved post" }});
expect(loadedPost).to.be.empty;
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "successfully saved category" }});
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "successfully saved category" }});
expect(loadedCategory).to.be.empty;
})));
@ -101,7 +101,7 @@ describe("transaction > method wrapped into transaction decorator", () => {
// call controller method and make its rejected since controller action should fail
let throwError: any;
try {
await controller.nonSafeSave.apply(controller, [connection.entityManager, post, category]);
await controller.nonSafeSave.apply(controller, [connection.manager, post, category]);
} catch (err) {
throwError = err;
@ -109,11 +109,11 @@ describe("transaction > method wrapped into transaction decorator", () => {
expect(throwError).not.to.be.empty;
// controller should have saved both post and category successfully
const loadedPost = await connection.entityManager.findOne(Post, { where: { title: "successfully saved post" }});
const loadedPost = await connection.manager.findOne(Post, { where: { title: "successfully saved post" }});
expect(loadedPost).not.to.be.empty;
loadedPost!.should.be.eql(post);
const loadedCategory = await connection.entityManager.findOne(Category, { where: { name: "successfully saved category" }});
const loadedCategory = await connection.manager.findOne(Category, { where: { name: "successfully saved category" }});
expect(loadedCategory).to.be.empty;
})));

View File

@ -21,7 +21,7 @@ describe("transaction > transaction with entity manager", () => {
let postId: number|undefined = undefined, categoryId: number|undefined = undefined;
await connection.entityManager.transaction(async entityManager => {
await connection.manager.transaction(async entityManager => {
const post = new Post();
post.title = "Post #1";
@ -36,14 +36,14 @@ describe("transaction > transaction with entity manager", () => {
});
const post = await connection.entityManager.findOne(Post, { where: { title: "Post #1" }});
const post = await connection.manager.findOne(Post, { where: { title: "Post #1" }});
expect(post).not.to.be.empty;
post!.should.be.eql({
id: postId,
title: "Post #1"
});
const category = await connection.entityManager.findOne(Category, { where: { name: "Category #1" }});
const category = await connection.manager.findOne(Category, { where: { name: "Category #1" }});
expect(category).not.to.be.empty;
category!.should.be.eql({
id: categoryId,
@ -57,7 +57,7 @@ describe("transaction > transaction with entity manager", () => {
let postId: number|undefined = undefined, categoryId: number|undefined = undefined;
try {
await connection.entityManager.transaction(async entityManager => {
await connection.manager.transaction(async entityManager => {
const post = new Post();
post.title = "Post #1";
@ -93,10 +93,10 @@ describe("transaction > transaction with entity manager", () => {
/* skip error */
}
const post = await connection.entityManager.findOne(Post, { where: { title: "Post #1" }});
const post = await connection.manager.findOne(Post, { where: { title: "Post #1" }});
expect(post).to.be.empty;
const category = await connection.entityManager.findOne(Category, { where: { name: "Category #1" }});
const category = await connection.manager.findOne(Category, { where: { name: "Category #1" }});
expect(category).to.be.empty;
})));

View File

@ -14,7 +14,7 @@ describe("uuid type", () => {
});
await Promise.all(connections.map(connection => {
return connection.entityManager.query(`CREATE extension IF NOT EXISTS "uuid-ossp"`);
return connection.manager.query(`CREATE extension IF NOT EXISTS "uuid-ossp"`);
}));
});
// beforeEach(() => reloadTestingDatabases(connections));

View File

@ -25,7 +25,7 @@ describe("github issues > #134 Error TIME is converted to 'HH-mm' instead of 'HH
post.creationDate = currentDate;
const savedPost = await postRepository.save(post);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.id=:id", { id: savedPost.id })
.getOne();

View File

@ -26,9 +26,9 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
post.title = "Hello post";
post.category = category;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection.entityManager.findOneById(Post, 1, {
const loadedPost = await connection.manager.findOneById(Post, 1, {
join: {
alias: "post",
innerJoinAndSelect: {
@ -58,13 +58,13 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
post.title = "Hello post";
post.category = category;
await connection.entityManager.save(post);
await connection.manager.save(post);
post.category = null;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPostWithCategory = await connection.entityManager.findOneById(Post, 1, {
const loadedPostWithCategory = await connection.manager.findOneById(Post, 1, {
join: {
alias: "post",
innerJoinAndSelect: {
@ -75,7 +75,7 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
expect(loadedPostWithCategory).to.be.empty;
const loadedPostWithoutCategory = await connection.entityManager.findOneById(Post, 1);
const loadedPostWithoutCategory = await connection.manager.findOneById(Post, 1);
expect(loadedPostWithoutCategory).not.to.be.empty;
loadedPostWithoutCategory!.should.be.eql({
@ -83,7 +83,7 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
title: "Hello post"
});
const loadedCategory = await connection.entityManager.findOneById(Category, 1);
const loadedCategory = await connection.manager.findOneById(Category, 1);
expect(loadedCategory).to.be.empty;
})));
@ -97,13 +97,13 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
post.title = "Hello post";
post.metadata = metadata;
await connection.entityManager.save(post);
await connection.manager.save(post);
post.metadata = null;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPostWithMetadata = await connection.entityManager.findOneById(Post, 1, {
const loadedPostWithMetadata = await connection.manager.findOneById(Post, 1, {
join: {
alias: "post",
innerJoinAndSelect: {
@ -113,14 +113,14 @@ describe("github issues > #151 joinAndSelect can't find entity from inverse side
});
expect(loadedPostWithMetadata).to.be.empty;
const loadedPostWithoutMetadata = await connection.entityManager.findOneById(Post, 1);
const loadedPostWithoutMetadata = await connection.manager.findOneById(Post, 1);
expect(loadedPostWithoutMetadata).not.to.be.empty;
loadedPostWithoutMetadata!.should.be.eql({
id: 1,
title: "Hello post"
});
const loadedMetadata = await connection.entityManager.findOneById(PostMetadata, 1);
const loadedMetadata = await connection.manager.findOneById(PostMetadata, 1);
expect(loadedMetadata).to.be.empty;
})));

View File

@ -28,7 +28,7 @@ describe.skip("github issues > #159 Referencing ClassTableChild build table erro
department.manager = employee;
await connection.entityManager.save(department);
await connection.manager.save(department);
department.id.should.be.equal(1);
department.name.should.be.equal("Software");

View File

@ -27,9 +27,9 @@ describe("github issues > #161 joinAndSelect can't find entity from inverse side
ticket.name = "ticket #1";
ticket.request = request;
await connection.entityManager.save(ticket);
await connection.manager.save(ticket);
const loadedTicketWithRequest = await connection.entityManager.findOneById(Ticket, 1, {
const loadedTicketWithRequest = await connection.manager.findOneById(Ticket, 1, {
join: {
alias: "ticket",
innerJoinAndSelect: {
@ -50,7 +50,7 @@ describe("github issues > #161 joinAndSelect can't find entity from inverse side
}
});
const loadedRequestWithTicket = await connection.entityManager.findOneById(Request, 1, {
const loadedRequestWithTicket = await connection.manager.findOneById(Request, 1, {
join: {
alias: "request",
innerJoinAndSelect: {
@ -79,7 +79,7 @@ describe("github issues > #161 joinAndSelect can't find entity from inverse side
authRequest.type = "authenticate";
authRequest.success = true;
await connection.entityManager.save(authRequest);
await connection.manager.save(authRequest);
const request = new Request();
request.owner = "somebody";
@ -92,9 +92,9 @@ describe("github issues > #161 joinAndSelect can't find entity from inverse side
ticket.request = request;
request.ticket = ticket;
await connection.entityManager.save(request);
await connection.manager.save(request);
const loadedRequest = await connection.entityManager.findOneById(Request, 2, {
const loadedRequest = await connection.manager.findOneById(Request, 2, {
join: {
alias: "request",
innerJoinAndSelect: { ticket: "request.ticket" }

View File

@ -33,7 +33,7 @@ describe("github issues > #163 ManyToMany relation : Cannot read property 'joinC
platform.slug = "windows";
platform.games = [battlefront, republicCommando];
await connection.entityManager.save(platform);
await connection.manager.save(platform);
const loadedPlatform = await connection
.getRepository(Platform)
@ -45,7 +45,7 @@ describe("github issues > #163 ManyToMany relation : Cannot read property 'joinC
jediAcademy.platforms = [loadedPlatform!];
jediAcademy.isReviewed = false;
await connection.entityManager.save(jediAcademy);
await connection.manager.save(jediAcademy);
const completePlatform = await connection
.getRepository(Platform)

View File

@ -23,14 +23,14 @@ describe("github issues > #174 Embeded types confusing with order by", () => {
organisation1.contact = new Contact();
organisation1.contact.name = "Albert Cow";
organisation1.contact.email = "ceo@mlkyway.com";
await connection.entityManager.save(organisation1);
await connection.manager.save(organisation1);
const organisation2 = new Organisation();
organisation2.name = "ChockoWay";
organisation2.contact = new Contact();
organisation2.contact.name = "Brendan Late";
organisation2.contact.email = "ceo@chockoway.com";
await connection.entityManager.save(organisation2);
await connection.manager.save(organisation2);
const organisations = await connection
.getRepository(Organisation)

View File

@ -20,18 +20,18 @@ describe("github issues > #175 ManyToMany relation doesn't put an empty array wh
const category1 = new Category();
category1.name = "category #1";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "category #2";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const postWithCategories = new Post();
postWithCategories.title = "post with categories";
postWithCategories.categories = [category1, category2];
await connection.entityManager.save(postWithCategories);
await connection.manager.save(postWithCategories);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.where("post.title = :title", { title: "post with categories" })
@ -55,21 +55,21 @@ describe("github issues > #175 ManyToMany relation doesn't put an empty array wh
const category1 = new Category();
category1.name = "category #1";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "category #2";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const postWithoutCategories = new Post();
postWithoutCategories.title = "post without categories";
postWithoutCategories.categories = [];
await connection.entityManager.save(postWithoutCategories);
await connection.manager.save(postWithoutCategories);
const justPost = new Post();
justPost.title = "just post";
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.where("post.title = :title", { title: "post without categories" })
@ -87,17 +87,17 @@ describe("github issues > #175 ManyToMany relation doesn't put an empty array wh
const category1 = new Category();
category1.name = "category #1";
await connection.entityManager.save(category1);
await connection.manager.save(category1);
const category2 = new Category();
category2.name = "category #2";
await connection.entityManager.save(category2);
await connection.manager.save(category2);
const justPost = new Post();
justPost.title = "just post";
await connection.entityManager.save(justPost);
await connection.manager.save(justPost);
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.secondaryCategories", "secondaryCategories")
.where("post.title = :title", { title: "just post" })

View File

@ -23,9 +23,9 @@ describe("github issues > #176 @CreateDateColumn and @UpdateDateColumn does not
post1.localDate = new Date(1484069886663); // stores "2017-01-10 22:38:06.000" into the database
// persist
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const loadedPosts1 = await connection.entityManager.findOne(Post, { where: { title: "Hello Post #1" } });
const loadedPosts1 = await connection.manager.findOne(Post, { where: { title: "Hello Post #1" } });
expect(loadedPosts1!).not.to.be.empty;
loadedPosts1!.date.toISOString().should.be.equal("2017-01-10T17:38:06.000Z");
@ -33,7 +33,7 @@ describe("github issues > #176 @CreateDateColumn and @UpdateDateColumn does not
// also make sure that local date really was saved as a local date (including timezone)
const rawPost = await connection.entityManager
const rawPost = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.title = :title", { title: "Hello Post #1" })
.getRawOne();

View File

@ -24,9 +24,9 @@ describe("github issues > #182 enums are not saved properly", () => {
post1.title = "Hello Post #1";
// persist
await connection.entityManager.save(post1);
await connection.manager.save(post1);
const loadedPosts1 = await connection.entityManager.findOne(Post, { where: { title: "Hello Post #1" } });
const loadedPosts1 = await connection.manager.findOne(Post, { where: { title: "Hello Post #1" } });
expect(loadedPosts1!).not.to.be.empty;
loadedPosts1!.should.be.eql({
id: 1,
@ -35,16 +35,16 @@ describe("github issues > #182 enums are not saved properly", () => {
});
// remove persisted
await connection.entityManager.remove(post1);
await connection.manager.remove(post1);
const post2 = new Post();
post2.status = PostStatus.ACTIVE;
post2.title = "Hello Post #1";
// persist
await connection.entityManager.save(post2);
await connection.manager.save(post2);
const loadedPosts2 = await connection.entityManager.findOne(Post, { where: { title: "Hello Post #1" } });
const loadedPosts2 = await connection.manager.findOne(Post, { where: { title: "Hello Post #1" } });
expect(loadedPosts2!).not.to.be.empty;
loadedPosts2!.should.be.eql({
id: 2,
@ -53,16 +53,16 @@ describe("github issues > #182 enums are not saved properly", () => {
});
// remove persisted
await connection.entityManager.remove(post2);
await connection.manager.remove(post2);
const post3 = new Post();
post3.status = PostStatus.ACHIEVED;
post3.title = "Hello Post #1";
// persist
await connection.entityManager.save(post3);
await connection.manager.save(post3);
const loadedPosts3 = await connection.entityManager.findOne(Post, { where: { title: "Hello Post #1" } });
const loadedPosts3 = await connection.manager.findOne(Post, { where: { title: "Hello Post #1" } });
expect(loadedPosts3!).not.to.be.empty;
loadedPosts3!.should.be.eql({
id: 3,
@ -71,7 +71,7 @@ describe("github issues > #182 enums are not saved properly", () => {
});
// remove persisted
await connection.entityManager.remove(post3);
await connection.manager.remove(post3);
})));

View File

@ -20,10 +20,10 @@ describe("github issues > #190 too many SQL variables when using setMaxResults i
for (let i = 0; i < 1000; i++) {
const post1 = new Post();
post1.title = "Hello Post #1";
await connection.entityManager.save(post1);
await connection.manager.save(post1);
}
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.take(1000)

View File

@ -27,9 +27,9 @@ describe("github issues > #204 jsonb array is not persisted correctly", () => {
{ id: 2, option1: "2", option2: "2", option3: "2", isActive: false, extra: { data1: "one", data2: "two" } },
{ id: 3, option1: "3", option2: "3", option3: "3", isActive: true, extra: { data1: "one", data2: "two" } },
];
await connection.entityManager.save(record);
await connection.manager.save(record);
const foundRecord = await connection.entityManager.findOneById(Record, record.id);
const foundRecord = await connection.manager.findOneById(Record, record.id);
expect(foundRecord).to.be.not.undefined;
foundRecord!.datas.should.be.eql([
new RecordData("hello1", "hello2", "hello3", "hello4", true, false),

View File

@ -20,17 +20,17 @@ describe("github issues > #211 where in query issue", () => {
const post1 = new Post();
post1.title = "post #" + i;
post1.text = "about post";
await connection.entityManager.save(post1);
await connection.manager.save(post1);
}
const loadedPosts1 = await connection.entityManager
const loadedPosts1 = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.id IN (:ids)", { ids: [1, 2, 3] })
.getMany();
loadedPosts1.length.should.be.equal(3);
const loadedPosts2 = await connection.entityManager
const loadedPosts2 = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.text = :text", { text: "about post" })
.andWhere("post.title IN (:titles)", { titles: ["post #1", "post #2", "post #3"] })

View File

@ -20,22 +20,22 @@ describe("github issues > #215 invalid replacements of join conditions", () => {
const author = new Author();
author.name = "John Doe";
await connection.entityManager.save(author);
await connection.manager.save(author);
const abbrev = new Abbreviation();
abbrev.name = "test";
await connection.entityManager.save(abbrev);
await connection.manager.save(abbrev);
const post = new Post();
post.author = author;
post.abbreviation = abbrev;
await connection.entityManager.save(post);
await connection.manager.save(post);
// generated query should end with "ON p.abbreviation_id = ab.id"
// not with ON p.abbreviation.id = ab.id (notice the dot) which would
// produce an error.
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "p")
.leftJoinAndMapOne("p.author", Author, "n", "p.author_id = n.id")
.leftJoinAndMapOne("p.abbreviation", Abbreviation, "ab", "p.abbreviation_id = ab.id")

View File

@ -21,14 +21,14 @@ describe("github issues > #219 FindOptions should be able to resolve null values
const post1 = new Post();
post1.title = "post #" + i;
post1.text = i > 5 ? "about post" : null;
promises.push(connection.entityManager.save(post1));
promises.push(connection.manager.save(post1));
}
await Promise.all(promises);
const postsWithoutText1 = await connection.entityManager.find(Post, { where: { text: null } });
const postsWithoutText1 = await connection.manager.find(Post, { where: { text: null } });
postsWithoutText1.length.should.be.equal(5);
const postsWithText1 = await connection.entityManager.find(Post, { where: { text: "about post" } });
const postsWithText1 = await connection.manager.find(Post, { where: { text: "about post" } });
postsWithText1.length.should.be.equal(5);
})));

View File

@ -30,7 +30,7 @@ describe("github issues > #234 and #223 lazy loading does not work correctly fro
category.name = "fake category!";
post.category = Promise.resolve(category);
}
promises.push(connection.entityManager.save(post));
promises.push(connection.manager.save(post));
}
await Promise.all(promises);
@ -50,11 +50,11 @@ describe("github issues > #234 and #223 lazy loading does not work correctly fro
post2.category = Promise.resolve(category2);
// persist
await connection.entityManager.save(post1);
await connection.entityManager.save(post2);
await connection.manager.save(post1);
await connection.manager.save(post2);
// check that all persisted objects exist
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.title = :firstTitle OR post.title = :secondTitle", { firstTitle: "Hello Post #1", secondTitle: "Hello Post #2" })
.getMany();
@ -89,7 +89,7 @@ describe("github issues > #234 and #223 lazy loading does not work correctly fro
tag.name = "fake tag!";
post.tags = Promise.resolve((await post.tags).concat([tag]));
}
promises.push(connection.entityManager.save(post));
promises.push(connection.manager.save(post));
}
await Promise.all(promises);
@ -118,11 +118,11 @@ describe("github issues > #234 and #223 lazy loading does not work correctly fro
post2.tags = Promise.resolve([tag2_1, tag2_2, tag2_3]);
// persist
await connection.entityManager.save(post1);
await connection.entityManager.save(post2);
await connection.manager.save(post1);
await connection.manager.save(post2);
// check that all persisted objects exist
const loadedPosts = await connection.entityManager
const loadedPosts = await connection.manager
.createQueryBuilder(Post, "post")
.where("post.title = :firstTitle OR post.title = :secondTitle", { firstTitle: "Hello Post #1", secondTitle: "Hello Post #2" })
.getMany();

View File

@ -20,9 +20,9 @@ describe("github issues > support of embeddeds that are not set", () => {
const race = new Race();
race.name = "National Race";
await connection.entityManager.save(race);
await connection.manager.save(race);
const loadedRace = await connection.entityManager.findOne(Race, { name: "National Race" });
const loadedRace = await connection.manager.findOne(Race, { name: "National Race" });
expect(loadedRace).to.be.not.empty;
expect(loadedRace!.id).to.be.not.empty;
loadedRace!.name.should.be.equal("National Race");

View File

@ -25,9 +25,9 @@ describe("github issues > embeddeds with custom column name don't work", () => {
race.duration.durationHours = 10;
race.duration.durationMinutes = 30;
await connection.entityManager.save(race);
await connection.manager.save(race);
const loadedRace = await connection.entityManager.findOne(Race, { name: "National Race" });
const loadedRace = await connection.manager.findOne(Race, { name: "National Race" });
expect(loadedRace).to.be.not.empty;
expect(loadedRace!.id).to.be.not.empty;
expect(loadedRace!.duration).to.be.not.empty;

View File

@ -20,15 +20,15 @@ describe("github issues > OneToOne relation with referencedColumnName does not w
const category = new Category();
category.name = "category #1";
await connection.entityManager.save(category);
await connection.manager.save(category);
const post = new Post();
post.title = "post #1";
post.category = category;
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection
.entityManager
.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.category", "category")
.getOne();

View File

@ -21,17 +21,17 @@ describe("github issues > Join query on ManyToMany relations not working", () =>
for (let i = 0; i < 20; i++) {
const category = new Category();
category.name = "Category #" + i;
await connection.entityManager.save(category);
await connection.manager.save(category);
}
const post = new Post();
post.title = "SuperRace";
post.categories = [new Category()];
post.categories[0].name = "SuperCategory";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection
.entityManager
.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "category")
.where("category.category_id IN (:ids)", { ids: [21] })

View File

@ -24,7 +24,7 @@ describe("github issues > #363 Can't save 2 unrelated entity types in a single p
const fruit = new Fruit();
fruit.name = "Banana";
const [savedCar, savedFruit] = await connection.entityManager.save([car, fruit]);
const [savedCar, savedFruit] = await connection.manager.save([car, fruit]);
expect(savedFruit).to.have.property("name", "Banana");
expect(savedFruit).to.be.instanceof(Fruit);
@ -32,13 +32,13 @@ describe("github issues > #363 Can't save 2 unrelated entity types in a single p
expect(savedCar).to.have.property("name", "Ferrari");
expect(savedCar).to.be.instanceof(Car);
const cars = await connection.entityManager.find(Car);
const cars = await connection.manager.find(Car);
// before the changes in this PR, all the tests before this one actually passed
expect(cars).to.length(1);
expect(cars[0]).to.have.property("name", "Ferrari");
const fruits = await connection.entityManager.find(Fruit);
const fruits = await connection.manager.find(Fruit);
expect(fruits).to.length(1);
expect(fruits[0]).to.have.property("name", "Banana");
@ -53,20 +53,20 @@ describe("github issues > #363 Can't save 2 unrelated entity types in a single p
const fruit2 = new Fruit();
fruit2.name = "Apple";
const [savedFruit] = await connection.entityManager.save([fruit, fruit2]);
const [savedFruit] = await connection.manager.save([fruit, fruit2]);
const car = new Car();
car.name = "Ferrari";
const savedCar = await connection.entityManager.save(car);
const savedCar = await connection.manager.save(car);
await connection.entityManager.remove([savedCar, savedFruit]);
await connection.manager.remove([savedCar, savedFruit]);
const cars = await connection.entityManager.find(Car);
const cars = await connection.manager.find(Car);
expect(cars).to.length(0);
const fruits = await connection.entityManager.find(Fruit);
const fruits = await connection.manager.find(Fruit);
expect(fruits).to.length(1);
expect(fruits[0]).to.have.property("name", "Apple");

View File

@ -35,13 +35,13 @@ describe("github issues > #47 wrong sql syntax when loading lazy relation", () =
post2.category = Promise.resolve(category2);
// persist
await connection.entityManager.save(category1);
await connection.entityManager.save(post1);
await connection.entityManager.save(category2);
await connection.entityManager.save(post2);
await connection.manager.save(category1);
await connection.manager.save(post1);
await connection.manager.save(category2);
await connection.manager.save(post2);
// check that all persisted objects exist
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.getMany();

View File

@ -41,11 +41,11 @@ describe("github issues > #58 relations with multiple primary keys", () => {
postCategory2.category = category2;
postCategory2.post = post;
await connection.entityManager.save(postCategory1);
await connection.entityManager.save(postCategory2);
await connection.manager.save(postCategory1);
await connection.manager.save(postCategory2);
// check that all persisted objects exist
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.categories", "postCategory")
.innerJoinAndSelect("postCategory.category", "category")

View File

@ -30,16 +30,16 @@ describe("github issues > #70 cascade deleting works incorrect", () => {
post.categories = [category1, category2];
// persist post (other are persisted by cascades)
await connection.entityManager.save(post);
await connection.manager.save(post);
// check that all persisted objects exist
const loadedPost = await connection.entityManager
const loadedPost = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.categories", "category")
.orderBy("post.id, category.id")
.getOne()!;
const loadedCategories = await connection.entityManager
const loadedCategories = await connection.manager
.createQueryBuilder(Category, "category")
.orderBy("category.id")
.getMany();
@ -56,14 +56,14 @@ describe("github issues > #70 cascade deleting works incorrect", () => {
loadedCategories[1].id.should.be.equal(2);
// now remove post. categories should be removed too
await connection.entityManager.remove(post);
await connection.manager.remove(post);
// load them again to make sure they are not exist anymore
const loadedPosts2 = await connection.entityManager
const loadedPosts2 = await connection.manager
.createQueryBuilder(Post, "post")
.getMany();
const loadedCategories2 = await connection.entityManager
const loadedCategories2 = await connection.manager
.createQueryBuilder(Category, "category")
.getMany();

View File

@ -28,9 +28,9 @@ describe("github issues > #71 ManyToOne relation with custom column name persist
artikel.saison = "------";
artikel.kollektion = kollektion;
await connection.entityManager.save(artikel);
await connection.manager.save(artikel);
const loadedArtikel = await connection.entityManager
const loadedArtikel = await connection.manager
.createQueryBuilder(Artikel, "artikel")
.innerJoinAndSelect("artikel.kollektion", "kollektion")
.where("artikel.id=:id", { id: 1 })

View File

@ -18,7 +18,7 @@ describe("github issues > #80 repository.persist fails when empty array is sent
it("should persist successfully and return persisted entity", () => Promise.all(connections.map(async connection => {
const post = new Post();
post.title = "Hello Post #1";
const returnedPost = await connection.entityManager.save(post);
const returnedPost = await connection.manager.save(post);
expect(returnedPost).not.to.be.empty;
returnedPost.should.be.equal(post);
@ -26,7 +26,7 @@ describe("github issues > #80 repository.persist fails when empty array is sent
it("should not fail if empty array is given to persist method", () => Promise.all(connections.map(async connection => {
const posts: Post[] = [];
const returnedPosts = await connection.entityManager.save(posts);
const returnedPosts = await connection.manager.save(posts);
expect(returnedPosts).not.to.be.undefined;
returnedPosts.should.be.equal(posts);
})));

View File

@ -20,10 +20,10 @@ describe("other issues > column with getter / setter should work", () => {
const post = new Post();
post.title = "Super title";
post.text = "About this post";
await connection.entityManager.save(post);
await connection.manager.save(post);
const loadedPost = await connection
.entityManager
.manager
.createQueryBuilder(Post, "post")
.where("post.id = :id", { id: 1 })
.getOne();

View File

@ -20,27 +20,27 @@ describe("other issues > entity change in listeners should affect persistence",
// insert a post
const post = new Post();
post.title = "hello";
await connection.entityManager.save(post);
await connection.manager.save(post);
// check if it was inserted correctly
const loadedPost = await connection.entityManager.findOne(Post);
const loadedPost = await connection.manager.findOne(Post);
expect(loadedPost).not.to.be.empty;
loadedPost!.title.should.be.equal("hello");
// now update some property and let update listener trigger
loadedPost!.active = true;
await connection.entityManager.save(loadedPost!);
await connection.manager.save(loadedPost!);
// check if update listener was triggered and entity was really updated by the changes in the listener
const loadedUpdatedPost = await connection.entityManager.findOne(Post);
const loadedUpdatedPost = await connection.manager.findOne(Post);
expect(loadedUpdatedPost).not.to.be.empty;
loadedUpdatedPost!.title.should.be.equal("hello!");
await connection.entityManager.save(loadedPost!);
await connection.entityManager.save(loadedPost!);
await connection.entityManager.save(loadedPost!);
await connection.entityManager.save(loadedPost!);
await connection.manager.save(loadedPost!);
await connection.manager.save(loadedPost!);
await connection.manager.save(loadedPost!);
await connection.manager.save(loadedPost!);
})));

View File

@ -19,11 +19,11 @@ describe("other issues > joining empty relations", () => {
const post = new Post();
post.title = "Hello Post";
await connection.entityManager.save(post);
await connection.manager.save(post);
// check if ordering by main object works correctly
const loadedPosts1 = await connection.entityManager
const loadedPosts1 = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.getMany();
@ -41,11 +41,11 @@ describe("other issues > joining empty relations", () => {
const post = new Post();
post.title = "Hello Post";
await connection.entityManager.save(post);
await connection.manager.save(post);
// check if ordering by main object works correctly
const loadedPosts1 = await connection.entityManager
const loadedPosts1 = await connection.manager
.createQueryBuilder(Post, "post")
.leftJoinAndSelect("post.categories", "categories")
.leftJoinAndSelect("categories.authors", "authors")

View File

@ -31,14 +31,14 @@ describe("other issues > using limit in conjunction with order by", () => {
category.name = "category #" + i;
post.categories.push(category);
}
promises.push(connection.entityManager.save(post));
promises.push(connection.manager.save(post));
}
await Promise.all(promises);
// check if ordering by main object works correctly
const loadedPosts1 = await connection.entityManager
const loadedPosts1 = await connection.manager
.createQueryBuilder(Post, "post")
.innerJoinAndSelect("post.categories", "categories")
.take(10)