mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added more docs
This commit is contained in:
parent
ae94b9bfc7
commit
ae76db3211
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
}
|
||||
24
README.md
24
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
|
||||
|
||||
3
docs/command-line-tools.md
Normal file
3
docs/command-line-tools.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Command Line Tools
|
||||
|
||||
TBD
|
||||
@ -1,3 +1,159 @@
|
||||
## Connection and connection options
|
||||
|
||||
TBD
|
||||
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);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@ -1,3 +1,36 @@
|
||||
## Databases and drivers
|
||||
|
||||
TBD
|
||||
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.
|
||||
|
||||
3
docs/decorators-reference.md
Normal file
3
docs/decorators-reference.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Decorators Reference
|
||||
|
||||
TBD
|
||||
@ -1,3 +1,41 @@
|
||||
## Relations
|
||||
|
||||
TBD
|
||||
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.
|
||||
@ -1,3 +1,75 @@
|
||||
## Repository
|
||||
|
||||
TBD
|
||||
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<Entity>`
|
||||
|
||||
Creates a new entity from the given plan javascript object. If entity already exist in the database, then
|
||||
it loads it (and everything related to it), replaces all values with the new ones from the given object
|
||||
and returns this new entity. This new entity is actually a loaded from the db entity with all properties
|
||||
replaced from the new object.
|
||||
|
||||
* `persist(entity: Entity): Promise<Entity>`
|
||||
|
||||
Persists (saves) a given entity in the database. If entity does not exist in the database then it inserts it,
|
||||
else if entity already exist in the database then it updates it.
|
||||
|
||||
* `remove(entity: Entity): Promise<Entity>`
|
||||
|
||||
Removes a given entity from the database.
|
||||
|
||||
* ```typescript
|
||||
find(): Promise<Entity[]>
|
||||
find(conditions: Object): Promise<Entity[]>;
|
||||
find(options: FindOptions): Promise<Entity[]>;
|
||||
find(conditions: Object, options: FindOptions): Promise<Entity[]>;
|
||||
```
|
||||
|
||||
Finds entities that match given conditions or given find options.
|
||||
|
||||
* ```typescript
|
||||
findOne(): Promise<Entity>;
|
||||
findOne(conditions: Object): Promise<Entity>;
|
||||
findOne(options: FindOptions): Promise<Entity>;
|
||||
findOne(conditions: Object, options: FindOptions): Promise<Entity>;
|
||||
```
|
||||
|
||||
Finds the first entity that match given conditions or given find options.
|
||||
|
||||
* `findById(id: any, options?: FindOptions): Promise<Entity>`
|
||||
|
||||
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<Entity>`
|
||||
|
||||
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<any>`
|
||||
|
||||
Executes raw SQL query.
|
||||
|
||||
* `transaction(runInTransaction: () => Promise<any>): Promise<any>`
|
||||
|
||||
Executes everything in the given function in a single transaction.
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
```
|
||||
@ -1,3 +1,57 @@
|
||||
## Tables and table inheritance
|
||||
|
||||
TBD
|
||||
### 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.
|
||||
@ -1,3 +1,17 @@
|
||||
## Updating database schema
|
||||
|
||||
TBD
|
||||
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.
|
||||
@ -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<any>[]) {
|
||||
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<any>[]) {
|
||||
this._subscribers = this._subscribers.concat(subscribers);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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.
|
||||
*/
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -32,7 +32,7 @@ export class Repository<Entity> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Entity> {
|
||||
return this.connection.driver
|
||||
@ -56,7 +56,7 @@ export class Repository<Entity> {
|
||||
/**
|
||||
* 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<Entity> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<Entity> {
|
||||
let loadedDbEntity: any;
|
||||
@ -115,7 +116,7 @@ export class Repository<Entity> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds entities that match given conditions.
|
||||
* Finds all entities.
|
||||
*/
|
||||
find(): Promise<Entity[]>;
|
||||
|
||||
@ -125,7 +126,7 @@ export class Repository<Entity> {
|
||||
find(conditions: Object): Promise<Entity[]>;
|
||||
|
||||
/**
|
||||
* Finds entities that match given conditions.
|
||||
* Finds entities with options applied.
|
||||
*/
|
||||
find(options: FindOptions): Promise<Entity[]>;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user