added todos, extracted entity persister from repository; clean up repository

This commit is contained in:
Umed Khudoiberdiev 2016-03-13 17:11:10 +05:00
parent 7a2fe7b143
commit 02e419aeb2
8 changed files with 271 additions and 302 deletions

View File

@ -14,4 +14,22 @@ usages.
## Todos
* add partial selection support
* in query builder should we use property names or table names? (right now its mixed)
* in query builder should we use property names or table names? (right now its mixed)
* should all entities have a primary column?
* check if inheritance and abstract table works fine
* think about indices
* make subscribers and listeners to work correctly
* think more about cascades
* add cascadePersist to cascades?
* naming strategy need to be done correctly
* fix all propertyName/tableName problems and make sure everything work correctly
* check column types, make validation there
* foreign keys for relations
* what happens if owner one-to-one on both sides
* check self referencing
* class lifecycle callbacks?
* query builder limit offset
* query with count? (Paginator)
* wrap persistment in transaction
* array / json / date column types
* exceptions everywhere!

View File

@ -7,9 +7,12 @@ import {EntityMetadataBuilder} from "../metadata-builder/EntityMetadataBuilder";
import {importClassesFromDirectories} from "../util/DirectoryExportedClassesLoader";
/**
* Connection manager holds all connections made to the databases.
* Connection manager holds all connections made to the databases and providers helper management functions
* for all exist connections.
*/
export class ConnectionManager {
// todo: inject naming strategy, make it configurable
// -------------------------------------------------------------------------
// Properties

View File

@ -13,7 +13,7 @@ export interface Join {
export class QueryBuilder<Entity> {
// -------------------------------------------------------------------------
// Pirvate properties
// Private properties
// -------------------------------------------------------------------------
private _aliasMap: AliasMap;
@ -221,7 +221,6 @@ export class QueryBuilder<Entity> {
}
getSql(): string {
// joins are before because their many-to-many relations can add aliases
let sql = this.createSelectExpression();
sql += this.createJoinExpression();
sql += this.createWhereExpression();

View File

@ -1,7 +1,6 @@
import {EntityMetadata} from "../metadata-builder/metadata/EntityMetadata";
import {ColumnMetadata} from "../metadata-builder/metadata/ColumnMetadata";
import {RelationMetadata} from "../metadata-builder/metadata/RelationMetadata";
import metadata = Reflect.metadata;
import {Connection} from "../connection/Connection";
export interface EntityWithId {

View File

@ -0,0 +1,173 @@
import {
JunctionRemoveOperation,
InsertOperation,
JunctionInsertOperation,
PersistOperation, UpdateByRelationOperation, UpdateOperation, RemoveOperation
} from "./EntityPersistOperationsBuilder";
import {Connection} from "../connection/Connection";
export class EntityPersister {
constructor(private connection: Connection) {
}
executePersistOperation(persistOperation: PersistOperation) {
return Promise.resolve()
.then(() => { // insert new relations
return Promise.all(persistOperation.inserts.map(operation => {
return this.insert(operation.entity).then((result: any) => {
operation.entityId = result.insertId;
});
}));
}).then(() => { // insert junction table insertions
return Promise.all(persistOperation.junctionInserts.map(junctionOperation => {
return this.insertJunctions(junctionOperation, persistOperation.inserts);
}));
}).then(() => { // remove junction table insertions
return Promise.all(persistOperation.junctionRemoves.map(junctionOperation => {
return this.removeJunctions(junctionOperation);
}));
}).then(() => {
return Promise.all(persistOperation.updatesByRelations.map(updateByRelation => {
this.updateByRelation(updateByRelation, persistOperation.inserts);
}));
}).then(() => { // perform updates
return Promise.all(persistOperation.updates.map(updateOperation => {
return this.update(updateOperation);
}));
}).then(() => { // remove removed relations
return Promise.all(persistOperation.removes.map(operation => {
return this.updateDeletedRelations(operation);
}));
}).then(() => { // remove removed entities
return Promise.all(persistOperation.removes.map(operation => {
return this.delete(operation.entity);
}));
}).then(() => { // update ids
persistOperation.inserts.forEach(insertOperation => {
const metadata = this.connection.getMetadata(insertOperation.entity.constructor);
insertOperation.entity[metadata.primaryColumn.name] = insertOperation.entityId;
});
});
}
private updateByRelation(operation: UpdateByRelationOperation, insertOperations: InsertOperation[]) {
let tableName: string, relationName: string, relationId: any, idColumn: string, id: any;
const idInInserts = insertOperations.find(o => o.entity === operation.targetEntity).entityId;
if (operation.updatedRelation.isOneToMany) {
const metadata = this.connection.getMetadata(operation.insertOperation.entity.constructor);
tableName = metadata.table.name;
relationName = operation.updatedRelation.inverseRelation.name;
relationId = operation.targetEntity[metadata.primaryColumn.propertyName] || idInInserts;
idColumn = metadata.primaryColumn.name;
id = operation.insertOperation.entityId;
} else {
const metadata = this.connection.getMetadata(operation.targetEntity.constructor);
tableName = metadata.table.name;
relationName = operation.updatedRelation.name;
relationId = operation.insertOperation.entityId;
idColumn = metadata.primaryColumn.name;
id = operation.targetEntity[metadata.primaryColumn.propertyName] || idInInserts;
}
const query = `UPDATE ${tableName} SET ${relationName}='${relationId}' WHERE ${idColumn}='${id}'`;
return this.connection.driver.query(query);
}
private update(updateOperation: UpdateOperation) {
const entity = updateOperation.entity;
const metadata = this.connection.getMetadata(entity.constructor);
const values = updateOperation.columns.map(column => {
return column.name + "='" + entity[column.propertyName] + "'";
});
const query = `UPDATE ${metadata.table.name} SET ${values} WHERE ${metadata.primaryColumn.name}='${metadata.getEntityId(entity)}'` ;
return this.connection.driver.query(query);
}
private updateDeletedRelations(removeOperation: RemoveOperation) { // todo: check if both many-to-one deletions work too
if (removeOperation.relation.isManyToMany || removeOperation.relation.isOneToMany) return;
const value = removeOperation.relation.name + "=NULL";
const query = `UPDATE ${removeOperation.metadata.table.name} SET ${value} WHERE ${removeOperation.metadata.primaryColumn.name}='${removeOperation.fromEntityId}'` ;
return this.connection.driver.query(query);
}
private delete(entity: any) {
const metadata = this.connection.getMetadata(entity.constructor);
const query = `DELETE FROM ${metadata.table.name} WHERE ${metadata.primaryColumn.name}='${entity[metadata.primaryColumn.propertyName]}'`;
return this.connection.driver.query(query);
}
private insert(entity: any) {
const metadata = this.connection.getMetadata(entity.constructor);
const columns = metadata.columns
.filter(column => !column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => column.name);
/*const virtualColumns = metadata.columns
.filter(column => column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => column.name);*/
const values = metadata.columns
.filter(column => !column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => "'" + entity[column.propertyName] + "'");
/*const virtualValues = metadata.columns
.filter(column => column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => "'" + entity[column.propertyName] + "'");
const allColumns = columns.concat(virtualColumns);
const allVolumes = values.concat(virtualValues);*/
const relationColumns = metadata.relations
.filter(relation => relation.isOwning && !!relation.relatedEntityMetadata)
.filter(relation => entity.hasOwnProperty(relation.propertyName))
.filter(relation => entity[relation.propertyName][relation.relatedEntityMetadata.primaryColumn.name])
.map(relation => relation.name);
const relationValues = metadata.relations
.filter(relation => relation.isOwning && !!relation.relatedEntityMetadata)
.filter(relation => entity.hasOwnProperty(relation.propertyName))
.filter(relation => entity[relation.propertyName].hasOwnProperty(relation.relatedEntityMetadata.primaryColumn.name))
.map(relation => "'" + entity[relation.propertyName][relation.relatedEntityMetadata.primaryColumn.name] + "'");
const query = `INSERT INTO ${metadata.table.name}(${columns.concat(relationColumns).join(",")}) VALUES (${values.concat(relationValues).join(",")})`;
return this.connection.driver.query(query);
}
private insertJunctions(junctionOperation: JunctionInsertOperation, insertOperations: InsertOperation[]) {
const junctionMetadata = junctionOperation.metadata;
const metadata1 = this.connection.getMetadata(junctionOperation.entity1.constructor);
const metadata2 = this.connection.getMetadata(junctionOperation.entity2.constructor);
const columns = junctionMetadata.columns.map(column => column.name);
const id1 = junctionOperation.entity1[metadata1.primaryColumn.name] || insertOperations.find(o => o.entity === junctionOperation.entity1).entityId;
const id2 = junctionOperation.entity2[metadata2.primaryColumn.name] || insertOperations.find(o => o.entity === junctionOperation.entity2).entityId;
const values = [id1, id2]; // todo: order may differ, find solution (column.table to compare with entity metadata table?)
const query = `INSERT INTO ${junctionMetadata.table.name}(${columns.join(",")}) VALUES (${values.join(",")})`;
return this.connection.driver.query(query);
}
private removeJunctions(junctionOperation: JunctionRemoveOperation) {
const junctionMetadata = junctionOperation.metadata;
const metadata1 = this.connection.getMetadata(junctionOperation.entity1.constructor);
const metadata2 = this.connection.getMetadata(junctionOperation.entity2.constructor);
const columns = junctionMetadata.columns.map(column => column.name);
const id1 = junctionOperation.entity1[metadata1.primaryColumn.name];
const id2 = junctionOperation.entity2[metadata2.primaryColumn.name];
const query = `DELETE FROM ${junctionMetadata.table.name} WHERE ${columns[0]}='${id1}' AND ${columns[1]}='${id2}'`;
return this.connection.driver.query(query);
}
}

View File

@ -4,10 +4,8 @@ import {OrmBroadcaster} from "../subscriber/OrmBroadcaster";
import {QueryBuilder} from "../query-builder/QueryBuilder";
import {PlainObjectToNewEntityTransformer} from "../query-builder/transformer/PlainObjectToNewEntityTransformer";
import {PlainObjectToDatabaseEntityTransformer} from "../query-builder/transformer/PlainObjectToDatabaseEntityTransformer";
import {
EntityPersistOperationsBuilder, PersistOperation, JunctionInsertOperation,
InsertOperation, JunctionRemoveOperation, UpdateOperation, UpdateByRelationOperation, RemoveOperation
} from "./EntityPersistOperationsBuilder";
import {EntityPersistOperationsBuilder, PersistOperation} from "./EntityPersistOperationsBuilder";
import {EntityPersister} from "./EntityPersister";
// todo: think how we can implement queryCount, queryManyAndCount
// todo: extract non safe methods from repository (removeById, removeByConditions)
@ -53,216 +51,6 @@ export class Repository<Entity> {
// Public Methods
// -------------------------------------------------------------------------
/**
* Creates a new entity.
*/
create(copyFrom?: any): Entity {
if (copyFrom) {
const transformer = new PlainObjectToNewEntityTransformer();
return transformer.transform(copyFrom, this.metadata);
}
return <Entity> this.metadata.create();
}
initialize(object: any): Promise<Entity> {
const transformer = new PlainObjectToDatabaseEntityTransformer();
const queryBuilder = this.createQueryBuilder(this.metadata.table.name);
return transformer.transform(object, this.metadata, queryBuilder);
}
merge(entity1: Entity, entity2: Entity): Entity {
return Object.assign(this.metadata.create(), entity1, entity2);
}
/**
* Finds columns and relations from entity2 which does not exist or does not match in entity1.
*/
difference(entity1: Entity, entity2: Entity): PersistOperation {
const builder = new EntityPersistOperationsBuilder(this.connection);
return builder.difference(this.metadata, entity1, entity2);
}
persist(entity: Entity) {
const promise = !this.hasId(entity) ? Promise.resolve(null) : this.initialize(entity);
//if (!this.hasId(entity)) { // do insert
return promise.then(dbEntity => {
const persistOperations = this.difference(dbEntity, entity);
// create update queries based on diff map
// return Promise.resolve()
return Promise.resolve()
.then(() => { // insert new relations
return Promise.all(persistOperations.inserts.map(operation => {
return this.insert(operation.entity).then((result: any) => {
operation.entityId = result.insertId;
});
}));
}).then(() => { // insert junction table insertions
return Promise.all(persistOperations.junctionInserts.map(junctionOperation => {
return this.insertJunctions(junctionOperation, persistOperations.inserts);
}));
}).then(() => { // remove junction table insertions
return Promise.all(persistOperations.junctionRemoves.map(junctionOperation => {
return this.removeJunctions(junctionOperation);
}));
}).then(() => {
return Promise.all(persistOperations.updatesByRelations.map(updateByRelation => {
this.updateByRelation(updateByRelation, persistOperations.inserts);
}));
}).then(() => { // perform updates
return Promise.all(persistOperations.updates.map(updateOperation => {
return this.update(updateOperation);
}));
}).then(() => { // remove removed relations
return Promise.all(persistOperations.removes.map(operation => {
return this.updateDeletedRelations(operation);
}));
}).then(() => { // remove removed entities
return Promise.all(persistOperations.removes.map(operation => {
return this.delete(operation.entity);
}));
}).then(() => { // update ids
persistOperations.inserts.forEach(insertOperation => {
const metadata = this.connection.getMetadata(insertOperation.entity.constructor);
insertOperation.entity[metadata.primaryColumn.name] = insertOperation.entityId;
});
return entity;
});
});
}
private updateByRelation(operation: UpdateByRelationOperation, insertOperations: InsertOperation[]) {
let tableName: string, relationName: string, relationId: any, idColumn: string, id: any;
const idInInserts = insertOperations.find(o => o.entity === operation.targetEntity).entityId;
if (operation.updatedRelation.isOneToMany) {
const metadata = this.connection.getMetadata(operation.insertOperation.entity.constructor);
tableName = metadata.table.name;
relationName = operation.updatedRelation.inverseRelation.name;
relationId = operation.targetEntity[metadata.primaryColumn.propertyName] || idInInserts;
idColumn = metadata.primaryColumn.name;
id = operation.insertOperation.entityId;
} else {
const metadata = this.connection.getMetadata(operation.targetEntity.constructor);
tableName = metadata.table.name;
relationName = operation.updatedRelation.name;
relationId = operation.insertOperation.entityId;
idColumn = metadata.primaryColumn.name;
id = operation.targetEntity[metadata.primaryColumn.propertyName] || idInInserts;
}
const query = `UPDATE ${tableName} SET ${relationName}='${relationId}' WHERE ${idColumn}='${id}'`;
return this.connection.driver.query(query);
}
private update(updateOperation: UpdateOperation) {
const entity = updateOperation.entity;
const metadata = this.connection.getMetadata(entity.constructor);
const values = updateOperation.columns.map(column => {
return column.name + "='" + entity[column.propertyName] + "'";
});
const query = `UPDATE ${metadata.table.name} SET ${values} WHERE ${metadata.primaryColumn.name}='${metadata.getEntityId(entity)}'` ;
return this.connection.driver.query(query);
}
private updateDeletedRelations(removeOperation: RemoveOperation) { // todo: check if both many-to-one deletions work too
if (removeOperation.relation.isManyToMany || removeOperation.relation.isOneToMany) return;
const value = removeOperation.relation.name + "=NULL";
const query = `UPDATE ${removeOperation.metadata.table.name} SET ${value} WHERE ${removeOperation.metadata.primaryColumn.name}='${removeOperation.fromEntityId}'` ;
return this.connection.driver.query(query);
}
private delete(entity: any) {
const metadata = this.connection.getMetadata(entity.constructor);
const query = `DELETE FROM ${metadata.table.name} WHERE ${metadata.primaryColumn.name}='${entity[metadata.primaryColumn.propertyName]}'`;
return this.connection.driver.query(query);
}
private insert(entity: any) {
const metadata = this.connection.getMetadata(entity.constructor);
const columns = metadata.columns
.filter(column => !column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => column.name);
/*const virtualColumns = metadata.columns
.filter(column => column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => column.name);*/
const values = metadata.columns
.filter(column => !column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => "'" + entity[column.propertyName] + "'");
/*const virtualValues = metadata.columns
.filter(column => column.isVirtual)
.filter(column => entity.hasOwnProperty(column.propertyName))
.map(column => "'" + entity[column.propertyName] + "'");
const allColumns = columns.concat(virtualColumns);
const allVolumes = values.concat(virtualValues);*/
const relationColumns = metadata.relations
.filter(relation => relation.isOwning && !!relation.relatedEntityMetadata)
.filter(relation => entity.hasOwnProperty(relation.propertyName))
.filter(relation => entity[relation.propertyName][relation.relatedEntityMetadata.primaryColumn.name])
.map(relation => relation.name);
const relationValues = metadata.relations
.filter(relation => relation.isOwning && !!relation.relatedEntityMetadata)
.filter(relation => entity.hasOwnProperty(relation.propertyName))
.filter(relation => entity[relation.propertyName].hasOwnProperty(relation.relatedEntityMetadata.primaryColumn.name))
.map(relation => "'" + entity[relation.propertyName][relation.relatedEntityMetadata.primaryColumn.name] + "'");
const query = `INSERT INTO ${metadata.table.name}(${columns.concat(relationColumns).join(",")}) VALUES (${values.concat(relationValues).join(",")})`;
return this.connection.driver.query(query);
}
private insertJunctions(junctionOperation: JunctionInsertOperation, insertOperations: InsertOperation[]) {
const junctionMetadata = junctionOperation.metadata;
const metadata1 = this.connection.getMetadata(junctionOperation.entity1.constructor);
const metadata2 = this.connection.getMetadata(junctionOperation.entity2.constructor);
const columns = junctionMetadata.columns.map(column => column.name);
const id1 = junctionOperation.entity1[metadata1.primaryColumn.name] || insertOperations.find(o => o.entity === junctionOperation.entity1).entityId;
const id2 = junctionOperation.entity2[metadata2.primaryColumn.name] || insertOperations.find(o => o.entity === junctionOperation.entity2).entityId;
const values = [id1, id2]; // todo: order may differ, find solution (column.table to compare with entity metadata table?)
const query = `INSERT INTO ${junctionMetadata.table.name}(${columns.join(",")}) VALUES (${values.join(",")})`;
return this.connection.driver.query(query);
}
private removeJunctions(junctionOperation: JunctionRemoveOperation) {
const junctionMetadata = junctionOperation.metadata;
const metadata1 = this.connection.getMetadata(junctionOperation.entity1.constructor);
const metadata2 = this.connection.getMetadata(junctionOperation.entity2.constructor);
const columns = junctionMetadata.columns.map(column => column.name);
const id1 = junctionOperation.entity1[metadata1.primaryColumn.name];
const id2 = junctionOperation.entity2[metadata2.primaryColumn.name];
const query = `DELETE FROM ${junctionMetadata.table.name} WHERE ${columns[0]}='${id1}' AND ${columns[1]}='${id2}'`;
return this.connection.driver.query(query);
}
/*copyEntity(entity1: Entity, entity2: Entity) {
this.metadata.columns
}*/
/**
* Creates a entities from the given array of plain javascript objects. If fetchAllData param is specified then
* entities data will be loaded from the database first, then filled with given json data.
*/
createMany(copyFromObjects: any[]): Entity[] {
return copyFromObjects.map(object => this.create(object));
}
/**
* Checks if entity has an id.
*/
@ -281,12 +69,67 @@ export class Repository<Entity> {
}
/**
* Executes query and returns raw database results.
* Creates a new entity. If fromRawEntity is given then it creates a new entity and copies all entity properties
* from this object into a new entity (copies only properties that should be in a new entity).
*/
query(query: string): Promise<any> {
return this.connection.driver.query(query);
create(fromRawEntity?: Object): Entity {
if (fromRawEntity) {
const transformer = new PlainObjectToNewEntityTransformer();
return transformer.transform(fromRawEntity, this.metadata);
}
return <Entity> this.metadata.create();
}
/**
* Creates a entities from the given array of plain javascript objects.
*/
createMany(copyFromObjects: any[]): Entity[] {
return copyFromObjects.map(object => this.create(object));
}
/**
* 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.
*/
initialize(object: Object): Promise<Entity> {
const transformer = new PlainObjectToDatabaseEntityTransformer();
const queryBuilder = this.createQueryBuilder(this.metadata.table.name);
return transformer.transform(object, this.metadata, queryBuilder);
}
/**
* Merges two entities into one new entity.
*/
merge(entity1: Entity, entity2: Entity): Entity {
return Object.assign(this.metadata.create(), entity1, entity2);
}
/**
* Persists (saves) a given entity in the database.
*/
persist(entity: Entity) {
const persister = new EntityPersister(this.connection);
const promise = !this.hasId(entity) ? Promise.resolve(null) : this.initialize(entity);
return promise.then(dbEntity => {
const persistOperation = this.difference(dbEntity, entity);
return persister.executePersistOperation(persistOperation);
}).then(() => entity);
}
/**
* Removes a given entity from the database.
*/
remove(entity: Entity) {
const persister = new EntityPersister(this.connection);
return this.initialize(entity).then(dbEntity => {
// make this only to remove
const persistOperation = this.difference(dbEntity, entity);
return persister.executePersistOperation(persistOperation);
}).then(() => entity);
}
/**
* Finds entities that match given conditions.
*/
@ -318,89 +161,24 @@ export class Repository<Entity> {
.getSingleResult();
}
// -------------------------------------------------------------------------
// Persist starts
// -------------------------------------------------------------------------
/**
* Saves a given entity. If entity is not inserted yet then it inserts a new entity.
* If entity already inserted then performs its update.
* Executes raw SQL query and returns raw database results.
*/
//persist(entity: Entity/*, dynamicCascadeOptions?: DynamicCascadeOptions<Entity>*/): Promise<Entity> {
// todo
// return Promise.resolve<Entity>(null);
// if (!this.schema.isEntityTypeCorrect(entity))
// throw new BadEntityInstanceException(entity, this.schema.entityClass);
// const remover = new EntityRemover<Entity>(this.connection);
// const persister = new EntityPersister<Entity>(this.connection);
/* return remover.computeRemovedRelations(this.metadata, entity, dynamicCascadeOptions)
.then(result => persister.persist(this.metadata, entity, dynamicCascadeOptions))
.then(result => remover.executeRemoveOperations())
.then(result => remover.executeUpdateInverseSideRelationRemoveIds())
.then(result => entity);*/
// }
/*computeChangeSet(entity: Entity) {
// if there is no primary key - there is no way to determine if object needs to be updated or insert
// since we cannot get the target object without identifier, that's why we always do insert for such objects
if (!this.metadata.primaryColumn)
return this.insert(entity);
// load entity from the db
this.findById(this.metadata.getEntityId(entity)).then(dbEntity => {
});
}*/
// -------------------------------------------------------------------------
// Persist ends
// -------------------------------------------------------------------------
/**
* Removes a given entity.
*/
remove(entity: Entity/*, dynamicCascadeOptions?: DynamicCascadeOptions<Entity>*/): Promise<void> {
// todo
return Promise.resolve();
// if (!this.schema.isEntityTypeCorrect(entity))
// throw new BadEntityInstanceException(entity, this.schema.entityClass);
/*const remover = new EntityRemover<Entity>(this.connection);
return remover.registerEntityRemoveOperation(this.metadata, this.metadata.getEntityId(entity), dynamicCascadeOptions)
.then(results => remover.executeRemoveOperations())
.then(results => remover.executeUpdateInverseSideRelationRemoveIds());*/
query(query: string): Promise<any> {
return this.connection.driver.query(query);
}
/**
* Removes entity by a given id. Does not take care about cascade remove operations.
*/
removeById(id: string): Promise<void> {
const alias = this.metadata.table.name;
return this.createQueryBuilder(alias)
.delete()
.where(alias + "." + this.metadata.primaryColumn.name + "=:id")
.setParameter("id", id)
.execute()
.then(() => {});
}
/**
* Removes entities by a given simple conditions. Does not take care about cascade remove operations.
*/
removeByConditions(conditions: Object): Promise<void> {
const alias = this.metadata.table.name;
const builder = this.createQueryBuilder(alias).delete();
Object.keys(conditions).forEach(key => builder.where(alias + "." + key + "=:" + key));
return builder
.setParameters(conditions)
.execute()
.then(() => {});
}
// -------------------------------------------------------------------------
// Private Methods
// -------------------------------------------------------------------------
/**
* Finds columns and relations from entity2 which does not exist or does not match in entity1. Returns an object
* that contains all information about what needs to be persisted.
*/
private difference(entity1: Entity, entity2: Entity): PersistOperation {
const builder = new EntityPersistOperationsBuilder(this.connection);
return builder.difference(this.metadata, entity1, entity2);
}
}

View File

@ -4,7 +4,6 @@
export interface RemoveEvent<Entity> {
entity?: Entity;
conditions?: any;
entityId?: string;
}

View File

@ -2,9 +2,9 @@
* This event is used on update events.
*/
export interface UpdateEvent<Entity> {
// todo: will we send an entity changeset ?
entity?: Entity;
options?: any;
conditions?: any;
}