mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactored require entities from directories part
This commit is contained in:
parent
5f92ede75c
commit
7a2fe7b143
@ -44,11 +44,12 @@
|
||||
"dependencies": {
|
||||
"fs": "^0.0.2",
|
||||
"lodash": "^4.5.0",
|
||||
"mysql": "^2.10.2",
|
||||
"path": "^0.11.14",
|
||||
"reflect-metadata": "^0.1.3",
|
||||
"require-all": "^2.0.0",
|
||||
"sha1": "^1.1.1",
|
||||
"typedi": "~0.2.0",
|
||||
"mysql": "^2.10.2"
|
||||
"typedi": "~0.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postversion": "./node_modules/.bin/gulp package",
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import {createMysqlConnection} from "../../src/typeorm";
|
||||
import {Post} from "./entity/Post";
|
||||
import {PostDetails} from "./entity/PostDetails";
|
||||
import {PostCategory} from "./entity/PostCategory";
|
||||
import {PostMetadata} from "./entity/PostMetadata";
|
||||
import {PostImage} from "./entity/PostImage";
|
||||
import {PostInformation} from "./entity/PostInformation";
|
||||
import {PostAuthor} from "./entity/PostAuthor";
|
||||
|
||||
// first create a connection
|
||||
let options = {
|
||||
@ -17,7 +12,7 @@ let options = {
|
||||
autoSchemaCreate: true
|
||||
};
|
||||
|
||||
createMysqlConnection(options, [Post, PostDetails, PostCategory, PostMetadata, PostImage, PostInformation, PostAuthor]).then(connection => {
|
||||
createMysqlConnection(options, [__dirname + "/entity"]).then(connection => {
|
||||
|
||||
let details1 = new PostDetails();
|
||||
details1.comment = "People";
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
import {Connection} from "./Connection";
|
||||
import {OrmUtils} from "../util/OrmUtils";
|
||||
import {defaultMetadataStorage} from "../metadata-builder/MetadataStorage";
|
||||
import {Driver} from "../driver/Driver";
|
||||
import {DefaultNamingStrategy} from "../naming-strategy/DefaultNamingStrategy";
|
||||
import {ConnectionNotFoundError} from "./error/ConnectionNotFoundError";
|
||||
import {EntityMetadataBuilder} from "../metadata-builder/EntityMetadataBuilder";
|
||||
import {importClassesFromDirectories} from "../util/DirectoryExportedClassesLoader";
|
||||
|
||||
/**
|
||||
* Connection manager holds all connections made to the databases.
|
||||
*/
|
||||
export class ConnectionManager {
|
||||
|
||||
// todo: add support for importing entities and subscribers from subdirectories, make support of glob patterns
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
@ -36,7 +34,7 @@ export class ConnectionManager {
|
||||
/**
|
||||
* Sets a container that can be used in custom user subscribers. This allows to inject services in user classes.
|
||||
*/
|
||||
set container(container: { get(someClass: any): any }) {
|
||||
set container(container: { get(someClass: Function): any }) {
|
||||
this._container = container;
|
||||
}
|
||||
|
||||
@ -69,24 +67,6 @@ export class ConnectionManager {
|
||||
return foundConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities for the given connection. If connection name is not given then default connection is used.
|
||||
*/
|
||||
importEntities(entities: Function[]): void;
|
||||
importEntities(connectionName: string, entities: Function[]): void;
|
||||
importEntities(connectionNameOrEntities: string|Function[], entities?: Function[]): void {
|
||||
let connectionName = "default";
|
||||
if (typeof connectionNameOrEntities === "string") {
|
||||
connectionName = <string> connectionNameOrEntities;
|
||||
} else {
|
||||
entities = <Function[]> connectionNameOrEntities;
|
||||
}
|
||||
|
||||
const metadatas = this.entityMetadataBuilder.build(entities);
|
||||
if (metadatas.length > 0)
|
||||
this.getConnection(connectionName).addMetadatas(metadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities from the given paths (directories) for the given connection. If connection name is not given
|
||||
* then default connection is used.
|
||||
@ -101,12 +81,7 @@ export class ConnectionManager {
|
||||
paths = <string[]> connectionNameOrPaths;
|
||||
}
|
||||
|
||||
const entitiesInFiles = OrmUtils.requireAll(paths);
|
||||
const allEntities = entitiesInFiles.reduce((allEntities, entities) => {
|
||||
return allEntities.concat(Object.keys(entities).map(key => entities[key]));
|
||||
}, []);
|
||||
|
||||
this.importEntities(connectionName, allEntities);
|
||||
this.importEntities(connectionName, importClassesFromDirectories(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,27 +90,45 @@ export class ConnectionManager {
|
||||
*/
|
||||
importSubscribersFromDirectories(paths: string[]): void;
|
||||
importSubscribersFromDirectories(connectionName: string, paths: string[]): void;
|
||||
importSubscribersFromDirectories(connectionName: any, paths?: string[]): void {
|
||||
if (typeof connectionName === "object") {
|
||||
paths = connectionName;
|
||||
connectionName = "default";
|
||||
importSubscribersFromDirectories(connectionNameOrPaths: string|string[], paths?: string[]): void {
|
||||
let connectionName = "default";
|
||||
if (typeof connectionNameOrPaths === "string") {
|
||||
connectionName = <string> connectionNameOrPaths;
|
||||
} else {
|
||||
paths = <string[]> connectionNameOrPaths;
|
||||
}
|
||||
|
||||
const subscribersInFiles = OrmUtils.requireAll(paths);
|
||||
const allSubscriberClasses = subscribersInFiles.reduce((all, subscriberInFile) => {
|
||||
return all.concat(Object.keys(subscriberInFile).map(key => subscriberInFile[key]));
|
||||
}, []);
|
||||
|
||||
const allSubscriberClasses = importClassesFromDirectories(paths);
|
||||
const subscribers = defaultMetadataStorage
|
||||
.ormEventSubscriberMetadatas
|
||||
.filter(metadata => allSubscriberClasses.indexOf(metadata.constructor) !== -1)
|
||||
.map(metadata => {
|
||||
const constructor: any = metadata.constructor;
|
||||
return this._container ? this._container.get(constructor) : new constructor();
|
||||
});
|
||||
|
||||
if (subscribers.length > 0)
|
||||
this.getConnection(connectionName).addSubscribers(subscribers);
|
||||
.findOrmEventSubscribersForClasses(allSubscriberClasses)
|
||||
.map(metadata => this.createContainerInstance(metadata.constructor));
|
||||
|
||||
this.getConnection(connectionName).addSubscribers(subscribers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports entities for the given connection. If connection name is not given then default connection is used.
|
||||
*/
|
||||
importEntities(entities: Function[]): void;
|
||||
importEntities(connectionName: string, entities: Function[]): void;
|
||||
importEntities(connectionNameOrEntities: string|Function[], entities?: Function[]): void {
|
||||
let connectionName = "default";
|
||||
if (typeof connectionNameOrEntities === "string") {
|
||||
connectionName = <string> connectionNameOrEntities;
|
||||
} else {
|
||||
entities = <Function[]> connectionNameOrEntities;
|
||||
}
|
||||
|
||||
const metadatas = this.entityMetadataBuilder.build(entities);
|
||||
this.getConnection(connectionName).addMetadatas(metadatas);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private createContainerInstance(constructor: Function) {
|
||||
return this._container ? this._container.get(constructor) : new (<any> constructor)();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -114,6 +114,11 @@ export class MetadataStorage {
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
findOrmEventSubscribersForClasses(classes: Function[]): OrmEventSubscriberMetadata[] {
|
||||
// todo: didn't checked. Check if is working. Maybe dont need to use target and use constructor somehow?
|
||||
return this.ormEventSubscriberMetadatas.filter(metadata => classes.indexOf(metadata.target) !== -1);
|
||||
}
|
||||
|
||||
findTableMetadatasForClasses(classes: Function[]): TableMetadata[] {
|
||||
return this.tableMetadatas.filter(metadata => classes.indexOf(metadata.target) !== -1);
|
||||
}
|
||||
|
||||
51
src/util/DirectoryExportedClassesLoader.ts
Normal file
51
src/util/DirectoryExportedClassesLoader.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import * as fs from "fs";
|
||||
|
||||
/**
|
||||
* Loads all exported classes from the given directory.
|
||||
*/
|
||||
export class DirectoryExportedClassesLoader {
|
||||
|
||||
// todo: this can be extracted into external module and used across all other modules
|
||||
// todo: add support for glob patterns
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Imports all entities (makes them "require") from the given directories.
|
||||
*/
|
||||
importClassesFromDirectories(directories: string[]): Function[] {
|
||||
const requireAll = require("require-all");
|
||||
const filter = /(.*)\.js$/;
|
||||
const dirs = directories
|
||||
.filter(directory => fs.existsSync(directory))
|
||||
.map(directory => requireAll({ dirname: directory, filter: filter, recursive: true }));
|
||||
|
||||
return this.loadFileClasses(dirs, []);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private loadFileClasses(exported: any, allLoaded: Function[]) {
|
||||
if (exported instanceof Function) {
|
||||
allLoaded.push(exported);
|
||||
|
||||
} else if (exported instanceof Object) {
|
||||
Object.keys(exported).forEach(key => this.loadFileClasses(exported[key], allLoaded));
|
||||
|
||||
} else if (exported instanceof Array) {
|
||||
exported.forEach((i: any) => this.loadFileClasses(i, allLoaded));
|
||||
}
|
||||
|
||||
return allLoaded;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function importClassesFromDirectories(directories: string[]): Function[] {
|
||||
const loader = new DirectoryExportedClassesLoader();
|
||||
return loader.importClassesFromDirectories(directories);
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
/**
|
||||
* Common utility functions.
|
||||
*/
|
||||
export class OrmUtils {
|
||||
|
||||
/**
|
||||
* Makes "require()" all js files (or custom extension files) in the given directory.
|
||||
* @deprecated use npm module instead
|
||||
*/
|
||||
static requireAll(directories: string[], extension: string = ".js"): any[] {
|
||||
let files: any[] = [];
|
||||
directories.forEach((dir: string) => {
|
||||
if (fs.existsSync(dir)) {
|
||||
fs.readdirSync(dir).forEach((file: string) => {
|
||||
if (fs.statSync(dir + "/" + file).isDirectory()) {
|
||||
let requiredFiles = this.requireAll([dir + "/" + file], extension);
|
||||
requiredFiles.forEach((file: string) => files.push(file));
|
||||
} else if (path.extname(file) === extension) {
|
||||
files.push(require(dir + "/" + file));
|
||||
}
|
||||
});
|
||||
}
|
||||
}); // todo: implement recursion
|
||||
return files;
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,7 +32,7 @@ describe("many-to-many", function() {
|
||||
// connect to db
|
||||
let connection: Connection;
|
||||
before(function() {
|
||||
return createMysqlConnection(options, [Post, PostDetails, PostCategory, PostMetadata, PostImage, PostInformation, PostAuthor]).then(conn => {
|
||||
return createMysqlConnection(options, [__dirname + "/../../sample/sample4-many-to-many/entity"]).then(conn => {
|
||||
connection = conn;
|
||||
}).catch(e => console.log("Error during connection to db: " + e));
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user