Skip to content

Commit 25813a7

Browse files
rjgtavRicardo Tavares
andauthored
perf: optimized collection create when versions are enabled (#14885)
### What? Optimized the collection create operation when versions are enabled. ### Why? To reduce the total request time when creating a new entry on a collection with versions enabled. ### How? By passing returning=false to the saveVersion method, as the result is not needed. Also updated drizzle's createVersion operation to ignore the result when returning==false. This saves multiple database queries, specially on collections with relationships and other complex fields, as it no longer needs to load the new entry after creation. --------- Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
1 parent 00fb6e8 commit 25813a7

4 files changed

Lines changed: 50 additions & 6 deletions

File tree

packages/drizzle/src/createVersion.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,13 @@ export async function createVersion<T extends JsonObject = JsonObject>(
2727
}: CreateVersionArgs<T>,
2828
): Promise<TypeWithVersion<T>> {
2929
const collection = this.payload.collections[collectionSlug].config
30-
const defaultTableName = toSnakeCase(collection.slug)
30+
if (collection.versions.drafts) {
31+
if (typeof select === 'object') {
32+
select.updatedAt = true
33+
}
34+
}
3135

36+
const defaultTableName = toSnakeCase(collection.slug)
3237
const tableName = this.tableNameMap.get(`_${defaultTableName}${this.versionsSuffix}`)
3338

3439
const version = { ...versionData }
@@ -54,6 +59,7 @@ export async function createVersion<T extends JsonObject = JsonObject>(
5459
data,
5560
db,
5661
fields: buildVersionCollectionFields(this.payload.config, collection, true),
62+
ignoreResult: returning === false ? 'idOnly' : undefined,
5763
operation: 'create',
5864
req,
5965
select,
@@ -70,7 +76,7 @@ export async function createVersion<T extends JsonObject = JsonObject>(
7076
SET latest = false
7177
WHERE ${table.id} != ${result.id}
7278
AND ${table.parent} = ${parent}
73-
AND ${table.updatedAt} < ${result.updatedAt}
79+
AND ${table.updatedAt} < ${result.updatedAt || updatedAt}
7480
`,
7581
})
7682
}

packages/payload/src/collections/operations/create.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ export const createOperation = async <
287287
payload,
288288
publishSpecificLocale,
289289
req,
290+
returning: false,
290291
})
291292
}
292293

packages/payload/src/versions/saveVersion.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,21 @@ type Args<T extends JsonObject = JsonObject> = {
2121
payload: Payload
2222
publishSpecificLocale?: string
2323
req?: PayloadRequest
24+
returning?: boolean
2425
select?: SelectType
2526
snapshot?: any
2627
}
2728

28-
export const saveVersion = async <TData extends JsonObject = JsonObject>({
29+
export async function saveVersion<TData extends JsonObject = JsonObject>(
30+
args: { returning: false } & Args<TData>,
31+
): Promise<null>
32+
export async function saveVersion<TData extends JsonObject = JsonObject>(
33+
args: { returning: true } & Args<TData>,
34+
): Promise<JsonObject>
35+
export async function saveVersion<TData extends JsonObject = JsonObject>(
36+
args: Omit<Args<TData>, 'returning'>,
37+
): Promise<JsonObject>
38+
export async function saveVersion<TData extends JsonObject = JsonObject>({
2939
id,
3040
autosave,
3141
collection,
@@ -36,9 +46,10 @@ export const saveVersion = async <TData extends JsonObject = JsonObject>({
3646
payload,
3747
publishSpecificLocale,
3848
req,
49+
returning,
3950
select,
4051
snapshot,
41-
}: Args<TData>): Promise<JsonObject> => {
52+
}: Args<TData>): Promise<JsonObject | null> {
4253
let result: JsonObject | undefined
4354
let createNewVersion = true
4455
const now = new Date().toISOString()
@@ -136,6 +147,7 @@ export const saveVersion = async <TData extends JsonObject = JsonObject>({
136147
parent: collection ? id : undefined,
137148
publishedLocale: publishSpecificLocale || undefined,
138149
req,
150+
returning,
139151
select: getQueryDraftsSelect({ select }),
140152
updatedAt: now,
141153
versionData,
@@ -190,6 +202,9 @@ export const saveVersion = async <TData extends JsonObject = JsonObject>({
190202
req,
191203
})
192204
}
205+
if (returning === false) {
206+
return null
207+
}
193208

194209
let createdVersion = (result as any).version
195210

test/versions/int.spec.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { JsonObject, Payload } from 'payload'
1+
import type { JsonObject, Payload} from 'payload';
22

33
import { schedulePublishHandler } from '@payloadcms/ui/utilities/schedulePublishHandler'
44
import path from 'path'
5-
import { createLocalReq, ValidationError } from 'payload'
5+
import { createLocalReq, saveVersion, ValidationError } from 'payload'
66
import { wait } from 'payload/shared'
77
import * as qs from 'qs-esm'
88
import { fileURLToPath } from 'url'
@@ -430,6 +430,28 @@ describe('Versions', () => {
430430
})
431431
expect(await getVersionsCount()).toBe(2)
432432
})
433+
434+
it('should return null when saving a version with returning:false', async () => {
435+
const collection = autosaveCollectionSlug
436+
const collectionConfig = payload.collections[autosaveCollectionSlug].config
437+
438+
const post = await payload.create({
439+
collection,
440+
data: { description: 'description' },
441+
draft: true,
442+
})
443+
444+
const result = await saveVersion({
445+
id: post.id,
446+
collection: collectionConfig,
447+
docWithLocales: post,
448+
operation: 'create',
449+
payload,
450+
returning: false,
451+
})
452+
453+
expect(result).toBeNull()
454+
})
433455
})
434456

435457
describe('Duplicate', () => {

0 commit comments

Comments
 (0)