Tweak IO of o2m

This commit is contained in:
rijkvanzanten
2020-10-09 13:03:29 -04:00
parent 5c2af0970d
commit a8a69f1fb8
2 changed files with 44 additions and 42 deletions

View File

@@ -435,6 +435,7 @@ export class ItemsService implements AbstractService {
const keys: PrimaryKey[] = itemsToUpdate.map(
(item: Partial<Item>) => item[primaryKeyField]
);
return await this.update(data, keys);
}

View File

@@ -6,7 +6,7 @@
import argon2 from 'argon2';
import { v4 as uuidv4 } from 'uuid';
import database from '../database';
import { clone, isObject } from 'lodash';
import { clone, isObject, cloneDeep } from 'lodash';
import { Relation, Item, AbstractServiceOptions, Accountability, PrimaryKey } from '../types';
import { ItemsService } from './items';
import { URL } from 'url';
@@ -15,6 +15,7 @@ import env from '../env';
import SchemaInspector from 'knex-schema-inspector';
import getLocalType from '../utils/get-local-type';
import { format, formatISO } from 'date-fns';
import { ForbiddenException } from '../exceptions';
type Action = 'create' | 'read' | 'update';
@@ -313,11 +314,7 @@ export class PayloadService {
const exists = hasPrimaryKey && !!(await itemsService.readByKey(relatedPrimaryKey));
if (exists) {
if (relatedRecord.hasOwnProperty('$delete') && relatedRecord.$delete) {
await itemsService.delete(relatedPrimaryKey);
} else {
await itemsService.update(relatedRecord, relatedPrimaryKey);
}
await itemsService.update(relatedRecord, relatedPrimaryKey);
} else {
relatedPrimaryKey = await itemsService.create(relatedRecord);
}
@@ -353,48 +350,52 @@ export class PayloadService {
});
for (const relation of relationsToProcess) {
const relatedRecords: Partial<Item>[] = payload[relation.one_field].map(
(record: string | number | Partial<Item>) => {
if (typeof record === 'string' || typeof record === 'number') {
record = {
[relation.many_primary]: record,
};
}
return {
...record,
[relation.many_field]: parent || payload[relation.one_primary],
};
}
);
const itemsService = new ItemsService(relation.many_collection, {
accountability: this.accountability,
knex: this.knex,
});
const toBeCreated = relatedRecords.filter(
(record) => record.hasOwnProperty(relation.many_primary) === false
const relatedRecords: Partial<Item>[] = [];
for (const relatedRecord of payload[relation.one_field]) {
let record = cloneDeep(relatedRecord);
if (typeof relatedRecord === 'string' || typeof relatedRecord === 'number') {
const exists = !!(await this.knex
.select(relation.many_primary)
.from(relation.many_collection)
.where({ [relation.many_primary]: record })
.first());
if (exists === false)
throw new ForbiddenException(undefined, {
item: record,
collection: relation.many_collection,
});
record = {
[relation.many_primary]: relatedRecord,
};
}
relatedRecords.push({
...record,
[relation.many_field]: parent || payload[relation.one_primary],
});
}
const primaryKeys = await itemsService.upsert(relatedRecords);
await itemsService.updateByQuery(
{ [relation.many_field]: null },
{
filter: {
[relation.many_primary]: {
_nin: primaryKeys,
},
},
}
);
const toBeUpdated = relatedRecords.filter(
(record) =>
record.hasOwnProperty(relation.many_primary) === true &&
record.hasOwnProperty('$delete') === false
);
const toBeDeleted = relatedRecords
.filter(
(record) =>
record.hasOwnProperty(relation.many_primary) === true &&
record.hasOwnProperty('$delete') &&
record.$delete === true
)
.map((record) => record[relation.many_primary]);
await itemsService.create(toBeCreated);
await itemsService.update(toBeUpdated);
await itemsService.delete(toBeDeleted);
}
}
}