Comparing version 0.0.2-alpha.48 to 0.0.2-alpha.49
/** | ||
* Used to mark simple objects with any string keys. | ||
* Interface of the simple literal object with any string keys. | ||
*/ | ||
@@ -4,0 +4,0 @@ export interface ObjectLiteral { |
import { Driver } from "../driver/Driver"; | ||
import { ConnectionOptions } from "./ConnectionOptions"; | ||
import { Repository } from "../repository/Repository"; | ||
import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
import { ConstructorFunction } from "../common/ConstructorFunction"; | ||
import { ObjectType } from "../common/ObjectType"; | ||
import { EntityManager } from "../entity-manager/EntityManager"; | ||
@@ -11,11 +9,15 @@ import { EntityMetadataCollection } from "../metadata-args/collection/EntityMetadataCollection"; | ||
import { TreeRepository } from "../repository/TreeRepository"; | ||
import { ReactiveTreeRepository } from "../repository/ReactiveTreeRepository"; | ||
import { TreeReactiveRepository } from "../repository/TreeReactiveRepository"; | ||
import { EntitySchema } from "../metadata/entity-schema/EntitySchema"; | ||
import { Broadcaster } from "../subscriber/Broadcaster"; | ||
import { SpecificRepository } from "../repository/SpecificRepository"; | ||
import { SpecificReactiveRepository } from "../repository/ReactiveSpecificRepository"; | ||
import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
/** | ||
* A single connection instance to the database. | ||
* Each connection has its own entity manager, repositories, subscribers and metadatas. | ||
* Each connection has its own entity manager, repositories, broadcaster and entity metadatas. | ||
*/ | ||
export declare class Connection { | ||
/** | ||
* The name of the connection. | ||
* Connection name. | ||
*/ | ||
@@ -32,2 +34,6 @@ readonly name: string; | ||
/** | ||
* Used to broadcast connection events. | ||
*/ | ||
readonly broadcaster: Broadcaster; | ||
/** | ||
* Gets EntityManager of this connection. | ||
@@ -41,22 +47,14 @@ */ | ||
/** | ||
* Used to initialize lazy relations. | ||
* Stores all registered metadatas with their repositories. | ||
*/ | ||
private readonly lazyRelationsWrapper; | ||
private readonly repositoryForMetadatas; | ||
/** | ||
* All entity listener metadatas that are registered for this connection. | ||
* Entity listeners that are registered for this connection. | ||
*/ | ||
private readonly entityListeners; | ||
/** | ||
* All subscribers that are registered for this connection. | ||
* Entity subscribers that are registered for this connection. | ||
*/ | ||
private readonly entitySubscribers; | ||
/** | ||
* Used to broadcast connection events. | ||
*/ | ||
private readonly broadcaster; | ||
/** | ||
* Connection options. | ||
*/ | ||
private readonly options; | ||
/** | ||
* Registered entity classes to be used for this connection. | ||
@@ -78,10 +76,2 @@ */ | ||
/** | ||
* All connection's repositories. | ||
*/ | ||
private readonly repositories; | ||
/** | ||
* All connection's reactive repositories. | ||
*/ | ||
private readonly reactiveRepositories; | ||
/** | ||
* Naming strategy to be used in this connection. | ||
@@ -94,14 +84,14 @@ */ | ||
private _isConnected; | ||
constructor(name: string, driver: Driver, options: ConnectionOptions); | ||
constructor(name: string, driver: Driver); | ||
/** | ||
* Returns true if connection to the database already established for this connection. | ||
* Indicates if connection to the database already established for this connection. | ||
*/ | ||
readonly isConnected: boolean; | ||
/** | ||
* Entity manager allows to work with any entity of your connection. | ||
* Gets entity manager that allows to perform repository operations with any entity of this connection. | ||
*/ | ||
readonly entityManager: EntityManager; | ||
/** | ||
* Entity manager allows to work with any entity of your connection. | ||
* This version of entity manager is reactive - works with Observables instead of promises. | ||
* Gets entity manager that allows to perform repository operations with any entity of this connection. | ||
* This version of entity manager is reactive - works with Observables instead of Promises. | ||
*/ | ||
@@ -114,6 +104,12 @@ readonly reactiveEntityManager: ReactiveEntityManager; | ||
/** | ||
* Closes this connection. | ||
* Closes connection with the database. | ||
* Once connection is closed, you cannot use repositories and perform any operations except | ||
* opening connection again. | ||
*/ | ||
close(): Promise<void>; | ||
/** | ||
* Drops the database and all its data. | ||
*/ | ||
dropDatabase(): Promise<void>; | ||
/** | ||
* Creates database schema for all entities registered in this connection. | ||
@@ -123,94 +119,128 @@ */ | ||
/** | ||
* Imports entities from the given paths (directories) for the current connection. | ||
* Imports entities from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
importEntitiesFromDirectories(paths: string[]): Promise<this>; | ||
/** | ||
* Imports entity schemas from the given paths (directories) for the current connection. | ||
* Imports entity schemas from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
importEntitySchemaFromDirectories(paths: string[]): Promise<this>; | ||
/** | ||
* Imports subscribers from the given paths (directories) for the current connection. | ||
* Imports subscribers from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
importSubscribersFromDirectories(paths: string[]): Promise<this>; | ||
/** | ||
* Imports naming strategies from the given paths (directories) for the current connection. | ||
* Imports naming strategies from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
importNamingStrategiesFromDirectories(paths: string[]): Promise<this>; | ||
/** | ||
* Imports entities for the current connection. | ||
* Imports entities and registers them in the current connection. | ||
*/ | ||
importEntities(entities: Function[]): Promise<this>; | ||
/** | ||
* Imports schemas for the current connection. | ||
* Imports schemas and registers them in the current connection. | ||
*/ | ||
importEntitySchemas(schemas: EntitySchema[]): Promise<this>; | ||
/** | ||
* Imports entities for the given connection. If connection name is not given then default connection is used. | ||
* Imports subscribers and registers them in the current connection. | ||
*/ | ||
importSubscribers(subscriberClasses: Function[]): Promise<this>; | ||
/** | ||
* Imports entities for the current connection. | ||
* Imports naming strategies and registers them in the current connection. | ||
*/ | ||
importNamingStrategies(strategies: Function[]): Promise<this>; | ||
/** | ||
* Sets given naming strategy to be used. Naming strategy must be set to be used before connection is established. | ||
* Sets given naming strategy to be used. | ||
* Naming strategy must be set to be used before connection is established. | ||
*/ | ||
useNamingStrategy(name: string): this; | ||
/** | ||
* Sets given naming strategy to be used. Naming strategy must be set to be used before connection is established. | ||
* Sets given naming strategy to be used. | ||
* Naming strategy must be set to be used before connection is established. | ||
*/ | ||
useNamingStrategy(strategy: Function): this; | ||
/** | ||
* Gets the entity metadata of the given entity target. | ||
* Gets the entity metadata of the given entity class. | ||
*/ | ||
getMetadata(entity: Function): EntityMetadata; | ||
/** | ||
* Gets repository for the given entity class. | ||
* Gets the entity metadata of the given entity name. | ||
*/ | ||
getRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): Repository<Entity>; | ||
getMetadata(entity: string): EntityMetadata; | ||
/** | ||
* Gets repository for the given entity name. | ||
* Gets repository for the given entity class. | ||
*/ | ||
getRepository<Entity>(entityClass: string): Repository<Entity>; | ||
getRepository<Entity>(entityClass: ObjectType<Entity>): Repository<Entity>; | ||
/** | ||
* Gets repository for the given entity name. | ||
*/ | ||
getRepository<Entity>(entityClassOrName: ConstructorFunction<Entity> | Function | string): Repository<Entity>; | ||
getRepository<Entity>(entityName: string): Repository<Entity>; | ||
/** | ||
* Gets tree repository for the given entity class. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
*/ | ||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): TreeRepository<Entity>; | ||
getTreeRepository<Entity>(entityClass: ObjectType<Entity>): TreeRepository<Entity>; | ||
/** | ||
* Gets tree repository for the given entity name. | ||
* Gets tree repository for the given entity class. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
*/ | ||
getTreeRepository<Entity>(entityName: string): TreeRepository<Entity>; | ||
/** | ||
* Gets tree repository for the given entity name. | ||
* Gets specific repository for the given entity class. | ||
* SpecificRepository is a special repository that contains specific and non standard repository methods. | ||
*/ | ||
getTreeRepository<Entity>(entityClassOrName: ConstructorFunction<Entity> | Function | string): Repository<Entity>; | ||
getSpecificRepository<Entity>(entityClass: ObjectType<Entity>): SpecificRepository<Entity>; | ||
/** | ||
* Gets specific repository for the given entity name. | ||
* SpecificRepository is a special repository that contains specific and non standard repository methods. | ||
*/ | ||
getSpecificRepository<Entity>(entityName: string): SpecificRepository<Entity>; | ||
/** | ||
* Gets reactive repository for the given entity class. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): ReactiveRepository<Entity>; | ||
getReactiveRepository<Entity>(entityClass: ObjectType<Entity>): ReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive repository for the given entity name. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveRepository<Entity>(entityName: string): ReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive repository for the given entity name. | ||
*/ | ||
getReactiveRepository<Entity>(entityClassOrName: ConstructorFunction<Entity> | Function | string): ReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive tree repository for the given entity class. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveTreeRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): ReactiveTreeRepository<Entity>; | ||
getReactiveTreeRepository<Entity>(entityClass: ObjectType<Entity>): TreeReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive tree repository for the given entity name. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveTreeRepository<Entity>(entityName: string): ReactiveTreeRepository<Entity>; | ||
getReactiveTreeRepository<Entity>(entityName: string): TreeReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive tree repository for the given entity name. | ||
* Gets specific repository for the given entity class. | ||
* SpecificReactiveRepository is a special repository that contains specific and non standard repository methods. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveTreeRepository<Entity>(entityClassOrName: ConstructorFunction<Entity> | Function | string): ReactiveTreeRepository<Entity>; | ||
getSpecificReactiveRepository<Entity>(entityClass: ObjectType<Entity>): SpecificReactiveRepository<Entity>; | ||
/** | ||
* Gets specific repository for the given entity name. | ||
* SpecificReactiveRepository is a special repository that contains specific and non standard repository methods. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getSpecificReactiveRepository<Entity>(entityName: string): SpecificReactiveRepository<Entity>; | ||
/** | ||
* Finds repository with metadata of the given entity class or name. | ||
*/ | ||
private findRepositoryForMetadata(entityClassOrName, options?); | ||
/** | ||
* Builds all registered metadatas. | ||
@@ -223,6 +253,2 @@ */ | ||
private createNamingStrategy(); | ||
/** | ||
* Creates repository and reactive repository for the given entity metadata. | ||
*/ | ||
private createRepository(metadata); | ||
} |
@@ -10,3 +10,2 @@ "use strict"; | ||
}; | ||
const Repository_1 = require("../repository/Repository"); | ||
const RepositoryNotFoundError_1 = require("./error/RepositoryNotFoundError"); | ||
@@ -23,8 +22,5 @@ const EntityListenerMetadata_1 = require("../metadata/EntityListenerMetadata"); | ||
const CannotConnectAlreadyConnectedError_1 = require("./error/CannotConnectAlreadyConnectedError"); | ||
const ReactiveRepository_1 = require("../repository/ReactiveRepository"); | ||
const NamingStrategyNotFoundError_1 = require("./error/NamingStrategyNotFoundError"); | ||
const EntityManagerFactory_1 = require("../entity-manager/EntityManagerFactory"); | ||
const RepositoryFactory_1 = require("../repository/RepositoryFactory"); | ||
const SchemaCreatorFactory_1 = require("../schema-creator/SchemaCreatorFactory"); | ||
const ReactiveRepositoryNotFoundError_1 = require("./error/ReactiveRepositoryNotFoundError"); | ||
const RepositoryNotTreeError_1 = require("./error/RepositoryNotTreeError"); | ||
@@ -36,5 +32,6 @@ const CannotSyncNotConnectedError_1 = require("./error/CannotSyncNotConnectedError"); | ||
const LazyRelationsWrapper_1 = require("../repository/LazyRelationsWrapper"); | ||
const RepositoryForMetadata_1 = require("../repository/RepositoryForMetadata"); | ||
/** | ||
* A single connection instance to the database. | ||
* Each connection has its own entity manager, repositories, subscribers and metadatas. | ||
* Each connection has its own entity manager, repositories, broadcaster and entity metadatas. | ||
*/ | ||
@@ -45,3 +42,3 @@ class Connection { | ||
// ------------------------------------------------------------------------- | ||
constructor(name, driver, options) { | ||
constructor(name, driver) { | ||
/** | ||
@@ -52,7 +49,11 @@ * All entity metadatas that are registered for this connection. | ||
/** | ||
* All entity listener metadatas that are registered for this connection. | ||
* Stores all registered metadatas with their repositories. | ||
*/ | ||
this.repositoryForMetadatas = []; | ||
/** | ||
* Entity listeners that are registered for this connection. | ||
*/ | ||
this.entityListeners = []; | ||
/** | ||
* All subscribers that are registered for this connection. | ||
* Entity subscribers that are registered for this connection. | ||
*/ | ||
@@ -77,10 +78,2 @@ this.entitySubscribers = []; | ||
/** | ||
* All connection's repositories. | ||
*/ | ||
this.repositories = []; | ||
/** | ||
* All connection's reactive repositories. | ||
*/ | ||
this.reactiveRepositories = []; | ||
/** | ||
* Indicates if connection has been done or not. | ||
@@ -91,8 +84,5 @@ */ | ||
this.driver = driver; | ||
this.driver.connectionOptions = options; | ||
this.options = options; | ||
this._entityManager = index_1.getFromContainer(EntityManagerFactory_1.EntityManagerFactory).createEntityManager(this); | ||
this._reactiveEntityManager = index_1.getFromContainer(EntityManagerFactory_1.EntityManagerFactory).createReactiveEntityManager(this); | ||
this.broadcaster = index_1.getFromContainer(BroadcasterFactory_1.BroadcasterFactory).createBroadcaster(this.entityMetadatas, this.entitySubscribers, this.entityListeners); | ||
this.lazyRelationsWrapper = new LazyRelationsWrapper_1.LazyRelationsWrapper(this.driver, this.entityMetadatas, this.broadcaster); | ||
} | ||
@@ -103,3 +93,3 @@ // ------------------------------------------------------------------------- | ||
/** | ||
* Returns true if connection to the database already established for this connection. | ||
* Indicates if connection to the database already established for this connection. | ||
*/ | ||
@@ -110,3 +100,3 @@ get isConnected() { | ||
/** | ||
* Entity manager allows to work with any entity of your connection. | ||
* Gets entity manager that allows to perform repository operations with any entity of this connection. | ||
*/ | ||
@@ -119,4 +109,4 @@ get entityManager() { | ||
/** | ||
* Entity manager allows to work with any entity of your connection. | ||
* This version of entity manager is reactive - works with Observables instead of promises. | ||
* Gets entity manager that allows to perform repository operations with any entity of this connection. | ||
* This version of entity manager is reactive - works with Observables instead of Promises. | ||
*/ | ||
@@ -144,5 +134,2 @@ get reactiveEntityManager() { | ||
this._isConnected = true; | ||
// second build schema | ||
if (this.options.autoSchemaCreate === true) | ||
yield this.syncSchema(); | ||
return this; | ||
@@ -152,3 +139,5 @@ }); | ||
/** | ||
* Closes this connection. | ||
* Closes connection with the database. | ||
* Once connection is closed, you cannot use repositories and perform any operations except | ||
* opening connection again. | ||
*/ | ||
@@ -164,2 +153,10 @@ close() { | ||
/** | ||
* Drops the database and all its data. | ||
*/ | ||
dropDatabase() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.driver.clearDatabase(); | ||
}); | ||
} | ||
/** | ||
* Creates database schema for all entities registered in this connection. | ||
@@ -172,3 +169,3 @@ */ | ||
if (dropBeforeSync) | ||
yield this.driver.clearDatabase(); | ||
yield this.dropDatabase(); | ||
const schemaBuilder = this.driver.createSchemaBuilder(); | ||
@@ -181,3 +178,3 @@ const schemaCreatorFactory = index_1.getFromContainer(SchemaCreatorFactory_1.SchemaCreatorFactory); | ||
/** | ||
* Imports entities from the given paths (directories) for the current connection. | ||
* Imports entities from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
@@ -191,3 +188,3 @@ importEntitiesFromDirectories(paths) { | ||
/** | ||
* Imports entity schemas from the given paths (directories) for the current connection. | ||
* Imports entity schemas from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
@@ -201,3 +198,3 @@ importEntitySchemaFromDirectories(paths) { | ||
/** | ||
* Imports subscribers from the given paths (directories) for the current connection. | ||
* Imports subscribers from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
@@ -211,3 +208,3 @@ importSubscribersFromDirectories(paths) { | ||
/** | ||
* Imports naming strategies from the given paths (directories) for the current connection. | ||
* Imports naming strategies from the given paths (directories) and registers them in the current connection. | ||
*/ | ||
@@ -221,3 +218,3 @@ importNamingStrategiesFromDirectories(paths) { | ||
/** | ||
* Imports entities for the current connection. | ||
* Imports entities and registers them in the current connection. | ||
*/ | ||
@@ -233,3 +230,3 @@ importEntities(entities) { | ||
/** | ||
* Imports schemas for the current connection. | ||
* Imports schemas and registers them in the current connection. | ||
*/ | ||
@@ -245,3 +242,3 @@ importEntitySchemas(schemas) { | ||
/** | ||
* Imports entities for the given connection. If connection name is not given then default connection is used. | ||
* Imports subscribers and registers them in the current connection. | ||
*/ | ||
@@ -257,3 +254,3 @@ importSubscribers(subscriberClasses) { | ||
/** | ||
* Imports entities for the current connection. | ||
* Imports naming strategies and registers them in the current connection. | ||
*/ | ||
@@ -269,3 +266,4 @@ importNamingStrategies(strategies) { | ||
/** | ||
* Sets given naming strategy to be used. Naming strategy must be set to be used before connection is established. | ||
* Sets given naming strategy to be used. | ||
* Naming strategy must be set to be used before connection is established. | ||
*/ | ||
@@ -279,3 +277,3 @@ useNamingStrategy(strategyClassOrName) { | ||
/** | ||
* Gets the entity metadata of the given entity target. | ||
Gets entity metadata for the given entity class or schema name. | ||
*/ | ||
@@ -289,46 +287,59 @@ getMetadata(entity) { | ||
getRepository(entityClassOrName) { | ||
if (!this.isConnected) | ||
throw new NoConnectionForRepositoryError_1.NoConnectionForRepositoryError(this.name); | ||
if (!this.entityMetadatas.hasTarget(entityClassOrName)) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName); | ||
const repository = this.repositories.find(repository => Repository_1.Repository.ownsMetadata(repository, metadata)); | ||
if (!repository) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
return repository; | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName); | ||
return repositoryForMetadata.repository; | ||
} | ||
/** | ||
* Gets tree repository for the given entity class or name. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
*/ | ||
getTreeRepository(entityClassOrName) { | ||
if (!this.isConnected) | ||
throw new NoConnectionForRepositoryError_1.NoConnectionForRepositoryError(this.name); | ||
if (!this.entityMetadatas.hasTarget(entityClassOrName)) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName); | ||
const repository = this.repositories.find(repository => Repository_1.Repository.ownsMetadata(repository, metadata)); | ||
if (!repository) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
if (!metadata.table.isClosure) | ||
throw new RepositoryNotTreeError_1.RepositoryNotTreeError(entityClassOrName); | ||
return repository; | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName, { checkIfTreeTable: true }); | ||
return repositoryForMetadata.repository; | ||
} | ||
/** | ||
* Gets reactive repository for the given entity class. | ||
* Gets specific repository for the given entity class or name. | ||
* SpecificRepository is a special repository that contains specific and non standard repository methods. | ||
*/ | ||
getSpecificRepository(entityClassOrName) { | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName); | ||
return repositoryForMetadata.specificRepository; | ||
} | ||
/** | ||
* Gets reactive repository for the given entity class or name. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveRepository(entityClassOrName) { | ||
if (!this.isConnected) | ||
throw new NoConnectionForRepositoryError_1.NoConnectionForRepositoryError(this.name); | ||
if (!this.entityMetadatas.hasTarget(entityClassOrName)) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName); | ||
const repository = this.reactiveRepositories.find(repository => ReactiveRepository_1.ReactiveRepository.ownsMetadata(repository, metadata)); | ||
if (!repository) | ||
throw new ReactiveRepositoryNotFoundError_1.ReactiveRepositoryNotFoundError(this.name, entityClassOrName); | ||
return repository; | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName); | ||
return repositoryForMetadata.reactiveRepository; | ||
} | ||
/** | ||
* Gets reactive tree repository for the given entity class. | ||
* Gets reactive tree repository for the given entity class or name. | ||
* Only tree-type entities can have a TreeRepository, | ||
* like ones decorated with @ClosureTable decorator. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getReactiveTreeRepository(entityClassOrName) { | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName, { checkIfTreeTable: true }); | ||
return repositoryForMetadata.reactiveRepository; | ||
} | ||
/** | ||
* Gets specific repository for the given entity class or name. | ||
* SpecificReactiveRepository is a special repository that contains specific and non standard repository methods. | ||
* Reactive repositories has same functionality as regular repositories, | ||
* the only difference is that reactive repository methods return Observable instead of Promise. | ||
*/ | ||
getSpecificReactiveRepository(entityClassOrName) { | ||
const repositoryForMetadata = this.findRepositoryForMetadata(entityClassOrName); | ||
return repositoryForMetadata.specificReactiveRepository; | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Private Methods | ||
// ------------------------------------------------------------------------- | ||
/** | ||
* Finds repository with metadata of the given entity class or name. | ||
*/ | ||
findRepositoryForMetadata(entityClassOrName, options) { | ||
if (!this.isConnected) | ||
@@ -339,12 +350,9 @@ throw new NoConnectionForRepositoryError_1.NoConnectionForRepositoryError(this.name); | ||
const metadata = this.entityMetadatas.findByTarget(entityClassOrName); | ||
const repository = this.reactiveRepositories.find(repository => ReactiveRepository_1.ReactiveRepository.ownsMetadata(repository, metadata)); | ||
if (!repository) | ||
const repositoryForMetadata = this.repositoryForMetadatas.find(metadataRepository => metadataRepository.metadata === metadata); | ||
if (!repositoryForMetadata) | ||
throw new RepositoryNotFoundError_1.RepositoryNotFoundError(this.name, entityClassOrName); | ||
if (!metadata.table.isClosure) | ||
if (options && options.checkIfTreeTable && !metadata.table.isClosure) | ||
throw new RepositoryNotTreeError_1.RepositoryNotTreeError(entityClassOrName); | ||
return repository; | ||
return repositoryForMetadata; | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Private Methods | ||
// ------------------------------------------------------------------------- | ||
/** | ||
@@ -355,2 +363,3 @@ * Builds all registered metadatas. | ||
const namingStrategy = this.createNamingStrategy(); | ||
const lazyRelationsWrapper = new LazyRelationsWrapper_1.LazyRelationsWrapper(this.driver, this.entityMetadatas, this.broadcaster); | ||
// take imported event subscribers | ||
@@ -374,6 +383,6 @@ if (this.subscriberClasses && this.subscriberClasses.length) { | ||
index_1.getFromContainer(EntityMetadataBuilder_1.EntityMetadataBuilder) | ||
.buildFromMetadataArgsStorage(this.lazyRelationsWrapper, namingStrategy, this.entityClasses) | ||
.buildFromMetadataArgsStorage(lazyRelationsWrapper, namingStrategy, this.entityClasses) | ||
.forEach(metadata => { | ||
this.entityMetadatas.push(metadata); | ||
this.createRepository(metadata); | ||
this.repositoryForMetadatas.push(new RepositoryForMetadata_1.RepositoryForMetadata(this, metadata)); | ||
}); | ||
@@ -384,6 +393,6 @@ } | ||
index_1.getFromContainer(EntityMetadataBuilder_1.EntityMetadataBuilder) | ||
.buildFromSchemas(this.lazyRelationsWrapper, namingStrategy, this.entitySchemas) | ||
.buildFromSchemas(lazyRelationsWrapper, namingStrategy, this.entitySchemas) | ||
.forEach(metadata => { | ||
this.entityMetadatas.push(metadata); | ||
this.createRepository(metadata); | ||
this.repositoryForMetadatas.push(new RepositoryForMetadata_1.RepositoryForMetadata(this, metadata)); | ||
}); | ||
@@ -417,20 +426,2 @@ } | ||
} | ||
/** | ||
* Creates repository and reactive repository for the given entity metadata. | ||
*/ | ||
createRepository(metadata) { | ||
const repositoryFactory = index_1.getFromContainer(RepositoryFactory_1.RepositoryFactory); | ||
if (metadata.table.isClosure) { | ||
const repository = repositoryFactory.createTreeRepository(this, this.broadcaster, this.entityMetadatas, metadata); | ||
const reactiveRepository = repositoryFactory.createReactiveTreeRepository(repository); | ||
this.repositories.push(repository); | ||
this.reactiveRepositories.push(reactiveRepository); | ||
} | ||
else { | ||
const repository = repositoryFactory.createRepository(this, this.broadcaster, this.entityMetadatas, metadata); | ||
const reactiveRepository = repositoryFactory.createReactiveRepository(repository); | ||
this.repositories.push(repository); | ||
this.reactiveRepositories.push(reactiveRepository); | ||
} | ||
} | ||
} | ||
@@ -437,0 +428,0 @@ exports.Connection = Connection; |
@@ -0,54 +1,66 @@ | ||
import { DriverOptions } from "../driver/DriverOptions"; | ||
import { EntitySchema } from "../metadata/entity-schema/EntitySchema"; | ||
/** | ||
* Connection options passed to the connection. | ||
* New connection options. | ||
*/ | ||
export interface ConnectionOptions { | ||
/** | ||
* Url to where perform connection. | ||
* Database connection options. | ||
*/ | ||
url?: string; | ||
driver: DriverOptions; | ||
/** | ||
* Database host. | ||
* Connection name. If connection name is not given then it will be called "default". | ||
* Different connections must have different names. | ||
*/ | ||
host?: string; | ||
connectionName?: string; | ||
/** | ||
* Database host port. | ||
* Name of the naming strategy or target class of the naming strategy to be used for this connection. | ||
*/ | ||
port?: number; | ||
usedNamingStrategy?: string | Function; | ||
/** | ||
* Database username. | ||
* Drops the schema each time connection is being established. | ||
* Be careful with this option and don't use this in production - otherwise you'll loose all your production data. | ||
* This option is useful during debug and development. | ||
*/ | ||
username?: string; | ||
dropSchemaOnConnection?: boolean; | ||
/** | ||
* Database password. | ||
* Indicates if database schema should be auto created on every application launch. | ||
*/ | ||
password?: string; | ||
autoSchemaCreate?: boolean; | ||
/** | ||
* Database name to connect to. | ||
* Entities to be loaded for the this connection. | ||
*/ | ||
database?: string; | ||
entities?: Function[]; | ||
/** | ||
* Indicates if database schema should be auto created every time application launch. | ||
* Subscribers to be loaded for the this connection. | ||
*/ | ||
autoSchemaCreate?: boolean; | ||
subscribers?: Function[]; | ||
/** | ||
* Logging options. | ||
* Naming strategies to be loaded for the this connection. | ||
*/ | ||
logging?: { | ||
/** | ||
* Some specific logger to be used. By default it is a console. | ||
*/ | ||
logger?: (message: any, level: string) => void; | ||
/** | ||
* Used if you want to log every executed query. | ||
*/ | ||
logQueries?: boolean; | ||
/** | ||
* Used if you want to log only failed query. | ||
*/ | ||
logOnlyFailedQueries?: boolean; | ||
/** | ||
* Used if you want to log error of the failed query. | ||
*/ | ||
logFailedQueryError?: boolean; | ||
}; | ||
namingStrategies?: Function[]; | ||
/** | ||
* Entity schemas to be loaded for the this connection. | ||
*/ | ||
entitySchemas?: EntitySchema[]; | ||
/** | ||
* List of files with entities from where they will be loaded. | ||
* Glob patterns are supported. | ||
*/ | ||
entityDirectories?: string[]; | ||
/** | ||
* List of files with subscribers from where they will be loaded. | ||
* Glob patterns are supported. | ||
*/ | ||
subscriberDirectories?: string[]; | ||
/** | ||
* List of files with naming strategies from where they will be loaded. | ||
* Glob patterns are supported. | ||
*/ | ||
namingStrategyDirectories?: string[]; | ||
/** | ||
* List of files with entity schemas from where they will be loaded. | ||
* Glob patterns are supported. | ||
*/ | ||
entitySchemaDirectories?: string[]; | ||
} |
@@ -1,2 +0,3 @@ | ||
import { ConstructorFunction } from "../common/ConstructorFunction"; | ||
/// <reference types="chai" /> | ||
import { ObjectType } from "../common/ObjectType"; | ||
/** | ||
@@ -7,2 +8,2 @@ * Property in entity can be marked as Embedded, and on persist all columns from the embedded are mapped to the | ||
*/ | ||
export declare function Embedded<T>(typeFunction: (type?: any) => ConstructorFunction<T>): (object: Object, propertyName: string) => void; | ||
export declare function Embedded<T>(typeFunction: (type?: any) => ObjectType<T>): (object: Object, propertyName: string) => void; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
export declare class AutoIncrementOnlyForPrimaryError extends Error { | ||
@@ -2,0 +3,0 @@ name: string; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
export declare class ColumnTypeUndefinedError extends Error { | ||
@@ -2,0 +3,0 @@ name: string; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
export declare class PrimaryColumnCannotBeNullableError extends Error { | ||
@@ -2,0 +3,0 @@ name: string; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Fields that needs to be indexed must be marked with this decorator. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied after this entity insertion. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied after entity is loaded. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied after this entity removal. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied after this entity update. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied before this entity insertion. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied before this entity removal. |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
/** | ||
@@ -2,0 +3,0 @@ * Calls a method on which this decorator is applied before this entity update. |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
primaryKeys?: string | ((object: any) => string | any)[]; | ||
primaryKeys?: (string | ((object: any) => string | any))[]; | ||
/** | ||
@@ -11,0 +11,0 @@ * Specifies a property name by which queries will perform ordering by default when fetching rows. |
import { RelationOptions } from "../options/RelationOptions"; | ||
import { ConstructorFunction } from "../../common/ConstructorFunction"; | ||
import { ObjectType } from "../../common/ObjectType"; | ||
/** | ||
@@ -8,3 +8,3 @@ * Many-to-many is a type of relationship when Entity1 can have multiple instances of Entity2, and Entity2 can have | ||
*/ | ||
export declare function ManyToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T>, options?: RelationOptions): Function; | ||
export declare function ManyToMany<T>(typeFunction: (type?: any) => ObjectType<T>, options?: RelationOptions): Function; | ||
/** | ||
@@ -15,2 +15,2 @@ * Many-to-many is a type of relationship when Entity1 can have multiple instances of Entity2, and Entity2 can have | ||
*/ | ||
export declare function ManyToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; | ||
export declare function ManyToMany<T>(typeFunction: (type?: any) => ObjectType<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; |
import { RelationOptions } from "../options/RelationOptions"; | ||
import { ConstructorFunction } from "../../common/ConstructorFunction"; | ||
import { ObjectType } from "../../common/ObjectType"; | ||
/** | ||
@@ -8,3 +8,3 @@ * Many-to-one relation allows to create type of relation when Entity1 can have single instance of Entity2, but | ||
*/ | ||
export declare function ManyToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>, options?: RelationOptions): Function; | ||
export declare function ManyToOne<T>(typeFunction: (type?: any) => ObjectType<T>, options?: RelationOptions): Function; | ||
/** | ||
@@ -15,2 +15,2 @@ * Many-to-one relation allows to create type of relation when Entity1 can have single instance of Entity2, but | ||
*/ | ||
export declare function ManyToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; | ||
export declare function ManyToOne<T>(typeFunction: (type?: any) => ObjectType<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; |
import { RelationOptions } from "../options/RelationOptions"; | ||
import { ConstructorFunction } from "../../common/ConstructorFunction"; | ||
import { ObjectType } from "../../common/ObjectType"; | ||
/** | ||
@@ -11,2 +11,2 @@ * One-to-many relation allows to create type of relation when Entity2 can have multiple instances of Entity1. | ||
*/ | ||
export declare function OneToMany<T>(typeFunction: (type?: any) => ConstructorFunction<T>, inverseSide: string | ((object: T) => any), options?: RelationOptions): Function; | ||
export declare function OneToMany<T>(typeFunction: (type?: any) => ObjectType<T>, inverseSide: string | ((object: T) => any), options?: RelationOptions): Function; |
import { RelationOptions } from "../options/RelationOptions"; | ||
import { ConstructorFunction } from "../../common/ConstructorFunction"; | ||
import { ObjectType } from "../../common/ObjectType"; | ||
/** | ||
@@ -7,3 +7,3 @@ * One-to-one relation allows to create direct relation between two entities. Entity1 have only one Entity2. | ||
*/ | ||
export declare function OneToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>, options?: RelationOptions): Function; | ||
export declare function OneToOne<T>(typeFunction: (type?: any) => ObjectType<T>, options?: RelationOptions): Function; | ||
/** | ||
@@ -13,2 +13,2 @@ * One-to-one relation allows to create direct relation between two entities. Entity1 have only one Entity2. | ||
*/ | ||
export declare function OneToOne<T>(typeFunction: (type?: any) => ConstructorFunction<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; | ||
export declare function OneToOne<T>(typeFunction: (type?: any) => ObjectType<T>, inverseSide?: string | ((object: T) => any), options?: RelationOptions): Function; |
@@ -1,3 +0,5 @@ | ||
import { ConnectionOptions } from "../connection/ConnectionOptions"; | ||
/// <reference types="chai" /> | ||
import { DriverOptions } from "./DriverOptions"; | ||
import { ColumnMetadata } from "../metadata/ColumnMetadata"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
/** | ||
@@ -7,3 +9,3 @@ * Provides base functionality for all driver implementations. | ||
export declare abstract class BaseDriver { | ||
abstract connectionOptions: ConnectionOptions; | ||
abstract connectionOptions: DriverOptions; | ||
private transactionActive; | ||
@@ -14,3 +16,3 @@ protected abstract checkIfConnectionSet(): void; | ||
*/ | ||
abstract query<T>(query: string): Promise<T>; | ||
abstract query<T>(query: string, parameters?: any[]): Promise<T>; | ||
/** | ||
@@ -24,7 +26,7 @@ * Escapes given value. | ||
update(tableName: string, valuesMap: Object, conditions: Object): Promise<void>; | ||
private escapeObjectMap(objectMap); | ||
protected escapeObjectMap(objectMap: ObjectLiteral): string[]; | ||
/** | ||
* Insert a new row into given table. | ||
*/ | ||
insert(tableName: string, keyValues: Object): Promise<any>; | ||
insert(tableName: string, keyValues: Object, idColumnName?: string): Promise<any>; | ||
/** | ||
@@ -31,0 +33,0 @@ * Deletes from the given table by a given conditions. |
@@ -50,3 +50,3 @@ "use strict"; | ||
*/ | ||
insert(tableName, keyValues) { | ||
insert(tableName, keyValues, idColumnName) { | ||
this.checkIfConnectionSet(); | ||
@@ -53,0 +53,0 @@ const columns = Object.keys(keyValues).join(","); |
@@ -0,4 +1,6 @@ | ||
/// <reference types="chai" /> | ||
import { SchemaBuilder } from "../schema-builder/SchemaBuilder"; | ||
import { ColumnMetadata } from "../metadata/ColumnMetadata"; | ||
import { ConnectionOptions } from "../connection/ConnectionOptions"; | ||
import { DriverOptions } from "./DriverOptions"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
/** | ||
@@ -19,3 +21,3 @@ * Driver communicates with specific database. | ||
*/ | ||
connectionOptions: ConnectionOptions; | ||
connectionOptions: DriverOptions; | ||
/** | ||
@@ -26,2 +28,6 @@ * Database name to which this connection is made. | ||
/** | ||
* Indicates if returned results are in lowercase. | ||
*/ | ||
readonly isResultsLowercase: boolean; | ||
/** | ||
* Creates a schema builder which can be used to build database/table schemas. | ||
@@ -41,3 +47,3 @@ */ | ||
*/ | ||
query<T>(query: string): Promise<T>; | ||
query<T>(query: string, parameters?: any[]): Promise<T>; | ||
/** | ||
@@ -48,2 +54,10 @@ * Removes all tables from the currently connected database. | ||
/** | ||
* Replaces parameters in the given sql with special character. | ||
*/ | ||
buildParameters(sql: string, parameters: ObjectLiteral): string[]; | ||
/** | ||
* Replaces parameters in the given sql with special character. | ||
*/ | ||
replaceParameters(sql: string, parameters: ObjectLiteral): string; | ||
/** | ||
* Updates rows that match given simple conditions in the given table. | ||
@@ -55,3 +69,3 @@ */ | ||
*/ | ||
insert(tableName: string, valuesMap: Object): Promise<any>; | ||
insert(tableName: string, valuesMap: Object, idColumnName?: string): Promise<any>; | ||
/** | ||
@@ -58,0 +72,0 @@ * Performs a simple DELETE query by a given conditions in a given table. |
import { Driver } from "./Driver"; | ||
import { SchemaBuilder } from "../schema-builder/SchemaBuilder"; | ||
import { BaseDriver } from "./BaseDriver"; | ||
import { ConnectionOptions } from "../connection/ConnectionOptions"; | ||
import { DriverOptions } from "./DriverOptions"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
/** | ||
@@ -9,7 +10,5 @@ * This driver organizes work with mysql database. | ||
export declare class MysqlDriver extends BaseDriver implements Driver { | ||
connectionOptions: DriverOptions; | ||
readonly isResultsLowercase: boolean; | ||
/** | ||
* Connection used in this driver. | ||
*/ | ||
connectionOptions: ConnectionOptions; | ||
/** | ||
* Mysql library. | ||
@@ -34,3 +33,3 @@ */ | ||
readonly db: string; | ||
constructor(mysql?: any); | ||
constructor(connectionOptions: DriverOptions, mysql?: any); | ||
/** | ||
@@ -55,3 +54,3 @@ * Creates a schema builder which can be used to build database/table schemas. | ||
*/ | ||
query<T>(query: string): Promise<T>; | ||
query<T>(query: string, parameters?: any[]): Promise<T>; | ||
/** | ||
@@ -61,3 +60,5 @@ * Clears all tables in the currently connected database. | ||
clearDatabase(): Promise<void>; | ||
buildParameters(sql: string, parameters: ObjectLiteral): any[]; | ||
replaceParameters(sql: string, parameters: ObjectLiteral): string; | ||
protected checkIfConnectionSet(): void; | ||
} |
@@ -12,4 +12,9 @@ "use strict"; | ||
// ------------------------------------------------------------------------- | ||
constructor(mysql) { | ||
constructor(connectionOptions, mysql) { | ||
super(); | ||
this.connectionOptions = connectionOptions; | ||
// ------------------------------------------------------------------------- | ||
// Public Properties | ||
// ------------------------------------------------------------------------- | ||
this.isResultsLowercase = false; | ||
// if driver dependency is not given explicitly, then try to load it via "require" | ||
@@ -97,6 +102,6 @@ if (!mysql && require) { | ||
*/ | ||
query(query) { | ||
query(query, parameters) { | ||
this.checkIfConnectionSet(); | ||
this.logQuery(query); | ||
return new Promise((ok, fail) => this.mysqlConnection.query(query, (err, result) => { | ||
return new Promise((ok, fail) => this.mysqlConnection.query(query, parameters, (err, result) => { | ||
if (err) { | ||
@@ -127,2 +132,22 @@ this.logFailedQuery(query); | ||
} | ||
buildParameters(sql, parameters) { | ||
const builtParameters = []; | ||
Object.keys(parameters).forEach((key, index) => { | ||
// const value = this.parameters[key] !== null && this.parameters[key] !== undefined ? this.driver.escape(this.parameters[key]) : "NULL"; | ||
sql = sql.replace(new RegExp(":" + key, "g"), (str) => { | ||
builtParameters.push(parameters[key]); | ||
return "?"; | ||
}); // todo: make replace only in value statements, otherwise problems | ||
}); | ||
return builtParameters; | ||
} | ||
replaceParameters(sql, parameters) { | ||
Object.keys(parameters).forEach((key, index) => { | ||
// const value = parameters[key] !== null && parameters[key] !== undefined ? this.driver.escape(parameters[key]) : "NULL"; | ||
sql = sql.replace(new RegExp(":" + key, "g"), (str) => { | ||
return "?"; | ||
}); // todo: make replace only in value statements, otherwise problems | ||
}); | ||
return sql; | ||
} | ||
// ------------------------------------------------------------------------- | ||
@@ -129,0 +154,0 @@ // Protected Methods |
import { Driver } from "./Driver"; | ||
import { SchemaBuilder } from "../schema-builder/SchemaBuilder"; | ||
import { BaseDriver } from "./BaseDriver"; | ||
import { ConnectionOptions } from "../connection/ConnectionOptions"; | ||
import { DriverOptions } from "./DriverOptions"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
/** | ||
@@ -9,7 +10,5 @@ * This driver organizes work with postgres database. | ||
export declare class PostgresDriver extends BaseDriver implements Driver { | ||
connectionOptions: DriverOptions; | ||
readonly isResultsLowercase: boolean; | ||
/** | ||
* Connection used in this driver. | ||
*/ | ||
connectionOptions: ConnectionOptions; | ||
/** | ||
* Postgres library. | ||
@@ -34,3 +33,3 @@ */ | ||
readonly db: string; | ||
constructor(postgres?: any); | ||
constructor(connectionOptions: DriverOptions, postgres?: any); | ||
/** | ||
@@ -55,3 +54,3 @@ * Creates a schema builder which can be used to build database/table schemas. | ||
*/ | ||
query<T>(query: string): Promise<T>; | ||
query<T>(query: string, parameters?: any[]): Promise<T>; | ||
/** | ||
@@ -61,3 +60,18 @@ * Clears all tables in the currently connected database. | ||
clearDatabase(): Promise<void>; | ||
buildParameters(sql: string, parameters: ObjectLiteral): any[]; | ||
replaceParameters(sql: string, parameters: ObjectLiteral): string; | ||
/** | ||
* Insert a new row into given table. | ||
*/ | ||
insert(tableName: string, keyValues: ObjectLiteral, idColumnName?: string): Promise<any>; | ||
/** | ||
* Updates rows that match given conditions in the given table. | ||
*/ | ||
update(tableName: string, valuesMap: ObjectLiteral, conditions: ObjectLiteral): Promise<void>; | ||
/** | ||
* Deletes from the given table by a given conditions. | ||
*/ | ||
delete(tableName: string, conditions: ObjectLiteral): Promise<void>; | ||
protected parametrizeObjectMap(objectMap: ObjectLiteral, startIndex?: number): string[]; | ||
protected checkIfConnectionSet(): void; | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments)).next()); | ||
}); | ||
}; | ||
const ConnectionIsNotSetError_1 = require("./error/ConnectionIsNotSetError"); | ||
@@ -12,4 +20,9 @@ const BaseDriver_1 = require("./BaseDriver"); | ||
// ------------------------------------------------------------------------- | ||
constructor(postgres) { | ||
constructor(connectionOptions, postgres) { | ||
super(); | ||
this.connectionOptions = connectionOptions; | ||
// ------------------------------------------------------------------------- | ||
// Public Properties | ||
// ------------------------------------------------------------------------- | ||
this.isResultsLowercase = true; | ||
// if driver dependency is not given explicitly, then try to load it via "require" | ||
@@ -93,3 +106,3 @@ if (!postgres && require) { | ||
escape(value) { | ||
return this.postgresConnection.escape(value); | ||
return value; // TODO: this.postgresConnection.escape(value); | ||
} | ||
@@ -99,6 +112,8 @@ /** | ||
*/ | ||
query(query) { | ||
query(query, parameters) { | ||
this.checkIfConnectionSet(); | ||
// console.log("query: ", query); | ||
// console.log("parameters: ", parameters); | ||
this.logQuery(query); | ||
return new Promise((ok, fail) => this.postgresConnection.query(query, (err, result) => { | ||
return new Promise((ok, fail) => this.postgresConnection.query(query, parameters, (err, result) => { | ||
if (err) { | ||
@@ -118,16 +133,86 @@ this.logFailedQuery(query); | ||
clearDatabase() { | ||
this.checkIfConnectionSet(); // todo: | ||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`; | ||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS q FROM ` + | ||
`information_schema.tables WHERE table_schema = '${this.db}';`; | ||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`; | ||
return this.query(disableForeignKeysCheckQuery) | ||
.then(() => this.query(dropTablesQuery)) | ||
this.checkIfConnectionSet(); | ||
const dropTablesQuery = `SELECT 'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;' as q FROM pg_tables WHERE schemaname = 'public';`; | ||
return this.query(dropTablesQuery) | ||
.then(results => Promise.all(results.map(q => this.query(q["q"])))) | ||
.then(() => this.query(enableForeignKeysCheckQuery)) | ||
.then(() => { }); | ||
} | ||
buildParameters(sql, parameters) { | ||
const builtParameters = []; | ||
Object.keys(parameters).forEach((key, index) => { | ||
// const value = this.parameters[key] !== null && this.parameters[key] !== undefined ? this.driver.escape(this.parameters[key]) : "NULL"; | ||
sql = sql.replace(new RegExp(":" + key, "g"), (str) => { | ||
builtParameters.push(parameters[key]); | ||
return ""; | ||
}); // todo: make replace only in value statements, otherwise problems | ||
}); | ||
return builtParameters; | ||
} | ||
replaceParameters(sql, parameters) { | ||
Object.keys(parameters).forEach((key, index) => { | ||
// const value = parameters[key] !== null && parameters[key] !== undefined ? this.driver.escape(parameters[key]) : "NULL"; | ||
sql = sql.replace(new RegExp(":" + key, "g"), (str) => { | ||
return "$" + (index + 1); | ||
}); // todo: make replace only in value statements, otherwise problems | ||
}); | ||
return sql; | ||
} | ||
/** | ||
* Insert a new row into given table. | ||
*/ | ||
insert(tableName, keyValues, idColumnName) { | ||
this.checkIfConnectionSet(); | ||
const columns = Object.keys(keyValues).join(","); | ||
const values = Object.keys(keyValues).map((key, index) => "$" + (index + 1)).join(","); // todo: escape here | ||
const params = Object.keys(keyValues).map(key => keyValues[key]); | ||
let query = `INSERT INTO ${tableName}(${columns}) VALUES (${values})`; | ||
if (idColumnName) { | ||
query += " RETURNING " + idColumnName; | ||
} | ||
return this.query(query, params).then(result => { | ||
if (idColumnName) | ||
return result[0][idColumnName]; | ||
return undefined; | ||
}); | ||
} | ||
/** | ||
* Updates rows that match given conditions in the given table. | ||
*/ | ||
update(tableName, valuesMap, conditions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.checkIfConnectionSet(); | ||
const updateValues = this.parametrizeObjectMap(valuesMap).join(","); | ||
const conditionString = this.parametrizeObjectMap(conditions, Object.keys(valuesMap).length).join(" AND "); | ||
const updateParams = Object.keys(valuesMap).map(key => valuesMap[key]); | ||
const conditionParams = Object.keys(conditions).map(key => conditions[key]); | ||
const query = `UPDATE ${tableName} SET ${updateValues} ${conditionString ? (" WHERE " + conditionString) : ""}`; | ||
// console.log("executing update: ", query); | ||
yield this.query(query, updateParams.concat(conditionParams)); | ||
}); | ||
} | ||
/** | ||
* Deletes from the given table by a given conditions. | ||
*/ | ||
delete(tableName, conditions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.checkIfConnectionSet(); | ||
const conditionString = this.parametrizeObjectMap(conditions).join(" AND "); | ||
const params = Object.keys(conditions).map(key => conditions[key]); | ||
const query = `DELETE FROM ${tableName} WHERE ${conditionString}`; | ||
yield this.query(query, params); | ||
}); | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Protected Methods | ||
// ------------------------------------------------------------------------- | ||
parametrizeObjectMap(objectMap, startIndex = 0) { | ||
return Object.keys(objectMap).map((key, index) => { | ||
const value = objectMap[key]; | ||
// if (value === null || value === undefined) { // todo: I think we dont really need this | ||
// return key + "=NULL"; | ||
// } else { | ||
return key + "=$" + (startIndex + index + 1); | ||
// } | ||
}); | ||
} | ||
checkIfConnectionSet() { | ||
@@ -134,0 +219,0 @@ if (!this.postgresConnection) |
@@ -0,9 +1,6 @@ | ||
/// <reference types="chai" /> | ||
import { Connection } from "../connection/Connection"; | ||
import { QueryBuilder } from "../query-builder/QueryBuilder"; | ||
import { FindOptions } from "../repository/FindOptions"; | ||
import { Repository } from "../repository/Repository"; | ||
import { ConstructorFunction } from "../common/ConstructorFunction"; | ||
import { ReactiveRepository } from "../repository/ReactiveRepository"; | ||
import { TreeRepository } from "../repository/TreeRepository"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
import { ObjectType } from "../common/ObjectType"; | ||
import { BaseEntityManager } from "./BaseEntityManager"; | ||
/** | ||
@@ -13,59 +10,5 @@ * Entity manager supposed to work with any entity, automatically find its repository and call its methods, whatever | ||
*/ | ||
export declare class EntityManager { | ||
private connection; | ||
export declare class EntityManager extends BaseEntityManager { | ||
constructor(connection: Connection); | ||
/** | ||
* Gets repository for the given entity class. | ||
*/ | ||
getRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): Repository<Entity>; | ||
/** | ||
* Gets repository for the given entity name. | ||
*/ | ||
getRepository<Entity>(entityClass: string): Repository<Entity>; | ||
/** | ||
* Gets repository for the given entity class or name. | ||
*/ | ||
getRepository<Entity>(entityClassOrName: ConstructorFunction<Entity> | Function | string): Repository<Entity>; | ||
/** | ||
* Gets repository for the given entity class. | ||
*/ | ||
getTreeRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): TreeRepository<Entity>; | ||
/** | ||
* Gets repository for the given entity name. | ||
*/ | ||
getTreeRepository<Entity>(entityClass: string): TreeRepository<Entity>; | ||
/** | ||
* Gets reactive repository of the given entity. | ||
*/ | ||
getReactiveRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function): ReactiveRepository<Entity>; | ||
/** | ||
* Checks if entity has an id. | ||
*/ | ||
hasId(entity: Function): boolean; | ||
hasId(target: Function | string, entity: Function): boolean; | ||
/** | ||
* Creates a new query builder that can be used to build an sql query. | ||
*/ | ||
createQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string): QueryBuilder<Entity>; | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
*/ | ||
create<Entity>(entityClass: ConstructorFunction<Entity> | Function, fromRawEntity?: Object): Entity; | ||
/** | ||
* Creates a entities from the given array of plain javascript objects. | ||
*/ | ||
createMany<Entity>(entityClass: ConstructorFunction<Entity> | Function, copyFromObjects: any[]): Entity[]; | ||
/** | ||
* 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. | ||
*/ | ||
initialize<Entity>(entityClass: ConstructorFunction<Entity> | Function, object: Object): Promise<Entity>; | ||
/** | ||
* Merges two entities into one new entity. | ||
*/ | ||
merge<Entity>(entityClass: ConstructorFunction<Entity> | Function, ...objects: ObjectLiteral[]): Entity; | ||
/** | ||
* Persists (saves) a given entity in the database. | ||
@@ -83,51 +26,51 @@ */ | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function): Promise<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>): Promise<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Promise<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Promise<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Promise<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Promise<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Promise<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Promise<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function): Promise<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>): Promise<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Promise<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Promise<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Promise<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Promise<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Promise<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Promise<[Entity[], number]>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function): Promise<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>): Promise<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Promise<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Promise<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Promise<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Promise<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Promise<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Promise<Entity>; | ||
/** | ||
* Finds entity with given id. | ||
*/ | ||
findOneById<Entity>(entityClass: ConstructorFunction<Entity> | Function, id: any, options?: FindOptions): Promise<Entity>; | ||
findOneById<Entity>(entityClass: ObjectType<Entity>, id: any, options?: FindOptions): Promise<Entity>; | ||
/** | ||
@@ -141,76 +84,2 @@ * Executes raw SQL query and returns raw database results. | ||
transaction(runInTransaction: () => Promise<any>): Promise<any>; | ||
/** | ||
* Sets given relatedEntityId to the value of the relation of the entity with entityId id. | ||
* Should be used when you want quickly and efficiently set a relation (for many-to-one and one-to-many) to some entity. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
setRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityId: any): Promise<void>; | ||
setRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityId: any): Promise<void>; | ||
/** | ||
* Adds a new relation between two entities into relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently add a relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addToRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
addToRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Removes a relation between two entities from relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
removeFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Performs both #addToRelation and #removeFromRelation operations. | ||
* Should be used when you want quickly and efficiently and and remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addAndRemoveFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relation: string, entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Promise<void>; | ||
addAndRemoveFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relation: ((t: Entity) => string | any), entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById<Entity>(entityClass: ConstructorFunction<Entity> | Function, id: any): Promise<void>; | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds<Entity>(entityClass: ConstructorFunction<Entity> | Function, ids: any[]): Promise<void>; | ||
/** | ||
* Roots are entities that have no ancestors. Finds them all. | ||
*/ | ||
findRoots<Entity>(entityClass: ConstructorFunction<Entity> | Function): Promise<Entity[]>; | ||
/** | ||
* Creates a query builder used to get descendants of the entities in a tree. | ||
*/ | ||
createDescendantsQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity>; | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them all in a flat array. | ||
*/ | ||
findDescendants<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<Entity[]>; | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them in a tree - nested into each other. | ||
*/ | ||
findDescendantsTree<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<Entity>; | ||
/** | ||
* Gets number of descendants of the entity. | ||
*/ | ||
countDescendants<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<number>; | ||
/** | ||
* Creates a query builder used to get ancestors of the entities in the tree. | ||
*/ | ||
createAncestorsQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity>; | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them all in a flat array. | ||
*/ | ||
findAncestors<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<Entity[]>; | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them in a tree - nested into each other. | ||
*/ | ||
findAncestorsTree<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<Entity>; | ||
/** | ||
* Gets number of ancestors of the entity. | ||
*/ | ||
countAncestors<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Promise<number>; | ||
} |
"use strict"; | ||
const BaseEntityManager_1 = require("./BaseEntityManager"); | ||
/** | ||
@@ -6,3 +7,3 @@ * Entity manager supposed to work with any entity, automatically find its repository and call its methods, whatever | ||
*/ | ||
class EntityManager { | ||
class EntityManager extends BaseEntityManager_1.BaseEntityManager { | ||
// ------------------------------------------------------------------------- | ||
@@ -12,71 +13,4 @@ // Constructor | ||
constructor(connection) { | ||
this.connection = connection; | ||
super(connection); | ||
} | ||
/** | ||
* Gets repository for the given entity class or name. | ||
*/ | ||
getRepository(entityClassOrName) { | ||
if (typeof entityClassOrName === "string") { | ||
return this.connection.getRepository(entityClassOrName); | ||
} | ||
else { | ||
return this.connection.getRepository(entityClassOrName); | ||
} | ||
} | ||
/** | ||
* Gets repository for the given entity class or name. | ||
*/ | ||
getTreeRepository(entityClassOrName) { | ||
if (typeof entityClassOrName === "string") { | ||
return this.connection.getTreeRepository(entityClassOrName); | ||
} | ||
else { | ||
return this.connection.getTreeRepository(entityClassOrName); | ||
} | ||
} | ||
/** | ||
* Gets reactive repository of the given entity. | ||
*/ | ||
getReactiveRepository(entityClass) { | ||
return this.connection.getReactiveRepository(entityClass); | ||
} | ||
hasId(targetOrEntity, maybeEntity) { | ||
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor; | ||
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity; | ||
return this.getRepository(target).hasId(entity); | ||
} | ||
/** | ||
* Creates a new query builder that can be used to build an sql query. | ||
*/ | ||
createQueryBuilder(entityClass, alias) { | ||
return this.getRepository(entityClass).createQueryBuilder(alias); | ||
} | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
*/ | ||
create(entityClass, fromRawEntity) { | ||
return this.getRepository(entityClass).create(fromRawEntity); | ||
} | ||
/** | ||
* Creates a entities from the given array of plain javascript objects. | ||
*/ | ||
createMany(entityClass, copyFromObjects) { | ||
return this.getRepository(entityClass).createMany(copyFromObjects); | ||
} | ||
/** | ||
* 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. | ||
*/ | ||
initialize(entityClass, object) { | ||
return this.getRepository(entityClass).initialize(object); | ||
} | ||
/** | ||
* Merges two entities into one new entity. | ||
*/ | ||
merge(entityClass, ...objects) { | ||
return this.getRepository(entityClass).merge(...objects); | ||
} | ||
persist(targetOrEntity, maybeEntity) { | ||
@@ -86,3 +20,3 @@ // todo: extra casting is used strange tsc error here, check later maybe typescript bug | ||
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity; | ||
return this.getRepository(target).persist(entity); | ||
return this.obtainRepository(target).persist(entity); | ||
} | ||
@@ -93,3 +27,3 @@ remove(targetOrEntity, maybeEntity) { | ||
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity; | ||
return this.getRepository(target).remove(entity); | ||
return this.obtainRepository(target).remove(entity); | ||
} | ||
@@ -101,9 +35,9 @@ /** | ||
if (conditionsOrFindOptions && options) { | ||
return this.getRepository(entityClass).find(conditionsOrFindOptions, options); | ||
return this.obtainRepository(entityClass).find(conditionsOrFindOptions, options); | ||
} | ||
else if (conditionsOrFindOptions) { | ||
return this.getRepository(entityClass).find(conditionsOrFindOptions); | ||
return this.obtainRepository(entityClass).find(conditionsOrFindOptions); | ||
} | ||
else { | ||
return this.getRepository(entityClass).find(); | ||
return this.obtainRepository(entityClass).find(); | ||
} | ||
@@ -116,9 +50,9 @@ } | ||
if (conditionsOrFindOptions && options) { | ||
return this.getRepository(entityClass).findAndCount(conditionsOrFindOptions, options); | ||
return this.obtainRepository(entityClass).findAndCount(conditionsOrFindOptions, options); | ||
} | ||
else if (conditionsOrFindOptions) { | ||
return this.getRepository(entityClass).findAndCount(conditionsOrFindOptions); | ||
return this.obtainRepository(entityClass).findAndCount(conditionsOrFindOptions); | ||
} | ||
else { | ||
return this.getRepository(entityClass).findAndCount(); | ||
return this.obtainRepository(entityClass).findAndCount(); | ||
} | ||
@@ -131,9 +65,9 @@ } | ||
if (conditionsOrFindOptions && options) { | ||
return this.getRepository(entityClass).findOne(conditionsOrFindOptions, options); | ||
return this.obtainRepository(entityClass).findOne(conditionsOrFindOptions, options); | ||
} | ||
else if (conditionsOrFindOptions) { | ||
return this.getRepository(entityClass).findOne(conditionsOrFindOptions); | ||
return this.obtainRepository(entityClass).findOne(conditionsOrFindOptions); | ||
} | ||
else { | ||
return this.getRepository(entityClass).findOne(); | ||
return this.obtainRepository(entityClass).findOne(); | ||
} | ||
@@ -145,3 +79,3 @@ } | ||
findOneById(entityClass, id, options) { | ||
return this.getRepository(entityClass).findOneById(id, options); | ||
return this.obtainRepository(entityClass).findOneById(id, options); | ||
} | ||
@@ -168,82 +102,2 @@ /** | ||
} | ||
setRelation(entityClass, relationName, entityId, relatedEntityId) { | ||
return this.getRepository(entityClass).setRelation(relationName, entityId, relatedEntityId); | ||
} | ||
addToRelation(entityClass, relationName, entityId, relatedEntityIds) { | ||
return this.getRepository(entityClass).addToRelation(relationName, entityId, relatedEntityIds); | ||
} | ||
removeFromRelation(entityClass, relationName, entityId, relatedEntityIds) { | ||
return this.getRepository(entityClass).removeFromRelation(relationName, entityId, relatedEntityIds); | ||
} | ||
addAndRemoveFromRelation(entityClass, relation, entityId, addRelatedEntityIds, removeRelatedEntityIds) { | ||
return this.getRepository(entityClass).addAndRemoveFromRelation(relation, entityId, addRelatedEntityIds, removeRelatedEntityIds); | ||
} | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(entityClass, id) { | ||
return this.getRepository(entityClass).removeById(id); | ||
} | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(entityClass, ids) { | ||
return this.getRepository(entityClass).removeByIds(ids); | ||
} | ||
/** | ||
* Roots are entities that have no ancestors. Finds them all. | ||
*/ | ||
findRoots(entityClass) { | ||
return this.getTreeRepository(entityClass).findRoots(); | ||
} | ||
/** | ||
* Creates a query builder used to get descendants of the entities in a tree. | ||
*/ | ||
createDescendantsQueryBuilder(entityClass, alias, closureTableAlias, entity) { | ||
return this.getTreeRepository(entityClass).createDescendantsQueryBuilder(alias, closureTableAlias, entity); | ||
} | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them all in a flat array. | ||
*/ | ||
findDescendants(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).findDescendants(entity); | ||
} | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them in a tree - nested into each other. | ||
*/ | ||
findDescendantsTree(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).findDescendantsTree(entity); | ||
} | ||
/** | ||
* Gets number of descendants of the entity. | ||
*/ | ||
countDescendants(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).countDescendants(entity); | ||
} | ||
/** | ||
* Creates a query builder used to get ancestors of the entities in the tree. | ||
*/ | ||
createAncestorsQueryBuilder(entityClass, alias, closureTableAlias, entity) { | ||
return this.getTreeRepository(entityClass).createAncestorsQueryBuilder(alias, closureTableAlias, entity); | ||
} | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them all in a flat array. | ||
*/ | ||
findAncestors(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).findAncestors(entity); | ||
} | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them in a tree - nested into each other. | ||
*/ | ||
findAncestorsTree(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).findAncestorsTree(entity); | ||
} | ||
/** | ||
* Gets number of ancestors of the entity. | ||
*/ | ||
countAncestors(entityClass, entity) { | ||
return this.getTreeRepository(entityClass).countAncestors(entity); | ||
} | ||
} | ||
@@ -250,0 +104,0 @@ exports.EntityManager = EntityManager; |
@@ -0,10 +1,7 @@ | ||
/// <reference types="chai" /> | ||
import * as Rx from "rxjs/Rx"; | ||
import { Connection } from "../connection/Connection"; | ||
import { QueryBuilder } from "../query-builder/QueryBuilder"; | ||
import { FindOptions } from "../repository/FindOptions"; | ||
import { Repository } from "../repository/Repository"; | ||
import { ConstructorFunction } from "../common/ConstructorFunction"; | ||
import { ReactiveRepository } from "../repository/ReactiveRepository"; | ||
import { ReactiveTreeRepository } from "../repository/ReactiveTreeRepository"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
import { ObjectType } from "../common/ObjectType"; | ||
import { BaseEntityManager } from "./BaseEntityManager"; | ||
/** | ||
@@ -14,47 +11,5 @@ * Entity manager supposed to work with any entity, automatically find its repository and call its method, whatever | ||
*/ | ||
export declare class ReactiveEntityManager { | ||
private connection; | ||
export declare class ReactiveEntityManager extends BaseEntityManager { | ||
constructor(connection: Connection); | ||
/** | ||
* Gets repository of the given entity. | ||
*/ | ||
getRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function | string): Repository<Entity>; | ||
/** | ||
* Gets reactive repository of the given entity. | ||
*/ | ||
getReactiveRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function | string): ReactiveRepository<Entity>; | ||
/** | ||
* Gets reactive tree repository of the given entity. | ||
*/ | ||
getReactiveTreeRepository<Entity>(entityClass: ConstructorFunction<Entity> | Function | string): ReactiveTreeRepository<Entity>; | ||
/** | ||
* Checks if entity has an id. | ||
*/ | ||
hasId(entity: Function): boolean; | ||
hasId(target: Function | string, entity: Function): boolean; | ||
/** | ||
* Creates a new query builder that can be used to build an sql query. | ||
*/ | ||
createQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string): QueryBuilder<Entity>; | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
*/ | ||
create<Entity>(entityClass: ConstructorFunction<Entity> | Function, fromRawEntity?: Object): Entity; | ||
/** | ||
* Creates a entities from the given array of plain javascript objects. | ||
*/ | ||
createMany<Entity>(entityClass: ConstructorFunction<Entity> | Function, copyFromObjects: any[]): Entity[]; | ||
/** | ||
* 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. | ||
*/ | ||
initialize<Entity>(entityClass: ConstructorFunction<Entity> | Function, object: Object): Rx.Observable<Entity>; | ||
/** | ||
* Merges two entities into one new entity. | ||
*/ | ||
merge<Entity>(entityClass: ConstructorFunction<Entity> | Function, ...objects: ObjectLiteral[]): Entity; | ||
/** | ||
* Persists (saves) a given entity in the database. | ||
@@ -72,51 +27,51 @@ */ | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function): Rx.Observable<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>): Rx.Observable<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Rx.Observable<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Rx.Observable<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Rx.Observable<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Rx.Observable<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
find<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Rx.Observable<Entity[]>; | ||
find<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Rx.Observable<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function): Rx.Observable<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>): Rx.Observable<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Rx.Observable<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Rx.Observable<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Rx.Observable<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Rx.Observable<[Entity[], number]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
*/ | ||
findAndCount<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Rx.Observable<[Entity[], number]>; | ||
findAndCount<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Rx.Observable<[Entity[], number]>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function): Rx.Observable<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>): Rx.Observable<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object): Rx.Observable<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, conditions: Object): Rx.Observable<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, options: FindOptions): Rx.Observable<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, options: FindOptions): Rx.Observable<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
*/ | ||
findOne<Entity>(entityClass: ConstructorFunction<Entity> | Function, conditions: Object, options: FindOptions): Rx.Observable<Entity>; | ||
findOne<Entity>(entityClass: ObjectType<Entity>, conditions: Object, options: FindOptions): Rx.Observable<Entity>; | ||
/** | ||
* Finds entity with given id. | ||
*/ | ||
findOneById<Entity>(entityClass: ConstructorFunction<Entity> | Function, id: any, options?: FindOptions): Rx.Observable<Entity>; | ||
findOneById<Entity>(entityClass: ObjectType<Entity>, id: any, options?: FindOptions): Rx.Observable<Entity>; | ||
/** | ||
@@ -130,85 +85,2 @@ * Executes raw SQL query and returns raw database results. | ||
transaction(runInTransaction: () => Promise<any>): Rx.Observable<any>; | ||
/** | ||
* Sets given relatedEntityId to the value of the relation of the entity with entityId id. | ||
* Should be used when you want quickly and efficiently set a relation (for many-to-one and one-to-many) to some entity. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
setRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityId: any): Rx.Observable<void>; | ||
setRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityId: any): Rx.Observable<void>; | ||
/** | ||
* Adds a new relation between two entities into relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently add a relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addToRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
addToRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Removes a relation between two entities from relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: string, entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
removeFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Performs both #addToRelation and #removeFromRelation operations. | ||
* Should be used when you want quickly and efficiently and and remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addAndRemoveFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relation: string, entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Rx.Observable<void>; | ||
addAndRemoveFromRelation<Entity>(entityClass: ConstructorFunction<Entity> | Function, relation: ((t: Entity) => string | any), entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById<Entity>(entityClass: ConstructorFunction<Entity> | Function, id: any): Rx.Observable<void>; | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds<Entity>(entityClass: ConstructorFunction<Entity> | Function, ids: any[]): Rx.Observable<void>; | ||
/** | ||
* Roots are entities that have no ancestors. Finds them all. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findRoots<Entity>(entityClass: ConstructorFunction<Entity> | Function): Rx.Observable<Entity[]>; | ||
/** | ||
* Creates a query builder used to get descendants of the entities in a tree. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
createDescendantsQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity>; | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them all in a flat array. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findDescendants<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<Entity[]>; | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them in a tree - nested into each other. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findDescendantsTree<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<Entity>; | ||
/** | ||
* Gets number of descendants of the entity. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
countDescendants<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<number>; | ||
/** | ||
* Creates a query builder used to get ancestors of the entities in the tree. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
createAncestorsQueryBuilder<Entity>(entityClass: ConstructorFunction<Entity> | Function, alias: string, closureTableAlias: string, entity: Entity): QueryBuilder<Entity>; | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them all in a flat array. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findAncestors<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<Entity[]>; | ||
/** | ||
* Gets all parents (ancestors) of the given entity. \Returns them in a tree - nested into each other. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findAncestorsTree<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<Entity>; | ||
/** | ||
* Gets number of ancestors of the entity. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
countAncestors<Entity>(entityClass: ConstructorFunction<Entity> | Function, entity: Entity): Rx.Observable<number>; | ||
} |
"use strict"; | ||
const Rx = require("rxjs/Rx"); | ||
const BaseEntityManager_1 = require("./BaseEntityManager"); | ||
/** | ||
@@ -7,3 +8,3 @@ * Entity manager supposed to work with any entity, automatically find its repository and call its method, whatever | ||
*/ | ||
class ReactiveEntityManager { | ||
class ReactiveEntityManager extends BaseEntityManager_1.BaseEntityManager { | ||
// ------------------------------------------------------------------------- | ||
@@ -13,64 +14,4 @@ // Constructor | ||
constructor(connection) { | ||
this.connection = connection; | ||
super(connection); | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Public Methods | ||
// ------------------------------------------------------------------------- | ||
/** | ||
* Gets repository of the given entity. | ||
*/ | ||
getRepository(entityClass) { | ||
return this.connection.getRepository(entityClass); | ||
} | ||
/** | ||
* Gets reactive repository of the given entity. | ||
*/ | ||
getReactiveRepository(entityClass) { | ||
return this.connection.getReactiveRepository(entityClass); | ||
} | ||
/** | ||
* Gets reactive tree repository of the given entity. | ||
*/ | ||
getReactiveTreeRepository(entityClass) { | ||
return this.connection.getReactiveTreeRepository(entityClass); | ||
} | ||
hasId(targetOrEntity, maybeEntity) { | ||
const target = arguments.length === 2 ? targetOrEntity : targetOrEntity.constructor; | ||
const entity = arguments.length === 2 ? maybeEntity : targetOrEntity; | ||
return this.getReactiveRepository(target).hasId(entity); | ||
} | ||
/** | ||
* Creates a new query builder that can be used to build an sql query. | ||
*/ | ||
createQueryBuilder(entityClass, alias) { | ||
return this.getReactiveRepository(entityClass).createQueryBuilder(alias); | ||
} | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
*/ | ||
create(entityClass, fromRawEntity) { | ||
return this.getReactiveRepository(entityClass).create(fromRawEntity); | ||
} | ||
/** | ||
* Creates a entities from the given array of plain javascript objects. | ||
*/ | ||
createMany(entityClass, copyFromObjects) { | ||
return this.getReactiveRepository(entityClass).createMany(copyFromObjects); | ||
} | ||
/** | ||
* 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. | ||
*/ | ||
initialize(entityClass, object) { | ||
return this.getReactiveRepository(entityClass).initialize(object); | ||
} | ||
/** | ||
* Merges two entities into one new entity. | ||
*/ | ||
merge(entityClass, ...objects) { | ||
return this.getRepository(entityClass).merge(...objects); | ||
} | ||
persist(targetOrEntity, maybeEntity) { | ||
@@ -156,91 +97,2 @@ // todo: extra casting is used strange tsc error here, check later maybe typescript bug | ||
} | ||
setRelation(entityClass, relationName, entityId, relatedEntityId) { | ||
return this.getReactiveRepository(entityClass).setRelation(relationName, entityId, relatedEntityId); | ||
} | ||
addToRelation(entityClass, relationName, entityId, relatedEntityIds) { | ||
return this.getReactiveRepository(entityClass).addToRelation(relationName, entityId, relatedEntityIds); | ||
} | ||
removeFromRelation(entityClass, relationName, entityId, relatedEntityIds) { | ||
return this.getReactiveRepository(entityClass).removeFromRelation(relationName, entityId, relatedEntityIds); | ||
} | ||
addAndRemoveFromRelation(entityClass, relation, entityId, addRelatedEntityIds, removeRelatedEntityIds) { | ||
return this.getReactiveRepository(entityClass).addAndRemoveFromRelation(relation, entityId, addRelatedEntityIds, removeRelatedEntityIds); | ||
} | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(entityClass, id) { | ||
return this.getReactiveRepository(entityClass).removeById(id); | ||
} | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(entityClass, ids) { | ||
return this.getReactiveRepository(entityClass).removeByIds(ids); | ||
} | ||
/** | ||
* Roots are entities that have no ancestors. Finds them all. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findRoots(entityClass) { | ||
return this.getReactiveTreeRepository(entityClass).findRoots(); | ||
} | ||
/** | ||
* Creates a query builder used to get descendants of the entities in a tree. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
createDescendantsQueryBuilder(entityClass, alias, closureTableAlias, entity) { | ||
return this.getReactiveTreeRepository(entityClass).createDescendantsQueryBuilder(alias, closureTableAlias, entity); | ||
} | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them all in a flat array. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findDescendants(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).findDescendants(entity); | ||
} | ||
/** | ||
* Gets all children (descendants) of the given entity. Returns them in a tree - nested into each other. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findDescendantsTree(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).findDescendantsTree(entity); | ||
} | ||
/** | ||
* Gets number of descendants of the entity. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
countDescendants(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).countDescendants(entity); | ||
} | ||
/** | ||
* Creates a query builder used to get ancestors of the entities in the tree. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
createAncestorsQueryBuilder(entityClass, alias, closureTableAlias, entity) { | ||
return this.getReactiveTreeRepository(entityClass).createAncestorsQueryBuilder(alias, closureTableAlias, entity); | ||
} | ||
/** | ||
* Gets all parents (ancestors) of the given entity. Returns them all in a flat array. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findAncestors(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).findAncestors(entity); | ||
} | ||
/** | ||
* Gets all parents (ancestors) of the given entity. \Returns them in a tree - nested into each other. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
findAncestorsTree(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).findAncestorsTree(entity); | ||
} | ||
/** | ||
* Gets number of ancestors of the entity. | ||
* Used on the tree-type (e.g. closure table) entities. | ||
*/ | ||
countAncestors(entityClass, entity) { | ||
return this.getReactiveTreeRepository(entityClass).countAncestors(entity); | ||
} | ||
} | ||
@@ -247,0 +99,0 @@ exports.ReactiveEntityManager = ReactiveEntityManager; |
/*! | ||
*/ | ||
import { ConnectionManager } from "./connection-manager/ConnectionManager"; | ||
import { ConnectionManager } from "./connection/ConnectionManager"; | ||
import { Connection } from "./connection/Connection"; | ||
import { MetadataArgsStorage } from "./metadata-args/MetadataArgsStorage"; | ||
import { CreateConnectionOptions } from "./connection-manager/CreateConnectionOptions"; | ||
import { ConnectionOptions } from "./connection/ConnectionOptions"; | ||
/** | ||
@@ -33,7 +33,7 @@ * Sets container to be used by this library. | ||
*/ | ||
export declare function createConnection(options: CreateConnectionOptions): Promise<Connection>; | ||
export declare function createConnection(options: ConnectionOptions): Promise<Connection>; | ||
export { Connection } from "./connection/Connection"; | ||
export { DriverOptions } from "./driver/DriverOptions"; | ||
export { ConnectionManager } from "./connection/ConnectionManager"; | ||
export { ConnectionOptions } from "./connection/ConnectionOptions"; | ||
export { ConnectionManager } from "./connection-manager/ConnectionManager"; | ||
export { CreateConnectionOptions } from "./connection-manager/CreateConnectionOptions"; | ||
export { Driver } from "./driver/Driver"; | ||
@@ -40,0 +40,0 @@ export { MysqlDriver } from "./driver/MysqlDriver"; |
@@ -5,3 +5,3 @@ /*! | ||
"use strict"; | ||
const ConnectionManager_1 = require("./connection-manager/ConnectionManager"); | ||
const ConnectionManager_1 = require("./connection/ConnectionManager"); | ||
const MetadataArgsStorage_1 = require("./metadata-args/MetadataArgsStorage"); | ||
@@ -86,3 +86,3 @@ // ------------------------------------------------------------------------- | ||
function createConnection(options) { | ||
return getConnectionManager().create(options).connect(); | ||
return getConnectionManager().createAndConnect(options); | ||
} | ||
@@ -95,3 +95,3 @@ exports.createConnection = createConnection; | ||
exports.Connection = Connection_1.Connection; | ||
var ConnectionManager_2 = require("./connection-manager/ConnectionManager"); | ||
var ConnectionManager_2 = require("./connection/ConnectionManager"); | ||
exports.ConnectionManager = ConnectionManager_2.ConnectionManager; | ||
@@ -98,0 +98,0 @@ var MysqlDriver_1 = require("./driver/MysqlDriver"); |
@@ -25,3 +25,3 @@ import { TableType } from "../metadata/TableMetadata"; | ||
*/ | ||
readonly primaryKeys?: string | ((object: any) => string | any)[]; | ||
readonly primaryKeys?: (string | ((object: any) => string | any))[]; | ||
/** | ||
@@ -28,0 +28,0 @@ * Specifies a property name by which queries will perform ordering by default when fetching rows. |
@@ -90,3 +90,3 @@ import { PropertyMetadata } from "./PropertyMetadata"; | ||
readonly name: string; | ||
readonly target: Function | string; | ||
readonly target: string | Function; | ||
/** | ||
@@ -93,0 +93,0 @@ * Indicates if this column is in embedded, not directly in the table. |
@@ -147,2 +147,5 @@ "use strict"; | ||
if (this.isInEmbedded) { | ||
if (entity[this.embeddedProperty] === undefined || | ||
entity[this.embeddedProperty] === null) | ||
return undefined; | ||
return entity[this.embeddedProperty][this.propertyName]; | ||
@@ -149,0 +152,0 @@ } |
@@ -34,3 +34,3 @@ "use strict"; | ||
const propertiesMap = this.entityMetadata.createPropertiesMap(); | ||
return this._columns(propertiesMap).map((i) => String(i)); | ||
return this._columns(propertiesMap).map((i) => String(i).toLowerCase()); | ||
} | ||
@@ -37,0 +37,0 @@ } |
@@ -104,3 +104,3 @@ import { PropertyMetadata } from "./PropertyMetadata"; | ||
constructor(args: RelationMetadataArgs); | ||
readonly target: Function | string; | ||
readonly target: string | Function; | ||
/** | ||
@@ -107,0 +107,0 @@ * Gets the name of column in the database. |
@@ -81,3 +81,3 @@ /** | ||
*/ | ||
static readonly supportedTypes: ("string" | "text" | "number" | "integer" | "int" | "smallint" | "bigint" | "float" | "double" | "decimal" | "date" | "time" | "datetime" | "boolean" | "json" | "simple_array")[]; | ||
static readonly supportedTypes: ColumnType[]; | ||
/** | ||
@@ -84,0 +84,0 @@ * Tries to guess a column type from the given function. |
{ | ||
"name": "typeorm", | ||
"private": false, | ||
"version": "0.0.2-alpha.48", | ||
"version": "0.0.2-alpha.49", | ||
"description": "Data-mapper ORM for Typescript", | ||
@@ -27,31 +27,37 @@ "license": "Apache-2.0", | ||
"devDependencies": { | ||
"@types/chai": "^3.4.30", | ||
"@types/chai-as-promised": "0.0.28", | ||
"@types/mocha": "^2.2.29", | ||
"@types/promises-a-plus": "0.0.26", | ||
"@types/sinon": "^1.16.27", | ||
"chai": "^3.4.1", | ||
"chai-as-promised": "^5.3.0", | ||
"del": "^2.2.0", | ||
"del": "^2.2.1", | ||
"gulp": "^3.9.1", | ||
"gulp-istanbul": "^0.10.4", | ||
"gulp-mocha": "^2.2.0", | ||
"gulp-istanbul": "^1.0.0", | ||
"gulp-mocha": "^3.0.0", | ||
"gulp-replace": "^0.5.4", | ||
"gulp-shell": "^0.5.1", | ||
"gulp-sourcemaps": "^1.6.0", | ||
"gulp-tslint": "^5.0.0", | ||
"gulp-tslint": "^6.0.2", | ||
"gulp-typescript": "^2.13.6", | ||
"gulpclass": "0.1.1", | ||
"mocha": "^2.5.3", | ||
"mysql": "^2.10.2", | ||
"pg": "^4.5.5", | ||
"mocha": "^3.0.1", | ||
"mysql": "^2.11.1", | ||
"pg": "^6.0.3", | ||
"remap-istanbul": "^0.6.4", | ||
"sinon": "^1.17.4", | ||
"sinon": "^1.17.5", | ||
"sinon-chai": "^2.8.0", | ||
"ts-node": "^0.8.0", | ||
"ts-node": "^1.2.2", | ||
"tslint": "next", | ||
"tslint-stylish": "^2.1.0-beta", | ||
"typescript": "next", | ||
"typings": "^1.0.4" | ||
"typescript": "^2.1.0-dev.20160808" | ||
}, | ||
"dependencies": { | ||
"@types/lodash": "0.0.29", | ||
"@types/node": "^6.0.31", | ||
"fs": "^0.0.2", | ||
"glob": "^7.0.3", | ||
"lodash": "^4.13.1", | ||
"moment": "^2.13.0", | ||
"glob": "^7.0.5", | ||
"lodash": "^4.14.1", | ||
"moment": "^2.14.1", | ||
"path": "^0.12.7", | ||
@@ -58,0 +64,0 @@ "reflect-metadata": "^0.1.3", |
@@ -401,3 +401,7 @@ "use strict"; | ||
// console.log("inserting: ", this.zipObject(allColumns, allValues)); | ||
return this.driver.insert(metadata.table.name, this.zipObject(allColumns, allValues)); | ||
let idColumnName; | ||
if (metadata.hasPrimaryColumn && metadata.primaryColumn.isGenerated) { | ||
idColumnName = metadata.primaryColumn.name; | ||
} | ||
return this.driver.insert(metadata.table.name, this.zipObject(allColumns, allValues), idColumnName); | ||
} | ||
@@ -404,0 +408,0 @@ insertIntoClosureTable(operation, updateMap) { |
@@ -1,2 +0,1 @@ | ||
import { ColumnMetadata } from "../../metadata/ColumnMetadata"; | ||
/** | ||
@@ -12,4 +11,2 @@ */ | ||
readonly selection: string; | ||
getPrimaryKeyValue(result: any, primaryColumn: ColumnMetadata): any; | ||
getColumnValue(result: any, columnName: string): any; | ||
} |
@@ -11,8 +11,2 @@ "use strict"; | ||
} | ||
getPrimaryKeyValue(result, primaryColumn) { | ||
return result[this.name + "_" + primaryColumn.name]; | ||
} | ||
getColumnValue(result, columnName) { | ||
return result[this.name + "_" + columnName]; | ||
} | ||
} | ||
@@ -19,0 +13,0 @@ exports.Alias = Alias; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
import { Alias } from "./alias/Alias"; | ||
@@ -6,2 +7,3 @@ import { Broadcaster } from "../subscriber/Broadcaster"; | ||
import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
export interface JoinRelationId { | ||
@@ -63,88 +65,32 @@ alias: Alias; | ||
from(entity: Function | string, alias: string): this; | ||
countRelationAndMap(mapProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
countRelation(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinRelationIdAndMap(mapToProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinRelationIdAndMap(mapToProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinRelationId(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinRelationId(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndMapMany(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndMapMany(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndMapOne(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndMapOne(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndSelect(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoinAndSelect(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoin(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
innerJoin(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndMapMany(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndMapMany(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndMapOne(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndMapOne(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndSelect(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoinAndSelect(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoin(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
leftJoin(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
where(where: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
andWhere(where: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
orWhere(where: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
countRelationAndMap(mapProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
countRelation(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinRelationIdAndMap(mapToProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinRelationIdAndMap(mapToProperty: string, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinRelationId(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinRelationId(property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndMapMany(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndMapMany(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndMapOne(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndMapOne(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndSelect(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoinAndSelect(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoin(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
innerJoin(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndMapMany(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndMapMany(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndMapOne(mapToProperty: string, property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndMapOne(mapToProperty: string, entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndSelect(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoinAndSelect(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoin(property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
leftJoin(entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
where(where: string, parameters?: ObjectLiteral): this; | ||
andWhere(where: string, parameters?: ObjectLiteral): this; | ||
orWhere(where: string, parameters?: ObjectLiteral): this; | ||
groupBy(groupBy: string): this; | ||
addGroupBy(groupBy: string): this; | ||
having(having: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
andHaving(having: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
orHaving(having: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
having(having: string, parameters?: ObjectLiteral): this; | ||
andHaving(having: string, parameters?: ObjectLiteral): this; | ||
orHaving(having: string, parameters?: ObjectLiteral): this; | ||
orderBy(sort: string, order?: "ASC" | "DESC"): this; | ||
@@ -157,9 +103,6 @@ addOrderBy(sort: string, order?: "ASC" | "DESC"): this; | ||
setParameter(key: string, value: any): this; | ||
setParameters(parameters: { | ||
[key: string]: any; | ||
}): this; | ||
addParameters(parameters: { | ||
[key: string]: any; | ||
}): this; | ||
setParameters(parameters: ObjectLiteral): this; | ||
addParameters(parameters: ObjectLiteral): this; | ||
getSql(): string; | ||
getParameters(): string[]; | ||
execute(): Promise<any>; | ||
@@ -198,16 +141,8 @@ getScalarResults<T>(): Promise<T[]>; | ||
private extractJoinMappings(); | ||
protected join(joinType: "INNER" | "LEFT", property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected join(joinType: "INNER" | "LEFT", entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected join(joinType: "INNER" | "LEFT", entityOrProperty: Function | string, alias: string, conditionType: "ON" | "WITH", condition: string, parameters?: { | ||
[key: string]: any; | ||
}, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected joinRelationId(joinType: "LEFT" | "INNER", mapToProperty: string | undefined, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: { | ||
[key: string]: any; | ||
}): this; | ||
protected join(joinType: "INNER" | "LEFT", property: string, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected join(joinType: "INNER" | "LEFT", entity: Function, alias: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected join(joinType: "INNER" | "LEFT", entityOrProperty: Function | string, alias: string, conditionType: "ON" | "WITH", condition: string, parameters?: ObjectLiteral, mapToProperty?: string, isMappingMany?: boolean): this; | ||
protected joinRelationId(joinType: "LEFT" | "INNER", mapToProperty: string | undefined, property: string, conditionType?: "ON" | "WITH", condition?: string, parameters?: ObjectLiteral): this; | ||
private isValueSimpleString(str); | ||
private isPropertyAlias(str); | ||
} |
@@ -274,7 +274,19 @@ "use strict"; | ||
} | ||
getParameters() { | ||
let sql = this.createSelectExpression(); | ||
sql += this.createJoinExpression(); | ||
sql += this.createJoinRelationIdsExpression(); | ||
sql += this.createWhereExpression(); | ||
sql += this.createGroupByExpression(); | ||
sql += this.createHavingExpression(); | ||
sql += this.createOrderByExpression(); | ||
sql += this.createLimitExpression(); | ||
sql += this.createOffsetExpression(); | ||
return this.driver.buildParameters(sql, this.parameters); | ||
} | ||
execute() { | ||
return this.driver.query(this.getSql()); | ||
return this.driver.query(this.getSql(), this.getParameters()); | ||
} | ||
getScalarResults() { | ||
return this.driver.query(this.getSql()); | ||
return this.driver.query(this.getSql(), this.getParameters()); | ||
} | ||
@@ -300,3 +312,3 @@ getSingleScalarResult() { | ||
idsQuery += ", " + this.orderBys.map(orderBy => orderBy.sort.replace(".", "_")).join(", "); | ||
idsQuery += ` FROM (${this.getSql()}) distinctAlias`; | ||
idsQuery += ` FROM (${this.getSql()}) distinctAlias`; // TODO: WHAT TO DO WITH PARAMETERS HERE? DO THEY WORK? | ||
if (this.orderBys && this.orderBys.length > 0) | ||
@@ -309,3 +321,3 @@ idsQuery += " ORDER BY " + this.orderBys.map(order => "distinctAlias." + order.sort.replace(".", "_") + " " + order.order).join(", "); | ||
return this.driver | ||
.query(idsQuery) | ||
.query(idsQuery, this.getParameters()) | ||
.then((results) => { | ||
@@ -317,5 +329,4 @@ scalarResults = results; | ||
const queryWithIds = this.clone() | ||
.andWhere(mainAliasName + "." + metadata.primaryColumn.name + " IN (" + ids + ")") | ||
.getSql(); | ||
return this.driver.query(queryWithIds); | ||
.andWhere(mainAliasName + "." + metadata.primaryColumn.name + " IN (" + ids + ")"); | ||
return this.driver.query(queryWithIds.getSql(), queryWithIds.getParameters()); | ||
}) | ||
@@ -333,3 +344,3 @@ .then(results => this.rawResultsToEntities(results)) | ||
return this.driver | ||
.query(this.getSql()) | ||
.query(this.getSql(), this.getParameters()) | ||
.then(results => { | ||
@@ -465,6 +476,5 @@ scalarResults = results; | ||
const countQuery = this.clone({ skipOrderBys: true }) | ||
.select(`COUNT(DISTINCT(${mainAlias}.${metadata.primaryColumn.name})) as cnt`) | ||
.getSql(); | ||
.select(`COUNT(DISTINCT(${mainAlias}.${metadata.primaryColumn.name})) as cnt`); | ||
return this.driver | ||
.query(countQuery) | ||
.query(countQuery.getSql(), countQuery.getParameters()) | ||
.then(results => { | ||
@@ -581,3 +591,3 @@ if (!results || !results[0] || !results[0]["cnt"]) | ||
joinMetadata.columns.forEach(column => { | ||
allSelects.push(join.alias.name + "." + column.name + " AS " + join.alias.name + "_" + column.propertyName); | ||
allSelects.push(join.alias.name + "." + column.name + " AS " + join.alias.name + "_" + column.name); | ||
}); | ||
@@ -782,7 +792,3 @@ } | ||
replaceParameters(sql) { | ||
Object.keys(this.parameters).forEach(key => { | ||
const value = this.parameters[key] !== null && this.parameters[key] !== undefined ? this.driver.escape(this.parameters[key]) : "NULL"; | ||
sql = sql.replace(new RegExp(":" + key, "g"), value); // todo: make replace only in value statements, otherwise problems | ||
}); | ||
return sql; | ||
return this.driver.replaceParameters(sql, this.parameters); | ||
} | ||
@@ -789,0 +795,0 @@ extractJoinMappings() { |
@@ -39,3 +39,4 @@ "use strict"; | ||
return; | ||
return alias.getPrimaryKeyValue(result, metadata.primaryColumn); | ||
const columnName = this.driver.isResultsLowercase ? metadata.primaryColumn.name.toLowerCase() : metadata.primaryColumn.name; | ||
return result[alias.name + "_" + columnName]; | ||
}); | ||
@@ -69,3 +70,4 @@ return groupedResults | ||
metadata.columns.forEach(column => { | ||
const valueInObject = alias.getColumnValue(rawSqlResults[0], column.name); // we use zero index since its grouped data | ||
const columnName = this.driver.isResultsLowercase ? column.name.toLowerCase() : column.name; | ||
const valueInObject = rawSqlResults[0][alias.name + "_" + columnName]; // we use zero index since its grouped data | ||
if (valueInObject !== undefined && valueInObject !== null && column.propertyName && !column.isVirtual) { | ||
@@ -128,3 +130,4 @@ const value = this.driver.prepareHydratedValue(valueInObject, column); | ||
else if (relation.idField) { | ||
entity[relation.idField] = alias.getColumnValue(rawSqlResults[0], relation.name); | ||
const relationName = this.driver.isResultsLowercase ? relation.name.toLowerCase() : relation.name; | ||
entity[relation.idField] = rawSqlResults[0][alias.name + "_" + relationName]; | ||
} | ||
@@ -131,0 +134,0 @@ // if relation counter |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
import { QueryBuilder } from "../query-builder/QueryBuilder"; | ||
@@ -2,0 +3,0 @@ /** |
@@ -11,3 +11,3 @@ "use strict"; | ||
const possibleOptions = object; | ||
return possibleOptions && possibleOptions.alias && typeof possibleOptions.alias === "string" && (!!possibleOptions.limit || | ||
return possibleOptions && !!possibleOptions.alias && typeof possibleOptions.alias === "string" && (!!possibleOptions.limit || | ||
!!possibleOptions.offset || | ||
@@ -14,0 +14,0 @@ !!possibleOptions.firstResult || |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
import { RelationMetadata } from "../metadata/RelationMetadata"; | ||
@@ -2,0 +3,0 @@ import { EntityMetadataCollection } from "../metadata-args/collection/EntityMetadataCollection"; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
import { QueryBuilder } from "../query-builder/QueryBuilder"; | ||
@@ -5,3 +6,2 @@ import { FindOptions } from "./FindOptions"; | ||
import * as Rx from "rxjs/Rx"; | ||
import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
@@ -11,2 +11,4 @@ /** | ||
* This version of Repository is using rxjs library and Observables instead of promises. | ||
* | ||
* @experimental | ||
*/ | ||
@@ -30,11 +32,16 @@ export declare class ReactiveRepository<Entity> { | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
* Creates a new entity instance. | ||
*/ | ||
create(fromRawEntity?: Object): Entity; | ||
create(): Entity; | ||
/** | ||
* Creates entities from a given array of plain javascript objects. | ||
* 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. | ||
*/ | ||
createMany(copyFromObjects: Object[]): Entity[]; | ||
create(plainObjects: Object[]): 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(plainObject: Object): Entity; | ||
/** | ||
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then | ||
@@ -45,3 +52,3 @@ * it loads it (and everything related to it), replaces all values with the new ones from the given object | ||
*/ | ||
initialize(object: Object): Rx.Observable<Entity>; | ||
preload(object: Object): Rx.Observable<Entity>; | ||
/** | ||
@@ -120,41 +127,2 @@ * Merges two entities into one new entity. | ||
transaction(runInTransaction: () => Promise<any>): Rx.Observable<any>; | ||
/** | ||
* Sets given relatedEntityId to the value of the relation of the entity with entityId id. | ||
* Should be used when you want quickly and efficiently set a relation (for many-to-one and one-to-many) to some entity. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
setRelation(relationName: string, entityId: any, relatedEntityId: any): Rx.Observable<void>; | ||
setRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityId: any): Rx.Observable<void>; | ||
/** | ||
* Adds a new relation between two entities into relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently add a relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addToRelation(relationName: string, entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
addToRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Removes a relation between two entities from relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeFromRelation(relationName: string, entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
removeFromRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Performs both #addToRelation and #removeFromRelation operations. | ||
* Should be used when you want quickly and efficiently and and remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addAndRemoveFromRelation(relation: string, entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Rx.Observable<void>; | ||
addAndRemoveFromRelation(relation: ((t: Entity) => string | any), entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Rx.Observable<void>; | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(id: any): Rx.Observable<void>; | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(ids: any[]): Rx.Observable<void>; | ||
static ownsMetadata(reactiveRepository: ReactiveRepository<any>, metadata: EntityMetadata): boolean; | ||
} |
"use strict"; | ||
const Repository_1 = require("./Repository"); | ||
const Rx = require("rxjs/Rx"); | ||
@@ -7,2 +6,4 @@ /** | ||
* This version of Repository is using rxjs library and Observables instead of promises. | ||
* | ||
* @experimental | ||
*/ | ||
@@ -39,15 +40,17 @@ class ReactiveRepository { | ||
/** | ||
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
* Creates a new entity instance or instances. | ||
* Can copy properties from the given object into new entities. | ||
*/ | ||
create(fromRawEntity) { | ||
return this.repository.create(fromRawEntity); | ||
create(plainObjectOrObjects) { | ||
if (plainObjectOrObjects instanceof Array) { | ||
return this.repository.create(plainObjectOrObjects); | ||
} | ||
else if (plainObjectOrObjects) { | ||
return this.repository.create(plainObjectOrObjects); | ||
} | ||
else { | ||
return this.repository.create(); | ||
} | ||
} | ||
/** | ||
* Creates entities from a given array of plain javascript objects. | ||
*/ | ||
createMany(copyFromObjects) { | ||
return this.repository.createMany(copyFromObjects); | ||
} | ||
/** | ||
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then | ||
@@ -58,4 +61,4 @@ * it loads it (and everything related to it), replaces all values with the new ones from the given object | ||
*/ | ||
initialize(object) { | ||
return Rx.Observable.fromPromise(this.repository.initialize(object)); | ||
preload(object) { | ||
return Rx.Observable.fromPromise(this.repository.preload(object)); | ||
} | ||
@@ -141,34 +144,2 @@ /** | ||
} | ||
setRelation(relationName, entityId, relatedEntityId) { | ||
return Rx.Observable.fromPromise(this.repository.setRelation(relationName, entityId, relatedEntityId)); | ||
} | ||
addToRelation(relationName, entityId, relatedEntityIds) { | ||
return Rx.Observable.fromPromise(this.repository.addToRelation(relationName, entityId, relatedEntityIds)); | ||
} | ||
removeFromRelation(relationName, entityId, relatedEntityIds) { | ||
return Rx.Observable.fromPromise(this.repository.removeFromRelation(relationName, entityId, relatedEntityIds)); | ||
} | ||
addAndRemoveFromRelation(relation, entityId, addRelatedEntityIds, removeRelatedEntityIds) { | ||
return Rx.Observable.fromPromise(this.repository.addAndRemoveFromRelation(relation, entityId, addRelatedEntityIds, removeRelatedEntityIds)); | ||
} | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(id) { | ||
return Rx.Observable.fromPromise(this.repository.removeById(id)); | ||
} | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(ids) { | ||
return Rx.Observable.fromPromise(this.repository.removeByIds(ids)); | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Static Methods | ||
// ------------------------------------------------------------------------- | ||
static ownsMetadata(reactiveRepository, metadata) { | ||
return Repository_1.Repository.ownsMetadata(reactiveRepository.repository, metadata); | ||
} | ||
} | ||
@@ -175,0 +146,0 @@ exports.ReactiveRepository = ReactiveRepository; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="chai" /> | ||
import { Connection } from "../connection/Connection"; | ||
@@ -9,5 +10,2 @@ import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
import { FindOptions } from "./FindOptions"; | ||
import { EntityMetadataCollection } from "../metadata-args/collection/EntityMetadataCollection"; | ||
import { Broadcaster } from "../subscriber/Broadcaster"; | ||
import { Driver } from "../driver/Driver"; | ||
import { ObjectLiteral } from "../common/ObjectLiteral"; | ||
@@ -19,6 +17,3 @@ /** | ||
protected connection: Connection; | ||
protected broadcaster: Broadcaster; | ||
protected entityMetadatas: EntityMetadataCollection; | ||
protected metadata: EntityMetadata; | ||
protected driver: Driver; | ||
protected persistOperationExecutor: PersistOperationExecutor; | ||
@@ -28,6 +23,6 @@ protected entityPersistOperationBuilder: EntityPersistOperationBuilder; | ||
protected plainObjectToDatabaseEntityTransformer: PlainObjectToDatabaseEntityTransformer<Entity>; | ||
constructor(connection: Connection, broadcaster: Broadcaster, entityMetadatas: EntityMetadataCollection, metadata: EntityMetadata); | ||
constructor(connection: Connection, metadata: EntityMetadata); | ||
/** | ||
* Repository's target is an object (or unique string in the case if entity is loaded from a schema) that is managed | ||
* by this repository. | ||
* Returns object that is managed by this repository. | ||
* If this repository manages entity from schema, then it returns a name of that schema instead. | ||
*/ | ||
@@ -44,11 +39,16 @@ readonly target: Function | string; | ||
/** | ||
* Creates a new entity. If plainObject is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
* Creates a new entity instance. | ||
*/ | ||
create(plainObject?: Object): Entity; | ||
create(): Entity; | ||
/** | ||
* Creates entities from a given array of plain javascript objects. | ||
* 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. | ||
*/ | ||
createMany(plainObjects: Object[]): Entity[]; | ||
create(plainObjects: Object[]): 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(plainObject: Object): Entity; | ||
/** | ||
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then | ||
@@ -59,3 +59,3 @@ * it loads it (and everything related to it), replaces all values with the new ones from the given object | ||
*/ | ||
initialize(object: Object): Promise<Entity>; | ||
preload(object: Object): Promise<Entity>; | ||
/** | ||
@@ -66,11 +66,16 @@ * Merges multiple entities (or entity-like objects) into one new entity. | ||
/** | ||
* Persists many objects in the same time. | ||
* Persists (saves) all given entities in the database. | ||
* If entities do not exist in the database then inserts, otherwise updates. | ||
*/ | ||
persistMany(...entities: Entity[]): Promise<Entity[]>; | ||
persist(entities: Entity[]): Promise<Entity[]>; | ||
/** | ||
* Persists (saves) a given entity in the database. If entity does not exist in the database then it inserts it, | ||
* else if entity already exist in the database then it updates it. | ||
* Persists (saves) a given entity in the database. | ||
* If entity does not exist in the database then inserts, otherwise updates. | ||
*/ | ||
persist(entity: Entity): Promise<Entity>; | ||
/** | ||
* Removes a given entities from the database. | ||
*/ | ||
remove(entities: Entity[]): Promise<Entity[]>; | ||
/** | ||
* Removes a given entity from the database. | ||
@@ -88,7 +93,7 @@ */ | ||
/** | ||
* Finds entities with . | ||
* Finds entities with given find options. | ||
*/ | ||
find(options: FindOptions): Promise<Entity[]>; | ||
/** | ||
* Finds entities that match given conditions. | ||
* Finds entities that match given conditions and find options. | ||
*/ | ||
@@ -121,7 +126,7 @@ find(conditions: Object, options: FindOptions): Promise<Entity[]>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
* Finds first entity that matches given find options. | ||
*/ | ||
findOne(options: FindOptions): Promise<Entity>; | ||
/** | ||
* Finds first entity that matches given conditions. | ||
* Finds first entity that matches given conditions and find options. | ||
*/ | ||
@@ -134,3 +139,3 @@ findOne(conditions: Object, options: FindOptions): Promise<Entity>; | ||
/** | ||
* Executes raw SQL query and returns raw database results. | ||
* Executes a raw SQL query and returns a raw database results. | ||
*/ | ||
@@ -141,69 +146,3 @@ query(query: string): Promise<any>; | ||
*/ | ||
transaction(runInTransaction: () => any | Promise<any>): Promise<any>; | ||
/** | ||
* Sets given relatedEntityId to the value of the relation of the entity with entityId id. | ||
* Should be used when you want quickly and efficiently set a relation (for many-to-one and one-to-many) to some entity. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
setRelation(relationName: string, entityId: any, relatedEntityId: any): Promise<void>; | ||
setRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityId: any): Promise<void>; | ||
/** | ||
* Sets given relatedEntityId to the value of the relation of the entity with entityId id. | ||
* Should be used when you want quickly and efficiently set a relation (for many-to-one and one-to-many) to some entity. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
setInverseRelation(relationName: string, relatedEntityId: any, entityId: any): Promise<void>; | ||
setInverseRelation(relationName: ((t: Entity) => string | any), relatedEntityId: any, entityId: any): Promise<void>; | ||
/** | ||
* Adds a new relation between two entities into relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently add a relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addToRelation(relationName: string, entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
addToRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Adds a new relation between two entities into relation's many-to-many table from inverse side of the given relation. | ||
* Should be used when you want quickly and efficiently add a relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addToInverseRelation(relationName: string, relatedEntityId: any, entityIds: any[]): Promise<void>; | ||
addToInverseRelation(relationName: ((t: Entity) => string | any), relatedEntityId: any, entityIds: any[]): Promise<void>; | ||
/** | ||
* Removes a relation between two entities from relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeFromRelation(relationName: string, entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
removeFromRelation(relationName: ((t: Entity) => string | any), entityId: any, relatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Removes a relation between two entities from relation's many-to-many table. | ||
* Should be used when you want quickly and efficiently remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeFromInverseRelation(relationName: string, relatedEntityId: any, entityIds: any[]): Promise<void>; | ||
removeFromInverseRelation(relationName: ((t: Entity) => string | any), relatedEntityId: any, entityIds: any[]): Promise<void>; | ||
/** | ||
* Performs both #addToRelation and #removeFromRelation operations. | ||
* Should be used when you want quickly and efficiently and and remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addAndRemoveFromRelation(relation: string, entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Promise<void>; | ||
addAndRemoveFromRelation(relation: ((t: Entity) => string | any), entityId: any, addRelatedEntityIds: any[], removeRelatedEntityIds: any[]): Promise<void>; | ||
/** | ||
* Performs both #addToRelation and #removeFromRelation operations. | ||
* Should be used when you want quickly and efficiently and and remove a many-to-many relation between two entities. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
addAndRemoveFromInverseRelation(relation: string, relatedEntityId: any, addEntityIds: any[], removeEntityIds: any[]): Promise<void>; | ||
addAndRemoveFromInverseRelation(relation: ((t: Entity) => string | any), relatedEntityId: any, addEntityIds: any[], removeEntityIds: any[]): Promise<void>; | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(id: any): Promise<void>; | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(ids: any[]): Promise<void>; | ||
transaction(runInTransaction: () => Promise<any> | any): Promise<any>; | ||
private createFindQueryBuilder(conditionsOrFindOptions?, options?); | ||
@@ -222,6 +161,2 @@ /** | ||
private extractObjectsById(entity, metadata, entityWithIds?); | ||
/** | ||
* Checks if given repository owns given metadata. | ||
*/ | ||
static ownsMetadata(repository: Repository<any>, metadata: EntityMetadata): boolean; | ||
} |
@@ -23,10 +23,7 @@ "use strict"; | ||
// ------------------------------------------------------------------------- | ||
constructor(connection, broadcaster, entityMetadatas, metadata) { | ||
constructor(connection, metadata) { | ||
this.connection = connection; | ||
this.broadcaster = broadcaster; | ||
this.entityMetadatas = entityMetadatas; | ||
this.metadata = metadata; | ||
this.driver = connection.driver; | ||
this.persistOperationExecutor = new PersistOperationExecutor_1.PersistOperationExecutor(connection.driver, entityMetadatas, this.broadcaster); | ||
this.entityPersistOperationBuilder = new EntityPersistOperationsBuilder_1.EntityPersistOperationBuilder(entityMetadatas); | ||
this.persistOperationExecutor = new PersistOperationExecutor_1.PersistOperationExecutor(connection.driver, connection.entityMetadatas, this.connection.broadcaster); // todo: better to pass connection? | ||
this.entityPersistOperationBuilder = new EntityPersistOperationsBuilder_1.EntityPersistOperationBuilder(connection.entityMetadatas); | ||
this.plainObjectToEntityTransformer = new PlainObjectToNewEntityTransformer_1.PlainObjectToNewEntityTransformer(); | ||
@@ -39,4 +36,4 @@ this.plainObjectToDatabaseEntityTransformer = new PlainObjectToDatabaseEntityTransformer_1.PlainObjectToDatabaseEntityTransformer(); | ||
/** | ||
* Repository's target is an object (or unique string in the case if entity is loaded from a schema) that is managed | ||
* by this repository. | ||
* Returns object that is managed by this repository. | ||
* If this repository manages entity from schema, then it returns a name of that schema instead. | ||
*/ | ||
@@ -51,7 +48,7 @@ get target() { | ||
const columnName = this.metadata.primaryColumn.propertyName; | ||
return !!(entity && | ||
return !!entity && | ||
entity.hasOwnProperty(columnName) && | ||
entity[columnName] !== null && | ||
entity[columnName] !== undefined && | ||
entity[columnName] !== ""); | ||
entity[columnName] !== ""; | ||
} | ||
@@ -62,3 +59,3 @@ /** | ||
createQueryBuilder(alias) { | ||
return new QueryBuilder_1.QueryBuilder(this.driver, this.entityMetadatas, this.broadcaster) | ||
return new QueryBuilder_1.QueryBuilder(this.connection.driver, this.connection.entityMetadatas, this.connection.broadcaster) // todo: better to pass connection? | ||
.select(alias) | ||
@@ -68,18 +65,15 @@ .from(this.metadata.target, alias); | ||
/** | ||
* Creates a new entity. If plainObject is given then it creates a new entity and copies all entity properties | ||
* from this object into a new entity (copies only properties that should be in a new entity). | ||
* Creates a new entity instance or instances. | ||
* Can copy properties from the given object into new entities. | ||
*/ | ||
create(plainObject) { | ||
create(plainObjectOrObjects) { | ||
if (plainObjectOrObjects instanceof Array) { | ||
return plainObjectOrObjects.map(object => this.create(object)); | ||
} | ||
const newEntity = this.metadata.create(); | ||
if (plainObject) | ||
this.plainObjectToEntityTransformer.transform(newEntity, plainObject, this.metadata); | ||
if (plainObjectOrObjects) | ||
this.plainObjectToEntityTransformer.transform(newEntity, plainObjectOrObjects, this.metadata); | ||
return newEntity; | ||
} | ||
/** | ||
* Creates entities from a given array of plain javascript objects. | ||
*/ | ||
createMany(plainObjects) { | ||
return plainObjects.map(object => this.create(object)); | ||
} | ||
/** | ||
* Creates a new entity from the given plan javascript object. If entity already exist in the database, then | ||
@@ -90,3 +84,3 @@ * it loads it (and everything related to it), replaces all values with the new ones from the given object | ||
*/ | ||
initialize(object) { | ||
preload(object) { | ||
const queryBuilder = this.createQueryBuilder(this.metadata.table.name); | ||
@@ -102,57 +96,17 @@ return this.plainObjectToDatabaseEntityTransformer.transform(object, this.metadata, queryBuilder); | ||
return newEntity; | ||
/*const comparator = new Comporator(metadata, entity, object, ComparationMode.NON_EMPTY); | ||
comparator.columns.forEach(column => { | ||
entity[column.propertyName] = object[column.propertyName]; | ||
}); | ||
comparator.singleValueRelations.forEach(relation => { | ||
entity[relation.propertyName] = this.mergeEntityWithPlainObject(relation.inverseEntityMetadata, entity[relation.propertyName], object[relation.propertyName]); | ||
}); | ||
comparator.multiValueRelations.forEach(relation => { | ||
entity[relation.propertyName] = (object[relation.propertyName] as ObjectLiteral[]).map(subObject => { | ||
return this.mergeEntityWithPlainObject(relation.inverseEntityMetadata, entity[relation.propertyName], subObject); | ||
}); | ||
}); | ||
// comparator.applyToRelationItems(() => {}); | ||
*/ | ||
/*metadata.extractNonEmptyColumns(object).forEach(column => { | ||
entity[column.propertyName] = object[column.propertyName]; | ||
}); | ||
metadata.extractExistSingleValueRelations(object).forEach(relation => { | ||
if (entity[relation.propertyName] instanceof Object) { | ||
entity[relation.propertyName] = this.mergeEntityWithPlainObject(relation.inverseEntityMetadata, entity[relation.propertyName], object[relation.propertyName]); | ||
} else { | ||
entity[relation.propertyName] = object[relation.propertyName]; // todo: do we really need to do it? - probably yes for null and undefined values, but what about others | ||
} | ||
}); | ||
metadata.extractExistMultiValueRelations(object).forEach(relation => { | ||
entity[relation.propertyName] = (object[relation.propertyName] as ObjectLiteral[]).map(subObject => { | ||
if (entity[relation.propertyName] instanceof Object) { | ||
return this.mergeEntityWithPlainObject(relation.inverseEntityMetadata, entity[relation.propertyName], subObject); | ||
} else { | ||
entity[relation.propertyName] = object[relation.propertyName]; // todo: do we really need to do it? - probably yes for null and undefined values, but what about others | ||
} | ||
}); | ||
});*/ | ||
} | ||
/** | ||
* Persists many objects in the same time. | ||
* Persists one or many given entities. | ||
*/ | ||
persistMany(...entities) { | ||
persist(entityOrEntities) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return Promise.all(entities.map(entity => this.persist(entity))); | ||
}); | ||
} | ||
/** | ||
* Persists (saves) a given entity in the database. If entity does not exist in the database then it inserts it, | ||
* else if entity already exist in the database then it updates it. | ||
*/ | ||
persist(entity) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield Promise.resolve(); // resolve is required because need to wait until lazy relations loaded | ||
const allPersistedEntities = yield this.extractObjectsById(entity, this.metadata); | ||
// if multiple entities given then go throw all of them and save them | ||
if (entityOrEntities instanceof Array) | ||
return Promise.all(entityOrEntities.map(entity => this.persist(entity))); | ||
// resolve is required because need to wait until lazy relations loaded | ||
yield Promise.resolve(); | ||
const allPersistedEntities = yield this.extractObjectsById(entityOrEntities, this.metadata); | ||
let loadedDbEntity = null; | ||
if (this.hasId(entity)) | ||
loadedDbEntity = yield this.initialize(entity); | ||
if (this.hasId(entityOrEntities)) | ||
loadedDbEntity = yield this.preload(entityOrEntities); | ||
let entityWithIds = []; | ||
@@ -164,5 +118,5 @@ if (loadedDbEntity) | ||
const persistedEntity = { | ||
id: this.metadata.getEntityId(entity), | ||
id: this.metadata.getEntityId(entityOrEntities), | ||
entityTarget: this.metadata.target, | ||
entity: entity | ||
entity: entityOrEntities | ||
}; | ||
@@ -176,20 +130,23 @@ const dbEntity = { | ||
yield this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
return entity; | ||
return entityOrEntities; | ||
}); | ||
} | ||
/** | ||
* Removes a given entity from the database. | ||
* Removes one or many given entities. | ||
*/ | ||
remove(entity) { | ||
remove(entityOrEntities) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const dbEntity = yield this.initialize(entity); | ||
entity[this.metadata.primaryColumn.name] = undefined; | ||
// 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 dbEntity = yield this.preload(entityOrEntities); | ||
entityOrEntities[this.metadata.primaryColumn.name] = undefined; | ||
const [dbEntities, allPersistedEntities] = yield Promise.all([ | ||
this.extractObjectsById(dbEntity, this.metadata), | ||
this.extractObjectsById(entity, this.metadata) | ||
this.extractObjectsById(entityOrEntities, this.metadata) | ||
]); | ||
const entityWithId = { | ||
id: this.metadata.getEntityId(entity), | ||
id: this.metadata.getEntityId(entityOrEntities), | ||
entityTarget: this.metadata.target, | ||
entity: entity | ||
entity: entityOrEntities | ||
}; | ||
@@ -203,7 +160,7 @@ const dbEntityWithId = { | ||
yield this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
return entity; | ||
return entityOrEntities; | ||
}); | ||
} | ||
/** | ||
* Finds entities that match given conditions. | ||
* Finds entities that match given conditions and/or find options. | ||
*/ | ||
@@ -221,8 +178,8 @@ find(conditionsOrFindOptions, options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const qb = this.createFindQueryBuilder(conditionsOrFindOptions, options); | ||
return qb.getResultsAndCount(); | ||
return this.createFindQueryBuilder(conditionsOrFindOptions, options) | ||
.getResultsAndCount(); | ||
}); | ||
} | ||
/** | ||
* Finds first entity that matches given conditions. | ||
* Finds first entity that matches given conditions and/or find options. | ||
*/ | ||
@@ -245,7 +202,7 @@ findOne(conditionsOrFindOptions, options) { | ||
/** | ||
* Executes raw SQL query and returns raw database results. | ||
* Executes a raw SQL query and returns a raw database results. | ||
*/ | ||
query(query) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.driver.query(query); | ||
return this.connection.driver.query(query); | ||
}); | ||
@@ -259,3 +216,3 @@ } | ||
let runInTransactionResult; | ||
return this.driver | ||
return this.connection.driver | ||
.beginTransaction() | ||
@@ -265,6 +222,6 @@ .then(() => runInTransaction()) | ||
runInTransactionResult = result; | ||
return this.driver.commitTransaction(); | ||
return this.connection.driver.commitTransaction(); | ||
}) | ||
.catch(err => { | ||
return this.driver.rollbackTransaction() | ||
return this.connection.driver.rollbackTransaction() | ||
.then(() => { | ||
@@ -280,185 +237,2 @@ throw err; | ||
} | ||
setRelation(relationName, entityId, relatedEntityId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
// if (relation.isManyToMany || relation.isOneToMany || relation.isOneToOneNotOwner) | ||
// throw new Error(`Only many-to-one and one-to-one with join column are supported for this operation. ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
if (relation.isManyToMany) | ||
throw new Error(`Many-to-many relation is not supported for this operation. Use #addToRelation method for many-to-many relations.`); | ||
let table, values = {}, conditions = {}; | ||
if (relation.isOwning) { | ||
table = relation.entityMetadata.table.name; | ||
values[relation.name] = relatedEntityId; | ||
conditions[relation.joinColumn.referencedColumn.name] = entityId; | ||
} | ||
else { | ||
table = relation.inverseEntityMetadata.table.name; | ||
values[relation.inverseRelation.name] = relatedEntityId; | ||
conditions[relation.inverseRelation.joinColumn.referencedColumn.name] = entityId; | ||
} | ||
return this.driver.update(table, values, conditions).then(() => { }); | ||
}); | ||
} | ||
setInverseRelation(relationName, relatedEntityId, entityId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
// if (relation.isManyToMany || relation.isOneToMany || relation.isOneToOneNotOwner) | ||
// throw new Error(`Only many-to-one and one-to-one with join column are supported for this operation. ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
if (relation.isManyToMany) | ||
throw new Error(`Many-to-many relation is not supported for this operation. Use #addToRelation method for many-to-many relations.`); | ||
let table, values = {}, conditions = {}; | ||
if (relation.isOwning) { | ||
table = relation.inverseEntityMetadata.table.name; | ||
values[relation.inverseRelation.name] = relatedEntityId; | ||
conditions[relation.inverseRelation.joinColumn.referencedColumn.name] = entityId; | ||
} | ||
else { | ||
table = relation.entityMetadata.table.name; | ||
values[relation.name] = relatedEntityId; | ||
conditions[relation.joinColumn.referencedColumn.name] = entityId; | ||
} | ||
return this.driver.update(table, values, conditions).then(() => { }); | ||
}); | ||
} | ||
addToRelation(relationName, entityId, relatedEntityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
if (!relation.isManyToMany) | ||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
const insertPromises = relatedEntityIds.map(relatedEntityId => { | ||
const values = {}; | ||
if (relation.isOwning) { | ||
values[relation.junctionEntityMetadata.columns[0].name] = entityId; | ||
values[relation.junctionEntityMetadata.columns[1].name] = relatedEntityId; | ||
} | ||
else { | ||
values[relation.junctionEntityMetadata.columns[1].name] = entityId; | ||
values[relation.junctionEntityMetadata.columns[0].name] = relatedEntityId; | ||
} | ||
return this.driver.insert(relation.junctionEntityMetadata.table.name, values); | ||
}); | ||
return Promise.all(insertPromises).then(() => { }); | ||
}); | ||
} | ||
addToInverseRelation(relationName, relatedEntityId, entityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
if (!relation.isManyToMany) | ||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
const insertPromises = entityIds.map(entityId => { | ||
const values = {}; | ||
if (relation.isOwning) { | ||
values[relation.junctionEntityMetadata.columns[0].name] = entityId; | ||
values[relation.junctionEntityMetadata.columns[1].name] = relatedEntityId; | ||
} | ||
else { | ||
values[relation.junctionEntityMetadata.columns[1].name] = entityId; | ||
values[relation.junctionEntityMetadata.columns[0].name] = relatedEntityId; | ||
} | ||
return this.driver.insert(relation.junctionEntityMetadata.table.name, values); | ||
}); | ||
return Promise.all(insertPromises).then(() => { }); | ||
}); | ||
} | ||
removeFromRelation(relationName, entityId, relatedEntityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
if (!relation.isManyToMany) | ||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
// check if given relation entity ids is empty - then nothing to do here (otherwise next code will remove all ids) | ||
if (!relatedEntityIds || !relatedEntityIds.length) | ||
return Promise.resolve(); | ||
const qb = this.createQueryBuilder("junctionEntity") | ||
.delete(relation.junctionEntityMetadata.table.name); | ||
const firstColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[0].name : relation.junctionEntityMetadata.columns[1].name; | ||
const secondColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[1].name : relation.junctionEntityMetadata.columns[0].name; | ||
relatedEntityIds.forEach((relatedEntityId, index) => { | ||
qb.orWhere(`(${firstColumnName}=:entityId AND ${secondColumnName}=:relatedEntity_${index})`) | ||
.setParameter("relatedEntity_" + index, relatedEntityId); | ||
}); | ||
return qb | ||
.setParameter("entityId", entityId) | ||
.execute() | ||
.then(() => { }); | ||
}); | ||
} | ||
removeFromInverseRelation(relationName, relatedEntityId, entityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const propertyName = this.metadata.computePropertyName(relationName); | ||
if (!this.metadata.hasRelationWithPropertyName(propertyName)) | ||
throw new Error(`Relation ${propertyName} was not found in the ${this.metadata.name} entity.`); | ||
const relation = this.metadata.findRelationWithPropertyName(propertyName); | ||
if (!relation.isManyToMany) | ||
throw new Error(`Only many-to-many relation supported for this operation. However ${this.metadata.name}#${propertyName} relation type is ${relation.relationType}`); | ||
// check if given entity ids is empty - then nothing to do here (otherwise next code will remove all ids) | ||
if (!entityIds || !entityIds.length) | ||
return Promise.resolve(); | ||
const qb = this.createQueryBuilder("junctionEntity") | ||
.delete(relation.junctionEntityMetadata.table.name); | ||
const firstColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[1].name : relation.junctionEntityMetadata.columns[0].name; | ||
const secondColumnName = relation.isOwning ? relation.junctionEntityMetadata.columns[0].name : relation.junctionEntityMetadata.columns[1].name; | ||
entityIds.forEach((entityId, index) => { | ||
qb.orWhere(`(${firstColumnName}=:relatedEntityId AND ${secondColumnName}=:entity_${index})`) | ||
.setParameter("entity_" + index, entityId); | ||
}); | ||
yield qb.setParameter("relatedEntityId", relatedEntityId).execute(); | ||
}); | ||
} | ||
addAndRemoveFromRelation(relation, entityId, addRelatedEntityIds, removeRelatedEntityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield Promise.all([ | ||
this.addToRelation(relation, entityId, addRelatedEntityIds), | ||
this.removeFromRelation(relation, entityId, removeRelatedEntityIds) | ||
]); | ||
}); | ||
} | ||
addAndRemoveFromInverseRelation(relation, relatedEntityId, addEntityIds, removeEntityIds) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield Promise.all([ | ||
this.addToInverseRelation(relation, relatedEntityId, addEntityIds), | ||
this.removeFromInverseRelation(relation, relatedEntityId, removeEntityIds) | ||
]); | ||
}); | ||
} | ||
/** | ||
* Removes entity with the given id. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeById(id) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const alias = this.metadata.table.name; | ||
yield this.createQueryBuilder(alias) | ||
.delete() | ||
.where(alias + "." + this.metadata.primaryColumn.propertyName + "=:id", { id: id }) | ||
.execute(); | ||
}); | ||
} | ||
/** | ||
* Removes all entities with the given ids. | ||
* Note that event listeners and event subscribers won't work (and will not send any events) when using this operation. | ||
*/ | ||
removeByIds(ids) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const alias = this.metadata.table.name; | ||
yield this.createQueryBuilder(alias) | ||
.delete() | ||
.where(alias + "." + this.metadata.primaryColumn.propertyName + " IN (:ids)", { ids: ids }) | ||
.execute(); | ||
}); | ||
} | ||
// ------------------------------------------------------------------------- | ||
@@ -496,3 +270,3 @@ // Private Methods | ||
.map(entityWithId => { | ||
const metadata = this.entityMetadatas.findByTarget(entityWithId.entityTarget); | ||
const metadata = this.connection.entityMetadatas.findByTarget(entityWithId.entityTarget); | ||
const repository = this.connection.getRepository(entityWithId.entityTarget); // todo: fix type | ||
@@ -543,11 +317,2 @@ return repository.findOneById(entityWithId.id).then(loadedEntity => { | ||
} | ||
// ------------------------------------------------------------------------- | ||
// Static Methods | ||
// ------------------------------------------------------------------------- | ||
/** | ||
* Checks if given repository owns given metadata. | ||
*/ | ||
static ownsMetadata(repository, metadata) { | ||
return repository.metadata === metadata; | ||
} | ||
} | ||
@@ -554,0 +319,0 @@ exports.Repository = Repository; |
import { TreeRepository } from "./TreeRepository"; | ||
import { EntityMetadata } from "../metadata/EntityMetadata"; | ||
import { EntityMetadataCollection } from "../metadata-args/collection/EntityMetadataCollection"; | ||
import { Connection } from "../connection/Connection"; | ||
import { Repository } from "./Repository"; | ||
import { ReactiveRepository } from "./ReactiveRepository"; | ||
import { ReactiveTreeRepository } from "./ReactiveTreeRepository"; | ||
import { Broadcaster } from "../subscriber/Broadcaster"; | ||
import { TreeReactiveRepository } from "./TreeReactiveRepository"; | ||
import { SpecificRepository } from "./SpecificRepository"; | ||
import { SpecificReactiveRepository } from "./ReactiveSpecificRepository"; | ||
/** | ||
*/ | ||
export declare class RepositoryFactory { | ||
createRepository(connection: Connection, broadcaster: Broadcaster, allMetadatas: EntityMetadataCollection, metadata: EntityMetadata): Repository<any>; | ||
createTreeRepository(connection: Connection, broadcaster: Broadcaster, allMetadatas: EntityMetadataCollection, metadata: EntityMetadata): TreeRepository<any>; | ||
createRepository(connection: Connection, metadata: EntityMetadata): Repository<any>; | ||
createTreeRepository(connection: Connection, metadata: EntityMetadata): TreeRepository<any>; | ||
createReactiveRepository(repository: Repository<any>): ReactiveRepository<any>; | ||
createReactiveTreeRepository(repository: TreeRepository<any>): ReactiveTreeRepository<any>; | ||
createReactiveTreeRepository(repository: TreeRepository<any>): TreeReactiveRepository<any>; | ||
createSpecificRepository(connection: Connection, metadata: EntityMetadata, repository: Repository<any>): SpecificRepository<any>; | ||
createSpecificReactiveRepository(repository: SpecificRepository<any>): SpecificReactiveRepository<any>; | ||
} |
@@ -5,3 +5,5 @@ "use strict"; | ||
const ReactiveRepository_1 = require("./ReactiveRepository"); | ||
const ReactiveTreeRepository_1 = require("./ReactiveTreeRepository"); | ||
const TreeReactiveRepository_1 = require("./TreeReactiveRepository"); | ||
const SpecificRepository_1 = require("./SpecificRepository"); | ||
const ReactiveSpecificRepository_1 = require("./ReactiveSpecificRepository"); | ||
/** | ||
@@ -13,7 +15,7 @@ */ | ||
// ------------------------------------------------------------------------- | ||
createRepository(connection, broadcaster, allMetadatas, metadata) { | ||
return new Repository_1.Repository(connection, broadcaster, allMetadatas, metadata); | ||
createRepository(connection, metadata) { | ||
return new Repository_1.Repository(connection, metadata); | ||
} | ||
createTreeRepository(connection, broadcaster, allMetadatas, metadata) { | ||
return new TreeRepository_1.TreeRepository(connection, broadcaster, allMetadatas, metadata); | ||
createTreeRepository(connection, metadata) { | ||
return new TreeRepository_1.TreeRepository(connection, metadata); | ||
} | ||
@@ -24,4 +26,10 @@ createReactiveRepository(repository) { | ||
createReactiveTreeRepository(repository) { | ||
return new ReactiveTreeRepository_1.ReactiveTreeRepository(repository); | ||
return new TreeReactiveRepository_1.TreeReactiveRepository(repository); | ||
} | ||
createSpecificRepository(connection, metadata, repository) { | ||
return new SpecificRepository_1.SpecificRepository(connection, metadata, repository); | ||
} | ||
createSpecificReactiveRepository(repository) { | ||
return new ReactiveSpecificRepository_1.SpecificReactiveRepository(repository); | ||
} | ||
} | ||
@@ -28,0 +36,0 @@ exports.RepositoryFactory = RepositoryFactory; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments)).next()); | ||
}); | ||
}; | ||
const SchemaBuilder_1 = require("./SchemaBuilder"); | ||
@@ -16,2 +24,3 @@ const ForeignKeyMetadata_1 = require("../metadata/ForeignKeyMetadata"); | ||
return this.query(sql).then(results => { | ||
// console.log("changed columns: ", results); | ||
return columns.filter(column => { | ||
@@ -54,3 +63,3 @@ const dbData = results.find(result => result.column_name === column.name); | ||
addForeignKeyQuery(foreignKey) { | ||
let sql = `ALTER TABLE ${foreignKey.tableName} ADD CONSTRAINT \`${foreignKey.name}\` ` + | ||
let sql = `ALTER TABLE ${foreignKey.tableName} ADD CONSTRAINT ${foreignKey.name} ` + | ||
`FOREIGN KEY (${foreignKey.columnNames.join(", ")}) ` + | ||
@@ -72,5 +81,7 @@ `REFERENCES ${foreignKey.referencedTable.name}(${foreignKey.referencedColumnNames.join(",")})`; | ||
getTableForeignQuery(tableName) { | ||
const sql = `SELECT * FROM INFORMATION_SCHEMA.table_constraints WHERE TABLE_CATALOG = '${this.driver.db}' ` | ||
+ `AND TABLE_NAME = '${tableName}' AND CONSTRAINT_TYPE='FOREIGN KEY'`; | ||
return this.query(sql).then(results => results.map(result => result.CONSTRAINT_NAME)); | ||
const sql = `SELECT tc.constraint_name FROM information_schema.table_constraints AS tc ` + | ||
`WHERE constraint_type = 'FOREIGN KEY' AND tc.table_catalog='${this.driver.db}' AND tc.table_name='${tableName}';`; | ||
// const sql = `SELECT * FROM INFORMATION_SCHEMA.table_constraints WHERE TABLE_CATALOG = '${this.driver.db}' ` | ||
// + `AND TABLE_NAME = '${tableName}' AND CONSTRAINT_TYPE='FOREIGN KEY'`; | ||
return this.query(sql).then(results => results.map(result => result.constraint_name)); | ||
} | ||
@@ -83,3 +94,23 @@ getTableUniqueKeysQuery(tableName) { | ||
getTableIndicesQuery(tableName) { | ||
const sql = `SHOW INDEX FROM ${tableName}`; | ||
const sql = `select | ||
t.relname as table_name, | ||
i.relname as index_name, | ||
a.attname as column_name, | ||
ix.indisprimary as is_primary | ||
from | ||
pg_class t, | ||
pg_class i, | ||
pg_index ix, | ||
pg_attribute a | ||
where | ||
t.oid = ix.indrelid | ||
and i.oid = ix.indexrelid | ||
and a.attrelid = t.oid | ||
and a.attnum = ANY(ix.indkey) | ||
and t.relkind = 'r' | ||
and t.relname = '${tableName}' | ||
order by | ||
t.relname, | ||
i.relname; | ||
`; | ||
return this.query(sql).then(results => { | ||
@@ -89,7 +120,7 @@ // exclude foreign keys | ||
return results | ||
.filter(result => result.Key_name !== "PRIMARY" && foreignKeys.indexOf(result.Key_name) === -1) | ||
.filter(result => result.is_primary !== true && foreignKeys.indexOf(result.index_name) === -1) | ||
.map(result => ({ | ||
key: result.Key_name, | ||
key: result.index_name, | ||
sequence: result.Seq_in_index, | ||
column: result.Column_name | ||
column: result.column_name | ||
})); | ||
@@ -104,5 +135,10 @@ }); | ||
} | ||
dropIndex(tableName, indexName) { | ||
const sql = `ALTER TABLE ${tableName} DROP INDEX \`${indexName}\``; | ||
return this.query(sql).then(() => { }); | ||
dropIndex(tableName, indexName, isGenerated = false) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (isGenerated) { | ||
yield this.query(`ALTER SEQUENCE foo_id_seq OWNED BY NONE`); | ||
} | ||
const sql = `ALTER TABLE ${tableName} DROP CONSTRAINT ${indexName}`; | ||
yield this.query(sql); | ||
}); | ||
} | ||
@@ -138,3 +174,7 @@ createIndex(tableName, index) { | ||
buildCreateColumnSql(column, skipPrimary) { | ||
let c = column.name + " " + this.normalizeType(column); | ||
let c = column.name; | ||
if (column.isGenerated === true) | ||
c += " SERIAL"; | ||
if (!column.isGenerated) | ||
c += " " + this.normalizeType(column); | ||
if (column.isNullable !== true) | ||
@@ -144,4 +184,2 @@ c += " NOT NULL"; | ||
c += " PRIMARY KEY"; | ||
// if (column.isGenerated === true) // don't use skipPrimary here since updates can update already exist primary without auto inc. | ||
// c += " AUTO_INCREMENT"; | ||
// TODO: implement auto increment | ||
@@ -148,0 +186,0 @@ if (column.comment) |
@@ -111,6 +111,6 @@ "use strict"; | ||
const updates = columns | ||
.filter(column => !!column.oldColumnName && column.name !== column.oldColumnName) | ||
.filter(column => !!column.oldColumnName && column.name.toLowerCase() !== column.oldColumnName) | ||
.filter(column => dbColumns.indexOf(column.oldColumnName) !== -1) | ||
.map((column) => __awaiter(this, void 0, void 0, function* () { | ||
yield this.dropColumnForeignKeys(table.name, column.name, foreignKeys); | ||
yield this.dropColumnForeignKeys(table.name, column.name.toLowerCase(), foreignKeys); | ||
return this.schemaBuilder.changeColumnQuery(table.name, column.oldColumnName, column); | ||
@@ -128,3 +128,3 @@ })); | ||
const dropColumnQueries = dbColumns | ||
.filter(dbColumn => !columns.find(column => column.name === dbColumn)) | ||
.filter(dbColumn => !columns.find(column => column.name.toLowerCase() === dbColumn)) | ||
.map((dbColumn) => __awaiter(this, void 0, void 0, function* () { | ||
@@ -143,3 +143,3 @@ yield this.dropColumnForeignKeys(table.name, dbColumn, foreignKeys); | ||
const newColumnQueries = columns | ||
.filter(column => dbColumns.indexOf(column.name) === -1) | ||
.filter(column => dbColumns.indexOf(column.name.toLowerCase()) === -1) | ||
.map(column => this.schemaBuilder.addColumnQuery(table.name, column)); | ||
@@ -156,7 +156,7 @@ return Promise.all(newColumnQueries); | ||
const updateQueries = changedColumns.map((changedColumn) => __awaiter(this, void 0, void 0, function* () { | ||
const column = columns.find(column => column.name === changedColumn.columnName); | ||
const column = columns.find(column => column.name.toLowerCase() === changedColumn.columnName); | ||
if (!column) | ||
throw new Error(`Column ${changedColumn.columnName} was not found in the given columns`); | ||
yield this.dropColumnForeignKeys(table.name, column.name, foreignKeys); | ||
return this.schemaBuilder.changeColumnQuery(table.name, column.name, column, changedColumn.hasPrimaryKey); | ||
yield this.dropColumnForeignKeys(table.name, column.name.toLowerCase(), foreignKeys); | ||
return this.schemaBuilder.changeColumnQuery(table.name, column.name.toLowerCase(), column, changedColumn.hasPrimaryKey); | ||
})); | ||
@@ -186,9 +186,9 @@ return Promise.all(updateQueries); | ||
.filter(column => column.isUnique) | ||
.filter(column => dbKeys.indexOf("uk_" + column.name) === -1) | ||
.map(column => this.schemaBuilder.addUniqueKey(table.name, column.name, "uk_" + column.name)); | ||
.filter(column => dbKeys.indexOf("uk_" + column.name.toLowerCase()) === -1) | ||
.map(column => this.schemaBuilder.addUniqueKey(table.name, column.name.toLowerCase(), "uk_" + column.name.toLowerCase())); | ||
// second find columns in db that are unique, however in metadata columns they are not unique | ||
const dropQueries = columns | ||
.filter(column => !column.isUnique) | ||
.filter(column => dbKeys.indexOf("uk_" + column.name) !== -1) | ||
.map(column => this.schemaBuilder.dropIndex(table.name, "uk_" + column.name)); | ||
.filter(column => dbKeys.indexOf("uk_" + column.name.toLowerCase()) !== -1) | ||
.map(column => this.schemaBuilder.dropIndex(table.name, "uk_" + column.name.toLowerCase())); | ||
return Promise.all([addQueries, dropQueries]); | ||
@@ -206,3 +206,5 @@ }); | ||
.filter(tableIndex => !compositeIndices.find(compositeIndex => compositeIndex.name === tableIndex.key)) | ||
.map(tableIndex => this.schemaBuilder.dropIndex(table.name, tableIndex.key)); | ||
.map(tableIndex => { | ||
return this.schemaBuilder.dropIndex(table.name, tableIndex.key); | ||
}); | ||
// then create table indices for all composite indices we have | ||
@@ -209,0 +211,0 @@ const addQueries = compositeIndices |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1470140
509
13780
11
27
+ Added@types/lodash@0.0.29
+ Added@types/node@^6.0.31
+ Added@types/lodash@0.0.29(transitive)
+ Added@types/node@6.14.13(transitive)
Updatedglob@^7.0.5
Updatedlodash@^4.14.1
Updatedmoment@^2.14.1