Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
666 lines
28 KiB
Plaintext
666 lines
28 KiB
Plaintext
import { and, desc, eq, isNull, or } from 'drizzle-orm';
|
|
import { buildFindManyArgs } from '../find/buildFindManyArgs.js';
|
|
import { transform } from '../transform/read/index.js';
|
|
import { transformForWrite } from '../transform/write/index.js';
|
|
import { deleteExistingArrayRows } from './deleteExistingArrayRows.js';
|
|
import { deleteExistingRowsByPath } from './deleteExistingRowsByPath.js';
|
|
import { handleUpsertError } from './handleUpsertError.js';
|
|
import { insertArrays } from './insertArrays.js';
|
|
import { shouldUseOptimizedUpsertRow } from './shouldUseOptimizedUpsertRow.js';
|
|
/**
|
|
* If `id` is provided, it will update the row with that ID.
|
|
* If `where` is provided, it will update the row that matches the `where`
|
|
* If neither `id` nor `where` is provided, it will create a new row.
|
|
*
|
|
* adapter function replaces the entire row and does not support partial updates.
|
|
*/ export const upsertRow = async ({ id, adapter, collectionSlug, data, db, fields, globalSlug, ignoreResult, // TODO:
|
|
// When we support joins for write operations (create/update) - pass collectionSlug to the buildFindManyArgs
|
|
// Make a new argument in upsertRow.ts and pass the slug from every operation.
|
|
customID, joinQuery: _joinQuery, operation, path = '', req, select, tableName, upsertTarget, where })=>{
|
|
if (operation === 'create' && !data.createdAt) {
|
|
data.createdAt = new Date().toISOString();
|
|
}
|
|
let insertedRow = {
|
|
id
|
|
};
|
|
if (id && shouldUseOptimizedUpsertRow({
|
|
data,
|
|
fields
|
|
})) {
|
|
try {
|
|
const transformedForWrite = transformForWrite({
|
|
adapter,
|
|
data,
|
|
enableAtomicWrites: true,
|
|
fields,
|
|
tableName
|
|
});
|
|
const { row } = transformedForWrite;
|
|
const { arraysToPush } = transformedForWrite;
|
|
const drizzle = db;
|
|
// First, handle $push arrays
|
|
if (arraysToPush && Object.keys(arraysToPush)?.length) {
|
|
await insertArrays({
|
|
adapter,
|
|
arrays: [
|
|
arraysToPush
|
|
],
|
|
db,
|
|
parentRows: [
|
|
insertedRow
|
|
],
|
|
uuidMap: {}
|
|
});
|
|
}
|
|
// If row.updatedAt is not set, delete it to avoid triggering hasDataToUpdate. `updatedAt` may be explicitly set to null to
|
|
// disable triggering hasDataToUpdate.
|
|
if (typeof row.updatedAt === 'undefined' || row.updatedAt === null) {
|
|
delete row.updatedAt;
|
|
}
|
|
const hasDataToUpdate = row && Object.keys(row)?.length;
|
|
// Then, handle regular row update
|
|
if (ignoreResult) {
|
|
if (hasDataToUpdate) {
|
|
// Only update row if there is something to update.
|
|
// Example: if the data only consists of a single $push, calling insertArrays is enough - we don't need to update the row.
|
|
await drizzle.update(adapter.tables[tableName]).set(row).where(eq(adapter.tables[tableName].id, id));
|
|
}
|
|
return ignoreResult === 'idOnly' ? {
|
|
id
|
|
} : null;
|
|
}
|
|
const findManyArgs = buildFindManyArgs({
|
|
adapter,
|
|
depth: 0,
|
|
fields,
|
|
joinQuery: false,
|
|
select,
|
|
tableName
|
|
});
|
|
const findManyKeysLength = Object.keys(findManyArgs).length;
|
|
const hasOnlyColumns = Object.keys(findManyArgs.columns || {}).length > 0;
|
|
if (!hasDataToUpdate) {
|
|
// Nothing to update => just fetch current row and return
|
|
findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id);
|
|
const doc = await db.query[tableName].findFirst(findManyArgs);
|
|
return transform({
|
|
adapter,
|
|
config: adapter.payload.config,
|
|
data: doc,
|
|
fields,
|
|
joinQuery: false,
|
|
tableName
|
|
});
|
|
}
|
|
if (findManyKeysLength === 0 || hasOnlyColumns) {
|
|
// Optimization - No need for joins => can simply use returning(). This is optimal for very simple collections
|
|
// without complex fields that live in separate tables like blocks, arrays, relationships, etc.
|
|
const selectedFields = {};
|
|
if (hasOnlyColumns) {
|
|
for (const [column, enabled] of Object.entries(findManyArgs.columns)){
|
|
if (enabled) {
|
|
selectedFields[column] = adapter.tables[tableName][column];
|
|
}
|
|
}
|
|
}
|
|
const docs = await drizzle.update(adapter.tables[tableName]).set(row).where(eq(adapter.tables[tableName].id, id)).returning(Object.keys(selectedFields).length ? selectedFields : undefined);
|
|
return transform({
|
|
adapter,
|
|
config: adapter.payload.config,
|
|
data: docs[0],
|
|
fields,
|
|
joinQuery: false,
|
|
tableName
|
|
});
|
|
}
|
|
// DB Update that needs the result, potentially with joins => need to update first, then find. returning() does not work with joins.
|
|
await drizzle.update(adapter.tables[tableName]).set(row).where(eq(adapter.tables[tableName].id, id));
|
|
findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id);
|
|
const doc = await db.query[tableName].findFirst(findManyArgs);
|
|
return transform({
|
|
adapter,
|
|
config: adapter.payload.config,
|
|
data: doc,
|
|
fields,
|
|
joinQuery: false,
|
|
tableName
|
|
});
|
|
} catch (error) {
|
|
handleUpsertError({
|
|
id,
|
|
adapter,
|
|
collectionSlug,
|
|
error,
|
|
globalSlug,
|
|
req,
|
|
tableName
|
|
});
|
|
}
|
|
}
|
|
// Split out the incoming data into the corresponding:
|
|
// base row, locales, relationships, blocks, and arrays
|
|
const rowToInsert = transformForWrite({
|
|
adapter,
|
|
data,
|
|
enableAtomicWrites: false,
|
|
fields,
|
|
path,
|
|
tableName
|
|
});
|
|
if (customID) {
|
|
rowToInsert.row.id = customID;
|
|
}
|
|
// First, we insert the main row
|
|
try {
|
|
if (operation === 'update') {
|
|
const target = upsertTarget || adapter.tables[tableName].id;
|
|
// Check if we only have relationship operations and no main row data to update
|
|
// Exclude timestamp-only updates when we only have relationship operations
|
|
const rowKeys = Object.keys(rowToInsert.row);
|
|
const hasMainRowData = rowKeys.length > 0 && !rowKeys.every((key)=>key === 'updatedAt' || key === 'createdAt');
|
|
if (hasMainRowData) {
|
|
if (id) {
|
|
rowToInsert.row.id = id;
|
|
[insertedRow] = await adapter.insert({
|
|
db,
|
|
onConflictDoUpdate: {
|
|
set: rowToInsert.row,
|
|
target
|
|
},
|
|
tableName,
|
|
values: rowToInsert.row
|
|
});
|
|
} else {
|
|
;
|
|
[insertedRow] = await adapter.insert({
|
|
db,
|
|
onConflictDoUpdate: {
|
|
set: rowToInsert.row,
|
|
target,
|
|
where
|
|
},
|
|
tableName,
|
|
values: rowToInsert.row
|
|
});
|
|
}
|
|
} else {
|
|
// No main row data to update, just use the existing ID
|
|
insertedRow = {
|
|
id
|
|
};
|
|
}
|
|
} else {
|
|
if (adapter.allowIDOnCreate && data.id) {
|
|
rowToInsert.row.id = data.id;
|
|
}
|
|
;
|
|
[insertedRow] = await adapter.insert({
|
|
db,
|
|
tableName,
|
|
values: rowToInsert.row
|
|
});
|
|
}
|
|
const localesToInsert = [];
|
|
const relationsToInsert = [];
|
|
const textsToInsert = [];
|
|
const numbersToInsert = [];
|
|
const blocksToInsert = {};
|
|
const selectsToInsert = {};
|
|
// If there are locale rows with data, add the parent and locale to each
|
|
if (Object.keys(rowToInsert.locales).length > 0) {
|
|
Object.entries(rowToInsert.locales).forEach(([locale, localeRow])=>{
|
|
localeRow._parentID = insertedRow.id;
|
|
localeRow._locale = locale;
|
|
localesToInsert.push(localeRow);
|
|
});
|
|
}
|
|
// If there are relationships, add parent to each
|
|
if (rowToInsert.relationships.length > 0) {
|
|
rowToInsert.relationships.forEach((relation)=>{
|
|
relation.parent = insertedRow.id;
|
|
relationsToInsert.push(relation);
|
|
});
|
|
}
|
|
// If there are texts, add parent to each
|
|
if (rowToInsert.texts.length > 0) {
|
|
rowToInsert.texts.forEach((textRow)=>{
|
|
textRow.parent = insertedRow.id;
|
|
textsToInsert.push(textRow);
|
|
});
|
|
}
|
|
// If there are numbers, add parent to each
|
|
if (rowToInsert.numbers.length > 0) {
|
|
rowToInsert.numbers.forEach((numberRow)=>{
|
|
numberRow.parent = insertedRow.id;
|
|
numbersToInsert.push(numberRow);
|
|
});
|
|
}
|
|
// If there are selects, add parent to each, and then
|
|
// store by table name and rows
|
|
if (Object.keys(rowToInsert.selects).length > 0) {
|
|
Object.entries(rowToInsert.selects).forEach(([selectTableName, selectRows])=>{
|
|
selectsToInsert[selectTableName] = [];
|
|
selectRows.forEach((row)=>{
|
|
if (typeof row.parent === 'undefined') {
|
|
row.parent = insertedRow.id;
|
|
}
|
|
selectsToInsert[selectTableName].push(row);
|
|
});
|
|
});
|
|
}
|
|
// If there are blocks, add parent to each, and then
|
|
// store by table name and rows
|
|
Object.keys(rowToInsert.blocks).forEach((tableName)=>{
|
|
rowToInsert.blocks[tableName].forEach((blockRow)=>{
|
|
blockRow.row._parentID = insertedRow.id;
|
|
if (!blocksToInsert[tableName]) {
|
|
blocksToInsert[tableName] = [];
|
|
}
|
|
if (blockRow.row.uuid) {
|
|
delete blockRow.row.uuid;
|
|
}
|
|
blocksToInsert[tableName].push(blockRow);
|
|
});
|
|
});
|
|
// //////////////////////////////////
|
|
// INSERT LOCALES
|
|
// //////////////////////////////////
|
|
if (localesToInsert.length > 0) {
|
|
const localeTableName = `${tableName}${adapter.localesSuffix}`;
|
|
const localeTable = adapter.tables[`${tableName}${adapter.localesSuffix}`];
|
|
if (operation === 'update') {
|
|
await adapter.deleteWhere({
|
|
db,
|
|
tableName: localeTableName,
|
|
where: eq(localeTable._parentID, insertedRow.id)
|
|
});
|
|
}
|
|
await adapter.insert({
|
|
db,
|
|
tableName: localeTableName,
|
|
values: localesToInsert
|
|
});
|
|
}
|
|
// //////////////////////////////////
|
|
// INSERT RELATIONSHIPS
|
|
// //////////////////////////////////
|
|
const relationshipsTableName = `${tableName}${adapter.relationshipsSuffix}`;
|
|
if (operation === 'update') {
|
|
// Filter out specific item deletions (those with itemToRemove) from general path deletions
|
|
const generalRelationshipDeletes = rowToInsert.relationshipsToDelete.filter((rel)=>!('itemToRemove' in rel));
|
|
await deleteExistingRowsByPath({
|
|
adapter,
|
|
db,
|
|
localeColumnName: 'locale',
|
|
parentColumnName: 'parent',
|
|
parentID: insertedRow.id,
|
|
pathColumnName: 'path',
|
|
rows: [
|
|
...relationsToInsert,
|
|
...generalRelationshipDeletes
|
|
],
|
|
tableName: relationshipsTableName
|
|
});
|
|
}
|
|
if (relationsToInsert.length > 0) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: relationshipsTableName,
|
|
values: relationsToInsert
|
|
});
|
|
}
|
|
// //////////////////////////////////
|
|
// HANDLE RELATIONSHIP $push OPERATIONS
|
|
// //////////////////////////////////
|
|
if (rowToInsert.relationshipsToAppend.length > 0) {
|
|
// Prepare all relationships for batch insert (order will be set after max query)
|
|
const relationshipsToInsert = rowToInsert.relationshipsToAppend.map((rel)=>{
|
|
const parentId = id || insertedRow.id;
|
|
const row = {
|
|
parent: parentId,
|
|
path: rel.path
|
|
};
|
|
// Only add locale if this relationship table has a locale column
|
|
const relationshipTable = adapter.rawTables[relationshipsTableName];
|
|
if (rel.locale && relationshipTable && relationshipTable.columns.locale) {
|
|
row.locale = rel.locale;
|
|
}
|
|
if (rel.relationTo) {
|
|
// Use camelCase key for Drizzle table (e.g., categoriesID not categories_id)
|
|
row[`${rel.relationTo}ID`] = rel.value;
|
|
}
|
|
return row;
|
|
});
|
|
if (relationshipsToInsert.length > 0) {
|
|
// Check for potential duplicates
|
|
const relationshipTable = adapter.tables[relationshipsTableName];
|
|
if (relationshipTable) {
|
|
// Build conditions only if we have relationships to check
|
|
if (relationshipsToInsert.length === 0) {
|
|
return; // No relationships to insert
|
|
}
|
|
const conditions = relationshipsToInsert.map((row)=>{
|
|
const parts = [
|
|
eq(relationshipTable.parent, row.parent),
|
|
eq(relationshipTable.path, row.path)
|
|
];
|
|
// Add locale condition
|
|
if (row.locale !== undefined && relationshipTable.locale) {
|
|
parts.push(eq(relationshipTable.locale, row.locale));
|
|
} else if (relationshipTable.locale) {
|
|
parts.push(isNull(relationshipTable.locale));
|
|
}
|
|
// Add all relationship ID matches using schema fields
|
|
for (const [key, value] of Object.entries(row)){
|
|
if (key.endsWith('ID') && value != null) {
|
|
const column = relationshipTable[key];
|
|
if (column && typeof column === 'object') {
|
|
parts.push(eq(column, value));
|
|
}
|
|
}
|
|
}
|
|
return and(...parts);
|
|
});
|
|
// Get both existing relationships AND max order in a single query
|
|
let existingRels = [];
|
|
let maxOrder = 0;
|
|
if (conditions.length > 0) {
|
|
// Query for existing relationships
|
|
existingRels = await db.select().from(relationshipTable).where(or(...conditions));
|
|
}
|
|
// Get max order for this parent across all paths in a single query
|
|
const parentId = id || insertedRow.id;
|
|
const maxOrderResult = await db.select({
|
|
maxOrder: relationshipTable.order
|
|
}).from(relationshipTable).where(eq(relationshipTable.parent, parentId)).orderBy(desc(relationshipTable.order)).limit(1);
|
|
if (maxOrderResult.length > 0 && maxOrderResult[0].maxOrder) {
|
|
maxOrder = maxOrderResult[0].maxOrder;
|
|
}
|
|
// Set order values for all relationships based on max order
|
|
relationshipsToInsert.forEach((row, index)=>{
|
|
row.order = maxOrder + index + 1;
|
|
});
|
|
// Filter out relationships that already exist
|
|
const relationshipsToActuallyInsert = relationshipsToInsert.filter((newRow)=>{
|
|
return !existingRels.some((existingRow)=>{
|
|
// Check if this relationship already exists
|
|
let matches = existingRow.parent === newRow.parent && existingRow.path === newRow.path;
|
|
if (newRow.locale !== undefined) {
|
|
matches = matches && existingRow.locale === newRow.locale;
|
|
}
|
|
// Check relationship value matches - convert to camelCase for comparison
|
|
for (const key of Object.keys(newRow)){
|
|
if (key.endsWith('ID')) {
|
|
// Now using camelCase keys
|
|
matches = matches && existingRow[key] === newRow[key];
|
|
}
|
|
}
|
|
return matches;
|
|
});
|
|
});
|
|
// Insert only non-duplicate relationships
|
|
if (relationshipsToActuallyInsert.length > 0) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: relationshipsTableName,
|
|
values: relationshipsToActuallyInsert
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// //////////////////////////////////
|
|
// HANDLE RELATIONSHIP $remove OPERATIONS
|
|
// //////////////////////////////////
|
|
if (rowToInsert.relationshipsToDelete.some((rel)=>'itemToRemove' in rel)) {
|
|
const relationshipTable = adapter.tables[relationshipsTableName];
|
|
if (relationshipTable) {
|
|
for (const relToDelete of rowToInsert.relationshipsToDelete){
|
|
if ('itemToRemove' in relToDelete && relToDelete.itemToRemove) {
|
|
const item = relToDelete.itemToRemove;
|
|
const parentId = id || insertedRow.id;
|
|
const conditions = [
|
|
eq(relationshipTable.parent, parentId),
|
|
eq(relationshipTable.path, relToDelete.path)
|
|
];
|
|
// Add locale condition if this relationship table has a locale column
|
|
if (adapter.rawTables[relationshipsTableName]?.columns.locale) {
|
|
if (relToDelete.locale) {
|
|
conditions.push(eq(relationshipTable.locale, relToDelete.locale));
|
|
} else {
|
|
conditions.push(isNull(relationshipTable.locale));
|
|
}
|
|
}
|
|
// Handle polymorphic vs simple relationships
|
|
if (typeof item === 'object' && 'relationTo' in item) {
|
|
// Polymorphic relationship - convert to camelCase key
|
|
const camelKey = `${item.relationTo}ID`;
|
|
if (relationshipTable[camelKey]) {
|
|
conditions.push(eq(relationshipTable[camelKey], item.value));
|
|
}
|
|
} else if (relToDelete.relationTo) {
|
|
// Simple relationship - convert to camelCase key
|
|
const camelKey = `${relToDelete.relationTo}ID`;
|
|
if (relationshipTable[camelKey]) {
|
|
conditions.push(eq(relationshipTable[camelKey], item));
|
|
}
|
|
}
|
|
// Execute DELETE using Drizzle query builder
|
|
await adapter.deleteWhere({
|
|
db,
|
|
tableName: relationshipsTableName,
|
|
where: and(...conditions)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// //////////////////////////////////
|
|
// INSERT hasMany TEXTS
|
|
// //////////////////////////////////
|
|
const textsTableName = `${tableName}_texts`;
|
|
if (operation === 'update') {
|
|
await deleteExistingRowsByPath({
|
|
adapter,
|
|
db,
|
|
localeColumnName: 'locale',
|
|
parentColumnName: 'parent',
|
|
parentID: insertedRow.id,
|
|
pathColumnName: 'path',
|
|
rows: [
|
|
...textsToInsert,
|
|
...rowToInsert.textsToDelete
|
|
],
|
|
tableName: textsTableName
|
|
});
|
|
}
|
|
if (textsToInsert.length > 0) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: textsTableName,
|
|
values: textsToInsert
|
|
});
|
|
}
|
|
// //////////////////////////////////
|
|
// INSERT hasMany NUMBERS
|
|
// //////////////////////////////////
|
|
const numbersTableName = `${tableName}_numbers`;
|
|
if (operation === 'update') {
|
|
await deleteExistingRowsByPath({
|
|
adapter,
|
|
db,
|
|
localeColumnName: 'locale',
|
|
parentColumnName: 'parent',
|
|
parentID: insertedRow.id,
|
|
pathColumnName: 'path',
|
|
rows: [
|
|
...numbersToInsert,
|
|
...rowToInsert.numbersToDelete
|
|
],
|
|
tableName: numbersTableName
|
|
});
|
|
}
|
|
if (numbersToInsert.length > 0) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: numbersTableName,
|
|
values: numbersToInsert
|
|
});
|
|
}
|
|
// //////////////////////////////////
|
|
// INSERT BLOCKS
|
|
// //////////////////////////////////
|
|
const insertedBlockRows = {};
|
|
if (operation === 'update') {
|
|
for (const tableName of rowToInsert.blocksToDelete){
|
|
const blockTable = adapter.tables[tableName];
|
|
await adapter.deleteWhere({
|
|
db,
|
|
tableName,
|
|
where: eq(blockTable._parentID, insertedRow.id)
|
|
});
|
|
}
|
|
}
|
|
// 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.
|
|
const arraysBlocksUUIDMap = {};
|
|
for (const [tableName, blockRows] of Object.entries(blocksToInsert)){
|
|
insertedBlockRows[tableName] = await adapter.insert({
|
|
db,
|
|
tableName,
|
|
values: blockRows.map(({ row })=>row)
|
|
});
|
|
insertedBlockRows[tableName].forEach((row, i)=>{
|
|
blockRows[i].row = row;
|
|
if (typeof row._uuid === 'string' && (typeof row.id === 'string' || typeof row.id === 'number')) {
|
|
arraysBlocksUUIDMap[row._uuid] = row.id;
|
|
}
|
|
});
|
|
const blockLocaleIndexMap = [];
|
|
const blockLocaleRowsToInsert = blockRows.reduce((acc, blockRow, i)=>{
|
|
if (Object.entries(blockRow.locales).length > 0) {
|
|
Object.entries(blockRow.locales).forEach(([blockLocale, blockLocaleData])=>{
|
|
if (Object.keys(blockLocaleData).length > 0) {
|
|
blockLocaleData._parentID = blockRow.row.id;
|
|
blockLocaleData._locale = blockLocale;
|
|
acc.push(blockLocaleData);
|
|
blockLocaleIndexMap.push(i);
|
|
}
|
|
});
|
|
}
|
|
return acc;
|
|
}, []);
|
|
if (blockLocaleRowsToInsert.length > 0) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: `${tableName}${adapter.localesSuffix}`,
|
|
values: blockLocaleRowsToInsert
|
|
});
|
|
}
|
|
await insertArrays({
|
|
adapter,
|
|
arrays: blockRows.map(({ arrays })=>arrays),
|
|
db,
|
|
parentRows: insertedBlockRows[tableName],
|
|
uuidMap: arraysBlocksUUIDMap
|
|
});
|
|
}
|
|
// //////////////////////////////////
|
|
// INSERT ARRAYS RECURSIVELY
|
|
// //////////////////////////////////
|
|
if (operation === 'update') {
|
|
for (const arrayTableName of Object.keys(rowToInsert.arrays)){
|
|
await deleteExistingArrayRows({
|
|
adapter,
|
|
db,
|
|
parentID: insertedRow.id,
|
|
tableName: arrayTableName
|
|
});
|
|
}
|
|
}
|
|
await insertArrays({
|
|
adapter,
|
|
arrays: [
|
|
rowToInsert.arrays,
|
|
rowToInsert.arraysToPush
|
|
],
|
|
db,
|
|
parentRows: [
|
|
insertedRow,
|
|
insertedRow
|
|
],
|
|
uuidMap: arraysBlocksUUIDMap
|
|
});
|
|
// //////////////////////////////////
|
|
// INSERT hasMany SELECTS
|
|
// //////////////////////////////////
|
|
for (const [selectTableName, tableRows] of Object.entries(selectsToInsert)){
|
|
const selectTable = adapter.tables[selectTableName];
|
|
if (operation === 'update') {
|
|
await adapter.deleteWhere({
|
|
db,
|
|
tableName: selectTableName,
|
|
where: eq(selectTable.parent, insertedRow.id)
|
|
});
|
|
}
|
|
if (Object.keys(arraysBlocksUUIDMap).length > 0) {
|
|
tableRows.forEach((row)=>{
|
|
if (row.parent in arraysBlocksUUIDMap) {
|
|
row.parent = arraysBlocksUUIDMap[row.parent];
|
|
}
|
|
});
|
|
}
|
|
if (tableRows.length) {
|
|
await adapter.insert({
|
|
db,
|
|
tableName: selectTableName,
|
|
values: tableRows
|
|
});
|
|
}
|
|
}
|
|
} catch (error) {
|
|
handleUpsertError({
|
|
id,
|
|
adapter,
|
|
collectionSlug,
|
|
error,
|
|
globalSlug,
|
|
req,
|
|
tableName
|
|
});
|
|
}
|
|
if (ignoreResult === 'idOnly') {
|
|
return {
|
|
id: insertedRow.id
|
|
};
|
|
}
|
|
if (ignoreResult) {
|
|
return data;
|
|
}
|
|
// //////////////////////////////////
|
|
// RETRIEVE NEWLY UPDATED ROW
|
|
// //////////////////////////////////
|
|
const findManyArgs = buildFindManyArgs({
|
|
adapter,
|
|
depth: 0,
|
|
fields,
|
|
joinQuery: false,
|
|
select,
|
|
tableName
|
|
});
|
|
findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id);
|
|
const doc = await db.query[tableName].findFirst(findManyArgs);
|
|
// //////////////////////////////////
|
|
// TRANSFORM DATA
|
|
// //////////////////////////////////
|
|
const result = transform({
|
|
adapter,
|
|
config: adapter.payload.config,
|
|
data: doc,
|
|
fields,
|
|
joinQuery: false,
|
|
tableName
|
|
});
|
|
return result;
|
|
};
|
|
|
|
//# sourceMappingURL=index.js.map |