|
1 | 1 | import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
2 |
| -import type { UpdateOne } from 'payload' |
| 2 | +import type { FlattenedField, UpdateOne } from 'payload' |
3 | 3 |
|
| 4 | +import { eq } from 'drizzle-orm' |
4 | 5 | import toSnakeCase from 'to-snake-case'
|
5 | 6 |
|
6 | 7 | import type { DrizzleAdapter } from './types.js'
|
7 | 8 |
|
| 9 | +import { buildFindManyArgs } from './find/buildFindManyArgs.js' |
8 | 10 | import { buildQuery } from './queries/buildQuery.js'
|
9 | 11 | import { selectDistinct } from './queries/selectDistinct.js'
|
| 12 | +import { transform } from './transform/read/index.js' |
| 13 | +import { transformForWrite } from './transform/write/index.js' |
10 | 14 | import { upsertRow } from './upsertRow/index.js'
|
11 | 15 | import { getTransaction } from './utilities/getTransaction.js'
|
12 | 16 |
|
| 17 | +/** |
| 18 | + * Checks whether we should use the upsertRow function for the passed data and otherwise use a simple SQL SET call. |
| 19 | + * We need to use upsertRow only when the data has arrays, blocks, hasMany select/text/number, localized fields, complex relationships. |
| 20 | + */ |
| 21 | +const shouldUseUpsertRow = ({ |
| 22 | + data, |
| 23 | + fields, |
| 24 | +}: { |
| 25 | + data: Record<string, unknown> |
| 26 | + fields: FlattenedField[] |
| 27 | +}) => { |
| 28 | + for (const key in data) { |
| 29 | + const value = data[key] |
| 30 | + const field = fields.find((each) => each.name === key) |
| 31 | + |
| 32 | + if (!field) { |
| 33 | + continue |
| 34 | + } |
| 35 | + |
| 36 | + if ( |
| 37 | + field.type === 'array' || |
| 38 | + field.type === 'blocks' || |
| 39 | + ((field.type === 'text' || |
| 40 | + field.type === 'relationship' || |
| 41 | + field.type === 'upload' || |
| 42 | + field.type === 'select' || |
| 43 | + field.type === 'number') && |
| 44 | + field.hasMany) || |
| 45 | + ((field.type === 'relationship' || field.type === 'upload') && |
| 46 | + Array.isArray(field.relationTo)) || |
| 47 | + field.localized |
| 48 | + ) { |
| 49 | + return true |
| 50 | + } |
| 51 | + |
| 52 | + if ( |
| 53 | + (field.type === 'group' || field.type === 'tab') && |
| 54 | + value && |
| 55 | + typeof value === 'object' && |
| 56 | + shouldUseUpsertRow({ data: value as Record<string, unknown>, fields: field.flattenedFields }) |
| 57 | + ) { |
| 58 | + return true |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + return false |
| 63 | +} |
| 64 | + |
13 | 65 | export const updateOne: UpdateOne = async function updateOne(
|
14 | 66 | this: DrizzleAdapter,
|
15 | 67 | {
|
@@ -74,23 +126,71 @@ export const updateOne: UpdateOne = async function updateOne(
|
74 | 126 | return null
|
75 | 127 | }
|
76 | 128 |
|
77 |
| - const result = await upsertRow({ |
78 |
| - id: idToUpdate, |
| 129 | + if (!idToUpdate || shouldUseUpsertRow({ data, fields: collection.flattenedFields })) { |
| 130 | + const result = await upsertRow({ |
| 131 | + id: idToUpdate, |
| 132 | + adapter: this, |
| 133 | + data, |
| 134 | + db, |
| 135 | + fields: collection.flattenedFields, |
| 136 | + ignoreResult: returning === false, |
| 137 | + joinQuery, |
| 138 | + operation: 'update', |
| 139 | + req, |
| 140 | + select, |
| 141 | + tableName, |
| 142 | + }) |
| 143 | + |
| 144 | + if (returning === false) { |
| 145 | + return null |
| 146 | + } |
| 147 | + |
| 148 | + return result |
| 149 | + } |
| 150 | + |
| 151 | + const { row } = transformForWrite({ |
79 | 152 | adapter: this,
|
80 | 153 | data,
|
81 |
| - db, |
82 | 154 | fields: collection.flattenedFields,
|
83 |
| - ignoreResult: returning === false, |
84 |
| - joinQuery, |
85 |
| - operation: 'update', |
86 |
| - req, |
87 |
| - select, |
88 | 155 | tableName,
|
89 | 156 | })
|
90 | 157 |
|
| 158 | + const drizzle = db as LibSQLDatabase |
| 159 | + await drizzle |
| 160 | + .update(this.tables[tableName]) |
| 161 | + .set(row) |
| 162 | + // TODO: we can skip fetching idToUpdate here with using the incoming where |
| 163 | + .where(eq(this.tables[tableName].id, idToUpdate)) |
| 164 | + |
91 | 165 | if (returning === false) {
|
92 | 166 | return null
|
93 | 167 | }
|
94 | 168 |
|
| 169 | + const findManyArgs = buildFindManyArgs({ |
| 170 | + adapter: this, |
| 171 | + depth: 0, |
| 172 | + fields: collection.flattenedFields, |
| 173 | + joinQuery: false, |
| 174 | + select, |
| 175 | + tableName, |
| 176 | + }) |
| 177 | + |
| 178 | + findManyArgs.where = eq(this.tables[tableName].id, idToUpdate) |
| 179 | + |
| 180 | + const doc = await db.query[tableName].findFirst(findManyArgs) |
| 181 | + |
| 182 | + // ////////////////////////////////// |
| 183 | + // TRANSFORM DATA |
| 184 | + // ////////////////////////////////// |
| 185 | + |
| 186 | + const result = transform({ |
| 187 | + adapter: this, |
| 188 | + config: this.payload.config, |
| 189 | + data: doc, |
| 190 | + fields: collection.flattenedFields, |
| 191 | + joinQuery: false, |
| 192 | + tableName, |
| 193 | + }) |
| 194 | + |
95 | 195 | return result
|
96 | 196 | }
|
0 commit comments