mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
removed naming strategy stuff, refactoring connection
This commit is contained in:
parent
c5a35d04a4
commit
365055c6ff
@ -26,6 +26,9 @@ each for its own `findOne*` or `find*` methods
|
||||
* custom repositories do not support container anymore
|
||||
* added ActiveRecord support (by extending EntityModel) class
|
||||
* controller / subscriber / migrations from options tsconfig now appended with a project root directory
|
||||
* removed naming strategy decorator, naming strategy by name functionality.
|
||||
Now naming strategy should be registered by passing naming strategy instance directly
|
||||
* driver options now deprecated in connection options
|
||||
|
||||
|
||||
### NEW FEATURES
|
||||
|
||||
@ -75,10 +75,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"app-root-path": "^2.0.1",
|
||||
"dotenv": "^4.0.0",
|
||||
"glob": "^7.1.1",
|
||||
"js-yaml": "^3.8.4",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"yargonaut": "^1.1.2",
|
||||
"yargs": "^8.0.1"
|
||||
"yargs": "^8.0.1",
|
||||
"xml2js": "^0.4.17"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node_modules/.bin/gulp tests"
|
||||
|
||||
@ -13,9 +13,8 @@ const options: ConnectionOptions = {
|
||||
database: "test"
|
||||
},
|
||||
autoSchemaSync: true,
|
||||
usedNamingStrategy: "custom_strategy",
|
||||
entities: [Post],
|
||||
namingStrategies: [CustomNamingStrategy]
|
||||
namingStrategy: new CustomNamingStrategy(),
|
||||
entities: [Post]
|
||||
};
|
||||
|
||||
createConnection(options).then(connection => {
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import {NamingStrategyInterface} from "../../../src/naming-strategy/NamingStrategyInterface";
|
||||
import {NamingStrategy} from "../../../src/decorator/NamingStrategy";
|
||||
import {DefaultNamingStrategy} from "../../../src/naming-strategy/DefaultNamingStrategy";
|
||||
import {snakeCase} from "../../../src/util/StringUtils";
|
||||
|
||||
@NamingStrategy("custom_strategy")
|
||||
export class CustomNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(targetName: string, userSpecifiedName: string): string {
|
||||
|
||||
@ -13,7 +13,6 @@ import {CannotCloseNotConnectedError} from "./error/CannotCloseNotConnectedError
|
||||
import {CannotConnectAlreadyConnectedError} from "./error/CannotConnectAlreadyConnectedError";
|
||||
import {TreeRepository} from "../repository/TreeRepository";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {NamingStrategyNotFoundError} from "./error/NamingStrategyNotFoundError";
|
||||
import {RepositoryNotTreeError} from "./error/RepositoryNotTreeError";
|
||||
import {EntitySchema} from "../entity-schema/EntitySchema";
|
||||
import {CannotSyncNotConnectedError} from "./error/CannotSyncNotConnectedError";
|
||||
@ -31,10 +30,6 @@ import {MigrationInterface} from "../migration/MigrationInterface";
|
||||
import {MigrationExecutor} from "../migration/MigrationExecutor";
|
||||
import {CannotRunMigrationNotConnectedError} from "./error/CannotRunMigrationNotConnectedError";
|
||||
import {PlatformTools} from "../platform/PlatformTools";
|
||||
import {AbstractRepository} from "../repository/AbstractRepository";
|
||||
import {CustomRepositoryNotFoundError} from "../repository/error/CustomRepositoryNotFoundError";
|
||||
import {CustomRepositoryReusedError} from "../repository/error/CustomRepositoryReusedError";
|
||||
import {CustomRepositoryCannotInheritRepositoryError} from "../repository/error/CustomRepositoryCannotInheritRepositoryError";
|
||||
import {MongoRepository} from "../repository/MongoRepository";
|
||||
import {MongoDriver} from "../driver/mongodb/MongoDriver";
|
||||
import {MongoEntityManager} from "../entity-manager/MongoEntityManager";
|
||||
@ -42,7 +37,8 @@ import {EntitySchemaTransformer} from "../entity-schema/EntitySchemaTransformer"
|
||||
import {EntityMetadataValidator} from "../metadata-builder/EntityMetadataValidator";
|
||||
|
||||
/**
|
||||
* Connection is a single database connection to a specific database of a database management system.
|
||||
* Connection is a single database ORM connection to a specific DBMS database.
|
||||
* Its not required to be a database connection, depend on database type it can create connection pool.
|
||||
* You can have multiple connections to multiple databases in your application.
|
||||
*/
|
||||
export class Connection {
|
||||
@ -54,31 +50,17 @@ export class Connection {
|
||||
/**
|
||||
* Connection name.
|
||||
*/
|
||||
public readonly name: string;
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* Indicates if connection is initialized or not.
|
||||
*/
|
||||
readonly isConnected = false;
|
||||
|
||||
/**
|
||||
* Database driver used by this connection.
|
||||
*/
|
||||
public readonly driver: Driver;
|
||||
|
||||
/**
|
||||
* Logger used to log orm events.
|
||||
*/
|
||||
public readonly logger: Logger;
|
||||
|
||||
/**
|
||||
* All entity metadatas that are registered for this connection.
|
||||
*/
|
||||
public readonly entityMetadatas: EntityMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Used to broadcast connection events.
|
||||
*/
|
||||
public readonly broadcaster: Broadcaster;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
readonly driver: Driver;
|
||||
|
||||
/**
|
||||
* Gets EntityManager of this connection.
|
||||
@ -86,54 +68,63 @@ export class Connection {
|
||||
readonly manager: EntityManager;
|
||||
|
||||
/**
|
||||
* Stores all registered repositories.
|
||||
* Logger used to log orm events.
|
||||
*/
|
||||
private readonly repositoryAggregators: RepositoryAggregator[] = [];
|
||||
readonly logger: Logger;
|
||||
|
||||
/**
|
||||
* Stores all entity repository instances.
|
||||
* Naming strategy used in the connection.
|
||||
*/
|
||||
private readonly entityRepositories: Object[] = [];
|
||||
readonly namingStrategy = new DefaultNamingStrategy();
|
||||
|
||||
/**
|
||||
* All entity metadatas that are registered for this connection.
|
||||
*/
|
||||
readonly entityMetadatas: EntityMetadata[] = [];
|
||||
|
||||
/**
|
||||
* Used to broadcast connection events.
|
||||
*/
|
||||
readonly broadcaster: Broadcaster;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
readonly lazyRelationsWrapper = new LazyRelationsWrapper(this);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stores all registered repositories.
|
||||
*/
|
||||
private repositoryAggregators: RepositoryAggregator[] = [];
|
||||
|
||||
/**
|
||||
* Entity subscribers that are registered for this connection.
|
||||
*/
|
||||
private readonly entitySubscribers: EntitySubscriberInterface<any>[] = [];
|
||||
private entitySubscribers: EntitySubscriberInterface<any>[] = [];
|
||||
|
||||
/**
|
||||
* Registered entity classes to be used for this connection.
|
||||
*/
|
||||
private readonly entityClasses: Function[] = [];
|
||||
private entityClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Registered entity schemas to be used for this connection.
|
||||
*/
|
||||
private readonly entitySchemas: EntitySchema[] = [];
|
||||
private entitySchemas: EntitySchema[] = [];
|
||||
|
||||
/**
|
||||
* Registered subscriber classes to be used for this connection.
|
||||
*/
|
||||
private readonly subscriberClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Registered naming strategy classes to be used for this connection.
|
||||
*/
|
||||
private readonly namingStrategyClasses: Function[] = [];
|
||||
private subscriberClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Registered migration classes to be used for this connection.
|
||||
*/
|
||||
private readonly migrationClasses: Function[] = [];
|
||||
|
||||
/**
|
||||
* Naming strategy to be used in this connection.
|
||||
*/
|
||||
private usedNamingStrategy: Function|string;
|
||||
|
||||
/**
|
||||
* Indicates if connection has been done or not.
|
||||
*/
|
||||
private _isConnected = false;
|
||||
private migrationClasses: Function[] = [];
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
@ -143,33 +134,19 @@ export class Connection {
|
||||
this.name = name;
|
||||
this.driver = driver;
|
||||
this.logger = logger;
|
||||
this.broadcaster = new Broadcaster(this, this.entitySubscribers);
|
||||
this.manager = this.createEntityManager();
|
||||
this.broadcaster = this.createBroadcaster();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Indicates if connection to the database already established for this connection.
|
||||
*/
|
||||
get isConnected(): boolean {
|
||||
return this._isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets entity manager that allows to perform repository operations with any entity in this connection.
|
||||
*
|
||||
* @deprecated use manager instead.
|
||||
*/
|
||||
get entityManager(): EntityManager {
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mongodb entity manager that allows to perform mongodb-specific repository operations
|
||||
* with any entity in this connection.
|
||||
*
|
||||
* Available only in mongodb connections.
|
||||
*/
|
||||
get mongoEntityManager(): MongoEntityManager {
|
||||
if (!(this.manager instanceof MongoEntityManager))
|
||||
@ -184,6 +161,9 @@ export class Connection {
|
||||
|
||||
/**
|
||||
* Performs connection to the database.
|
||||
* This method should be called once on application bootstrap.
|
||||
* This method not necessarily creates database connection (depend on database type),
|
||||
* but it also can setup a connection pool with database to use.
|
||||
*/
|
||||
async connect(): Promise<this> {
|
||||
if (this.isConnected)
|
||||
@ -193,7 +173,7 @@ export class Connection {
|
||||
await this.driver.connect();
|
||||
|
||||
// set connected status for the current connection
|
||||
this._isConnected = true;
|
||||
Object.assign(this, { isConnected: true });
|
||||
|
||||
// build all metadatas registered in the current connection
|
||||
try {
|
||||
@ -212,23 +192,14 @@ export class Connection {
|
||||
|
||||
/**
|
||||
* Closes connection with the database.
|
||||
* Once connection is closed, you cannot use repositories and perform any operations except
|
||||
* opening connection again.
|
||||
* Once connection is closed, you cannot use repositories or perform any operations except opening connection again.
|
||||
*/
|
||||
async close(): Promise<void> {
|
||||
if (!this.isConnected)
|
||||
throw new CannotCloseNotConnectedError(this.name);
|
||||
|
||||
await this.driver.disconnect();
|
||||
this._isConnected = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the database and all its data.
|
||||
*/
|
||||
async dropDatabase(): Promise<void> {
|
||||
const queryRunner = await this.driver.createQueryRunner();
|
||||
await queryRunner.clearDatabase();
|
||||
Object.assign(this, { isConnected: false });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,10 +219,20 @@ export class Connection {
|
||||
await this.driver.syncSchema(this.entityMetadatas);
|
||||
|
||||
} else {
|
||||
await this.createSchemaBuilder().build();
|
||||
const schemaBuilder = new SchemaBuilder(this.driver, this.logger, this.entityMetadatas);
|
||||
await schemaBuilder.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the database and all its data.
|
||||
* Be careful with this method on production since this method will erase all your database tables and data inside them.
|
||||
*/
|
||||
async dropDatabase(): Promise<void> {
|
||||
const queryRunner = await this.driver.createQueryRunner();
|
||||
await queryRunner.clearDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all pending migrations.
|
||||
*/
|
||||
@ -300,14 +281,6 @@ export class Connection {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports naming strategies from the given paths (directories) and registers them in the current connection.
|
||||
*/
|
||||
importNamingStrategiesFromDirectories(paths: string[]): this {
|
||||
this.importNamingStrategies(importClassesFromDirectories(paths));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports migrations from the given paths (directories) and registers them in the current connection.
|
||||
*/
|
||||
@ -349,17 +322,6 @@ export class Connection {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports naming strategies and registers them in the current connection.
|
||||
*/
|
||||
importNamingStrategies(strategies: Function[]): this {
|
||||
if (this.isConnected)
|
||||
throw new CannotImportAlreadyConnectedError("naming strategies", this.name);
|
||||
|
||||
strategies.forEach(cls => this.namingStrategyClasses.push(cls));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports migrations and registers them in the current connection.
|
||||
*/
|
||||
@ -375,23 +337,11 @@ export class Connection {
|
||||
* 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.
|
||||
*/
|
||||
useNamingStrategy(strategy: Function): this;
|
||||
|
||||
/**
|
||||
* Sets given naming strategy to be used.
|
||||
* Naming strategy must be set to be used before connection is established.
|
||||
*/
|
||||
useNamingStrategy(strategyClassOrName: string|Function): this {
|
||||
useNamingStrategy(namingStrategy: NamingStrategyInterface): this {
|
||||
if (this.isConnected)
|
||||
throw new CannotUseNamingStrategyNotConnectedError(this.name);
|
||||
|
||||
this.usedNamingStrategy = strategyClassOrName;
|
||||
Object.assign(this, { namingStrategy: namingStrategy });
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -570,6 +520,19 @@ export class Connection {
|
||||
return this.manager.getCustomRepository(customRepository);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Deprecated
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets entity manager that allows to perform repository operations with any entity in this connection.
|
||||
*
|
||||
* @deprecated use manager instead.
|
||||
*/
|
||||
get entityManager(): EntityManager {
|
||||
return this.manager;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -601,12 +564,12 @@ export class Connection {
|
||||
this.repositoryAggregators.length = 0;
|
||||
this.entityMetadatas.length = 0;
|
||||
|
||||
this.driver.namingStrategy = this.createNamingStrategy(); // todo: why they are in the driver
|
||||
this.driver.lazyRelationsWrapper = this.createLazyRelationsWrapper(); // todo: why they are in the driver
|
||||
const entityMetadataValidator = new EntityMetadataValidator();
|
||||
|
||||
// take imported event subscribers
|
||||
if (this.subscriberClasses && this.subscriberClasses.length && !PlatformTools.getEnvVariable("SKIP_SUBSCRIBERS_LOADING")) {
|
||||
if (this.subscriberClasses &&
|
||||
this.subscriberClasses.length &&
|
||||
!PlatformTools.getEnvVariable("SKIP_SUBSCRIBERS_LOADING")) {
|
||||
getMetadataArgsStorage()
|
||||
.filterSubscribers(this.subscriberClasses)
|
||||
.map(metadata => getFromContainer(metadata.target))
|
||||
@ -639,34 +602,6 @@ export class Connection {
|
||||
entityMetadataValidator.validateMany(this.entityMetadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a naming strategy to be used for this connection.
|
||||
*/
|
||||
protected createNamingStrategy(): NamingStrategyInterface {
|
||||
|
||||
// if naming strategies are not loaded, or used naming strategy is not set then use default naming strategy
|
||||
if (!this.namingStrategyClasses || !this.namingStrategyClasses.length || !this.usedNamingStrategy)
|
||||
return getFromContainer(DefaultNamingStrategy);
|
||||
|
||||
// try to find used naming strategy in the list of loaded naming strategies
|
||||
const namingMetadata = getMetadataArgsStorage()
|
||||
.filterNamingStrategies(this.namingStrategyClasses)
|
||||
.find(strategy => {
|
||||
if (typeof this.usedNamingStrategy === "string") {
|
||||
return strategy.name === this.usedNamingStrategy;
|
||||
} else {
|
||||
return strategy.target === this.usedNamingStrategy;
|
||||
}
|
||||
});
|
||||
|
||||
// throw an error if not found
|
||||
if (!namingMetadata)
|
||||
throw new NamingStrategyNotFoundError(this.usedNamingStrategy, this.name);
|
||||
|
||||
// initialize a naming strategy instance
|
||||
return getFromContainer<NamingStrategyInterface>(namingMetadata.target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new default entity manager without single connection setup.
|
||||
*/
|
||||
@ -677,25 +612,4 @@ export class Connection {
|
||||
return new EntityManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new entity broadcaster using in this connection.
|
||||
*/
|
||||
protected createBroadcaster() {
|
||||
return new Broadcaster(this, this.entitySubscribers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a schema builder used to build a database schema for the entities of the current connection.
|
||||
*/
|
||||
protected createSchemaBuilder() {
|
||||
return new SchemaBuilder(this.driver, this.logger, this.entityMetadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy relations wrapper.
|
||||
*/
|
||||
protected createLazyRelationsWrapper() {
|
||||
return new LazyRelationsWrapper(this);
|
||||
}
|
||||
|
||||
}
|
||||
@ -65,7 +65,7 @@ export class ConnectionManager {
|
||||
create(options: ConnectionOptions): Connection {
|
||||
|
||||
const logger = new Logger(options.logging || {});
|
||||
const driver = this.createDriver(options.driver, logger);
|
||||
const driver = this.createDriver(options.driver || {} as DriverOptions, logger); // || {} is temporary
|
||||
const connection = this.createConnection(options.name || "default", driver, logger);
|
||||
|
||||
// import entity schemas
|
||||
@ -92,14 +92,6 @@ export class ConnectionManager {
|
||||
.importSubscribersFromDirectories(directories);
|
||||
}
|
||||
|
||||
// import naming strategies
|
||||
if (options.namingStrategies) {
|
||||
const [directories, classes] = this.splitStringsAndClasses(options.namingStrategies);
|
||||
connection
|
||||
.importNamingStrategies(classes)
|
||||
.importNamingStrategiesFromDirectories(directories);
|
||||
}
|
||||
|
||||
// import migrations
|
||||
if (options.migrations) {
|
||||
const [directories, classes] = this.splitStringsAndClasses(options.migrations);
|
||||
@ -109,8 +101,8 @@ export class ConnectionManager {
|
||||
}
|
||||
|
||||
// set naming strategy to be used for this connection
|
||||
if (options.usedNamingStrategy)
|
||||
connection.useNamingStrategy(options.usedNamingStrategy as any);
|
||||
if (options.namingStrategy)
|
||||
connection.useNamingStrategy(options.namingStrategy);
|
||||
|
||||
return connection;
|
||||
}
|
||||
@ -341,8 +333,6 @@ export class ConnectionManager {
|
||||
entities: PlatformTools.getEnvVariable("TYPEORM_ENTITIES") ? PlatformTools.getEnvVariable("TYPEORM_ENTITIES").split(",") : [],
|
||||
subscribers: PlatformTools.getEnvVariable("TYPEORM_SUBSCRIBERS") ? PlatformTools.getEnvVariable("TYPEORM_SUBSCRIBERS").split(",") : [],
|
||||
entitySchemas: PlatformTools.getEnvVariable("TYPEORM_ENTITY_SCHEMAS") ? PlatformTools.getEnvVariable("TYPEORM_ENTITY_SCHEMAS").split(",") : [],
|
||||
namingStrategies: PlatformTools.getEnvVariable("TYPEORM_NAMING_STRATEGIES") ? PlatformTools.getEnvVariable("TYPEORM_NAMING_STRATEGIES").split(",") : [],
|
||||
usedNamingStrategy: PlatformTools.getEnvVariable("TYPEORM_USED_NAMING_STRATEGY"),
|
||||
logging: {
|
||||
logQueries: OrmUtils.toBoolean(PlatformTools.getEnvVariable("TYPEORM_LOGGING_QUERIES")),
|
||||
logFailedQueryError: OrmUtils.toBoolean(PlatformTools.getEnvVariable("TYPEORM_LOGGING_FAILED_QUERIES")),
|
||||
@ -415,14 +405,6 @@ export class ConnectionManager {
|
||||
return migration;
|
||||
});
|
||||
}
|
||||
if (options.namingStrategies) {
|
||||
options.namingStrategies = (options.namingStrategies as any[]).map(namingStrategy => {
|
||||
if (typeof namingStrategy === "string" || namingStrategy.substr(0, 1) !== "/")
|
||||
return PlatformTools.load("app-root-path").path + "/" + namingStrategy;
|
||||
|
||||
return namingStrategy;
|
||||
});
|
||||
}
|
||||
|
||||
return this.createAndConnectByConnectionOptions(options);
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import {DriverOptions} from "../driver/DriverOptions";
|
||||
import {EntitySchema} from "../entity-schema/EntitySchema";
|
||||
import {LoggerOptions} from "../logger/LoggerOptions";
|
||||
import {NamingStrategyInterface} from "../naming-strategy/NamingStrategyInterface";
|
||||
import {DriverType} from "../driver/DriverType";
|
||||
|
||||
/**
|
||||
* ConnectionOptions is an interface with settings and options for specific connection.
|
||||
@ -9,11 +11,6 @@ import {LoggerOptions} from "../logger/LoggerOptions";
|
||||
*/
|
||||
export interface ConnectionOptions {
|
||||
|
||||
/**
|
||||
* Database options of this connection.
|
||||
*/
|
||||
driver: DriverOptions;
|
||||
|
||||
/**
|
||||
* Connection name. If connection name is not given then it will be called "default".
|
||||
* Different connections must have different names.
|
||||
@ -21,9 +18,87 @@ export interface ConnectionOptions {
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* Name of the naming strategy or target class of the naming strategy to be used for this connection.
|
||||
* Database options of this connection.
|
||||
*
|
||||
* @deprecated Define options right in the connection options section.
|
||||
*/
|
||||
usedNamingStrategy?: string|Function;
|
||||
driver?: DriverOptions;
|
||||
|
||||
/**
|
||||
* Database type. This value is required.
|
||||
*/
|
||||
type?: DriverType;
|
||||
|
||||
/**
|
||||
* Connection url to where perform connection to.
|
||||
*/
|
||||
url?: string;
|
||||
|
||||
/**
|
||||
* Database host.
|
||||
*/
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Database host port.
|
||||
*/
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Database username.
|
||||
*/
|
||||
username?: string;
|
||||
|
||||
/**
|
||||
* Database password.
|
||||
*/
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* Database name to connect to.
|
||||
*/
|
||||
database?: string;
|
||||
|
||||
/**
|
||||
* Schema name. By default is "public" (used only in Postgres databases).
|
||||
*/
|
||||
schemaName?: string;
|
||||
|
||||
/**
|
||||
* Connection SID (used for Oracle databases).
|
||||
*/
|
||||
sid?: string;
|
||||
|
||||
/**
|
||||
* Storage type or path to the storage (used for SQLite databases).
|
||||
*/
|
||||
storage?: string;
|
||||
|
||||
/**
|
||||
* Indicates if connection pooling should be used or not.
|
||||
* Be default it is enabled if its supported by a platform.
|
||||
* Set to false to disable it.
|
||||
*
|
||||
* @todo: rename to disablePool? What about mongodb pool?
|
||||
*/
|
||||
usePool?: boolean;
|
||||
|
||||
/**
|
||||
* Extra connection options to be passed to the underlying driver.
|
||||
*/
|
||||
extra?: any;
|
||||
|
||||
/**
|
||||
* Prefix to use on all tables (collections) of this connection in the database.
|
||||
*
|
||||
* @todo: rename to entityPrefix
|
||||
*/
|
||||
tablesPrefix?: string;
|
||||
|
||||
/**
|
||||
* Naming strategy to be used to name tables and columns in the database.
|
||||
*/
|
||||
namingStrategy?: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Entities to be loaded for this connection.
|
||||
@ -39,13 +114,6 @@ export interface ConnectionOptions {
|
||||
*/
|
||||
subscribers?: Function[]|string[];
|
||||
|
||||
/**
|
||||
* Naming strategies to be loaded for this connection.
|
||||
* Accepts both naming strategy classes and directories where from naming strategies need to be loaded.
|
||||
* Directories support glob patterns.
|
||||
*/
|
||||
namingStrategies?: Function[]|string[];
|
||||
|
||||
/**
|
||||
* Entity schemas to be loaded for this connection.
|
||||
* Accepts both entity schema classes and directories where from entity schemas need to be loaded.
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
import {getMetadataArgsStorage} from "../index";
|
||||
import {NamingStrategyMetadataArgs} from "../metadata-args/NamingStrategyMetadataArgs";
|
||||
|
||||
/**
|
||||
* Decorator registers a new naming strategy to be used in naming things.
|
||||
*
|
||||
* todo: deprecate using naming strategies this way. use it without decorators
|
||||
* todo: but add multiple default naming strategies for use
|
||||
*/
|
||||
export function NamingStrategy(name?: string): Function {
|
||||
return function (target: Function) {
|
||||
const strategyName = name ? name : (<any> target).name;
|
||||
const args: NamingStrategyMetadataArgs = {
|
||||
target: target,
|
||||
name: strategyName
|
||||
};
|
||||
getMetadataArgsStorage().namingStrategies.push(args);
|
||||
};
|
||||
}
|
||||
@ -10,16 +10,6 @@ import {LazyRelationsWrapper} from "../lazy-loading/LazyRelationsWrapper";
|
||||
*/
|
||||
export interface Driver {
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver options contains connectivity options used to connection to the database.
|
||||
*/
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
/**
|
||||
* Driver type.
|
||||
*/
|
||||
export type DriverType = "mysql"|"postgres"|"mariadb"|"sqlite"|"oracle"|"mssql"|"websql"|"mongodb";
|
||||
import {DriverType} from "./DriverType";
|
||||
|
||||
/**
|
||||
* Connectivity options used to connect to the database, and other database-driver-specific options.
|
||||
@ -11,52 +8,52 @@ export interface DriverOptions {
|
||||
/**
|
||||
* Database type. This value is required.
|
||||
*/
|
||||
readonly type: DriverType;
|
||||
type: DriverType;
|
||||
|
||||
/**
|
||||
* Connection url to where perform connection to.
|
||||
*/
|
||||
readonly url?: string;
|
||||
url?: string;
|
||||
|
||||
/**
|
||||
* Database host.
|
||||
*/
|
||||
readonly host?: string;
|
||||
host?: string;
|
||||
|
||||
/**
|
||||
* Database host port.
|
||||
*/
|
||||
readonly port?: number;
|
||||
port?: number;
|
||||
|
||||
/**
|
||||
* Database username.
|
||||
*/
|
||||
readonly username?: string;
|
||||
username?: string;
|
||||
|
||||
/**
|
||||
* Database password.
|
||||
*/
|
||||
readonly password?: string;
|
||||
password?: string;
|
||||
|
||||
/**
|
||||
* Database name to connect to.
|
||||
*/
|
||||
readonly database?: string;
|
||||
database?: string;
|
||||
|
||||
/**
|
||||
* Schema name. By default is "public" (used only in Postgres databases).
|
||||
*/
|
||||
readonly schemaName?: string;
|
||||
schemaName?: string;
|
||||
|
||||
/**
|
||||
* Connection SID (used for Oracle databases).
|
||||
*/
|
||||
readonly sid?: string;
|
||||
sid?: string;
|
||||
|
||||
/**
|
||||
* Storage type or path to the storage (used for SQLite databases).
|
||||
*/
|
||||
readonly storage?: string;
|
||||
storage?: string;
|
||||
|
||||
/**
|
||||
* Indicates if connection pooling should be used or not.
|
||||
@ -65,18 +62,18 @@ export interface DriverOptions {
|
||||
*
|
||||
* @todo: rename to disablePool? What about mongodb pool?
|
||||
*/
|
||||
readonly usePool?: boolean;
|
||||
usePool?: boolean;
|
||||
|
||||
/**
|
||||
* Extra connection options to be passed to the underlying driver.
|
||||
*/
|
||||
readonly extra?: any;
|
||||
extra?: any;
|
||||
|
||||
/**
|
||||
* Prefix to use on all tables (collections) of this connection in the database.
|
||||
*
|
||||
* @todo: rename to entityPrefix
|
||||
*/
|
||||
readonly tablesPrefix?: string;
|
||||
tablesPrefix?: string;
|
||||
|
||||
}
|
||||
|
||||
4
src/driver/DriverType.ts
Normal file
4
src/driver/DriverType.ts
Normal file
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Driver type.
|
||||
*/
|
||||
export type DriverType = "mysql"|"postgres"|"mariadb"|"sqlite"|"oracle"|"mssql"|"websql"|"mongodb";
|
||||
@ -23,16 +23,6 @@ export class MongoDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Mongodb does not require to dynamically create query runner each time,
|
||||
* because it does not have a regular pool.
|
||||
|
||||
@ -25,16 +25,6 @@ export class MysqlDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -27,16 +27,6 @@ export class OracleDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -30,16 +30,6 @@ export class PostgresDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -24,16 +24,6 @@ export class SqliteDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -14,6 +14,7 @@ import {ForeignKeySchema} from "../../schema-builder/schema/ForeignKeySchema";
|
||||
import {PrimaryKeySchema} from "../../schema-builder/schema/PrimaryKeySchema";
|
||||
import {QueryRunnerAlreadyReleasedError} from "../../query-runner/error/QueryRunnerAlreadyReleasedError";
|
||||
import {ColumnType} from "../../metadata/types/ColumnTypes";
|
||||
import {RandomGenerator} from "../../util/RandomGenerator";
|
||||
|
||||
/**
|
||||
* Runs queries on a single sqlite database connection.
|
||||
@ -316,7 +317,10 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
const columnForeignKeys = dbForeignKeys
|
||||
.filter(foreignKey => foreignKey["from"] === dbColumn["name"])
|
||||
.map(foreignKey => {
|
||||
const keyName = this.driver.namingStrategy.foreignKeyName(dbTable["name"], [foreignKey["from"]], foreignKey["table"], [foreignKey["to"]]);
|
||||
// const keyName = this.driver.namingStrategy.foreignKeyName(dbTable["name"], [foreignKey["from"]], foreignKey["table"], [foreignKey["to"]]);
|
||||
// todo: figure out solution here, name should be same as naming strategy generates!
|
||||
const key = `${dbTable["name"]}_${[foreignKey["from"]].join("_")}_${foreignKey["table"]}_${[foreignKey["to"]].join("_")}`;
|
||||
const keyName = "fk_" + RandomGenerator.sha1(key).substr(0, 27);
|
||||
return new ForeignKeySchema(keyName, [foreignKey["from"]], [foreignKey["to"]], foreignKey["table"], foreignKey["on_delete"]); // todo: how sqlite return from and to when they are arrays? (multiple column foreign keys)
|
||||
});
|
||||
tableSchema.addForeignKeys(columnForeignKeys);
|
||||
|
||||
@ -25,16 +25,6 @@ export class SqlServerDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -28,16 +28,6 @@ export class WebsqlDriver implements Driver {
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Naming strategy used in the connection where this driver is used.
|
||||
*/
|
||||
namingStrategy: NamingStrategyInterface;
|
||||
|
||||
/**
|
||||
* Used to wrap lazy relations to be able to perform lazy loadings.
|
||||
*/
|
||||
lazyRelationsWrapper: LazyRelationsWrapper;
|
||||
|
||||
/**
|
||||
* Driver connection options.
|
||||
*/
|
||||
|
||||
@ -65,7 +65,6 @@ export * from "./decorator/tree/TreeLevelColumn";
|
||||
export * from "./decorator/tree/TreeParent";
|
||||
export * from "./decorator/tree/TreeChildren";
|
||||
export * from "./decorator/Index";
|
||||
export * from "./decorator/NamingStrategy";
|
||||
export * from "./decorator/Embedded";
|
||||
export * from "./decorator/DiscriminatorValue";
|
||||
export * from "./decorator/EntityRepository";
|
||||
|
||||
@ -157,7 +157,7 @@ export class EntityMetadataBuilder {
|
||||
|
||||
// build all indices (need to do it after relations and their join columns are built)
|
||||
entityMetadatas.forEach(entityMetadata => {
|
||||
entityMetadata.indices.forEach(index => index.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.indices.forEach(index => index.build(this.connection.namingStrategy));
|
||||
});
|
||||
|
||||
entityMetadatas
|
||||
@ -165,7 +165,7 @@ export class EntityMetadataBuilder {
|
||||
.forEach(metadata => {
|
||||
const parentPrimaryColumns = metadata.parentEntityMetadata.primaryColumns;
|
||||
const parentRelationColumns = parentPrimaryColumns.map(parentPrimaryColumn => {
|
||||
const columnName = this.connection.driver.namingStrategy.classTableInheritanceParentColumnName(metadata.parentEntityMetadata.tableName, parentPrimaryColumn.propertyPath);
|
||||
const columnName = this.connection.namingStrategy.classTableInheritanceParentColumnName(metadata.parentEntityMetadata.tableName, parentPrimaryColumn.propertyPath);
|
||||
const column = new ColumnMetadata({
|
||||
entityMetadata: metadata,
|
||||
referencedColumn: parentPrimaryColumn,
|
||||
@ -183,7 +183,7 @@ export class EntityMetadataBuilder {
|
||||
}
|
||||
});
|
||||
metadata.registerColumn(column);
|
||||
column.build(this.connection.driver.namingStrategy);
|
||||
column.build(this.connection.namingStrategy);
|
||||
return column;
|
||||
});
|
||||
|
||||
@ -191,7 +191,7 @@ export class EntityMetadataBuilder {
|
||||
new ForeignKeyMetadata({
|
||||
entityMetadata: metadata,
|
||||
referencedEntityMetadata: metadata.parentEntityMetadata,
|
||||
namingStrategy: this.connection.driver.namingStrategy,
|
||||
namingStrategy: this.connection.namingStrategy,
|
||||
columns: parentRelationColumns,
|
||||
referencedColumns: parentPrimaryColumns,
|
||||
onDelete: "CASCADE"
|
||||
@ -206,7 +206,7 @@ export class EntityMetadataBuilder {
|
||||
entityMetadata.relations
|
||||
.filter(relation => relation.isLazy)
|
||||
.forEach(relation => {
|
||||
this.connection.driver.lazyRelationsWrapper.wrap((entityMetadata.target as Function).prototype, relation);
|
||||
this.connection.lazyRelationsWrapper.wrap((entityMetadata.target as Function).prototype, relation);
|
||||
});
|
||||
});
|
||||
|
||||
@ -307,12 +307,12 @@ export class EntityMetadataBuilder {
|
||||
* Computes all entity metadata's computed properties, and all its sub-metadatas (relations, columns, embeds, etc).
|
||||
*/
|
||||
protected computeEntityMetadata(entityMetadata: EntityMetadata) {
|
||||
entityMetadata.embeddeds.forEach(embedded => embedded.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.embeddeds.forEach(embedded => embedded.build(this.connection.namingStrategy));
|
||||
entityMetadata.embeddeds.forEach(embedded => {
|
||||
embedded.columnsFromTree.forEach(column => column.build(this.connection.driver.namingStrategy));
|
||||
embedded.columnsFromTree.forEach(column => column.build(this.connection.namingStrategy));
|
||||
embedded.relationsFromTree.forEach(relation => relation.build());
|
||||
});
|
||||
entityMetadata.ownColumns.forEach(column => column.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.ownColumns.forEach(column => column.build(this.connection.namingStrategy));
|
||||
entityMetadata.ownRelations.forEach(relation => relation.build());
|
||||
entityMetadata.relations = entityMetadata.embeddeds.reduce((relations, embedded) => relations.concat(embedded.relationsFromTree), entityMetadata.ownRelations);
|
||||
entityMetadata.oneToOneRelations = entityMetadata.relations.filter(relation => relation.isOneToOne);
|
||||
@ -334,7 +334,7 @@ export class EntityMetadataBuilder {
|
||||
entityMetadata.treeLevelColumn = entityMetadata.columns.find(column => column.isTreeLevel);
|
||||
entityMetadata.parentIdColumns = entityMetadata.columns.filter(column => column.isParentId);
|
||||
entityMetadata.objectIdColumn = entityMetadata.columns.find(column => column.isObjectId);
|
||||
entityMetadata.foreignKeys.forEach(foreignKey => foreignKey.build(this.connection.driver.namingStrategy));
|
||||
entityMetadata.foreignKeys.forEach(foreignKey => foreignKey.build(this.connection.namingStrategy));
|
||||
entityMetadata.propertiesMap = entityMetadata.createPropertiesMap();
|
||||
entityMetadata.relationIds.forEach(relationId => relationId.build());
|
||||
entityMetadata.relationCounts.forEach(relationCount => relationCount.build());
|
||||
|
||||
@ -30,7 +30,7 @@ export class JunctionEntityMetadataBuilder {
|
||||
const referencedColumns = this.collectReferencedColumns(relation, joinTable);
|
||||
const inverseReferencedColumns = this.collectInverseReferencedColumns(relation, joinTable);
|
||||
|
||||
const joinTableName = joinTable.name || this.connection.driver.namingStrategy.joinTableName(
|
||||
const joinTableName = joinTable.name || this.connection.namingStrategy.joinTableName(
|
||||
relation.entityMetadata.tableNameWithoutPrefix,
|
||||
relation.inverseEntityMetadata.tableNameWithoutPrefix,
|
||||
relation.propertyPath,
|
||||
@ -52,7 +52,7 @@ export class JunctionEntityMetadataBuilder {
|
||||
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === referencedColumn.propertyName) &&
|
||||
!!joinColumnArgs.name;
|
||||
}) : undefined;
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.driver.namingStrategy.joinTableColumnName(relation.entityMetadata.tableNameWithoutPrefix, referencedColumn.propertyName, referencedColumn.databaseName);
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.namingStrategy.joinTableColumnName(relation.entityMetadata.tableNameWithoutPrefix, referencedColumn.propertyName, referencedColumn.databaseName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
entityMetadata: entityMetadata,
|
||||
@ -78,7 +78,7 @@ export class JunctionEntityMetadataBuilder {
|
||||
return (!joinColumnArgs.referencedColumnName || joinColumnArgs.referencedColumnName === inverseReferencedColumn.propertyName) &&
|
||||
!!joinColumnArgs.name;
|
||||
}) : undefined;
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.driver.namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.tableNameWithoutPrefix, inverseReferencedColumn.propertyName, inverseReferencedColumn.databaseName);
|
||||
const columnName = joinColumn && joinColumn.name ? joinColumn.name : this.connection.namingStrategy.joinTableColumnName(relation.inverseEntityMetadata.tableNameWithoutPrefix, inverseReferencedColumn.propertyName, inverseReferencedColumn.databaseName);
|
||||
|
||||
return new ColumnMetadata({
|
||||
entityMetadata: entityMetadata,
|
||||
|
||||
@ -59,7 +59,7 @@ export class RelationJoinColumnBuilder {
|
||||
return new ForeignKeyMetadata({
|
||||
entityMetadata: relation.entityMetadata,
|
||||
referencedEntityMetadata: relation.inverseEntityMetadata,
|
||||
namingStrategy: this.connection.driver.namingStrategy,
|
||||
namingStrategy: this.connection.namingStrategy,
|
||||
columns: columns,
|
||||
referencedColumns: referencedColumns,
|
||||
onDelete: relation.onDelete,
|
||||
@ -102,7 +102,7 @@ export class RelationJoinColumnBuilder {
|
||||
return (!joinColumn.referencedColumnName || joinColumn.referencedColumnName === referencedColumn.propertyName) &&
|
||||
!!joinColumn.name;
|
||||
});
|
||||
const joinColumnName = joinColumnMetadataArg ? joinColumnMetadataArg.name : this.connection.driver.namingStrategy.joinColumnName(relation.propertyName, referencedColumn.propertyName);
|
||||
const joinColumnName = joinColumnMetadataArg ? joinColumnMetadataArg.name : this.connection.namingStrategy.joinColumnName(relation.propertyName, referencedColumn.propertyName);
|
||||
|
||||
let relationalColumn = relation.entityMetadata.ownColumns.find(column => column.databaseName === joinColumnName);
|
||||
if (!relationalColumn) {
|
||||
@ -125,7 +125,7 @@ export class RelationJoinColumnBuilder {
|
||||
relationalColumn.referencedColumn = referencedColumn; // its important to set it here because we need to set referenced column for user defined join column
|
||||
relationalColumn.type = referencedColumn.type; // also since types of relational column and join column must be equal we override user defined column type
|
||||
relationalColumn.relationMetadata = relation;
|
||||
relationalColumn.build(this.connection.driver.namingStrategy);
|
||||
relationalColumn.build(this.connection.namingStrategy);
|
||||
return relationalColumn;
|
||||
});
|
||||
}
|
||||
|
||||
@ -342,9 +342,9 @@ export class EntityMetadata {
|
||||
parentClosureEntityMetadata?: EntityMetadata,
|
||||
args: TableMetadataArgs
|
||||
}) {
|
||||
const namingStrategy = options.connection.driver.namingStrategy;
|
||||
const namingStrategy = options.connection.namingStrategy;
|
||||
const tablesPrefix = options.connection.driver.options.tablesPrefix;
|
||||
this.lazyRelationsWrapper = options.connection.driver.lazyRelationsWrapper;
|
||||
this.lazyRelationsWrapper = options.connection.lazyRelationsWrapper;
|
||||
this.parentClosureEntityMetadata = options.parentClosureEntityMetadata!;
|
||||
this.target = options.args.target;
|
||||
this.tableType = options.args.type;
|
||||
|
||||
@ -13,7 +13,7 @@ export class DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
* @param targetName Name of the target entity that can be used to generate a table name.
|
||||
* @param userSpecifiedName For example if user specified a table name in a decorator, e.g. @Entity("name")
|
||||
*/
|
||||
tableName(targetName: string, userSpecifiedName: string): string {
|
||||
tableName(targetName: string, userSpecifiedName: string|undefined): string {
|
||||
return userSpecifiedName ? userSpecifiedName : snakeCase(targetName);
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import {Blog} from "./modules/blog/entity/Blog";
|
||||
import {Question} from "./modules/question/entity/Question";
|
||||
import {Video} from "./modules/video/entity/Video";
|
||||
import {ConnectionOptions} from "../../../src/connection/ConnectionOptions";
|
||||
import {DefaultNamingStrategy} from "../../../src/naming-strategy/DefaultNamingStrategy";
|
||||
|
||||
describe("Connection", () => {
|
||||
const resourceDir = __dirname + "/../../../../../test/functional/connection/";
|
||||
@ -127,11 +128,9 @@ describe("Connection", () => {
|
||||
expect(() => connection.importEntities([Post])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importEntitySchemas([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importSubscribers([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importNamingStrategies([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importEntitiesFromDirectories([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importEntitySchemaFromDirectories([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importSubscribersFromDirectories([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
expect(() => connection.importNamingStrategiesFromDirectories([])).to.throw(Error); // CannotImportAlreadyConnectedError
|
||||
}));
|
||||
|
||||
it("should not be able to connect again", () => connections.forEach(connection => {
|
||||
@ -139,7 +138,7 @@ describe("Connection", () => {
|
||||
}));
|
||||
|
||||
it("should not be able to change used naming strategy", () => connections.forEach(connection => {
|
||||
expect(() => connection.useNamingStrategy("something")).to.throw(Error); // CannotUseNamingStrategyNotConnectedError
|
||||
expect(() => connection.useNamingStrategy(new DefaultNamingStrategy())).to.throw(Error); // CannotUseNamingStrategyNotConnectedError
|
||||
}));
|
||||
|
||||
it("should be able to close a connection", async () => Promise.all(connections.map(connection => {
|
||||
@ -295,7 +294,6 @@ describe("Connection", () => {
|
||||
it("should successfully load entities / entity schemas / subscribers / naming strategies from directories", async () => {
|
||||
connection.importEntitiesFromDirectories([__dirname + "/entity/*"]);
|
||||
connection.importEntitySchemaFromDirectories([resourceDir + "/schema/*"]);
|
||||
connection.importNamingStrategiesFromDirectories([__dirname + "/naming-strategy/*"]);
|
||||
connection.importSubscribersFromDirectories([__dirname + "/subscriber/*"]);
|
||||
await connection.connect();
|
||||
connection.getRepository(Post).should.be.instanceOf(Repository);
|
||||
@ -311,7 +309,6 @@ describe("Connection", () => {
|
||||
it("should successfully load entities / entity schemas / subscribers / naming strategies from glob-patterned directories", async () => {
|
||||
connection.importEntitiesFromDirectories([__dirname + "/modules/**/entity/*"]);
|
||||
connection.importEntitySchemaFromDirectories([resourceDir + "/modules/**/schema/*"]);
|
||||
connection.importNamingStrategiesFromDirectories([__dirname + "/modules/**/naming-strategy/*"]);
|
||||
connection.importSubscribersFromDirectories([__dirname + "/modules/**/subscriber/*"]);
|
||||
await connection.connect();
|
||||
connection.getRepository(Blog).should.be.instanceOf(Repository);
|
||||
@ -329,49 +326,6 @@ describe("Connection", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("using naming strategy", function() {
|
||||
|
||||
let connection: Connection;
|
||||
beforeEach(async () => {
|
||||
connection = getConnectionManager().create(setupSingleTestingConnection("mysql", {
|
||||
name: "default",
|
||||
entities: []
|
||||
}));
|
||||
});
|
||||
afterEach(() => connection.isConnected ? connection.close() : {});
|
||||
|
||||
it("should use naming strategy when its class passed to useNamingStrategy method", async () => {
|
||||
connection.importEntities([Post]);
|
||||
connection.importNamingStrategies([FirstCustomNamingStrategy]);
|
||||
connection.useNamingStrategy(FirstCustomNamingStrategy);
|
||||
await connection.connect();
|
||||
connection.getMetadata(Post).tableName.should.be.equal("POST");
|
||||
});
|
||||
|
||||
it("should use naming strategy when its name passed to useNamingStrategy method", async () => {
|
||||
connection.importEntities([Category]);
|
||||
connection.importNamingStrategies([SecondCustomNamingStrategy]);
|
||||
connection.useNamingStrategy("secondCustomNamingStrategy");
|
||||
await connection.connect();
|
||||
connection.getMetadata(Category).tableName.should.be.equal("category");
|
||||
});
|
||||
|
||||
it("should throw an error if not registered naming strategy was used (assert by name)", () => {
|
||||
connection.importEntities([Category]);
|
||||
connection.importNamingStrategies([FirstCustomNamingStrategy]);
|
||||
connection.useNamingStrategy("secondCustomNamingStrategy");
|
||||
return connection.connect().should.be.rejected; // NamingStrategyNotFoundError
|
||||
});
|
||||
|
||||
it("should throw an error if not registered naming strategy was used (assert by Function)", () => {
|
||||
connection.importEntities([Category]);
|
||||
connection.importNamingStrategies([SecondCustomNamingStrategy]);
|
||||
connection.useNamingStrategy(FirstCustomNamingStrategy);
|
||||
return connection.connect().should.be.rejected; // NamingStrategyNotFoundError
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("skip schema generation when skipSchemaSync option is used", function() {
|
||||
|
||||
let connections: Connection[];
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import {DefaultNamingStrategy} from "../../../../src/naming-strategy/DefaultNamingStrategy";
|
||||
import {NamingStrategy} from "../../../../src/decorator/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../../../../src/naming-strategy/NamingStrategyInterface";
|
||||
|
||||
@NamingStrategy("firstCustomNamingStrategy")
|
||||
export class FirstCustomNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(className: string, customName: string): string {
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import {DefaultNamingStrategy} from "../../../../src/naming-strategy/DefaultNamingStrategy";
|
||||
import {NamingStrategy} from "../../../../src/decorator/NamingStrategy";
|
||||
import {NamingStrategyInterface} from "../../../../src/naming-strategy/NamingStrategyInterface";
|
||||
|
||||
@NamingStrategy("secondCustomNamingStrategy")
|
||||
export class SecondCustomNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {
|
||||
|
||||
tableName(className: string, customName: string): string {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {ConnectionOptions} from "../../src/connection/ConnectionOptions";
|
||||
import {createConnection, createConnections} from "../../src/index";
|
||||
import {Connection} from "../../src/connection/Connection";
|
||||
import {DriverType} from "../../src/driver/DriverOptions";
|
||||
import {EntitySchema} from "../../src/entity-schema/EntitySchema";
|
||||
import {DriverType} from "../../src/driver/DriverType";
|
||||
|
||||
/**
|
||||
* Interface in which data is stored in ormconfig.json of the project.
|
||||
@ -128,7 +128,7 @@ export function setupTestingConnections(options?: TestingOptions) {
|
||||
return false;
|
||||
|
||||
if (options && options.enabledDrivers && options.enabledDrivers.length)
|
||||
return options.enabledDrivers.indexOf(connectionOptions.driver.type) !== -1;
|
||||
return options.enabledDrivers.indexOf(connectionOptions.driver!.type) !== -1; // ! is temporary
|
||||
|
||||
if (connectionOptions.disabledIfNotEnabledImplicitly === true)
|
||||
return false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user