From def50a82abce82b78c287ddea9b9411ec51c94df Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 17 Jul 2020 15:05:33 -0400 Subject: [PATCH] Finish batch crud --- src/routes/items.ts | 43 ++++++++++------------- src/services/collections.ts | 7 +--- src/services/items.ts | 69 ++++++++++++++++++++++--------------- src/services/payload.ts | 3 +- src/services/settings.ts | 3 +- 5 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/routes/items.ts b/src/routes/items.ts index f0316f5630..a5266eac63 100644 --- a/src/routes/items.ts +++ b/src/routes/items.ts @@ -73,15 +73,15 @@ router.get( throw new RouteNotFoundException(req.path); } - const record = await ItemsService.readItem( - req.collection, - req.params.pk, - req.sanitizedQuery, - { role: req.role, admin: req.admin } - ); + const pk = req.params.pk.includes(',') ? req.params.pk.split(',') : req.params.pk; + + const result = await ItemsService.readItem(req.collection, pk, req.sanitizedQuery, { + role: req.role, + admin: req.admin, + }); return res.json({ - data: record || null, + data: result || null, }); }) ); @@ -107,6 +107,8 @@ router.patch( return res.json({ data: item || null }); } + + throw new RouteNotFoundException(req.path); }) ); @@ -150,28 +152,19 @@ router.delete( '/:collection/:pk', collectionExists, asyncHandler(async (req, res) => { - const primaryKey = req.params.pk; + const accountability: Accountability = { + user: req.user, + role: req.role, + admin: req.admin, + ip: req.ip, + userAgent: req.get('user-agent'), + }; - const isBatch = primaryKey.includes(','); + const pk = req.params.pk.includes(',') ? req.params.pk.split(',') : req.params.pk; - if (isBatch) { - const primaryKeys = primaryKey.split(','); - await Promise.all(primaryKeys.map(deleteItem)); - } else { - await deleteItem(primaryKey); - } + await ItemsService.deleteItem(req.collection, pk, accountability); return res.status(200).end(); - - async function deleteItem(pk: string | number) { - await ItemsService.deleteItem(req.collection, pk, { - role: req.role, - admin: req.admin, - ip: req.ip, - userAgent: req.get('user-agent'), - user: req.user, - }); - } }) ); diff --git a/src/services/collections.ts b/src/services/collections.ts index 19a255305d..25e6f3d876 100644 --- a/src/services/collections.ts +++ b/src/services/collections.ts @@ -101,12 +101,7 @@ export const readOne = async ( ) => { const [table, collectionInfo] = await Promise.all([ schemaInspector.tableInfo(collection), - ItemsService.readItem( - 'directus_collections', - collection, - query, - accountability - ), + ItemsService.readItem('directus_collections', collection, query, accountability), ]); return { diff --git a/src/services/items.ts b/src/services/items.ts index 1c57a687e8..777b507595 100644 --- a/src/services/items.ts +++ b/src/services/items.ts @@ -148,6 +148,7 @@ export const readItem = async ( operation = operation || 'read'; const primaryKeyField = await schemaInspector.primary(collection); + const primaryKeys: any[] = Array.isArray(pk) ? pk : [pk]; const isBatch = Array.isArray(pk); if (isBatch) { @@ -156,7 +157,7 @@ export const readItem = async ( filter: { ...(query.filter || {}), [primaryKeyField]: { - _in: pk, + _in: primaryKeys, }, }, }; @@ -191,7 +192,7 @@ export const updateItem = async => { const primaryKeys: any[] = Array.isArray(pk) ? pk : [pk]; - const updatedPrimaryKeys = database.transaction(async (tx) => { + await database.transaction(async (tx) => { let payload = clone(data); return await Promise.all( @@ -231,13 +232,13 @@ export const updateItem = async logger.error(err)); + // saveActivityAndRevision( + // ActivityService.Action.UPDATE, + // collection, + // String(pk), + // payloadWithoutAlias, + // accountability + // ).catch((err) => logger.error(err)); } return pk; @@ -245,32 +246,46 @@ export const updateItem = async ( collection: string, - pk: number | string, + pk: T, accountability?: Accountability -) => { +): Promise => { const primaryKeyField = await schemaInspector.primary(collection); + const primaryKeys: any[] = Array.isArray(pk) ? pk : [pk]; - if (accountability && accountability.admin === false) { - await PermissionsService.checkAccess('delete', collection, pk, accountability.role); + await database.transaction(async (tx) => { + await Promise.all( + primaryKeys.map(async (key) => { + if (accountability && accountability.admin === false) { + await PermissionsService.checkAccess( + 'delete', + collection, + key, + accountability.role + ); + } - // Don't await this. It can run async in the background - saveActivityAndRevision( - ActivityService.Action.DELETE, - collection, - String(pk), - {}, - accountability - ).catch((err) => logger.error(err)); - } + await tx(collection) + .where({ [primaryKeyField]: key }) + .delete(); + }) + ); + }); - return await database(collection) - .delete() - .where({ [primaryKeyField]: pk }); + // Don't await this. It can run async in the background + // saveActivityAndRevision( + // ActivityService.Action.DELETE, + // collection, + // String(pk), + // {}, + // accountability + // ).catch((err) => logger.error(err)); + + return pk; }; export const readSingleton = async ( diff --git a/src/services/payload.ts b/src/services/payload.ts index b969fd2640..26d43a02da 100644 --- a/src/services/payload.ts +++ b/src/services/payload.ts @@ -8,8 +8,7 @@ import argon2 from 'argon2'; import { v4 as uuidv4 } from 'uuid'; import database from '../database'; import { clone, isObject } from 'lodash'; -import { File } from '../types/files'; -import { Relation } from '../types/relation'; +import { File, Relation, Item } from '../types'; import * as ItemsService from './items'; type Operation = 'create' | 'read' | 'update'; diff --git a/src/services/settings.ts b/src/services/settings.ts index 60023c737f..8b26badd14 100644 --- a/src/services/settings.ts +++ b/src/services/settings.ts @@ -1,6 +1,5 @@ -import { Query, Item } from '../types/query'; +import { Query, Item, Accountability } from '../types'; import * as ItemsService from './items'; -import { Accountability } from '../types'; export const readSettings = async (query: Query, accountability?: Accountability) => { return await ItemsService.readSingleton('directus_settings', query, accountability);