@payloadcms/drizzle 3.58.0 → 3.59.0-internal.56a1b3b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { eq } from 'drizzle-orm';
1
+ import { and, desc, eq, isNull, or } from 'drizzle-orm';
2
2
  import { ValidationError } from 'payload';
3
3
  import { buildFindManyArgs } from '../find/buildFindManyArgs.js';
4
4
  import { transform } from '../transform/read/index.js';
@@ -139,29 +139,40 @@ joinQuery: _joinQuery, operation, path = '', req, select, tableName, upsertTarge
139
139
  try {
140
140
  if (operation === 'update') {
141
141
  const target = upsertTarget || adapter.tables[tableName].id;
142
- if (id) {
143
- rowToInsert.row.id = id;
144
- [insertedRow] = await adapter.insert({
145
- db,
146
- onConflictDoUpdate: {
147
- set: rowToInsert.row,
148
- target
149
- },
150
- tableName,
151
- values: rowToInsert.row
152
- });
142
+ // Check if we only have relationship operations and no main row data to update
143
+ // Exclude timestamp-only updates when we only have relationship operations
144
+ const rowKeys = Object.keys(rowToInsert.row);
145
+ const hasMainRowData = rowKeys.length > 0 && !rowKeys.every((key)=>key === 'updatedAt' || key === 'createdAt');
146
+ if (hasMainRowData) {
147
+ if (id) {
148
+ rowToInsert.row.id = id;
149
+ [insertedRow] = await adapter.insert({
150
+ db,
151
+ onConflictDoUpdate: {
152
+ set: rowToInsert.row,
153
+ target
154
+ },
155
+ tableName,
156
+ values: rowToInsert.row
157
+ });
158
+ } else {
159
+ ;
160
+ [insertedRow] = await adapter.insert({
161
+ db,
162
+ onConflictDoUpdate: {
163
+ set: rowToInsert.row,
164
+ target,
165
+ where
166
+ },
167
+ tableName,
168
+ values: rowToInsert.row
169
+ });
170
+ }
153
171
  } else {
154
- ;
155
- [insertedRow] = await adapter.insert({
156
- db,
157
- onConflictDoUpdate: {
158
- set: rowToInsert.row,
159
- target,
160
- where
161
- },
162
- tableName,
163
- values: rowToInsert.row
164
- });
172
+ // No main row data to update, just use the existing ID
173
+ insertedRow = {
174
+ id
175
+ };
165
176
  }
166
177
  } else {
167
178
  if (adapter.allowIDOnCreate && data.id) {
@@ -260,6 +271,8 @@ joinQuery: _joinQuery, operation, path = '', req, select, tableName, upsertTarge
260
271
  // //////////////////////////////////
261
272
  const relationshipsTableName = `${tableName}${adapter.relationshipsSuffix}`;
262
273
  if (operation === 'update') {
274
+ // Filter out specific item deletions (those with itemToRemove) from general path deletions
275
+ const generalRelationshipDeletes = rowToInsert.relationshipsToDelete.filter((rel)=>!('itemToRemove' in rel));
263
276
  await deleteExistingRowsByPath({
264
277
  adapter,
265
278
  db,
@@ -269,7 +282,7 @@ joinQuery: _joinQuery, operation, path = '', req, select, tableName, upsertTarge
269
282
  pathColumnName: 'path',
270
283
  rows: [
271
284
  ...relationsToInsert,
272
- ...rowToInsert.relationshipsToDelete
285
+ ...generalRelationshipDeletes
273
286
  ],
274
287
  tableName: relationshipsTableName
275
288
  });
@@ -282,6 +295,152 @@ joinQuery: _joinQuery, operation, path = '', req, select, tableName, upsertTarge
282
295
  });
283
296
  }
284
297
  // //////////////////////////////////
298
+ // HANDLE RELATIONSHIP $push OPERATIONS
299
+ // //////////////////////////////////
300
+ if (rowToInsert.relationshipsToAppend.length > 0) {
301
+ // Prepare all relationships for batch insert (order will be set after max query)
302
+ const relationshipsToInsert = rowToInsert.relationshipsToAppend.map((rel)=>{
303
+ const parentId = id || insertedRow.id;
304
+ const row = {
305
+ parent: parentId,
306
+ path: rel.path
307
+ };
308
+ // Only add locale if this relationship table has a locale column
309
+ const relationshipTable = adapter.rawTables[relationshipsTableName];
310
+ if (rel.locale && relationshipTable && relationshipTable.columns.locale) {
311
+ row.locale = rel.locale;
312
+ }
313
+ if (rel.relationTo) {
314
+ // Use camelCase key for Drizzle table (e.g., categoriesID not categories_id)
315
+ row[`${rel.relationTo}ID`] = rel.value;
316
+ }
317
+ return row;
318
+ });
319
+ if (relationshipsToInsert.length > 0) {
320
+ // Check for potential duplicates
321
+ const relationshipTable = adapter.tables[relationshipsTableName];
322
+ if (relationshipTable) {
323
+ // Build conditions only if we have relationships to check
324
+ if (relationshipsToInsert.length === 0) {
325
+ return; // No relationships to insert
326
+ }
327
+ const conditions = relationshipsToInsert.map((row)=>{
328
+ const parts = [
329
+ eq(relationshipTable.parent, row.parent),
330
+ eq(relationshipTable.path, row.path)
331
+ ];
332
+ // Add locale condition
333
+ if (row.locale !== undefined && relationshipTable.locale) {
334
+ parts.push(eq(relationshipTable.locale, row.locale));
335
+ } else if (relationshipTable.locale) {
336
+ parts.push(isNull(relationshipTable.locale));
337
+ }
338
+ // Add all relationship ID matches using schema fields
339
+ for (const [key, value] of Object.entries(row)){
340
+ if (key.endsWith('ID') && value != null) {
341
+ const column = relationshipTable[key];
342
+ if (column && typeof column === 'object') {
343
+ parts.push(eq(column, value));
344
+ }
345
+ }
346
+ }
347
+ return and(...parts);
348
+ });
349
+ // Get both existing relationships AND max order in a single query
350
+ let existingRels = [];
351
+ let maxOrder = 0;
352
+ if (conditions.length > 0) {
353
+ // Query for existing relationships
354
+ existingRels = await db.select().from(relationshipTable).where(or(...conditions));
355
+ }
356
+ // Get max order for this parent across all paths in a single query
357
+ const parentId = id || insertedRow.id;
358
+ const maxOrderResult = await db.select({
359
+ maxOrder: relationshipTable.order
360
+ }).from(relationshipTable).where(eq(relationshipTable.parent, parentId)).orderBy(desc(relationshipTable.order)).limit(1);
361
+ if (maxOrderResult.length > 0 && maxOrderResult[0].maxOrder) {
362
+ maxOrder = maxOrderResult[0].maxOrder;
363
+ }
364
+ // Set order values for all relationships based on max order
365
+ relationshipsToInsert.forEach((row, index)=>{
366
+ row.order = maxOrder + index + 1;
367
+ });
368
+ // Filter out relationships that already exist
369
+ const relationshipsToActuallyInsert = relationshipsToInsert.filter((newRow)=>{
370
+ return !existingRels.some((existingRow)=>{
371
+ // Check if this relationship already exists
372
+ let matches = existingRow.parent === newRow.parent && existingRow.path === newRow.path;
373
+ if (newRow.locale !== undefined) {
374
+ matches = matches && existingRow.locale === newRow.locale;
375
+ }
376
+ // Check relationship value matches - convert to camelCase for comparison
377
+ for (const key of Object.keys(newRow)){
378
+ if (key.endsWith('ID')) {
379
+ // Now using camelCase keys
380
+ matches = matches && existingRow[key] === newRow[key];
381
+ }
382
+ }
383
+ return matches;
384
+ });
385
+ });
386
+ // Insert only non-duplicate relationships
387
+ if (relationshipsToActuallyInsert.length > 0) {
388
+ await adapter.insert({
389
+ db,
390
+ tableName: relationshipsTableName,
391
+ values: relationshipsToActuallyInsert
392
+ });
393
+ }
394
+ }
395
+ }
396
+ }
397
+ // //////////////////////////////////
398
+ // HANDLE RELATIONSHIP $remove OPERATIONS
399
+ // //////////////////////////////////
400
+ if (rowToInsert.relationshipsToDelete.some((rel)=>'itemToRemove' in rel)) {
401
+ const relationshipTable = adapter.tables[relationshipsTableName];
402
+ if (relationshipTable) {
403
+ for (const relToDelete of rowToInsert.relationshipsToDelete){
404
+ if ('itemToRemove' in relToDelete && relToDelete.itemToRemove) {
405
+ const item = relToDelete.itemToRemove;
406
+ const parentId = id || insertedRow.id;
407
+ const conditions = [
408
+ eq(relationshipTable.parent, parentId),
409
+ eq(relationshipTable.path, relToDelete.path)
410
+ ];
411
+ // Add locale condition if this relationship table has a locale column
412
+ if (adapter.rawTables[relationshipsTableName]?.columns.locale) {
413
+ if (relToDelete.locale) {
414
+ conditions.push(eq(relationshipTable.locale, relToDelete.locale));
415
+ } else {
416
+ conditions.push(isNull(relationshipTable.locale));
417
+ }
418
+ }
419
+ // Handle polymorphic vs simple relationships
420
+ if (typeof item === 'object' && 'relationTo' in item) {
421
+ // Polymorphic relationship - convert to camelCase key
422
+ const camelKey = `${item.relationTo}ID`;
423
+ if (relationshipTable[camelKey]) {
424
+ conditions.push(eq(relationshipTable[camelKey], item.value));
425
+ }
426
+ } else if (relToDelete.relationTo) {
427
+ // Simple relationship - convert to camelCase key
428
+ const camelKey = `${relToDelete.relationTo}ID`;
429
+ if (relationshipTable[camelKey]) {
430
+ conditions.push(eq(relationshipTable[camelKey], item));
431
+ }
432
+ }
433
+ // Execute DELETE using Drizzle query builder
434
+ await adapter.deleteWhere({
435
+ db,
436
+ tableName: relationshipsTableName,
437
+ where: and(...conditions)
438
+ });
439
+ }
440
+ }
441
+ }
442
+ }
443
+ // //////////////////////////////////
285
444
  // INSERT hasMany TEXTS
286
445
  // //////////////////////////////////
287
446
  const textsTableName = `${tableName}_texts`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/upsertRow/index.ts"],"sourcesContent":["import type { LibSQLDatabase } from 'drizzle-orm/libsql'\nimport type { SelectedFields } from 'drizzle-orm/sqlite-core'\nimport type { TypeWithID } from 'payload'\n\nimport { eq } from 'drizzle-orm'\nimport { ValidationError } from 'payload'\n\nimport type { BlockRowToInsert } from '../transform/write/types.js'\nimport type { Args } from './types.js'\n\nimport { buildFindManyArgs } from '../find/buildFindManyArgs.js'\nimport { transform } from '../transform/read/index.js'\nimport { transformForWrite } from '../transform/write/index.js'\nimport { deleteExistingArrayRows } from './deleteExistingArrayRows.js'\nimport { deleteExistingRowsByPath } from './deleteExistingRowsByPath.js'\nimport { insertArrays } from './insertArrays.js'\nimport { shouldUseOptimizedUpsertRow } from './shouldUseOptimizedUpsertRow.js'\n\n/**\n * If `id` is provided, it will update the row with that ID.\n * If `where` is provided, it will update the row that matches the `where`\n * If neither `id` nor `where` is provided, it will create a new row.\n *\n * adapter function replaces the entire row and does not support partial updates.\n */\nexport const upsertRow = async <T extends Record<string, unknown> | TypeWithID>({\n id,\n adapter,\n data,\n db,\n fields,\n ignoreResult,\n // TODO:\n // When we support joins for write operations (create/update) - pass collectionSlug to the buildFindManyArgs\n // Make a new argument in upsertRow.ts and pass the slug from every operation.\n joinQuery: _joinQuery,\n operation,\n path = '',\n req,\n select,\n tableName,\n upsertTarget,\n where,\n}: Args): Promise<T> => {\n if (operation === 'create' && !data.createdAt) {\n data.createdAt = new Date().toISOString()\n }\n\n let insertedRow: Record<string, unknown> = { id }\n if (id && shouldUseOptimizedUpsertRow({ data, fields })) {\n const transformedForWrite = transformForWrite({\n adapter,\n data,\n enableAtomicWrites: true,\n fields,\n tableName,\n })\n const { row } = transformedForWrite\n const { arraysToPush } = transformedForWrite\n\n const drizzle = db as LibSQLDatabase\n\n // First, handle $push arrays\n\n if (arraysToPush && Object.keys(arraysToPush)?.length) {\n await insertArrays({\n adapter,\n arrays: [arraysToPush],\n db,\n parentRows: [insertedRow],\n uuidMap: {},\n })\n }\n\n // If row.updatedAt is not set, delete it to avoid triggering hasDataToUpdate. `updatedAt` may be explicitly set to null to\n // disable triggering hasDataToUpdate.\n if (typeof row.updatedAt === 'undefined' || row.updatedAt === null) {\n delete row.updatedAt\n }\n\n const hasDataToUpdate = row && Object.keys(row)?.length\n\n // Then, handle regular row update\n if (ignoreResult) {\n if (hasDataToUpdate) {\n // Only update row if there is something to update.\n // Example: if the data only consists of a single $push, calling insertArrays is enough - we don't need to update the row.\n await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n }\n return ignoreResult === 'idOnly' ? ({ id } as T) : null\n }\n\n const findManyArgs = buildFindManyArgs({\n adapter,\n depth: 0,\n fields,\n joinQuery: false,\n select,\n tableName,\n })\n\n const findManyKeysLength = Object.keys(findManyArgs).length\n const hasOnlyColumns = Object.keys(findManyArgs.columns || {}).length > 0\n\n if (!hasDataToUpdate) {\n // Nothing to update => just fetch current row and return\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n }\n\n if (findManyKeysLength === 0 || hasOnlyColumns) {\n // Optimization - No need for joins => can simply use returning(). This is optimal for very simple collections\n // without complex fields that live in separate tables like blocks, arrays, relationships, etc.\n\n const selectedFields: SelectedFields = {}\n if (hasOnlyColumns) {\n for (const [column, enabled] of Object.entries(findManyArgs.columns)) {\n if (enabled) {\n selectedFields[column] = adapter.tables[tableName][column]\n }\n }\n }\n\n const docs = await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n .returning(Object.keys(selectedFields).length ? selectedFields : undefined)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: docs[0],\n fields,\n joinQuery: false,\n tableName,\n })\n }\n\n // DB Update that needs the result, potentially with joins => need to update first, then find. returning() does not work with joins.\n\n await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n }\n // Split out the incoming data into the corresponding:\n // base row, locales, relationships, blocks, and arrays\n const rowToInsert = transformForWrite({\n adapter,\n data,\n enableAtomicWrites: false,\n fields,\n path,\n tableName,\n })\n\n // First, we insert the main row\n try {\n if (operation === 'update') {\n const target = upsertTarget || adapter.tables[tableName].id\n\n if (id) {\n rowToInsert.row.id = id\n ;[insertedRow] = await adapter.insert({\n db,\n onConflictDoUpdate: { set: rowToInsert.row, target },\n tableName,\n values: rowToInsert.row,\n })\n } else {\n ;[insertedRow] = await adapter.insert({\n db,\n onConflictDoUpdate: { set: rowToInsert.row, target, where },\n tableName,\n values: rowToInsert.row,\n })\n }\n } else {\n if (adapter.allowIDOnCreate && data.id) {\n rowToInsert.row.id = data.id\n }\n ;[insertedRow] = await adapter.insert({\n db,\n tableName,\n values: rowToInsert.row,\n })\n }\n\n const localesToInsert: Record<string, unknown>[] = []\n const relationsToInsert: Record<string, unknown>[] = []\n const textsToInsert: Record<string, unknown>[] = []\n const numbersToInsert: Record<string, unknown>[] = []\n const blocksToInsert: { [blockType: string]: BlockRowToInsert[] } = {}\n const selectsToInsert: { [selectTableName: string]: Record<string, unknown>[] } = {}\n\n // If there are locale rows with data, add the parent and locale to each\n if (Object.keys(rowToInsert.locales).length > 0) {\n Object.entries(rowToInsert.locales).forEach(([locale, localeRow]) => {\n localeRow._parentID = insertedRow.id\n localeRow._locale = locale\n localesToInsert.push(localeRow)\n })\n }\n\n // If there are relationships, add parent to each\n if (rowToInsert.relationships.length > 0) {\n rowToInsert.relationships.forEach((relation) => {\n relation.parent = insertedRow.id\n relationsToInsert.push(relation)\n })\n }\n\n // If there are texts, add parent to each\n if (rowToInsert.texts.length > 0) {\n rowToInsert.texts.forEach((textRow) => {\n textRow.parent = insertedRow.id\n textsToInsert.push(textRow)\n })\n }\n\n // If there are numbers, add parent to each\n if (rowToInsert.numbers.length > 0) {\n rowToInsert.numbers.forEach((numberRow) => {\n numberRow.parent = insertedRow.id\n numbersToInsert.push(numberRow)\n })\n }\n\n // If there are selects, add parent to each, and then\n // store by table name and rows\n if (Object.keys(rowToInsert.selects).length > 0) {\n Object.entries(rowToInsert.selects).forEach(([selectTableName, selectRows]) => {\n selectsToInsert[selectTableName] = []\n\n selectRows.forEach((row) => {\n if (typeof row.parent === 'undefined') {\n row.parent = insertedRow.id\n }\n\n selectsToInsert[selectTableName].push(row)\n })\n })\n }\n\n // If there are blocks, add parent to each, and then\n // store by table name and rows\n Object.keys(rowToInsert.blocks).forEach((tableName) => {\n rowToInsert.blocks[tableName].forEach((blockRow) => {\n blockRow.row._parentID = insertedRow.id\n if (!blocksToInsert[tableName]) {\n blocksToInsert[tableName] = []\n }\n if (blockRow.row.uuid) {\n delete blockRow.row.uuid\n }\n blocksToInsert[tableName].push(blockRow)\n })\n })\n\n // //////////////////////////////////\n // INSERT LOCALES\n // //////////////////////////////////\n\n if (localesToInsert.length > 0) {\n const localeTableName = `${tableName}${adapter.localesSuffix}`\n const localeTable = adapter.tables[`${tableName}${adapter.localesSuffix}`]\n\n if (operation === 'update') {\n await adapter.deleteWhere({\n db,\n tableName: localeTableName,\n where: eq(localeTable._parentID, insertedRow.id),\n })\n }\n\n await adapter.insert({\n db,\n tableName: localeTableName,\n values: localesToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT RELATIONSHIPS\n // //////////////////////////////////\n\n const relationshipsTableName = `${tableName}${adapter.relationshipsSuffix}`\n\n if (operation === 'update') {\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...relationsToInsert, ...rowToInsert.relationshipsToDelete],\n tableName: relationshipsTableName,\n })\n }\n\n if (relationsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: relationshipsTableName,\n values: relationsToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT hasMany TEXTS\n // //////////////////////////////////\n\n const textsTableName = `${tableName}_texts`\n\n if (operation === 'update') {\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...textsToInsert, ...rowToInsert.textsToDelete],\n tableName: textsTableName,\n })\n }\n\n if (textsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: textsTableName,\n values: textsToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT hasMany NUMBERS\n // //////////////////////////////////\n\n const numbersTableName = `${tableName}_numbers`\n\n if (operation === 'update') {\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...numbersToInsert, ...rowToInsert.numbersToDelete],\n tableName: numbersTableName,\n })\n }\n\n if (numbersToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: numbersTableName,\n values: numbersToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT BLOCKS\n // //////////////////////////////////\n\n const insertedBlockRows: Record<string, Record<string, unknown>[]> = {}\n\n if (operation === 'update') {\n for (const tableName of rowToInsert.blocksToDelete) {\n const blockTable = adapter.tables[tableName]\n await adapter.deleteWhere({\n db,\n tableName,\n where: eq(blockTable._parentID, insertedRow.id),\n })\n }\n }\n\n // When versions are enabled, adapter is used to track mapping between blocks/arrays ObjectID to their numeric generated representation, then we use it for nested to arrays/blocks select hasMany in versions.\n const arraysBlocksUUIDMap: Record<string, number | string> = {}\n\n for (const [tableName, blockRows] of Object.entries(blocksToInsert)) {\n insertedBlockRows[tableName] = await adapter.insert({\n db,\n tableName,\n values: blockRows.map(({ row }) => row),\n })\n\n insertedBlockRows[tableName].forEach((row, i) => {\n blockRows[i].row = row\n if (\n typeof row._uuid === 'string' &&\n (typeof row.id === 'string' || typeof row.id === 'number')\n ) {\n arraysBlocksUUIDMap[row._uuid] = row.id\n }\n })\n\n const blockLocaleIndexMap: number[] = []\n\n const blockLocaleRowsToInsert = blockRows.reduce((acc, blockRow, i) => {\n if (Object.entries(blockRow.locales).length > 0) {\n Object.entries(blockRow.locales).forEach(([blockLocale, blockLocaleData]) => {\n if (Object.keys(blockLocaleData).length > 0) {\n blockLocaleData._parentID = blockRow.row.id\n blockLocaleData._locale = blockLocale\n acc.push(blockLocaleData)\n blockLocaleIndexMap.push(i)\n }\n })\n }\n\n return acc\n }, [])\n\n if (blockLocaleRowsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: `${tableName}${adapter.localesSuffix}`,\n values: blockLocaleRowsToInsert,\n })\n }\n\n await insertArrays({\n adapter,\n arrays: blockRows.map(({ arrays }) => arrays),\n db,\n parentRows: insertedBlockRows[tableName],\n uuidMap: arraysBlocksUUIDMap,\n })\n }\n\n // //////////////////////////////////\n // INSERT ARRAYS RECURSIVELY\n // //////////////////////////////////\n\n if (operation === 'update') {\n for (const arrayTableName of Object.keys(rowToInsert.arrays)) {\n await deleteExistingArrayRows({\n adapter,\n db,\n parentID: insertedRow.id,\n tableName: arrayTableName,\n })\n }\n }\n\n await insertArrays({\n adapter,\n arrays: [rowToInsert.arrays, rowToInsert.arraysToPush],\n db,\n parentRows: [insertedRow, insertedRow],\n uuidMap: arraysBlocksUUIDMap,\n })\n\n // //////////////////////////////////\n // INSERT hasMany SELECTS\n // //////////////////////////////////\n\n for (const [selectTableName, tableRows] of Object.entries(selectsToInsert)) {\n const selectTable = adapter.tables[selectTableName]\n if (operation === 'update') {\n await adapter.deleteWhere({\n db,\n tableName: selectTableName,\n where: eq(selectTable.parent, insertedRow.id),\n })\n }\n\n if (Object.keys(arraysBlocksUUIDMap).length > 0) {\n tableRows.forEach((row: any) => {\n if (row.parent in arraysBlocksUUIDMap) {\n row.parent = arraysBlocksUUIDMap[row.parent]\n }\n })\n }\n\n if (tableRows.length) {\n await adapter.insert({\n db,\n tableName: selectTableName,\n values: tableRows,\n })\n }\n }\n\n // //////////////////////////////////\n // Error Handling\n // //////////////////////////////////\n } catch (caughtError) {\n // Unique constraint violation error\n // '23505' is the code for PostgreSQL, and 'SQLITE_CONSTRAINT_UNIQUE' is for SQLite\n\n let error = caughtError\n if (typeof caughtError === 'object' && 'cause' in caughtError) {\n error = caughtError.cause\n }\n\n if (error.code === '23505' || error.code === 'SQLITE_CONSTRAINT_UNIQUE') {\n let fieldName: null | string = null\n // We need to try and find the right constraint for the field but if we can't we fallback to a generic message\n if (error.code === '23505') {\n // For PostgreSQL, we can try to extract the field name from the error constraint\n if (adapter.fieldConstraints?.[tableName]?.[error.constraint]) {\n fieldName = adapter.fieldConstraints[tableName]?.[error.constraint]\n } else {\n const replacement = `${tableName}_`\n\n if (error.constraint.includes(replacement)) {\n const replacedConstraint = error.constraint.replace(replacement, '')\n\n if (replacedConstraint && adapter.fieldConstraints[tableName]?.[replacedConstraint]) {\n fieldName = adapter.fieldConstraints[tableName][replacedConstraint]\n }\n }\n }\n\n if (!fieldName) {\n // Last case scenario we extract the key and value from the detail on the error\n const detail = error.detail\n const regex = /Key \\(([^)]+)\\)=\\(([^)]+)\\)/\n const match: string[] = detail.match(regex)\n\n if (match && match[1]) {\n const key = match[1]\n\n fieldName = key\n }\n }\n } else if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {\n /**\n * For SQLite, we can try to extract the field name from the error message\n * The message typically looks like:\n * \"UNIQUE constraint failed: table_name.field_name\"\n */\n const regex = /UNIQUE constraint failed: ([^.]+)\\.([^.]+)/\n const match: string[] = error.message.match(regex)\n\n if (match && match[2]) {\n if (adapter.fieldConstraints[tableName]) {\n fieldName = adapter.fieldConstraints[tableName][`${match[2]}_idx`]\n }\n\n if (!fieldName) {\n fieldName = match[2]\n }\n }\n }\n\n throw new ValidationError(\n {\n id,\n errors: [\n {\n message: req?.t ? req.t('error:valueMustBeUnique') : 'Value must be unique',\n path: fieldName,\n },\n ],\n req,\n },\n req?.t,\n )\n } else {\n throw error\n }\n }\n\n if (ignoreResult === 'idOnly') {\n return { id: insertedRow.id } as T\n }\n\n if (ignoreResult) {\n return data as T\n }\n\n // //////////////////////////////////\n // RETRIEVE NEWLY UPDATED ROW\n // //////////////////////////////////\n\n const findManyArgs = buildFindManyArgs({\n adapter,\n depth: 0,\n fields,\n joinQuery: false,\n select,\n tableName,\n })\n\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n // //////////////////////////////////\n // TRANSFORM DATA\n // //////////////////////////////////\n\n const result = transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n\n return result\n}\n"],"names":["eq","ValidationError","buildFindManyArgs","transform","transformForWrite","deleteExistingArrayRows","deleteExistingRowsByPath","insertArrays","shouldUseOptimizedUpsertRow","upsertRow","id","adapter","data","db","fields","ignoreResult","joinQuery","_joinQuery","operation","path","req","select","tableName","upsertTarget","where","createdAt","Date","toISOString","insertedRow","transformedForWrite","enableAtomicWrites","row","arraysToPush","drizzle","Object","keys","length","arrays","parentRows","uuidMap","updatedAt","hasDataToUpdate","update","tables","set","findManyArgs","depth","findManyKeysLength","hasOnlyColumns","columns","doc","query","findFirst","config","payload","selectedFields","column","enabled","entries","docs","returning","undefined","rowToInsert","target","insert","onConflictDoUpdate","values","allowIDOnCreate","localesToInsert","relationsToInsert","textsToInsert","numbersToInsert","blocksToInsert","selectsToInsert","locales","forEach","locale","localeRow","_parentID","_locale","push","relationships","relation","parent","texts","textRow","numbers","numberRow","selects","selectTableName","selectRows","blocks","blockRow","uuid","localeTableName","localesSuffix","localeTable","deleteWhere","relationshipsTableName","relationshipsSuffix","localeColumnName","parentColumnName","parentID","pathColumnName","rows","relationshipsToDelete","textsTableName","textsToDelete","numbersTableName","numbersToDelete","insertedBlockRows","blocksToDelete","blockTable","arraysBlocksUUIDMap","blockRows","map","i","_uuid","blockLocaleIndexMap","blockLocaleRowsToInsert","reduce","acc","blockLocale","blockLocaleData","arrayTableName","tableRows","selectTable","caughtError","error","cause","code","fieldName","fieldConstraints","constraint","replacement","includes","replacedConstraint","replace","detail","regex","match","key","message","errors","t","result"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/upsertRow/index.ts"],"sourcesContent":["import type { LibSQLDatabase } from 'drizzle-orm/libsql'\nimport type { SelectedFields } from 'drizzle-orm/sqlite-core'\nimport type { TypeWithID } from 'payload'\n\nimport { and, desc, eq, isNull, or } from 'drizzle-orm'\nimport { ValidationError } from 'payload'\n\nimport type { BlockRowToInsert } from '../transform/write/types.js'\nimport type { Args } from './types.js'\n\ntype RelationshipRow = {\n [key: string]: number | string | undefined // For relationship ID columns like categoriesID, moviesID, etc.\n id?: number | string\n locale?: string\n order: number\n parent: number | string // Drizzle table uses 'parent' key\n path: string\n}\n\nimport { buildFindManyArgs } from '../find/buildFindManyArgs.js'\nimport { transform } from '../transform/read/index.js'\nimport { transformForWrite } from '../transform/write/index.js'\nimport { deleteExistingArrayRows } from './deleteExistingArrayRows.js'\nimport { deleteExistingRowsByPath } from './deleteExistingRowsByPath.js'\nimport { insertArrays } from './insertArrays.js'\nimport { shouldUseOptimizedUpsertRow } from './shouldUseOptimizedUpsertRow.js'\n\n/**\n * If `id` is provided, it will update the row with that ID.\n * If `where` is provided, it will update the row that matches the `where`\n * If neither `id` nor `where` is provided, it will create a new row.\n *\n * adapter function replaces the entire row and does not support partial updates.\n */\nexport const upsertRow = async <T extends Record<string, unknown> | TypeWithID>({\n id,\n adapter,\n data,\n db,\n fields,\n ignoreResult,\n // TODO:\n // When we support joins for write operations (create/update) - pass collectionSlug to the buildFindManyArgs\n // Make a new argument in upsertRow.ts and pass the slug from every operation.\n joinQuery: _joinQuery,\n operation,\n path = '',\n req,\n select,\n tableName,\n upsertTarget,\n where,\n}: Args): Promise<T> => {\n if (operation === 'create' && !data.createdAt) {\n data.createdAt = new Date().toISOString()\n }\n\n let insertedRow: Record<string, unknown> = { id }\n if (id && shouldUseOptimizedUpsertRow({ data, fields })) {\n const transformedForWrite = transformForWrite({\n adapter,\n data,\n enableAtomicWrites: true,\n fields,\n tableName,\n })\n const { row } = transformedForWrite\n const { arraysToPush } = transformedForWrite\n\n const drizzle = db as LibSQLDatabase\n\n // First, handle $push arrays\n\n if (arraysToPush && Object.keys(arraysToPush)?.length) {\n await insertArrays({\n adapter,\n arrays: [arraysToPush],\n db,\n parentRows: [insertedRow],\n uuidMap: {},\n })\n }\n\n // If row.updatedAt is not set, delete it to avoid triggering hasDataToUpdate. `updatedAt` may be explicitly set to null to\n // disable triggering hasDataToUpdate.\n if (typeof row.updatedAt === 'undefined' || row.updatedAt === null) {\n delete row.updatedAt\n }\n\n const hasDataToUpdate = row && Object.keys(row)?.length\n\n // Then, handle regular row update\n if (ignoreResult) {\n if (hasDataToUpdate) {\n // Only update row if there is something to update.\n // Example: if the data only consists of a single $push, calling insertArrays is enough - we don't need to update the row.\n await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n }\n return ignoreResult === 'idOnly' ? ({ id } as T) : null\n }\n\n const findManyArgs = buildFindManyArgs({\n adapter,\n depth: 0,\n fields,\n joinQuery: false,\n select,\n tableName,\n })\n\n const findManyKeysLength = Object.keys(findManyArgs).length\n const hasOnlyColumns = Object.keys(findManyArgs.columns || {}).length > 0\n\n if (!hasDataToUpdate) {\n // Nothing to update => just fetch current row and return\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n }\n\n if (findManyKeysLength === 0 || hasOnlyColumns) {\n // Optimization - No need for joins => can simply use returning(). This is optimal for very simple collections\n // without complex fields that live in separate tables like blocks, arrays, relationships, etc.\n\n const selectedFields: SelectedFields = {}\n if (hasOnlyColumns) {\n for (const [column, enabled] of Object.entries(findManyArgs.columns)) {\n if (enabled) {\n selectedFields[column] = adapter.tables[tableName][column]\n }\n }\n }\n\n const docs = await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n .returning(Object.keys(selectedFields).length ? selectedFields : undefined)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: docs[0],\n fields,\n joinQuery: false,\n tableName,\n })\n }\n\n // DB Update that needs the result, potentially with joins => need to update first, then find. returning() does not work with joins.\n\n await drizzle\n .update(adapter.tables[tableName])\n .set(row)\n .where(eq(adapter.tables[tableName].id, id))\n\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n return transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n }\n // Split out the incoming data into the corresponding:\n // base row, locales, relationships, blocks, and arrays\n const rowToInsert = transformForWrite({\n adapter,\n data,\n enableAtomicWrites: false,\n fields,\n path,\n tableName,\n })\n\n // First, we insert the main row\n try {\n if (operation === 'update') {\n const target = upsertTarget || adapter.tables[tableName].id\n\n // Check if we only have relationship operations and no main row data to update\n // Exclude timestamp-only updates when we only have relationship operations\n const rowKeys = Object.keys(rowToInsert.row)\n const hasMainRowData =\n rowKeys.length > 0 && !rowKeys.every((key) => key === 'updatedAt' || key === 'createdAt')\n\n if (hasMainRowData) {\n if (id) {\n rowToInsert.row.id = id\n ;[insertedRow] = await adapter.insert({\n db,\n onConflictDoUpdate: { set: rowToInsert.row, target },\n tableName,\n values: rowToInsert.row,\n })\n } else {\n ;[insertedRow] = await adapter.insert({\n db,\n onConflictDoUpdate: { set: rowToInsert.row, target, where },\n tableName,\n values: rowToInsert.row,\n })\n }\n } else {\n // No main row data to update, just use the existing ID\n insertedRow = { id }\n }\n } else {\n if (adapter.allowIDOnCreate && data.id) {\n rowToInsert.row.id = data.id\n }\n ;[insertedRow] = await adapter.insert({\n db,\n tableName,\n values: rowToInsert.row,\n })\n }\n\n const localesToInsert: Record<string, unknown>[] = []\n const relationsToInsert: Record<string, unknown>[] = []\n const textsToInsert: Record<string, unknown>[] = []\n const numbersToInsert: Record<string, unknown>[] = []\n const blocksToInsert: { [blockType: string]: BlockRowToInsert[] } = {}\n const selectsToInsert: { [selectTableName: string]: Record<string, unknown>[] } = {}\n\n // If there are locale rows with data, add the parent and locale to each\n if (Object.keys(rowToInsert.locales).length > 0) {\n Object.entries(rowToInsert.locales).forEach(([locale, localeRow]) => {\n localeRow._parentID = insertedRow.id\n localeRow._locale = locale\n localesToInsert.push(localeRow)\n })\n }\n\n // If there are relationships, add parent to each\n if (rowToInsert.relationships.length > 0) {\n rowToInsert.relationships.forEach((relation) => {\n relation.parent = insertedRow.id\n relationsToInsert.push(relation)\n })\n }\n\n // If there are texts, add parent to each\n if (rowToInsert.texts.length > 0) {\n rowToInsert.texts.forEach((textRow) => {\n textRow.parent = insertedRow.id\n textsToInsert.push(textRow)\n })\n }\n\n // If there are numbers, add parent to each\n if (rowToInsert.numbers.length > 0) {\n rowToInsert.numbers.forEach((numberRow) => {\n numberRow.parent = insertedRow.id\n numbersToInsert.push(numberRow)\n })\n }\n\n // If there are selects, add parent to each, and then\n // store by table name and rows\n if (Object.keys(rowToInsert.selects).length > 0) {\n Object.entries(rowToInsert.selects).forEach(([selectTableName, selectRows]) => {\n selectsToInsert[selectTableName] = []\n\n selectRows.forEach((row) => {\n if (typeof row.parent === 'undefined') {\n row.parent = insertedRow.id\n }\n\n selectsToInsert[selectTableName].push(row)\n })\n })\n }\n\n // If there are blocks, add parent to each, and then\n // store by table name and rows\n Object.keys(rowToInsert.blocks).forEach((tableName) => {\n rowToInsert.blocks[tableName].forEach((blockRow) => {\n blockRow.row._parentID = insertedRow.id\n if (!blocksToInsert[tableName]) {\n blocksToInsert[tableName] = []\n }\n if (blockRow.row.uuid) {\n delete blockRow.row.uuid\n }\n blocksToInsert[tableName].push(blockRow)\n })\n })\n\n // //////////////////////////////////\n // INSERT LOCALES\n // //////////////////////////////////\n\n if (localesToInsert.length > 0) {\n const localeTableName = `${tableName}${adapter.localesSuffix}`\n const localeTable = adapter.tables[`${tableName}${adapter.localesSuffix}`]\n\n if (operation === 'update') {\n await adapter.deleteWhere({\n db,\n tableName: localeTableName,\n where: eq(localeTable._parentID, insertedRow.id),\n })\n }\n\n await adapter.insert({\n db,\n tableName: localeTableName,\n values: localesToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT RELATIONSHIPS\n // //////////////////////////////////\n\n const relationshipsTableName = `${tableName}${adapter.relationshipsSuffix}`\n\n if (operation === 'update') {\n // Filter out specific item deletions (those with itemToRemove) from general path deletions\n const generalRelationshipDeletes = rowToInsert.relationshipsToDelete.filter(\n (rel) => !('itemToRemove' in rel),\n )\n\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...relationsToInsert, ...generalRelationshipDeletes],\n tableName: relationshipsTableName,\n })\n }\n\n if (relationsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: relationshipsTableName,\n values: relationsToInsert,\n })\n }\n\n // //////////////////////////////////\n // HANDLE RELATIONSHIP $push OPERATIONS\n // //////////////////////////////////\n\n if (rowToInsert.relationshipsToAppend.length > 0) {\n // Prepare all relationships for batch insert (order will be set after max query)\n const relationshipsToInsert = rowToInsert.relationshipsToAppend.map((rel) => {\n const parentId = id || insertedRow.id\n const row: Record<string, unknown> = {\n parent: parentId as number | string, // Use 'parent' key for Drizzle table\n path: rel.path,\n }\n\n // Only add locale if this relationship table has a locale column\n const relationshipTable = adapter.rawTables[relationshipsTableName]\n if (rel.locale && relationshipTable && relationshipTable.columns.locale) {\n row.locale = rel.locale\n }\n\n if (rel.relationTo) {\n // Use camelCase key for Drizzle table (e.g., categoriesID not categories_id)\n row[`${rel.relationTo}ID`] = rel.value\n }\n\n return row\n })\n\n if (relationshipsToInsert.length > 0) {\n // Check for potential duplicates\n const relationshipTable = adapter.tables[relationshipsTableName]\n\n if (relationshipTable) {\n // Build conditions only if we have relationships to check\n if (relationshipsToInsert.length === 0) {\n return // No relationships to insert\n }\n\n const conditions = relationshipsToInsert.map((row: RelationshipRow) => {\n const parts = [\n eq(relationshipTable.parent, row.parent),\n eq(relationshipTable.path, row.path),\n ]\n\n // Add locale condition\n if (row.locale !== undefined && relationshipTable.locale) {\n parts.push(eq(relationshipTable.locale, row.locale))\n } else if (relationshipTable.locale) {\n parts.push(isNull(relationshipTable.locale))\n }\n\n // Add all relationship ID matches using schema fields\n for (const [key, value] of Object.entries(row)) {\n if (key.endsWith('ID') && value != null) {\n const column = relationshipTable[key]\n if (column && typeof column === 'object') {\n parts.push(eq(column, value))\n }\n }\n }\n\n return and(...parts)\n })\n\n // Get both existing relationships AND max order in a single query\n let existingRels: Record<string, unknown>[] = []\n let maxOrder = 0\n\n if (conditions.length > 0) {\n // Query for existing relationships\n existingRels = await (db as any)\n .select()\n .from(relationshipTable)\n .where(or(...conditions))\n }\n\n // Get max order for this parent across all paths in a single query\n const parentId = id || insertedRow.id\n const maxOrderResult = await (db as any)\n .select({ maxOrder: relationshipTable.order })\n .from(relationshipTable)\n .where(eq(relationshipTable.parent, parentId))\n .orderBy(desc(relationshipTable.order))\n .limit(1)\n\n if (maxOrderResult.length > 0 && maxOrderResult[0].maxOrder) {\n maxOrder = maxOrderResult[0].maxOrder\n }\n\n // Set order values for all relationships based on max order\n relationshipsToInsert.forEach((row, index) => {\n row.order = maxOrder + index + 1\n })\n\n // Filter out relationships that already exist\n const relationshipsToActuallyInsert = relationshipsToInsert.filter((newRow) => {\n return !existingRels.some((existingRow: Record<string, unknown>) => {\n // Check if this relationship already exists\n let matches = existingRow.parent === newRow.parent && existingRow.path === newRow.path\n\n if (newRow.locale !== undefined) {\n matches = matches && existingRow.locale === newRow.locale\n }\n\n // Check relationship value matches - convert to camelCase for comparison\n for (const key of Object.keys(newRow)) {\n if (key.endsWith('ID')) {\n // Now using camelCase keys\n matches = matches && existingRow[key] === newRow[key]\n }\n }\n\n return matches\n })\n })\n\n // Insert only non-duplicate relationships\n if (relationshipsToActuallyInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: relationshipsTableName,\n values: relationshipsToActuallyInsert,\n })\n }\n }\n }\n }\n\n // //////////////////////////////////\n // HANDLE RELATIONSHIP $remove OPERATIONS\n // //////////////////////////////////\n\n if (rowToInsert.relationshipsToDelete.some((rel) => 'itemToRemove' in rel)) {\n const relationshipTable = adapter.tables[relationshipsTableName]\n\n if (relationshipTable) {\n for (const relToDelete of rowToInsert.relationshipsToDelete) {\n if ('itemToRemove' in relToDelete && relToDelete.itemToRemove) {\n const item = relToDelete.itemToRemove\n const parentId = (id || insertedRow.id) as number | string\n\n const conditions = [\n eq(relationshipTable.parent, parentId),\n eq(relationshipTable.path, relToDelete.path),\n ]\n\n // Add locale condition if this relationship table has a locale column\n if (adapter.rawTables[relationshipsTableName]?.columns.locale) {\n if (relToDelete.locale) {\n conditions.push(eq(relationshipTable.locale, relToDelete.locale))\n } else {\n conditions.push(isNull(relationshipTable.locale))\n }\n }\n\n // Handle polymorphic vs simple relationships\n if (typeof item === 'object' && 'relationTo' in item) {\n // Polymorphic relationship - convert to camelCase key\n const camelKey = `${item.relationTo}ID`\n if (relationshipTable[camelKey]) {\n conditions.push(eq(relationshipTable[camelKey], item.value))\n }\n } else if (relToDelete.relationTo) {\n // Simple relationship - convert to camelCase key\n const camelKey = `${relToDelete.relationTo}ID`\n if (relationshipTable[camelKey]) {\n conditions.push(eq(relationshipTable[camelKey], item))\n }\n }\n\n // Execute DELETE using Drizzle query builder\n await adapter.deleteWhere({\n db,\n tableName: relationshipsTableName,\n where: and(...conditions),\n })\n }\n }\n }\n }\n\n // //////////////////////////////////\n // INSERT hasMany TEXTS\n // //////////////////////////////////\n\n const textsTableName = `${tableName}_texts`\n\n if (operation === 'update') {\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...textsToInsert, ...rowToInsert.textsToDelete],\n tableName: textsTableName,\n })\n }\n\n if (textsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: textsTableName,\n values: textsToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT hasMany NUMBERS\n // //////////////////////////////////\n\n const numbersTableName = `${tableName}_numbers`\n\n if (operation === 'update') {\n await deleteExistingRowsByPath({\n adapter,\n db,\n localeColumnName: 'locale',\n parentColumnName: 'parent',\n parentID: insertedRow.id,\n pathColumnName: 'path',\n rows: [...numbersToInsert, ...rowToInsert.numbersToDelete],\n tableName: numbersTableName,\n })\n }\n\n if (numbersToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: numbersTableName,\n values: numbersToInsert,\n })\n }\n\n // //////////////////////////////////\n // INSERT BLOCKS\n // //////////////////////////////////\n\n const insertedBlockRows: Record<string, Record<string, unknown>[]> = {}\n\n if (operation === 'update') {\n for (const tableName of rowToInsert.blocksToDelete) {\n const blockTable = adapter.tables[tableName]\n await adapter.deleteWhere({\n db,\n tableName,\n where: eq(blockTable._parentID, insertedRow.id),\n })\n }\n }\n\n // When versions are enabled, adapter is used to track mapping between blocks/arrays ObjectID to their numeric generated representation, then we use it for nested to arrays/blocks select hasMany in versions.\n const arraysBlocksUUIDMap: Record<string, number | string> = {}\n\n for (const [tableName, blockRows] of Object.entries(blocksToInsert)) {\n insertedBlockRows[tableName] = await adapter.insert({\n db,\n tableName,\n values: blockRows.map(({ row }) => row),\n })\n\n insertedBlockRows[tableName].forEach((row, i) => {\n blockRows[i].row = row\n if (\n typeof row._uuid === 'string' &&\n (typeof row.id === 'string' || typeof row.id === 'number')\n ) {\n arraysBlocksUUIDMap[row._uuid] = row.id\n }\n })\n\n const blockLocaleIndexMap: number[] = []\n\n const blockLocaleRowsToInsert = blockRows.reduce((acc, blockRow, i) => {\n if (Object.entries(blockRow.locales).length > 0) {\n Object.entries(blockRow.locales).forEach(([blockLocale, blockLocaleData]) => {\n if (Object.keys(blockLocaleData).length > 0) {\n blockLocaleData._parentID = blockRow.row.id\n blockLocaleData._locale = blockLocale\n acc.push(blockLocaleData)\n blockLocaleIndexMap.push(i)\n }\n })\n }\n\n return acc\n }, [])\n\n if (blockLocaleRowsToInsert.length > 0) {\n await adapter.insert({\n db,\n tableName: `${tableName}${adapter.localesSuffix}`,\n values: blockLocaleRowsToInsert,\n })\n }\n\n await insertArrays({\n adapter,\n arrays: blockRows.map(({ arrays }) => arrays),\n db,\n parentRows: insertedBlockRows[tableName],\n uuidMap: arraysBlocksUUIDMap,\n })\n }\n\n // //////////////////////////////////\n // INSERT ARRAYS RECURSIVELY\n // //////////////////////////////////\n\n if (operation === 'update') {\n for (const arrayTableName of Object.keys(rowToInsert.arrays)) {\n await deleteExistingArrayRows({\n adapter,\n db,\n parentID: insertedRow.id,\n tableName: arrayTableName,\n })\n }\n }\n\n await insertArrays({\n adapter,\n arrays: [rowToInsert.arrays, rowToInsert.arraysToPush],\n db,\n parentRows: [insertedRow, insertedRow],\n uuidMap: arraysBlocksUUIDMap,\n })\n\n // //////////////////////////////////\n // INSERT hasMany SELECTS\n // //////////////////////////////////\n\n for (const [selectTableName, tableRows] of Object.entries(selectsToInsert)) {\n const selectTable = adapter.tables[selectTableName]\n if (operation === 'update') {\n await adapter.deleteWhere({\n db,\n tableName: selectTableName,\n where: eq(selectTable.parent, insertedRow.id),\n })\n }\n\n if (Object.keys(arraysBlocksUUIDMap).length > 0) {\n tableRows.forEach((row: RelationshipRow) => {\n if (row.parent in arraysBlocksUUIDMap) {\n row.parent = arraysBlocksUUIDMap[row.parent]\n }\n })\n }\n\n if (tableRows.length) {\n await adapter.insert({\n db,\n tableName: selectTableName,\n values: tableRows,\n })\n }\n }\n\n // //////////////////////////////////\n // Error Handling\n // //////////////////////////////////\n } catch (caughtError) {\n // Unique constraint violation error\n // '23505' is the code for PostgreSQL, and 'SQLITE_CONSTRAINT_UNIQUE' is for SQLite\n\n let error = caughtError\n if (typeof caughtError === 'object' && 'cause' in caughtError) {\n error = caughtError.cause\n }\n\n if (error.code === '23505' || error.code === 'SQLITE_CONSTRAINT_UNIQUE') {\n let fieldName: null | string = null\n // We need to try and find the right constraint for the field but if we can't we fallback to a generic message\n if (error.code === '23505') {\n // For PostgreSQL, we can try to extract the field name from the error constraint\n if (adapter.fieldConstraints?.[tableName]?.[error.constraint]) {\n fieldName = adapter.fieldConstraints[tableName]?.[error.constraint]\n } else {\n const replacement = `${tableName}_`\n\n if (error.constraint.includes(replacement)) {\n const replacedConstraint = error.constraint.replace(replacement, '')\n\n if (replacedConstraint && adapter.fieldConstraints[tableName]?.[replacedConstraint]) {\n fieldName = adapter.fieldConstraints[tableName][replacedConstraint]\n }\n }\n }\n\n if (!fieldName) {\n // Last case scenario we extract the key and value from the detail on the error\n const detail = error.detail\n const regex = /Key \\(([^)]+)\\)=\\(([^)]+)\\)/\n const match: string[] = detail.match(regex)\n\n if (match && match[1]) {\n const key = match[1]\n\n fieldName = key\n }\n }\n } else if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {\n /**\n * For SQLite, we can try to extract the field name from the error message\n * The message typically looks like:\n * \"UNIQUE constraint failed: table_name.field_name\"\n */\n const regex = /UNIQUE constraint failed: ([^.]+)\\.([^.]+)/\n const match: string[] = error.message.match(regex)\n\n if (match && match[2]) {\n if (adapter.fieldConstraints[tableName]) {\n fieldName = adapter.fieldConstraints[tableName][`${match[2]}_idx`]\n }\n\n if (!fieldName) {\n fieldName = match[2]\n }\n }\n }\n\n throw new ValidationError(\n {\n id,\n errors: [\n {\n message: req?.t ? req.t('error:valueMustBeUnique') : 'Value must be unique',\n path: fieldName,\n },\n ],\n req,\n },\n req?.t,\n )\n } else {\n throw error\n }\n }\n\n if (ignoreResult === 'idOnly') {\n return { id: insertedRow.id } as T\n }\n\n if (ignoreResult) {\n return data as T\n }\n\n // //////////////////////////////////\n // RETRIEVE NEWLY UPDATED ROW\n // //////////////////////////////////\n\n const findManyArgs = buildFindManyArgs({\n adapter,\n depth: 0,\n fields,\n joinQuery: false,\n select,\n tableName,\n })\n\n findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)\n\n const doc = await db.query[tableName].findFirst(findManyArgs)\n\n // //////////////////////////////////\n // TRANSFORM DATA\n // //////////////////////////////////\n\n const result = transform<T>({\n adapter,\n config: adapter.payload.config,\n data: doc,\n fields,\n joinQuery: false,\n tableName,\n })\n\n return result\n}\n"],"names":["and","desc","eq","isNull","or","ValidationError","buildFindManyArgs","transform","transformForWrite","deleteExistingArrayRows","deleteExistingRowsByPath","insertArrays","shouldUseOptimizedUpsertRow","upsertRow","id","adapter","data","db","fields","ignoreResult","joinQuery","_joinQuery","operation","path","req","select","tableName","upsertTarget","where","createdAt","Date","toISOString","insertedRow","transformedForWrite","enableAtomicWrites","row","arraysToPush","drizzle","Object","keys","length","arrays","parentRows","uuidMap","updatedAt","hasDataToUpdate","update","tables","set","findManyArgs","depth","findManyKeysLength","hasOnlyColumns","columns","doc","query","findFirst","config","payload","selectedFields","column","enabled","entries","docs","returning","undefined","rowToInsert","target","rowKeys","hasMainRowData","every","key","insert","onConflictDoUpdate","values","allowIDOnCreate","localesToInsert","relationsToInsert","textsToInsert","numbersToInsert","blocksToInsert","selectsToInsert","locales","forEach","locale","localeRow","_parentID","_locale","push","relationships","relation","parent","texts","textRow","numbers","numberRow","selects","selectTableName","selectRows","blocks","blockRow","uuid","localeTableName","localesSuffix","localeTable","deleteWhere","relationshipsTableName","relationshipsSuffix","generalRelationshipDeletes","relationshipsToDelete","filter","rel","localeColumnName","parentColumnName","parentID","pathColumnName","rows","relationshipsToAppend","relationshipsToInsert","map","parentId","relationshipTable","rawTables","relationTo","value","conditions","parts","endsWith","existingRels","maxOrder","from","maxOrderResult","order","orderBy","limit","index","relationshipsToActuallyInsert","newRow","some","existingRow","matches","relToDelete","itemToRemove","item","camelKey","textsTableName","textsToDelete","numbersTableName","numbersToDelete","insertedBlockRows","blocksToDelete","blockTable","arraysBlocksUUIDMap","blockRows","i","_uuid","blockLocaleIndexMap","blockLocaleRowsToInsert","reduce","acc","blockLocale","blockLocaleData","arrayTableName","tableRows","selectTable","caughtError","error","cause","code","fieldName","fieldConstraints","constraint","replacement","includes","replacedConstraint","replace","detail","regex","match","message","errors","t","result"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"shouldUseOptimizedUpsertRow.d.ts","sourceRoot":"","sources":["../../src/upsertRow/shouldUseOptimizedUpsertRow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,2BAA2B,sBAGrC;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAA;CACzB,QAiDA,CAAA"}
1
+ {"version":3,"file":"shouldUseOptimizedUpsertRow.d.ts","sourceRoot":"","sources":["../../src/upsertRow/shouldUseOptimizedUpsertRow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C;;;GAGG;AACH,eAAO,MAAM,2BAA2B,sBAGrC;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,cAAc,EAAE,CAAA;CACzB,QA8EA,CAAA"}
@@ -2,12 +2,14 @@
2
2
  * Checks whether we should use the upsertRow function for the passed data and otherwise use a simple SQL SET call.
3
3
  * We need to use upsertRow only when the data has arrays, blocks, hasMany select/text/number, localized fields, complex relationships.
4
4
  */ export const shouldUseOptimizedUpsertRow = ({ data, fields })=>{
5
+ let fieldsMatched = false;
5
6
  for(const key in data){
6
7
  const value = data[key];
7
8
  const field = fields.find((each)=>each.name === key);
8
9
  if (!field) {
9
10
  continue;
10
11
  }
12
+ fieldsMatched = true;
11
13
  if (field.type === 'blocks' || (field.type === 'text' || field.type === 'relationship' || field.type === 'upload' || field.type === 'select' || field.type === 'number') && field.hasMany || (field.type === 'relationship' || field.type === 'upload') && Array.isArray(field.relationTo) || field.localized) {
12
14
  return false;
13
15
  }
@@ -21,6 +23,13 @@
21
23
  }
22
24
  return false;
23
25
  }
26
+ // Handle relationship $push and $remove operations
27
+ if ((field.type === 'relationship' || field.type === 'upload') && field.hasMany) {
28
+ if (typeof value === 'object' && ('$push' in value || '$remove' in value)) {
29
+ return false // Use full upsertRow for relationship operations
30
+ ;
31
+ }
32
+ }
24
33
  if ((field.type === 'group' || field.type === 'tab') && value && typeof value === 'object' && !shouldUseOptimizedUpsertRow({
25
34
  data: value,
26
35
  fields: field.flattenedFields
@@ -28,6 +37,26 @@
28
37
  return false;
29
38
  }
30
39
  }
40
+ // Handle dot-notation paths when no fields matched
41
+ if (!fieldsMatched) {
42
+ for(const key in data){
43
+ if (key.includes('.')) {
44
+ // Split on first dot only
45
+ const firstDotIndex = key.indexOf('.');
46
+ const fieldName = key.substring(0, firstDotIndex);
47
+ const remainingPath = key.substring(firstDotIndex + 1);
48
+ const nestedData = {
49
+ [fieldName]: {
50
+ [remainingPath]: data[key]
51
+ }
52
+ };
53
+ return shouldUseOptimizedUpsertRow({
54
+ data: nestedData,
55
+ fields
56
+ });
57
+ }
58
+ }
59
+ }
31
60
  return true;
32
61
  };
33
62
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/upsertRow/shouldUseOptimizedUpsertRow.ts"],"sourcesContent":["import type { FlattenedField } from 'payload'\n\n/**\n * Checks whether we should use the upsertRow function for the passed data and otherwise use a simple SQL SET call.\n * We need to use upsertRow only when the data has arrays, blocks, hasMany select/text/number, localized fields, complex relationships.\n */\nexport const shouldUseOptimizedUpsertRow = ({\n data,\n fields,\n}: {\n data: Record<string, unknown>\n fields: FlattenedField[]\n}) => {\n for (const key in data) {\n const value = data[key]\n const field = fields.find((each) => each.name === key)\n\n if (!field) {\n continue\n }\n\n if (\n field.type === 'blocks' ||\n ((field.type === 'text' ||\n field.type === 'relationship' ||\n field.type === 'upload' ||\n field.type === 'select' ||\n field.type === 'number') &&\n field.hasMany) ||\n ((field.type === 'relationship' || field.type === 'upload') &&\n Array.isArray(field.relationTo)) ||\n field.localized\n ) {\n return false\n }\n\n if (field.type === 'array') {\n if (typeof value === 'object' && '$push' in value && value.$push) {\n return shouldUseOptimizedUpsertRow({\n // Only check first row - this function cares about field definitions. Each array row will have the same field definitions.\n data: Array.isArray(value.$push) ? value.$push?.[0] : value.$push,\n fields: field.flattenedFields,\n })\n }\n return false\n }\n\n if (\n (field.type === 'group' || field.type === 'tab') &&\n value &&\n typeof value === 'object' &&\n !shouldUseOptimizedUpsertRow({\n data: value as Record<string, unknown>,\n fields: field.flattenedFields,\n })\n ) {\n return false\n }\n }\n\n return true\n}\n"],"names":["shouldUseOptimizedUpsertRow","data","fields","key","value","field","find","each","name","type","hasMany","Array","isArray","relationTo","localized","$push","flattenedFields"],"mappings":"AAEA;;;CAGC,GACD,OAAO,MAAMA,8BAA8B,CAAC,EAC1CC,IAAI,EACJC,MAAM,EAIP;IACC,IAAK,MAAMC,OAAOF,KAAM;QACtB,MAAMG,QAAQH,IAAI,CAACE,IAAI;QACvB,MAAME,QAAQH,OAAOI,IAAI,CAAC,CAACC,OAASA,KAAKC,IAAI,KAAKL;QAElD,IAAI,CAACE,OAAO;YACV;QACF;QAEA,IACEA,MAAMI,IAAI,KAAK,YACd,AAACJ,CAAAA,MAAMI,IAAI,KAAK,UACfJ,MAAMI,IAAI,KAAK,kBACfJ,MAAMI,IAAI,KAAK,YACfJ,MAAMI,IAAI,KAAK,YACfJ,MAAMI,IAAI,KAAK,QAAO,KACtBJ,MAAMK,OAAO,IACd,AAACL,CAAAA,MAAMI,IAAI,KAAK,kBAAkBJ,MAAMI,IAAI,KAAK,QAAO,KACvDE,MAAMC,OAAO,CAACP,MAAMQ,UAAU,KAChCR,MAAMS,SAAS,EACf;YACA,OAAO;QACT;QAEA,IAAIT,MAAMI,IAAI,KAAK,SAAS;YAC1B,IAAI,OAAOL,UAAU,YAAY,WAAWA,SAASA,MAAMW,KAAK,EAAE;gBAChE,OAAOf,4BAA4B;oBACjC,2HAA2H;oBAC3HC,MAAMU,MAAMC,OAAO,CAACR,MAAMW,KAAK,IAAIX,MAAMW,KAAK,EAAE,CAAC,EAAE,GAAGX,MAAMW,KAAK;oBACjEb,QAAQG,MAAMW,eAAe;gBAC/B;YACF;YACA,OAAO;QACT;QAEA,IACE,AAACX,CAAAA,MAAMI,IAAI,KAAK,WAAWJ,MAAMI,IAAI,KAAK,KAAI,KAC9CL,SACA,OAAOA,UAAU,YACjB,CAACJ,4BAA4B;YAC3BC,MAAMG;YACNF,QAAQG,MAAMW,eAAe;QAC/B,IACA;YACA,OAAO;QACT;IACF;IAEA,OAAO;AACT,EAAC"}
1
+ {"version":3,"sources":["../../src/upsertRow/shouldUseOptimizedUpsertRow.ts"],"sourcesContent":["import type { FlattenedField } from 'payload'\n\n/**\n * Checks whether we should use the upsertRow function for the passed data and otherwise use a simple SQL SET call.\n * We need to use upsertRow only when the data has arrays, blocks, hasMany select/text/number, localized fields, complex relationships.\n */\nexport const shouldUseOptimizedUpsertRow = ({\n data,\n fields,\n}: {\n data: Record<string, unknown>\n fields: FlattenedField[]\n}) => {\n let fieldsMatched = false\n\n for (const key in data) {\n const value = data[key]\n const field = fields.find((each) => each.name === key)\n\n if (!field) {\n continue\n }\n\n fieldsMatched = true\n\n if (\n field.type === 'blocks' ||\n ((field.type === 'text' ||\n field.type === 'relationship' ||\n field.type === 'upload' ||\n field.type === 'select' ||\n field.type === 'number') &&\n field.hasMany) ||\n ((field.type === 'relationship' || field.type === 'upload') &&\n Array.isArray(field.relationTo)) ||\n field.localized\n ) {\n return false\n }\n\n if (field.type === 'array') {\n if (typeof value === 'object' && '$push' in value && value.$push) {\n return shouldUseOptimizedUpsertRow({\n // Only check first row - this function cares about field definitions. Each array row will have the same field definitions.\n data: Array.isArray(value.$push) ? value.$push?.[0] : value.$push,\n fields: field.flattenedFields,\n })\n }\n return false\n }\n\n // Handle relationship $push and $remove operations\n if ((field.type === 'relationship' || field.type === 'upload') && field.hasMany) {\n if (typeof value === 'object' && ('$push' in value || '$remove' in value)) {\n return false // Use full upsertRow for relationship operations\n }\n }\n\n if (\n (field.type === 'group' || field.type === 'tab') &&\n value &&\n typeof value === 'object' &&\n !shouldUseOptimizedUpsertRow({\n data: value as Record<string, unknown>,\n fields: field.flattenedFields,\n })\n ) {\n return false\n }\n }\n\n // Handle dot-notation paths when no fields matched\n if (!fieldsMatched) {\n for (const key in data) {\n if (key.includes('.')) {\n // Split on first dot only\n const firstDotIndex = key.indexOf('.')\n const fieldName = key.substring(0, firstDotIndex)\n const remainingPath = key.substring(firstDotIndex + 1)\n\n const nestedData = { [fieldName]: { [remainingPath]: data[key] } }\n return shouldUseOptimizedUpsertRow({\n data: nestedData,\n fields,\n })\n }\n }\n }\n\n return true\n}\n"],"names":["shouldUseOptimizedUpsertRow","data","fields","fieldsMatched","key","value","field","find","each","name","type","hasMany","Array","isArray","relationTo","localized","$push","flattenedFields","includes","firstDotIndex","indexOf","fieldName","substring","remainingPath","nestedData"],"mappings":"AAEA;;;CAGC,GACD,OAAO,MAAMA,8BAA8B,CAAC,EAC1CC,IAAI,EACJC,MAAM,EAIP;IACC,IAAIC,gBAAgB;IAEpB,IAAK,MAAMC,OAAOH,KAAM;QACtB,MAAMI,QAAQJ,IAAI,CAACG,IAAI;QACvB,MAAME,QAAQJ,OAAOK,IAAI,CAAC,CAACC,OAASA,KAAKC,IAAI,KAAKL;QAElD,IAAI,CAACE,OAAO;YACV;QACF;QAEAH,gBAAgB;QAEhB,IACEG,MAAMI,IAAI,KAAK,YACd,AAACJ,CAAAA,MAAMI,IAAI,KAAK,UACfJ,MAAMI,IAAI,KAAK,kBACfJ,MAAMI,IAAI,KAAK,YACfJ,MAAMI,IAAI,KAAK,YACfJ,MAAMI,IAAI,KAAK,QAAO,KACtBJ,MAAMK,OAAO,IACd,AAACL,CAAAA,MAAMI,IAAI,KAAK,kBAAkBJ,MAAMI,IAAI,KAAK,QAAO,KACvDE,MAAMC,OAAO,CAACP,MAAMQ,UAAU,KAChCR,MAAMS,SAAS,EACf;YACA,OAAO;QACT;QAEA,IAAIT,MAAMI,IAAI,KAAK,SAAS;YAC1B,IAAI,OAAOL,UAAU,YAAY,WAAWA,SAASA,MAAMW,KAAK,EAAE;gBAChE,OAAOhB,4BAA4B;oBACjC,2HAA2H;oBAC3HC,MAAMW,MAAMC,OAAO,CAACR,MAAMW,KAAK,IAAIX,MAAMW,KAAK,EAAE,CAAC,EAAE,GAAGX,MAAMW,KAAK;oBACjEd,QAAQI,MAAMW,eAAe;gBAC/B;YACF;YACA,OAAO;QACT;QAEA,mDAAmD;QACnD,IAAI,AAACX,CAAAA,MAAMI,IAAI,KAAK,kBAAkBJ,MAAMI,IAAI,KAAK,QAAO,KAAMJ,MAAMK,OAAO,EAAE;YAC/E,IAAI,OAAON,UAAU,YAAa,CAAA,WAAWA,SAAS,aAAaA,KAAI,GAAI;gBACzE,OAAO,MAAM,iDAAiD;;YAChE;QACF;QAEA,IACE,AAACC,CAAAA,MAAMI,IAAI,KAAK,WAAWJ,MAAMI,IAAI,KAAK,KAAI,KAC9CL,SACA,OAAOA,UAAU,YACjB,CAACL,4BAA4B;YAC3BC,MAAMI;YACNH,QAAQI,MAAMW,eAAe;QAC/B,IACA;YACA,OAAO;QACT;IACF;IAEA,mDAAmD;IACnD,IAAI,CAACd,eAAe;QAClB,IAAK,MAAMC,OAAOH,KAAM;YACtB,IAAIG,IAAIc,QAAQ,CAAC,MAAM;gBACrB,0BAA0B;gBAC1B,MAAMC,gBAAgBf,IAAIgB,OAAO,CAAC;gBAClC,MAAMC,YAAYjB,IAAIkB,SAAS,CAAC,GAAGH;gBACnC,MAAMI,gBAAgBnB,IAAIkB,SAAS,CAACH,gBAAgB;gBAEpD,MAAMK,aAAa;oBAAE,CAACH,UAAU,EAAE;wBAAE,CAACE,cAAc,EAAEtB,IAAI,CAACG,IAAI;oBAAC;gBAAE;gBACjE,OAAOJ,4BAA4B;oBACjCC,MAAMuB;oBACNtB;gBACF;YACF;QACF;IACF;IAEA,OAAO;AACT,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/drizzle",
3
- "version": "3.58.0",
3
+ "version": "3.59.0-internal.56a1b3b",
4
4
  "description": "A library of shared functions used by different payload database adapters",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -60,10 +60,10 @@
60
60
  "@types/pg": "8.10.2",
61
61
  "@types/to-snake-case": "1.0.0",
62
62
  "@payloadcms/eslint-config": "3.28.0",
63
- "payload": "3.58.0"
63
+ "payload": "3.59.0-internal.56a1b3b"
64
64
  },
65
65
  "peerDependencies": {
66
- "payload": "3.58.0"
66
+ "payload": "3.59.0-internal.56a1b3b"
67
67
  },
68
68
  "scripts": {
69
69
  "build": "pnpm build:swc && pnpm build:types",