( db: Awaited<ReturnType<typeof getDB>>, table: string, record: Record<string, unknown>, pk: string, )
| 403 | } |
| 404 | |
| 405 | async function upsertRecord( |
| 406 | db: Awaited<ReturnType<typeof getDB>>, |
| 407 | table: string, |
| 408 | record: Record<string, unknown>, |
| 409 | pk: string, |
| 410 | ): Promise<void> { |
| 411 | const filteredRecord = await filterRecordToExistingColumns(db, table, record); |
| 412 | const columns = Object.keys(filteredRecord); |
| 413 | if (columns.length === 0 || !columns.includes(pk)) return; |
| 414 | |
| 415 | const values = Object.values(filteredRecord); |
| 416 | const placeholders = columns.map(() => "?").join(", "); |
| 417 | const updateColumns = columns.filter((c) => c !== pk); |
| 418 | const updateSet = updateColumns.map((c) => `${c} = excluded.${c}`).join(", "); |
| 419 | |
| 420 | if (updateColumns.length === 0) { |
| 421 | await db.execute( |
| 422 | `INSERT INTO ${table} (${columns.join(", ")}) |
| 423 | VALUES (${placeholders}) |
| 424 | ON CONFLICT(${pk}) DO NOTHING`, |
| 425 | values, |
| 426 | ); |
| 427 | return; |
| 428 | } |
| 429 | |
| 430 | await db.execute( |
| 431 | `INSERT INTO ${table} (${columns.join(", ")}) |
| 432 | VALUES (${placeholders}) |
| 433 | ON CONFLICT(${pk}) DO UPDATE SET ${updateSet}`, |
| 434 | values, |
| 435 | ); |
| 436 | } |
| 437 | |
| 438 | function normalizeDeletedAt(value: unknown): number | null | undefined { |
| 439 | if (value === undefined) return undefined; |
no test coverage detected