From ae76db32118fa366a351648e9a6c8deaa0acc78a Mon Sep 17 00:00:00 2001 From: Umed Khudoiberdiev Date: Tue, 12 Apr 2016 09:38:57 +0300 Subject: [PATCH] added more docs --- .vscode/settings.json | 3 + README.md | 24 +-- docs/command-line-tools.md | 3 + docs/connection-and-connection-options.md | 158 +++++++++++++++- docs/databases-and-drivers.md | 35 +++- docs/decorators-reference.md | 3 + docs/relations.md | 40 +++- docs/repository.md | 74 +++++++- docs/table-columns.md | 212 ++++++++++++++++------ docs/tables-and-table-inheritance.md | 56 +++++- docs/updating-database-schema.md | 16 +- src/connection/Connection.ts | 45 ++--- src/connection/ConnectionOptions.ts | 2 +- src/driver/Driver.ts | 5 + src/driver/MysqlDriver.ts | 7 + src/repository/Repository.ts | 11 +- 16 files changed, 595 insertions(+), 99 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 docs/command-line-tools.md create mode 100644 docs/decorators-reference.md diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..20af2f68a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +// Place your settings in this file to overwrite default and user settings. +{ +} \ No newline at end of file diff --git a/README.md b/README.md index 51a0c21b7..3150f5248 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ TypeORM is an [Object Relational Mapper](1) (ORM) for node.js written in Typescript that can help you to: -* automatically create your table schemas based on your model +* automatically create your table schemas based on your models (javascript class, decorated with special decorators) * ability to transparently insert / update / delete to the database your objects @@ -17,7 +17,7 @@ between tables TypeORM uses Data Mapper pattern, unlike all other javascript ORMs that currently exist, which means you can write loosely coupled, scalable, -maintainable enterprise applications easily. +maintainable enterprise applications with less problems. The benefit of using ORM for the programmer is the ability to focus on the business logic and worry about persistence only as a secondary problem. @@ -49,11 +49,11 @@ need to do: ## Example -Lets create a sample application - photo album. +Lets create a sample application - a photo album. #### create Photo entity class -First we create a new file `Photo.ts` and create a class there: +First we create a new file `Photo.ts` and put a class there: ```typescript import {Table} from "typeorm/decorator/Tables"; @@ -659,7 +659,7 @@ whose name is "My" or "Mishka", it will select results from 5 position Selection result will be ordered by id in descending order. Photo's albums will be left-joined and photo's metadata will be inner joined. -Learn more about FindOptions [here](). +Learn more about FindOptions [here](docs/repository.md#find-options). #### using QueryBuilder to build complex queries @@ -688,7 +688,7 @@ whose name is "My" or "Mishka", it will select results from 5 position Selection result will be ordered by id in descending order. Photo's albums will be left-joined and photo's metadata will be inner joined. -Learn more about QueryBuilder [here](). +Learn more about QueryBuilder [here](docs/query-builder.md). #### using EntityManager to work with any entity @@ -739,13 +739,13 @@ entityManager }); ``` -Learn more about EntityManager [here](). +Learn more about EntityManager [here](docs/entity-manager.md). ## Learn more * [connection and connection options](docs/connection-and-connection-options.md) -* [updating database schema](docs/updating-database-schema.md) * [databases and drivers](docs/databases-and-drivers.md) +* [updating database schema](docs/updating-database-schema.md) * [tables and table inheritance](docs/tables-and-table-inheritance.md) * [table columns](docs/table-columns.md) * [relations](docs/relations.md) @@ -755,6 +755,8 @@ Learn more about EntityManager [here](). * [entity manager](docs/entity-manager.md) * [subscribers and entity listeners](docs/subscribers-and-entity-listeners.md) * [naming strategies](docs/naming-strategies.md) +* [decorators reference](docs/decorators-reference.md) +* [command line tools](docs/command-line-tools.md) ## Samples @@ -763,11 +765,11 @@ usages. ## Todos -ORM development is in progress. Readme and documentations expected to be soon. +ORM development is in progress. Api can be changed a lot. More documentation and features expected to be soon. Feel free to contribute ;) -* add partial selection support -* in query builder should we use property names or table names? (right now its mixed) +* add partial selection support (lot of problems with partial selection. Is there real benefit for users to use it?) +* in query builder should we use property names or table names? (right now its kinda mixed) * should all entities have a primary column? * think about indices * think more about cascades diff --git a/docs/command-line-tools.md b/docs/command-line-tools.md new file mode 100644 index 000000000..197085075 --- /dev/null +++ b/docs/command-line-tools.md @@ -0,0 +1,3 @@ +## Command Line Tools + +TBD \ No newline at end of file diff --git a/docs/connection-and-connection-options.md b/docs/connection-and-connection-options.md index 40e8428c0..272b402fb 100644 --- a/docs/connection-and-connection-options.md +++ b/docs/connection-and-connection-options.md @@ -1,3 +1,159 @@ ## Connection and connection options -TBD \ No newline at end of file +You start using ORM by creating a connection with the database. In this section you will learn about: + +* [Connection Manager that contains all connections to the databases](#connection-manager) +* [Working with connections](#working-with-connection) +* [Connection options](#connection-options) +* [How to use connection manager, connections and connection options](#example) + +### Connection Manager + +Connection manager allows to create a new connections and retrive previously created connections. Also it allows to import +entities and subscribers into specific connection. These are main public methods of the `ConnectionManager`: + +* `createConnection(connectionName: string = "default", driver: Driver, options: ConnectionOptions): Connection` + +Creates a new connection and registers it in the connection manager. It returns a newly created connection. +New connection will have a given *connection name*. If connection name is not given then "default" will be used as a + connection name. This name will be used to retrieve this connection later. +*Driver* needs to be specified to understand what kind of database will be used for this connection. +Right now it can be only a `mysql` driver. +*Options* specifies connection options. More about it later. + +* `getConnection(connectionName: string = "default"): Connection` + +Gets a connection with a given name that was created using `createConnection` method. Connection later can be used to +perform actions on it. +* `importEntities(connectionName: string = "default", entities: Function[]): void` + +Imports all given entities and registers them in the connection with a given name. +* `importSubscribers(connectionName: string = "default", subscribers: Function[]): void` + +Imports all given subscribers and registers them in the connection with a given name. +* `importEntitiesFromDirectories(connectionName: string = "default", paths: string[]): void` + +Imports all entities from the given directories and registers them in the connection with a given name. +Paths is an array of directories from where to import entities. +* `importSubscribersFromDirectories(connectionName: string = "default", paths: string[]): void` + +Imports all subscribers from the given directories and registers them in the connection with a given name. +Paths is an array of directories from where to import subscribers. + +### Working with Connection + +Connection is a database connection to specific database of the specific database management system. +There are several useful methods in the Connection object: + +* `connect()` +Opens a new connection with the database. +* `close()` +Closes connection with the database. +* `getEntityManager()` +Gets [EntityManager](entity-manager.md) that is used to execute database operations on any entity +that is registered in this connection. +* `getRepository(entityClass: Function)` +Gets a [repository](repository.md) of the specific entity that provides all functionality +(selects/inserts/updates/deletes) with a table of the given entity class. + +### Connection Options + +To perform a connection you need to specify a connection options. ConnectionOptions is an interface: + +```typescript +export interface ConnectionOptions { + + url?: string; // connection url + host?: string; // database host + port?: number; // database host port + username?: string; // database username + password?: string; // database password + database?: string; // database name + autoSchemaCreate?: boolean; // set to true if you want your database schema to be auto created on each application launch + logging?: { + + logger?: (message: any, level: string) => void; // some specific logger to be used. By default it is a console + logQueries?: boolean; // used if you want to log every executed query + logOnlyFailedQueries?: boolean; // used if you want to log only failed query + logFailedQueryError?: boolean; // used if you want to log error of the failed query + + }; + +} +``` + +* To perform a connection you either must specify a connection `url`, either specify `host/port/username/password/database`. +* `autoSchemaCreate` allows you to automatically synchronize your database schema (create new tables, +remove/rename old columns, create foreign keys, etc.) on each application run. Note that there can be errors in schema +synchronization (mostly errors can be caused by unresolved foreign keys) and this will crash your application. +This option should not be used in production, only during development and only if you are too lazy to use +[command line tools](command-line-tools.md). Alternatively you can use [schema update gulp plugin](todo). + + +### Example + +```typescript +// create a new connection manager +let connectionManager = new ConnectionManager(); + +// prepare connection options +let connectionOptions: ConnectionOptions = { + host: "localhost", + port: 3306, + username: "root", + password: "admin", + database: "test", + autoSchemaCreate: true +}; + +// create a new connection with mysql driver +connectionManager.createConnection(new MysqlDriver(), connectionOptions); + +// import all entities from specific directory +connectionManager.importEntitiesFromDirectories(__dirname + "/entities"); + +// get our connection: +let connection = connectionManager.getConnection(); +connection.connect().then(connection => { + + // now we are connected to the database + // here we have a connection and we can use any of its methods + // lets say we have a Photo entity in the /entities directory + + // and lets create a new Photo entity instance + + // lets try to use entity manager + let entityManager = connection.getEntityManager(); + + // and lets create a new Photo entity instance + let photo = new Photo(); + photo.name = "photo #1"; + + // and save it using entity manager + entityManager + .persist(photo) + .then(photo => { + console.log("Photo has been saved using entity manager"); + }); + + // lets try to use repository + let repository = connection.getRepository(Photo); + + // and lets create a new Photo entity instance + let photo = new Photo(); + photo.name = "photo #2"; + + // and save it using repository + repository + .persist(photo) + .then(photo => { + console.log("Photo has been saved using repository"); + }); + + +}).catch(error => { + // looks like some error during connection. Lets log it to find details + console.log("error during connection to the database ", error); +}); +``` + diff --git a/docs/databases-and-drivers.md b/docs/databases-and-drivers.md index 40fe8e55e..e492877cc 100644 --- a/docs/databases-and-drivers.md +++ b/docs/databases-and-drivers.md @@ -1,3 +1,36 @@ ## Databases and drivers -TBD \ No newline at end of file +ORM is working with databases. To communicate with database it uses **database drivers**. +Database Driver communicates with specific database and performs queries you need. + +### Driver Interface + +Right now only `mysql` database driver is supported. If you need other driver, or you simply +want to contribute then feel free to add it - adding new drivers is not complicated. + +Drivers are typically used within connection: + +`let connection = connectionManager.createConnection("my-connection", new MysqlDriver());` + +To access the driver you can do it from your connection instance: + +`connection.driver` + +There are several useful methods in the driver object: + +* `driver.native` + +Allows you to access a native layer of the driver. For example MysqlDriver is depend of npm's `mysql` package +and `mysqlDriver.native` will give you instance to that package. + +* `driver.nativeConnection` + +Allows you to access to a connection instance of the native layer of the driver. For example MysqlDriver is depend of +npm's `mysql` package and when we create a connection using that package it returns us some `connection instance` that + we save in the driver.nativeConnection. + +Both methods are not recommended to use, but sometimes you have no choice because of the limits of the ORM abstraction +and you have to use them. In such situations both methods are very useful. + +There are lot of other methods in the Driver, but you won't use them directly - they are used by other components, like +[Entity Manager](entity-manager.md) or [Repository](repository.md). You should use those components instead. diff --git a/docs/decorators-reference.md b/docs/decorators-reference.md new file mode 100644 index 000000000..100732dec --- /dev/null +++ b/docs/decorators-reference.md @@ -0,0 +1,3 @@ +## Decorators Reference + +TBD \ No newline at end of file diff --git a/docs/relations.md b/docs/relations.md index d16030e89..47842ffa4 100644 --- a/docs/relations.md +++ b/docs/relations.md @@ -1,3 +1,41 @@ ## Relations -TBD \ No newline at end of file +One of the best sides of TypeORM is relations support. You can build relations between your tables +easily without thinking of database schema and foreign keys. Relations are created using special decorators +on specific fields of entity objects. + +* [@OneToOne and @OneToOneInverse decorators](#@OneToOne-and-@OneToOneInverse-decorators) +* [@OneToMany and @ManyToOne decorators](#@OneToMany-and-@ManyToOne-decorators) +* [@ManyToMany and @ManyToManyInverse decorators](#@ManyToMany-and-@ManyToManyInverse-decorators) +* [Self referencing](#self-referencing) +* [Relational decorators options](#RelationOptions) + +### @OneToOne and @OneToOneInverse decorators + +TBD + +### @OneToMany and @ManyToOne decorators + +TBD + +### @ManyToMany and @ManyToManyInverse decorators + +TBD + +### Self referencing + +TBD + +### Relational decorators options + +RelationOptions is an object with additional relation options: + +* `name?: string` - column name for the relation in the database +* `cascadeInsert?: boolean` - allow cascade insert operations or not. If you set this to true, then any entity that +is new (means does not exist in the database) on the relation will be persisted too. +* `cascadeUpdate?: boolean` - allow cascade update operations or not. If you set this to true, then related entity + will be updated in the database if it was changed. +* `cascadeRemove?: boolean` - allow cascade remove operations or not. If you set this to true, then related entity + will be removed from the database if it was removed from this object. +* `onDelete?: string` - Database-level operation `ON DELETE` is an action that must be performed when related row in + the database has been removed. \ No newline at end of file diff --git a/docs/repository.md b/docs/repository.md index 95b778e1c..cb323bb44 100644 --- a/docs/repository.md +++ b/docs/repository.md @@ -1,3 +1,75 @@ ## Repository -TBD \ No newline at end of file +For each entity you have there is a Repository for it. Repository provides functionality to work with your entity. +There are several useful methods of the Repository: + +* `hasId(entity: Entity): boolean` + +Sometimes you want to check if your entity already has id or not. This maybe useful in situations when you want to +check if your object is new or not. + +* `create(plainJsObject?: Object): Entity` + +Creates a new empty instance of entity. If `plainJsObject` is given then new entity will be created and all properties +from the `plainJsObject` that can be mapped to this entity will be copied to the new entity. + +* `createMany(plainJsObjects: Object[]): Entity[]` + +Creates multiple new entities based on array of plain javascript objects. Properties for each plain javascript object +will be copied to newly created entities if they should exist there. + +* `initialize(object: Object): Promise` + +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. + +* `persist(entity: Entity): Promise` + +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. + +* `remove(entity: Entity): Promise` + +Removes a given entity from the database. + +* ```typescript +find(): Promise +find(conditions: Object): Promise; +find(options: FindOptions): Promise; +find(conditions: Object, options: FindOptions): Promise; +``` + +Finds entities that match given conditions or given find options. + +* ```typescript +findOne(): Promise; +findOne(conditions: Object): Promise; +findOne(options: FindOptions): Promise; +findOne(conditions: Object, options: FindOptions): Promise; +``` + +Finds the first entity that match given conditions or given find options. + +* `findById(id: any, options?: FindOptions): Promise` + +Finds entity with a given entity id. + +* `findAndCount(conditions?: Object, options?: FindOptions): Promise<{ items: Entity[], count: number }>` + +Finds entities that match given conditions or given find options plus gets a overall count of this items (for +pagination purposes). + +* `createQueryBuilder(alias: string): QueryBuilder` + +Creates a new query builder that can be used to build a sql query and get the results of the executed query. You can +learn more about query builder [here](docs/query-builder.md). + +* `query(sql: string): Promise` + +Executes raw SQL query. + +* `transaction(runInTransaction: () => Promise): Promise` + +Executes everything in the given function in a single transaction. diff --git a/docs/table-columns.md b/docs/table-columns.md index 07eb7db5f..305a06afd 100644 --- a/docs/table-columns.md +++ b/docs/table-columns.md @@ -1,70 +1,172 @@ -## Tables and columns +## Table columns -### Creating a basic table +Entity consist of columns. For each entity column, column in the database will be created. -Every object that you want to be saved in the database must have `@Table` -decorator and each property you want to be saved from your object must -have `@Column` decorator. Let's start with an example: +* [@Column decorator](#@column) +* [@PrimaryColumn decorator](#@primary-column) +* [@CreateDateColumn decorator](#@create-date-column) +* [@UpdateDateColumn decorator](#@update-date-column) +* [Column types](#column-type) +* [Column options](#column-options) +* [Columns usage example](#example) + +#### @Column + +Column decorator simply marks an entity property to be a table column. +There are several column decorator signatures: + +```typescript +@Column(options?: ColumnOptions) +@Column(type?: ColumnType, options?: ColumnOptions) +``` + +#### @PrimaryColumn + +PrimaryColumn marks an entity property as a column and creates a primary key for it. +There are several column decorator signatures: + +```typescript +@PrimaryColumn(options?: ColumnOptions) +@PrimaryColumn(type?: ColumnType, options?: ColumnOptions) +``` + +#### @CreateDateColumn + +CreateDateColumn adds a simple datetime column to the table. During its first persistence (e.g. insertion) it +sets current date as a value of the property object. + +```typescript +@CreateDateColumn(options?: ColumnOptions) +``` + +#### @UpdateDateColumn + +UpdateDateColumn adds a simple datetime column to the table. Each time object is persisted, this column value is updated +to the current date. + +```typescript +@CreateDateColumn(options?: ColumnOptions) +``` + +#### ColumnType + +ColumnType can be one of: + +* `string` will be mapped to db's `varchar` +* `text` will be mapped to db's `text` +* `number` will be mapped to db's `double` +* `integer` will be mapped to db's `int` +* `int` will be mapped to db's `int` +* `smallint` will be mapped to db's `int` +* `bigint` will be mapped to db's `int` +* `float` will be mapped to db's `float` +* `double` will be mapped to db's `double` +* `decimal` will be mapped to db's `decimal` +* `date` will be mapped to db's `datetime` +* `time` will be mapped to db's `time` +* `datetime` will be mapped to db's `datetime` +* `boolean` will be mapped to db's `boolean` +* `json` will be mapped to db's `text` +* `simple_array` will be mapped to db's `text` + +If you omit a column type, type will be guessed automatically based on variable type: + +* `number` will be mapped to `float` +* `boolean` will be mapped to `boolean` +* `string` will be mapped to `varchar` +* `Date` will be mapped to `datetime` + +#### ColumnOptions + +ColumnOptions is an object with additional column options: + +* `name?: string` - column name in the database +* `type?: ColumnType` - column type also can be specified via column options +* `length?: string` - column type's length. For example type = "string" and length = 100 means that ORM will create a + column with type varchar(100). +* `autoIncrement?: boolean` - specifies if this column will use AUTO_INCREMENT or not (e.g. generated number) +* `unique?: boolean` - specifies if column's value must be unique or not. +* `nullable?: boolean` - indicates if column's value can be set to NULL. +* `columnDefinition?: string` - Extra column definition. Should be used only in emergency situations. +Note that if you'll use this property auto schema generation will not work properly anymore. +* `comment?: string` - column comment +* `precision?: number` - The precision for a decimal (exact numeric) column (applies only for decimal column), which is the maximum +number of digits that are stored for the values. +* `scale?: number` - The scale for a decimal (exact numeric) column (applies only for decimal column), which represents the number +of digits to the right of the decimal point and must not be greater than precision. +* `collation?: string` - Column collation. Note that not all databases support it. + +#### Example ```typescript @Table("photo") class Photo { - - @PrimaryColumn() + + /** + * Primary column with auto increment key. + */ + @PrimaryColumn("int", { autoIncrement: true }) id: number; - + + /** + * Simple string column. + */ @Column() name: string; - + + /** + * Simple boolean column. + */ @Column() - filename: string; - + isPublished: boolean; + + /** + * Simple numeric (float) column. + */ @Column() + scale: number; + + /** + * Simple numeric (integer) column. + */ + @Column("integer") + size: number; + + /** + * Simple column that contains a date. + */ + @Column() + publishedDate: Date; + + /** + * Simple column that contains a big text. + */ + @Column("text") description: string; + + /** + * Simple column that contains a short text. + */ + @Column({ + length: 3 + }) + locale: string; + + /** + * This column's value must be unique. + */ + @Column({ + unique: true + }) + slug: string; + + /** + * This column's value can be nullable. + */ + @Column({ + nullable: true + }) + metadata: string; } ``` - -* `@Table` decorator registers your class in ORM, and allows you to make -different operations with instances of this class directly in the db. -After you mark your class with this decorator and run schema update -process, ORM will create a table in the db for you, with all proper -columns, keys and so on. After you define your class as a @Table you -can do various operations like inserting, updating, removing, fining -objects of this class in the database. In this example we also specified -a name for this table (`@Table("photo")`). ORM will create a table in -the database with such name - "photos". - -* `@Column` decorator marks properties of your class to be persisted into -the database. For each property of your class decorated by `@Table` -decorator ORM will create a column in the table, and this property's -value will be saved to database when you'll save a class instance. - -* `@PrimaryColumn` decorator marks a property of your class that must -be a primary-key in your table. It works the same way as @Column decorator, -but the main difference is that it also creates a PRIMARY KEY for this -column. This decorator is always used when you want to create an id-based -column, including auto-increment id. - -### Primary and regular columns - -By default column type used in the database is automatically guessed -from property type. But type that is set for property is not desirable -for the type used in the database. For example type `number -You can specify a type of column that will be used `@Column` - -```typescript -@Table("photo") -class Photo { - - @Column("string") - name: string; - - @Column() - filename: string; - - @Column() - description: string; - -} -``` \ No newline at end of file diff --git a/docs/tables-and-table-inheritance.md b/docs/tables-and-table-inheritance.md index 44431e68a..46f39cb93 100644 --- a/docs/tables-and-table-inheritance.md +++ b/docs/tables-and-table-inheritance.md @@ -1,3 +1,57 @@ ## Tables and table inheritance -TBD \ No newline at end of file +### Tables + +ORM creates tables for each class that you decorated with `@Table` decorator and which you loaded into your +connection. + +```typescript +@Table("photos") +export class Photo { + +} +``` + +Each table must have a primary column (using `@PrimaryColumn` decotator) [*todo: really?*] and can contain +other [columns](table-columns.md). + +### Table inheritance + +If multiple tables has same properties you may want to find them a common abstraction and create a base +class for them. In this base class you'll have a common for all inherited classes columns. To ahieve this you +must mark your table with `@AbstractTable()` decorator: + +```typescript +@AbstractTable() +export class BasePhoto { + + @PrimaryColumn("int", { autoIncrement: true }) + id: string; + + @Column() + name: string; + + @Column() + url: string; + +} + +@Table("public_photos") +export class Photo extends BasePhoto { + + @Column() + authorName: string; + +} + +@Table("private_photos") +export class Photo extends BasePhoto { + + @Column() + isPublished: boolean; + +} +``` + +This will create you two tables `public_photos` and `private_photos` with 5 columns each. +Right now only columns are inherited. Relations are ignored. \ No newline at end of file diff --git a/docs/updating-database-schema.md b/docs/updating-database-schema.md index 86652ce86..dd7f96cf3 100644 --- a/docs/updating-database-schema.md +++ b/docs/updating-database-schema.md @@ -1,3 +1,17 @@ ## Updating database schema -TBD \ No newline at end of file +Your database schema is managed automatically by ORM: + +* tables are created for all entities +* columns are created for all entity columns +* foreign keys are set for all relations +* junction tables are created for all many-to-many relations + +All this must be in sync to make ORM to work correctly. To make a synchronization there are two ways: + +* set in [connection options](connection-and-connection-options.md#connection-options) `autoSchemaCreate: true`. +In this case database schema will be automatically synchronized each time you run the application. + +* use [schema update gulp plugin](todo) and run schema synchronization process each time you need it. + +First approach is not recommended to use in production, however it can be handy during development. \ No newline at end of file diff --git a/src/connection/Connection.ts b/src/connection/Connection.ts index 0757f2109..f95e3f235 100644 --- a/src/connection/Connection.ts +++ b/src/connection/Connection.ts @@ -121,27 +121,8 @@ export class Connection { } /** - * Registers entity metadatas for the current connection. + * Gets EntityManager of this connection. */ - addEntityMetadatas(metadatas: EntityMetadata[]) { - this._entityMetadatas = this._entityMetadatas.concat(metadatas); - this.repositoryAndMetadatas = this.repositoryAndMetadatas.concat(metadatas.map(metadata => this.createRepoMeta(metadata))); - } - - /** - * Registers entity listener metadatas for the current connection. - */ - addEntityListenerMetadatas(metadatas: EntityListenerMetadata[]) { - this._entityListenerMetadatas = this._entityListenerMetadatas.concat(metadatas); - } - - /** - * Registers subscribers for the current connection. - */ - addSubscribers(subscribers: OrmSubscriber[]) { - this._subscribers = this._subscribers.concat(subscribers); - } - getEntityManager() { return this.entityManager; } @@ -164,11 +145,33 @@ export class Connection { getEntityMetadata(entityClass: Function): EntityMetadata { const metadata = this.entityMetadatas.find(metadata => metadata.target === entityClass); if (!metadata) - throw new MetadataNotFoundError(entityClass); + throw new MetadataNotFoundError(entityClass); return metadata; } + /** + * Registers entity metadatas for the current connection. + */ + addEntityMetadatas(metadatas: EntityMetadata[]) { + this._entityMetadatas = this._entityMetadatas.concat(metadatas); + this.repositoryAndMetadatas = this.repositoryAndMetadatas.concat(metadatas.map(metadata => this.createRepoMeta(metadata))); + } + + /** + * Registers entity listener metadatas for the current connection. + */ + addEntityListenerMetadatas(metadatas: EntityListenerMetadata[]) { + this._entityListenerMetadatas = this._entityListenerMetadatas.concat(metadatas); + } + + /** + * Registers subscribers for the current connection. + */ + addSubscribers(subscribers: OrmSubscriber[]) { + this._subscribers = this._subscribers.concat(subscribers); + } + // ------------------------------------------------------------------------- // Private Methods // ------------------------------------------------------------------------- diff --git a/src/connection/ConnectionOptions.ts b/src/connection/ConnectionOptions.ts index 4acb3794d..543940ef4 100644 --- a/src/connection/ConnectionOptions.ts +++ b/src/connection/ConnectionOptions.ts @@ -44,7 +44,7 @@ export interface ConnectionOptions { logging?: { /** - * Some specific logger to be used. By default it console. + * Some specific logger to be used. By default it is a console. */ logger?: (message: any, level: string) => void; diff --git a/src/driver/Driver.ts b/src/driver/Driver.ts index 251622e82..6dcd7045a 100644 --- a/src/driver/Driver.ts +++ b/src/driver/Driver.ts @@ -13,6 +13,11 @@ export interface Driver { */ native: any; + /** + * Access to the connection of the native interface of the database. + */ + nativeConnection: any; + /** * Connection used in this driver. */ diff --git a/src/driver/MysqlDriver.ts b/src/driver/MysqlDriver.ts index 9e0cb7692..f7a4fd546 100644 --- a/src/driver/MysqlDriver.ts +++ b/src/driver/MysqlDriver.ts @@ -45,6 +45,13 @@ export class MysqlDriver extends BaseDriver implements Driver { get native(): any { return this.mysql; } + + /** + * Access to the native implementation of the database. + */ + get nativeConnection(): any { + return this.mysqlConnection; + } /** * Database name to which this connection is made. diff --git a/src/repository/Repository.ts b/src/repository/Repository.ts index 4d694bf5a..4426db66a 100644 --- a/src/repository/Repository.ts +++ b/src/repository/Repository.ts @@ -32,7 +32,7 @@ export class Repository { } /** - * Creates a new query builder that can be used to build an sql query. + * Creates a new query builder that can be used to build a sql query. */ createQueryBuilder(alias: string): QueryBuilder { return this.connection.driver @@ -56,7 +56,7 @@ export class Repository { /** * Creates a entities from the given array of plain javascript objects. */ - createMany(copyFromObjects: any[]): Entity[] { + createMany(copyFromObjects: Object[]): Entity[] { return copyFromObjects.map(object => this.create(object)); } @@ -80,7 +80,8 @@ export class Repository { } /** - * Persists (saves) a given entity in the database. + * 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: Entity): Promise { let loadedDbEntity: any; @@ -115,7 +116,7 @@ export class Repository { } /** - * Finds entities that match given conditions. + * Finds all entities. */ find(): Promise; @@ -125,7 +126,7 @@ export class Repository { find(conditions: Object): Promise; /** - * Finds entities that match given conditions. + * Finds entities with options applied. */ find(options: FindOptions): Promise;