Comparing version 0.0.2-alpha.36 to 0.0.2-alpha.37
@@ -8,2 +8,3 @@ import { ConnectionOptions } from "../connection/ConnectionOptions"; | ||
abstract connectionOptions: ConnectionOptions; | ||
private transactionActive; | ||
protected abstract checkIfConnectionSet(): void; | ||
@@ -32,10 +33,18 @@ /** | ||
/** | ||
* Starts postgres transaction. | ||
* Starts transaction. | ||
*/ | ||
beginTransaction(): Promise<void>; | ||
/** | ||
* Ends postgres transaction. | ||
* Commits transaction. | ||
*/ | ||
endTransaction(): Promise<void>; | ||
commitTransaction(): Promise<void>; | ||
/** | ||
* Rollbacks transaction. | ||
*/ | ||
rollbackTransaction(): Promise<void>; | ||
/** | ||
* Checks if transaction is active. | ||
*/ | ||
isTransactionActive(): boolean; | ||
/** | ||
* Prepares given value to a value to be persisted, based on its column type and metadata. | ||
@@ -42,0 +51,0 @@ */ |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments)).next()); | ||
}); | ||
}; | ||
const ColumnTypes_1 = require("../metadata/types/ColumnTypes"); | ||
@@ -8,2 +16,8 @@ const moment = require("moment"); | ||
class BaseDriver { | ||
constructor() { | ||
// ------------------------------------------------------------------------- | ||
// Private Properties | ||
// ------------------------------------------------------------------------- | ||
this.transactionActive = false; | ||
} | ||
// ------------------------------------------------------------------------- | ||
@@ -54,14 +68,35 @@ // Public Methods | ||
/** | ||
* Starts postgres transaction. | ||
* Starts transaction. | ||
*/ | ||
beginTransaction() { | ||
return this.query("START TRANSACTION").then(() => { }); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.transactionActive = true; | ||
yield this.query("START TRANSACTION"); | ||
}); | ||
} | ||
/** | ||
* Ends postgres transaction. | ||
* Commits transaction. | ||
*/ | ||
endTransaction() { | ||
return this.query("COMMIT").then(() => { }); | ||
commitTransaction() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.transactionActive = false; | ||
yield this.query("COMMIT"); | ||
}); | ||
} | ||
/** | ||
* Rollbacks transaction. | ||
*/ | ||
rollbackTransaction() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.transactionActive = false; | ||
yield this.query("ROLLBACK"); | ||
}); | ||
} | ||
/** | ||
* Checks if transaction is active. | ||
*/ | ||
isTransactionActive() { | ||
return this.transactionActive; | ||
} | ||
/** | ||
* Prepares given value to a value to be persisted, based on its column type and metadata. | ||
@@ -68,0 +103,0 @@ */ |
@@ -61,6 +61,14 @@ import { SchemaBuilder } from "../schema-builder/SchemaBuilder"; | ||
/** | ||
* Commits transaction. | ||
*/ | ||
commitTransaction(): Promise<void>; | ||
/** | ||
* Ends transaction. | ||
*/ | ||
endTransaction(): Promise<void>; | ||
rollbackTransaction(): Promise<void>; | ||
/** | ||
* Checks if transaction has been already started. | ||
*/ | ||
isTransactionActive(): boolean; | ||
/** | ||
* Prepares given value to a value to be persisted, based on its column type and metadata. | ||
@@ -67,0 +75,0 @@ */ |
@@ -156,3 +156,3 @@ "use strict"; | ||
runInTransactionResult = result; | ||
return this.connection.driver.endTransaction(); | ||
return this.connection.driver.commitTransaction(); | ||
}) | ||
@@ -159,0 +159,0 @@ .then(() => runInTransactionResult); |
@@ -150,3 +150,3 @@ "use strict"; | ||
runInTransactionResult = result; | ||
return this.connection.driver.endTransaction(); | ||
return this.connection.driver.commitTransaction(); | ||
}) | ||
@@ -153,0 +153,0 @@ .then(() => runInTransactionResult)); |
{ | ||
"name": "typeorm", | ||
"private": false, | ||
"version": "0.0.2-alpha.36", | ||
"version": "0.0.2-alpha.37", | ||
"description": "Data-mapper ORM for Typescript", | ||
@@ -6,0 +6,0 @@ "license": "Apache-2.0", |
@@ -24,3 +24,7 @@ "use strict"; | ||
.then(() => this.broadcastBeforeEvents(persistOperation)) | ||
.then(() => this.driver.beginTransaction()) | ||
.then(() => { | ||
if (!this.driver.isTransactionActive()) | ||
return this.driver.beginTransaction(); | ||
return Promise.resolve(); | ||
}) | ||
.then(() => this.executeInsertOperations(persistOperation)) | ||
@@ -36,7 +40,23 @@ .then(() => this.executeInsertClosureTableOperations(persistOperation)) | ||
.then(() => this.executeRemoveOperations(persistOperation)) | ||
.then(() => this.driver.endTransaction()) | ||
.then(() => { | ||
if (!this.driver.isTransactionActive()) | ||
return this.driver.commitTransaction(); | ||
return Promise.resolve(); | ||
}) | ||
.then(() => this.updateIdsOfInsertedEntities(persistOperation)) | ||
.then(() => this.updateIdsOfRemovedEntities(persistOperation)) | ||
.then(() => this.updateSpecialColumnsInEntities(persistOperation)) | ||
.then(() => this.broadcastAfterEvents(persistOperation)); | ||
.then(() => this.broadcastAfterEvents(persistOperation)) | ||
.catch(error => { | ||
if (!this.driver.isTransactionActive()) { | ||
return this.driver.rollbackTransaction() | ||
.then(() => { | ||
throw error; | ||
}) | ||
.catch(() => { | ||
throw error; | ||
}); | ||
} | ||
throw error; | ||
}); | ||
} | ||
@@ -43,0 +63,0 @@ // ------------------------------------------------------------------------- |
@@ -552,3 +552,5 @@ "use strict"; | ||
entities.forEach(entity => { | ||
const metadata = this.entityMetadatas.findByTarget(entity.constructor); | ||
if (entity.constructor.name === "Object") | ||
return; // tempraroy , must be removed after fixing entity.constructor | ||
const metadata = this.entityMetadatas.findByTarget(entity.constructor); // todo: fix it | ||
metadata.relations | ||
@@ -555,0 +557,0 @@ .filter(relation => relation.isLazy) |
@@ -23,3 +23,3 @@ "use strict"; | ||
// if plain object does not have id then nothing to load really | ||
if (!metadata.hasPrimaryColumn || !plainObject[metadata.primaryColumn.name]) | ||
if (!metadata.hasPrimaryColumn || !plainObject.hasOwnProperty(metadata.primaryColumn.name)) | ||
return Promise.reject("Given object does not have a primary column, cannot transform it to database entity."); | ||
@@ -33,3 +33,2 @@ const alias = queryBuilder.alias; | ||
const entity = yield queryBuilder.getSingleResult(); | ||
// this.mergeEntityWithPlainObject(metadata, entity, plainObject); | ||
return entity; | ||
@@ -41,4 +40,2 @@ }); | ||
// ------------------------------------------------------------------------- | ||
mergeEntityWithPlainObject(metadata, entity, object) { | ||
} | ||
join(qb, needToLoad, parentAlias) { | ||
@@ -45,0 +42,0 @@ needToLoad.forEach(i => { |
@@ -37,3 +37,10 @@ "use strict"; | ||
entity[relation.propertyName] = object[relation.propertyName].map((subObject) => { | ||
return this.groupAndTransform(relationMetadata.create(), subObject, relationMetadata); | ||
let subEntity = relationMetadata.create(); | ||
if (entity[relation.propertyName] instanceof Array) { | ||
// todo: support custom initial fields here | ||
subEntity = entity[relation.propertyName].find((subEntity) => { | ||
return subEntity[relation.referencedColumnName] === subObject[relation.referencedColumnName]; | ||
}); | ||
} | ||
return this.groupAndTransform(subEntity, subObject, relationMetadata); | ||
}); | ||
@@ -47,3 +54,4 @@ } | ||
if (object[relation.propertyName]) { | ||
entity[relation.propertyName] = this.groupAndTransform(relationMetadata.create(), object[relation.propertyName], relationMetadata); | ||
const subEntity = entity[relation.propertyName] || relationMetadata.create(); | ||
entity[relation.propertyName] = this.groupAndTransform(subEntity, object[relation.propertyName], relationMetadata); | ||
} | ||
@@ -50,0 +58,0 @@ else { |
@@ -69,3 +69,3 @@ "use strict"; | ||
const valueInObject = alias.getColumnValue(rawSqlResults[0], column.name); // we use zero index since its grouped data | ||
if (valueInObject && column.propertyName && !column.isVirtual) { | ||
if (valueInObject !== undefined && valueInObject !== null && column.propertyName && !column.isVirtual) { | ||
const value = this.driver.prepareHydratedValue(valueInObject, column); | ||
@@ -72,0 +72,0 @@ if (column.isInEmbedded) { |
@@ -14,21 +14,25 @@ # TypeORM | ||
TypeORM is an [Object Relational Mapper](1) (ORM) for node.js written in | ||
Typescript that can help you to: | ||
Typescript that can be used with Typescript or Javascript (ES5, ES6, ES7). | ||
Its goal to always support latest Javascript features and provide features | ||
that help you to develop any kind of applications that use database - from | ||
small applications with a few tables to large scale enterprise applications. | ||
TypeORM helps you to: | ||
* automatically create your table schemas based on your models | ||
(javascript class, decorated with special decorators) | ||
* ability to transparently insert / update / delete to the database | ||
* automatically create in the database table schemas based on your models | ||
* ability to transparently insert / update / delete to the database | ||
your objects | ||
* map your selections from tables to javascript objects, map table columns | ||
* map your selections from tables to javascript objects and map table columns | ||
to javascript object's properties | ||
* create one-to-one, many-to-one, one-to-many, many-to-many relations | ||
between tables | ||
* create one-to-one, many-to-one, one-to-many, many-to-many relations between tables | ||
* and much more ... | ||
TypeORM uses Data Mapper pattern, unlike all other javascript ORMs that | ||
currently exist, which means you can write loosely coupled, scalable, | ||
maintainable enterprise applications with less problems. | ||
TypeORM uses Data Mapper pattern, unlike all other javascript ORMs that | ||
currently exist, which means you can write loosely coupled, scalable, | ||
maintainable 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. | ||
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. | ||
TypeORM is highly influenced by other ORMs, such as [Hibernate](http://hibernate.org/orm/) and [Doctrine](http://www.doctrine-project.org/). | ||
## Installation | ||
@@ -40,21 +44,32 @@ | ||
2. Use [typings](https://github.com/typings/typings) to install all | ||
required definition dependencies. | ||
2. Install required shims: | ||
`typings install` | ||
`npm install es6-shim reflect-metadata --save` | ||
3. ES6 features are used, so you may want to install | ||
[es6-shim](https://github.com/paulmillr/es6-shim) too: | ||
And add these lines into some global place in your code, before you starting to use orm: | ||
`npm install es6-shim --save` | ||
```javascript | ||
require("es6-shim"); | ||
require("reflect-metadata"); | ||
``` | ||
Also you'll need to do `require("es6-shim");` in your app. | ||
`es6-shim` is optional for newer versions of node which supports all es6 features. | ||
`reflect-metadata` you definitely need because no platform support this feature yet. | ||
4. Install database driver: | ||
Right now only `mysql` database is supported, so to install it you | ||
need to do: | ||
`npm install mysql --save` | ||
3. Install database driver: | ||
3.1. Mysql | ||
If you want to use ORM with mysql then install its driver: | ||
`npm install mysql --save` | ||
3.2. Postgres | ||
`npm install pg --save` | ||
Right now only `mysql` and `postgres` databases are supported. Feel free to contribute and add support of new drivers. | ||
## Example | ||
@@ -61,0 +76,0 @@ |
@@ -57,3 +57,3 @@ import { Connection } from "../connection/Connection"; | ||
/** | ||
* Merges multiple entity-like structures into one new entity. | ||
* Merges multiple entities (or entity-like objects) into one new entity. | ||
*/ | ||
@@ -60,0 +60,0 @@ merge(...objects: ObjectLiteral[]): Entity; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments)).next()); | ||
}); | ||
}; | ||
const QueryBuilder_1 = require("../query-builder/QueryBuilder"); | ||
@@ -81,7 +89,7 @@ const PlainObjectToNewEntityTransformer_1 = require("../query-builder/transformer/PlainObjectToNewEntityTransformer"); | ||
/** | ||
* Merges multiple entity-like structures into one new entity. | ||
* Merges multiple entities (or entity-like objects) into one new entity. | ||
*/ | ||
merge(...objects) { | ||
const newEntity = this.create(); | ||
objects.forEach(entity => this.plainObjectToEntityTransformer.transform(newEntity, entity, this.metadata)); | ||
objects.forEach(object => this.plainObjectToEntityTransformer.transform(newEntity, object, this.metadata)); | ||
return newEntity; | ||
@@ -129,20 +137,13 @@ /*const comparator = new Comporator(metadata, entity, object, ComparationMode.NON_EMPTY); | ||
persist(entity) { | ||
let loadedDbEntity, allPersistedEntities; | ||
return Promise.resolve() // resolve is required because need to wait until lazy relations loaded | ||
.then(() => { | ||
return this.extractObjectsById(entity, this.metadata); | ||
}) | ||
.then(allPersisted => { | ||
allPersistedEntities = allPersisted; | ||
if (!this.hasId(entity)) | ||
return Promise.resolve(null); | ||
return this.initialize(entity); | ||
}) | ||
.then(dbEntity => { | ||
loadedDbEntity = dbEntity; | ||
return dbEntity ? this.extractObjectsById(dbEntity, this.metadata) : []; | ||
}).then(entityWithIds => { | ||
return this.findNotLoadedIds(entityWithIds, allPersistedEntities); | ||
}) // need to find db entities that were not loaded by initialize method | ||
.then(allDbEntities => { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield Promise.resolve(); // resolve is required because need to wait until lazy relations loaded | ||
const allPersistedEntities = yield this.extractObjectsById(entity, this.metadata); | ||
let loadedDbEntity = null; | ||
if (this.hasId(entity)) | ||
loadedDbEntity = yield this.initialize(entity); | ||
let entityWithIds = []; | ||
if (loadedDbEntity) | ||
entityWithIds = yield this.extractObjectsById(loadedDbEntity, this.metadata); | ||
// need to find db entities that were not loaded by initialize method | ||
const allDbEntities = yield this.findNotLoadedIds(entityWithIds, allPersistedEntities); | ||
const persistedEntity = { | ||
@@ -158,8 +159,6 @@ id: this.metadata.getEntityId(entity), | ||
}; | ||
return this.entityPersistOperationBuilder.buildFullPersistment(this.metadata, dbEntity, persistedEntity, allDbEntities, allPersistedEntities); | ||
}) | ||
.then(persistOperation => { | ||
return this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
}) | ||
.then(() => entity); | ||
const persistOperation = yield this.entityPersistOperationBuilder.buildFullPersistment(this.metadata, dbEntity, persistedEntity, allDbEntities, allPersistedEntities); | ||
yield this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
return entity; | ||
}); | ||
} | ||
@@ -170,14 +169,9 @@ /** | ||
remove(entity) { | ||
let dbEntity; | ||
return this | ||
.initialize(entity) | ||
.then(dbEnt => { | ||
dbEntity = dbEnt; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const dbEntity = yield this.initialize(entity); | ||
entity[this.metadata.primaryColumn.name] = undefined; | ||
return Promise.all([ | ||
const [dbEntities, allPersistedEntities] = yield Promise.all([ | ||
this.extractObjectsById(dbEntity, this.metadata), | ||
this.extractObjectsById(entity, this.metadata) | ||
]); | ||
}) | ||
.then(results => { | ||
const entityWithId = { | ||
@@ -193,5 +187,6 @@ id: this.metadata.getEntityId(entity), | ||
}; | ||
const persistOperation = this.entityPersistOperationBuilder.buildOnlyRemovement(this.metadata, dbEntityWithId, entityWithId, results[0], results[1]); | ||
return this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
}).then(() => entity); | ||
const persistOperation = this.entityPersistOperationBuilder.buildOnlyRemovement(this.metadata, dbEntityWithId, entityWithId, dbEntities, allPersistedEntities); | ||
yield this.persistOperationExecutor.executePersistOperation(persistOperation); | ||
return entity; | ||
}); | ||
} | ||
@@ -202,4 +197,6 @@ /** | ||
find(conditionsOrFindOptions, options) { | ||
return this.createFindQueryBuilder(conditionsOrFindOptions, options) | ||
.getResults(); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.createFindQueryBuilder(conditionsOrFindOptions, options) | ||
.getResults(); | ||
}); | ||
} | ||
@@ -210,4 +207,6 @@ /** | ||
findAndCount(conditionsOrFindOptions, options) { | ||
const qb = this.createFindQueryBuilder(conditionsOrFindOptions, options); | ||
return qb.getResultsAndCount(); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const qb = this.createFindQueryBuilder(conditionsOrFindOptions, options); | ||
return qb.getResultsAndCount(); | ||
}); | ||
} | ||
@@ -218,4 +217,6 @@ /** | ||
findOne(conditionsOrFindOptions, options) { | ||
return this.createFindQueryBuilder(conditionsOrFindOptions, options) | ||
.getSingleResult(); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.createFindQueryBuilder(conditionsOrFindOptions, options) | ||
.getSingleResult(); | ||
}); | ||
} | ||
@@ -226,4 +227,6 @@ /** | ||
findOneById(id, options) { | ||
return this.createFindQueryBuilder({ [this.metadata.primaryColumn.name]: id }, options) | ||
.getSingleResult(); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.createFindQueryBuilder({ [this.metadata.primaryColumn.name]: id }, options) | ||
.getSingleResult(); | ||
}); | ||
} | ||
@@ -234,3 +237,5 @@ /** | ||
query(query) { | ||
return this.driver.query(query); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.driver.query(query); | ||
}); | ||
} | ||
@@ -241,11 +246,14 @@ /** | ||
transaction(runInTransaction) { | ||
let runInTransactionResult; | ||
return this.driver | ||
.beginTransaction() | ||
.then(() => runInTransaction()) | ||
.then(result => { | ||
runInTransactionResult = result; | ||
return this.driver.endTransaction(); | ||
}) | ||
.then(() => runInTransactionResult); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let runInTransactionResult; | ||
return this.driver | ||
.beginTransaction() | ||
.then(() => runInTransaction()) | ||
.then(result => { | ||
runInTransactionResult = result; | ||
return this.driver.commitTransaction(); | ||
}) | ||
.catch(() => this.driver.rollbackTransaction()) | ||
.then(() => runInTransactionResult); | ||
}); | ||
} | ||
@@ -252,0 +260,0 @@ setRelation(relationName, entityId, relatedEntityId) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
906927
13065
795