Commit a06106be authored by nanahira's avatar nanahira

add createOrUpdate

parent 20908b8f
...@@ -55,6 +55,7 @@ export interface CrudOptions<T extends ValidCrudEntity<T>> { ...@@ -55,6 +55,7 @@ export interface CrudOptions<T extends ValidCrudEntity<T>> {
relations?: (string | RelationDef)[]; relations?: (string | RelationDef)[];
extraGetQuery?: (qb: SelectQueryBuilder<T>) => void; extraGetQuery?: (qb: SelectQueryBuilder<T>) => void;
hardDelete?: boolean; hardDelete?: boolean;
createOrUpdate?: boolean;
} }
export class CrudBase<T extends ValidCrudEntity<T>> { export class CrudBase<T extends ValidCrudEntity<T>> {
...@@ -103,7 +104,9 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -103,7 +104,9 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
where: { where: {
id: In<string | number>(chunk), id: In<string | number>(chunk),
}, },
select: ['id', 'deleteTime'], select: this.crudOptions.createOrUpdate
? undefined
: ['id', 'deleteTime'],
withDeleted: true, withDeleted: true,
}), }),
), ),
...@@ -117,23 +120,43 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -117,23 +120,43 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
(ent) => ent.deleteTime != null, (ent) => ent.deleteTime != null,
); );
if (existingEntsWithoutDeleteTime.length) { if (existingEntsWithoutDeleteTime.length) {
if (!skipErrors) { if (this.crudOptions.createOrUpdate) {
throw new BlankReturnMessageDto( const existingIdMap = new Map<number, T>();
404, existingEntsWithoutDeleteTime.forEach((ent) => {
`${this.entityName} ID ${existingEntsWithoutDeleteTime.join( existingIdMap.set(ent.id, ent);
',', });
)} already exists`, entsToSave = [];
).toException(); for (const ent of ents) {
if (existingIdMap.has(ent.id)) {
const existingEnt = existingIdMap.get(ent.id);
Object.assign(existingEnt, ent);
entsToSave.push(existingEnt);
} else {
entsToSave.push(ent);
}
}
} else {
if (!skipErrors) {
throw new BlankReturnMessageDto(
404,
`${this.entityName} ID ${existingEntsWithoutDeleteTime.join(
',',
)} already exists`,
).toException();
}
const existingEntsWithoutDeleteTimeIdSet = new Set(
existingEntsWithoutDeleteTime.map((e) => e.id),
);
const skippedEnts = ents.filter((ent) =>
existingEntsWithoutDeleteTimeIdSet.has(ent.id),
);
skipped = skippedEnts.map((ent) => ({
result: 'Already exists',
entry: ent,
}));
const skippedEntsSet = new Set(skippedEnts);
entsToSave = ents.filter((ent) => !skippedEntsSet.has(ent));
} }
const skippedEnts = ents.filter((ent) =>
existingEntsWithoutDeleteTime.some((e) => e.id === ent.id),
);
skipped = skippedEnts.map((ent) => ({
result: 'Already exists',
entry: ent,
}));
const skippedEntsSet = new Set(skippedEnts);
entsToSave = ents.filter((ent) => !skippedEntsSet.has(ent));
} }
if (existingEntsWithDeleteTime.length) { if (existingEntsWithDeleteTime.length) {
await repo.delete( await repo.delete(
...@@ -177,7 +200,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -177,7 +200,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
if (!_ent) { if (!_ent) {
throw new BlankReturnMessageDto(400, 'Invalid entity').toException(); throw new BlankReturnMessageDto(400, 'Invalid entity').toException();
} }
const ent = new this.entityClass(); let ent = new this.entityClass();
Object.assign(ent, _ent); Object.assign(ent, _ent);
const invalidReason = ent.isValidInCreate(); const invalidReason = ent.isValidInCreate();
if (invalidReason) { if (invalidReason) {
...@@ -188,12 +211,17 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -188,12 +211,17 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
if (ent.id != null) { if (ent.id != null) {
const existingEnt = await repo.findOne({ const existingEnt = await repo.findOne({
where: { id: ent.id }, where: { id: ent.id },
select: ['id', 'deleteTime'], select: this.crudOptions.createOrUpdate
? undefined
: ['id', 'deleteTime'],
withDeleted: true, withDeleted: true,
}); });
if (existingEnt) { if (existingEnt) {
if (existingEnt.deleteTime) { if (existingEnt.deleteTime) {
await repo.delete(existingEnt.id); await repo.delete(existingEnt.id);
} else if (this.crudOptions.createOrUpdate) {
Object.assign(existingEnt, ent);
ent = existingEnt;
} else { } else {
throw new BlankReturnMessageDto( throw new BlankReturnMessageDto(
404, 404,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment