Skip to content

Commit

Permalink
fix(db-postgres): payload.db.upsert inserts new rows instead of upd…
Browse files Browse the repository at this point in the history
…ating existing ones (#9916)

### What?
`payload.db.updateOne` (and so `payload.db.upsert`) with drizzle
adapters used incoming `where` incorrectly and worked properly only
either if you passed `id` or some where query path required table joins
(like `where: { 'array.title'`) which is also the reason why `upsert`
_worked_ with user preferences specifically, because we need to join the
`preferences_rels` table to query by `user.relationTo` and `user.value`

Fixes #9915

This was found here - #9913,
the database KV adapter uses `upsert` with `where` by unique fields.
  • Loading branch information
r1tsuu authored Dec 12, 2024
1 parent d9efd19 commit 5e39634
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/drizzle/src/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import toSnakeCase from 'to-snake-case'

import type { DrizzleAdapter } from './types.js'

import { buildFindManyArgs } from './find/buildFindManyArgs.js'
import buildQuery from './queries/buildQuery.js'
import { selectDistinct } from './queries/selectDistinct.js'
import { upsertRow } from './upsertRow/index.js'
Expand Down Expand Up @@ -38,6 +39,22 @@ export const updateOne: UpdateOne = async function updateOne(

if (selectDistinctResult?.[0]?.id) {
idToUpdate = selectDistinctResult?.[0]?.id

// If id wasn't passed but `where` without any joins, retrieve it with findFirst
} else if (whereArg && !joins.length) {
const findManyArgs = buildFindManyArgs({
adapter: this,
depth: 0,
fields: collection.flattenedFields,
joinQuery: false,
select: {},
tableName,
})

findManyArgs.where = where

const docToUpdate = await db.query[tableName].findFirst(findManyArgs)
idToUpdate = docToUpdate?.id
}

const result = await upsertRow({
Expand Down
33 changes: 33 additions & 0 deletions test/database/int.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1076,4 +1076,37 @@ describe('database', () => {

expect(relationBDocs.docs).toHaveLength(0)
})

it('should upsert', async () => {
const postShouldCreated = await payload.db.upsert({
req: {},
collection: 'posts',
data: {
title: 'some-title-here',
},
where: {
title: {
equals: 'some-title-here',
},
},
})

expect(postShouldCreated).toBeTruthy()

const postShouldUpdated = await payload.db.upsert({
req: {},
collection: 'posts',
data: {
title: 'some-title-here',
},
where: {
title: {
equals: 'some-title-here',
},
},
})

// Should stay the same ID
expect(postShouldCreated.id).toBe(postShouldUpdated.id)
})
})

0 comments on commit 5e39634

Please sign in to comment.