mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
re-implemented update, updateById, removeById methods; added delete and insert methods
This commit is contained in:
parent
568db03ab9
commit
62345012f8
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@ -1,2 +0,0 @@
|
||||
<!-- Love typeorm? Please consider supporting our collective:
|
||||
👉 https://opencollective.com/typeorm/donate -->
|
||||
@ -9,8 +9,13 @@ feel free to ask us and community.
|
||||
|
||||
* added support for `pg-native` for postgres (#975). To use it you just need to install `npm i pg-native` and it will be picked up automatically.
|
||||
* now Find Options support `-1` and `1` for `DESC` and `ASC` values. This is better user experience for MongoDB users.
|
||||
* now inheritances in embeddeds are supported (#966)
|
||||
* now inheritances in embeddeds are supported (#966).
|
||||
* `isArray: boolean` in `ColumnOptions` is deprecated. Use `array: boolean` instead.
|
||||
* deprecated `removeById` method, now use `deleteById` method instead.
|
||||
* added `insert` and `delete` methods into repository and entity manager.
|
||||
* fixed multiple issues with `update`, `updateById` and `removeById` methods in repository and entity manager. Now they do not use `save` and `remove` methods anymore - instead they are using QueryBuilder to build and execute their queries.
|
||||
* removed opencollective dependency
|
||||
* multiple small bugfixes
|
||||
|
||||
## 0.1.0
|
||||
|
||||
|
||||
@ -82,7 +82,6 @@
|
||||
"glob": "^7.1.2",
|
||||
"js-yaml": "^3.8.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"opencollective": "^1.0.3",
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"xml2js": "^0.4.17",
|
||||
"yargonaut": "^1.1.2",
|
||||
@ -92,8 +91,7 @@
|
||||
"test": "gulp ci-tests",
|
||||
"compile": "tsc",
|
||||
"setup:config": "gulp createTravisOrmConfig",
|
||||
"package": "gulp package",
|
||||
"postinstall": "opencollective postinstall"
|
||||
"package": "gulp package"
|
||||
},
|
||||
"bin": {
|
||||
"typeorm": "./cli.js"
|
||||
|
||||
@ -28,6 +28,7 @@ import {RepositoryFactory} from "../repository/RepositoryFactory";
|
||||
import {EntityManagerFactory} from "./EntityManagerFactory";
|
||||
import {TreeRepositoryNotSupportedError} from "../error/TreeRepositoryNotSupportedError";
|
||||
import {EntityMetadata} from "../metadata/EntityMetadata";
|
||||
import {QueryPartialEntity} from "../query-builder/QueryPartialEntity";
|
||||
|
||||
/**
|
||||
* Entity manager supposed to work with any entity, automatically find its repository and call its methods,
|
||||
@ -358,37 +359,59 @@ export class EntityManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given conditions.
|
||||
* Inserts a given entity into the database.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient INSERT query.
|
||||
* Does not check if entity exist in the database, so query will fail if duplicate entity is being inserted.
|
||||
* You can execute bulk inserts using this method.
|
||||
*/
|
||||
async update<Entity>(target: ObjectType<Entity>|string, conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
|
||||
async insert<Entity>(target: ObjectType<Entity>|string, entity: QueryPartialEntity<Entity>|QueryPartialEntity<Entity>[], options?: SaveOptions): Promise<void> {
|
||||
// todo: in the future create InsertResult with query result information
|
||||
// todo: think if subscribers and listeners can be executed here as well
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given find options.
|
||||
*/
|
||||
async update<Entity>(target: ObjectType<Entity>|string, findOptions: FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
|
||||
await this.createQueryBuilder()
|
||||
.insert()
|
||||
.into(target)
|
||||
.values(entity)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given conditions.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient UPDATE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async update<Entity>(target: ObjectType<Entity>|string, conditionsOrFindOptions: Partial<Entity>|FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
const entity = await this.findOne(target, conditionsOrFindOptions as any); // this is temporary, in the future can be refactored to perform better
|
||||
if (!entity)
|
||||
throw new Error(`Cannot find entity to update by a given criteria`);
|
||||
async update<Entity>(target: ObjectType<Entity>|string, conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
// todo: in the future create UpdateResult with query result information
|
||||
// todo: think if subscribers and listeners can be executed here as well
|
||||
|
||||
Object.assign(entity, partialEntity);
|
||||
await this.save(entity, options);
|
||||
const queryBuilder = this.createQueryBuilder()
|
||||
.update(target)
|
||||
.set(partialEntity);
|
||||
|
||||
FindOptionsUtils.applyConditions(queryBuilder, conditions); // todo: move condition-like syntax into .where method of query builder?
|
||||
await queryBuilder.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity will be found by a given id.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient UPDATE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async updateById<Entity>(target: ObjectType<Entity>|string, id: any, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
const entity = await this.findOneById(target, id as any); // this is temporary, in the future can be refactored to perform better
|
||||
if (!entity)
|
||||
throw new Error(`Cannot find entity to update by a id`);
|
||||
async updateById<Entity>(target: ObjectType<Entity>|string, id: any|any[], partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
// todo: in the future create UpdateResult with query result information
|
||||
// todo: think if subscribers and listeners can be executed here as well
|
||||
|
||||
Object.assign(entity, partialEntity);
|
||||
await this.save(entity, options);
|
||||
await this.createQueryBuilder()
|
||||
.update(target)
|
||||
.set(partialEntity)
|
||||
.whereInIds(id)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -498,29 +521,58 @@ export class EntityManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entity by a given entity id.
|
||||
* Deletes entities by a given conditions.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient DELETE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async removeById<Entity>(targetOrEntity: ObjectType<Entity>|string, id: any, options?: RemoveOptions): Promise<void> {
|
||||
const entity = await this.findOneById<any>(targetOrEntity, id); // this is temporary, in the future can be refactored to perform better
|
||||
if (!entity)
|
||||
throw new Error(`Cannot find entity to remove by a given id`);
|
||||
async delete<Entity>(targetOrEntity: ObjectType<Entity>|string, conditions: Partial<Entity>, options?: RemoveOptions): Promise<void> {
|
||||
// todo: in the future create DeleteResult with query result information
|
||||
// todo: think if subscribers and listeners can be executed here as well
|
||||
|
||||
await this.remove(entity, options);
|
||||
const queryBuilder = this.createQueryBuilder()
|
||||
.delete()
|
||||
.from(targetOrEntity);
|
||||
|
||||
FindOptionsUtils.applyConditions(queryBuilder, conditions); // todo: move condition-like syntax into .where method of query builder?
|
||||
await queryBuilder.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entity by a given entity ids.
|
||||
* Deletes entities by a given entity id or ids.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient DELETE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async deleteById<Entity>(targetOrEntity: ObjectType<Entity>|string, id: any|any[], options?: RemoveOptions): Promise<void> {
|
||||
// todo: in the future create DeleteResult with query result information
|
||||
// todo: think if subscribers and listeners can be executed here as well
|
||||
|
||||
await this.createQueryBuilder()
|
||||
.delete()
|
||||
.from(targetOrEntity)
|
||||
.whereInIds(id)
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes entity by a given entity id.
|
||||
*
|
||||
* @deprecated use deleteById method instead.
|
||||
*/
|
||||
async removeById<Entity>(targetOrEntity: ObjectType<Entity>|string, id: any, options?: RemoveOptions): Promise<void> {
|
||||
return this.deleteById(targetOrEntity, id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes entity by a given entity ids.
|
||||
*
|
||||
* @deprecated use deleteById method instead.
|
||||
*/
|
||||
async removeByIds<Entity>(targetOrEntity: ObjectType<Entity>|string, ids: any[], options?: RemoveOptions): Promise<void> {
|
||||
const promises = ids.map(async id => {
|
||||
const entity = await this.findOneById<any>(targetOrEntity, id); // this is temporary, in the future can be refactored to perform better
|
||||
if (!entity)
|
||||
throw new Error(`Cannot find entity to remove by a given id`);
|
||||
|
||||
await this.remove(entity, options);
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
return this.deleteById(targetOrEntity, ids, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2,6 +2,7 @@ import {FindManyOptions} from "./FindManyOptions";
|
||||
import {FindOneOptions} from "./FindOneOptions";
|
||||
import {ObjectLiteral} from "../common/ObjectLiteral";
|
||||
import {SelectQueryBuilder} from "../query-builder/SelectQueryBuilder";
|
||||
import {WhereExpression} from "../query-builder/WhereExpression";
|
||||
|
||||
/**
|
||||
* Utilities to work with FindOptions.
|
||||
@ -161,7 +162,7 @@ export class FindOptionsUtils {
|
||||
/**
|
||||
* Applies given simple conditions set to a given query builder.
|
||||
*/
|
||||
static applyConditions<T>(qb: SelectQueryBuilder<T>, conditions: ObjectLiteral): SelectQueryBuilder<T> {
|
||||
static applyConditions<QB extends WhereExpression & { alias: string, setParameter(name: string, value: any): QB }>(qb: QB, conditions: ObjectLiteral): QB {
|
||||
Object.keys(conditions).forEach((key, index) => {
|
||||
if (conditions![key] === null) {
|
||||
qb.andWhere(`${qb.alias}.${key} IS NULL`);
|
||||
|
||||
@ -46,17 +46,7 @@ export class InsertQueryBuilder<Entity> extends QueryBuilder<Entity> {
|
||||
/**
|
||||
* Values needs to be inserted into table.
|
||||
*/
|
||||
values(values: QueryPartialEntity<Entity>): this;
|
||||
|
||||
/**
|
||||
* Values needs to be inserted into table.
|
||||
*/
|
||||
values(values: QueryPartialEntity<Entity>[]): this;
|
||||
|
||||
/**
|
||||
* Values needs to be inserted into table.
|
||||
*/
|
||||
values(values: ObjectLiteral|ObjectLiteral[]): this {
|
||||
values(values: QueryPartialEntity<Entity>|QueryPartialEntity<Entity>[]): this {
|
||||
this.expressionMap.valuesSet = values;
|
||||
return this;
|
||||
}
|
||||
@ -92,7 +82,7 @@ export class InsertQueryBuilder<Entity> extends QueryBuilder<Entity> {
|
||||
const values = valueSets.map((valueSet, key) => {
|
||||
const columnNames = insertColumns.map(column => {
|
||||
const paramName = "_inserted_" + key + "_" + column.databaseName;
|
||||
const value = valueSet[column.propertyName];
|
||||
const value = column.getEntityValue(valueSet);
|
||||
|
||||
if (value instanceof Function) { // support for SQL expressions in update query
|
||||
return value();
|
||||
|
||||
@ -191,7 +191,7 @@ export class BaseEntity {
|
||||
* Removes entity by a given entity id.
|
||||
*/
|
||||
static removeById<T extends BaseEntity>(this: ObjectType<T>, id: any, options?: RemoveOptions): Promise<void> {
|
||||
return (this as any).getRepository().removeById(id, options);
|
||||
return (this as any).getRepository().deleteById(id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -133,25 +133,21 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given conditions.
|
||||
* Inserts a given entity into the database.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient INSERT query.
|
||||
* Does not check if entity exist in the database, so query will fail if duplicate entity is being inserted.
|
||||
*/
|
||||
async update(conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given find options.
|
||||
*/
|
||||
async update(findOptions: FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void>;
|
||||
async insert(entity: Partial<Entity>|Partial<Entity>[], options?: SaveOptions): Promise<void> {
|
||||
return this.manager.insert(this.metadata.target, entity, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entity partially. Entity can be found by a given conditions.
|
||||
*/
|
||||
async update(conditionsOrFindOptions: Partial<Entity>|FindOneOptions<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
const entity = await this.findOne(conditionsOrFindOptions as any); // this is temporary, in the future can be refactored to perform better
|
||||
if (!entity)
|
||||
throw new Error(`Cannot find entity to update by a given criteria`);
|
||||
|
||||
Object.assign(entity, partialEntity);
|
||||
await this.save(entity, options);
|
||||
async update(conditions: Partial<Entity>, partialEntity: DeepPartial<Entity>, options?: SaveOptions): Promise<void> {
|
||||
return this.manager.update(this.metadata.target, conditions, partialEntity, options);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,14 +175,40 @@ export class Repository<Entity extends ObjectLiteral> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entity by a given entity id.
|
||||
* Deletes entities by a given conditions.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient DELETE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async removeById(id: any, options?: RemoveOptions): Promise<void> {
|
||||
return this.manager.removeById(this.metadata.target, id, options);
|
||||
async delete(conditions: Partial<Entity>, options?: RemoveOptions): Promise<void> {
|
||||
return this.manager.delete(this.metadata.target, conditions, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes entities by a given conditions.
|
||||
* Unlike save method executes a primitive operation without cascades, relations and other operations included.
|
||||
* Does not modify source entity and does not execute listeners and subscribers.
|
||||
* Executes fast and efficient DELETE query.
|
||||
* Does not check if entity exist in the database.
|
||||
*/
|
||||
async deleteById(id: any, options?: RemoveOptions): Promise<void> {
|
||||
return this.manager.deleteById(this.metadata.target, id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entity by a given entity id.
|
||||
*
|
||||
* @deprecated use deleteById method instead.
|
||||
*/
|
||||
async removeById(id: any, options?: RemoveOptions): Promise<void> {
|
||||
return this.manager.deleteById(this.metadata.target, id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes entity by a given entity id.
|
||||
*
|
||||
* @deprecated use deleteById method instead.
|
||||
*/
|
||||
async removeByIds(ids: any[], options?: RemoveOptions): Promise<void> {
|
||||
return this.manager.removeByIds(this.metadata.target, ids, options);
|
||||
|
||||
@ -44,7 +44,7 @@ describe("repository > removeById and removeByIds methods", function() {
|
||||
]);
|
||||
|
||||
// remove one
|
||||
await postRepository.removeById(1);
|
||||
await postRepository.deleteById(1);
|
||||
|
||||
// load to check
|
||||
const loadedPosts = await postRepository.find();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user