Skip to content

Commit 1347b6c

Browse files
r1tsuuDanRibbensjmikrut
authored
fix(db-postgres): port many various fixes from 3.0 (#8468)
This fixes many various issues that are already fixed in 3.0. Updates Drizzle to match beta to fix some issues #4673 #6845 #6266, prev Drizzle update PR #7460 Ported PRs: - #6158 - #7900 - #7962 (does include duplication fixes for blocks / arrays with specific for 2.0 method) - #8355 - #8456 - #8331 (not in the commits list, as it was a clean merge) - #8369 - #7749 - #8539 --------- Co-authored-by: Dan Ribbens <[email protected]> Co-authored-by: James Mikrut <[email protected]>
1 parent 0a56d50 commit 1347b6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2473
-341
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"copyfiles": "2.4.1",
6969
"cross-env": "7.0.3",
7070
"dotenv": "8.6.0",
71-
"drizzle-orm": "0.29.3",
71+
"drizzle-orm": "0.32.1",
7272
"express": "4.18.2",
7373
"form-data": "3.0.1",
7474
"fs-extra": "10.1.0",

packages/db-postgres/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
"dependencies": {
2727
"@libsql/client": "^0.3.1",
2828
"console-table-printer": "2.11.2",
29-
"drizzle-kit": "0.20.14-1f2c838",
30-
"drizzle-orm": "0.29.3",
29+
"drizzle-kit": "0.23.2-df9e596",
30+
"drizzle-orm": "0.32.1",
3131
"pg": "8.11.3",
3232
"prompts": "2.4.2",
3333
"to-snake-case": "1.0.0",
34-
"uuid": "9.0.0"
34+
"uuid": "10.0.0"
3535
},
3636
"devDependencies": {
3737
"@payloadcms/eslint-config": "workspace:*",

packages/db-postgres/src/connect.ts

+9-74
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import type { Payload } from 'payload'
22
import type { Connect } from 'payload/database'
33

4-
import { eq, sql } from 'drizzle-orm'
4+
import { sql } from 'drizzle-orm'
55
import { drizzle } from 'drizzle-orm/node-postgres'
6-
import { numeric, timestamp, varchar } from 'drizzle-orm/pg-core'
76
import { Pool } from 'pg'
8-
import prompts from 'prompts'
97

108
import type { PostgresAdapter } from './types'
119

10+
import { pushDevSchema } from './utilities/pushDevSchema'
11+
1212
const connectWithReconnect = async function ({
1313
adapter,
1414
payload,
@@ -48,6 +48,7 @@ const connectWithReconnect = async function ({
4848

4949
export const connect: Connect = async function connect(this: PostgresAdapter, payload) {
5050
this.schema = {
51+
pgSchema: this.pgSchema,
5152
...this.tables,
5253
...this.relations,
5354
...this.enums,
@@ -77,76 +78,10 @@ export const connect: Connect = async function connect(this: PostgresAdapter, pa
7778

7879
// Only push schema if not in production
7980
if (
80-
process.env.NODE_ENV === 'production' ||
81-
process.env.PAYLOAD_MIGRATING === 'true' ||
82-
this.push === false
83-
)
84-
return
85-
86-
const { pushSchema } = require('drizzle-kit/payload')
87-
88-
// This will prompt if clarifications are needed for Drizzle to push new schema
89-
const { apply, hasDataLoss, statementsToExecute, warnings } = await pushSchema(
90-
this.schema,
91-
this.drizzle,
92-
)
93-
94-
if (warnings.length) {
95-
let message = `Warnings detected during schema push: \n\n${warnings.join('\n')}\n\n`
96-
97-
if (hasDataLoss) {
98-
message += `DATA LOSS WARNING: Possible data loss detected if schema is pushed.\n\n`
99-
}
100-
101-
message += `Accept warnings and push schema to database?`
102-
103-
const { confirm: acceptWarnings } = await prompts(
104-
{
105-
name: 'confirm',
106-
type: 'confirm',
107-
initial: false,
108-
message,
109-
},
110-
{
111-
onCancel: () => {
112-
process.exit(0)
113-
},
114-
},
115-
)
116-
117-
// Exit if user does not accept warnings.
118-
// Q: Is this the right type of exit for this interaction?
119-
if (!acceptWarnings) {
120-
process.exit(0)
121-
}
122-
}
123-
124-
await apply()
125-
126-
// Migration table def in order to use query using drizzle
127-
const migrationsSchema = this.pgSchema.table('payload_migrations', {
128-
name: varchar('name'),
129-
batch: numeric('batch'),
130-
created_at: timestamp('created_at'),
131-
updated_at: timestamp('updated_at'),
132-
})
133-
134-
const devPush = await this.drizzle
135-
.select()
136-
.from(migrationsSchema)
137-
.where(eq(migrationsSchema.batch, '-1'))
138-
139-
if (!devPush.length) {
140-
await this.drizzle.insert(migrationsSchema).values({
141-
name: 'dev',
142-
batch: '-1',
143-
})
144-
} else {
145-
await this.drizzle
146-
.update(migrationsSchema)
147-
.set({
148-
updated_at: new Date(),
149-
})
150-
.where(eq(migrationsSchema.batch, '-1'))
81+
process.env.NODE_ENV !== 'production' &&
82+
process.env.PAYLOAD_MIGRATING !== 'true' &&
83+
this.push !== false
84+
) {
85+
await pushDevSchema(this)
15186
}
15287
}

packages/db-postgres/src/count.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Count } from 'payload/database'
22
import type { SanitizedCollectionConfig } from 'payload/types'
33

4-
import { sql } from 'drizzle-orm'
4+
import { sql, count as sqlCount } from 'drizzle-orm'
55
import toSnakeCase from 'to-snake-case'
66

77
import type { ChainedMethods } from './find/chainMethods'
@@ -51,8 +51,11 @@ export const count: Count = async function count(
5151
methods: selectCountMethods,
5252
query: db
5353
.select({
54-
count: sql<number>`count
55-
(DISTINCT ${this.tables[tableName].id})`,
54+
count:
55+
selectCountMethods.length > 0
56+
? sql<number>`count
57+
(DISTINCT ${this.tables[tableName].id})`
58+
: sqlCount(),
5659
})
5760
.from(table)
5861
.where(where),

packages/db-postgres/src/createMigration.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable no-restricted-syntax, no-await-in-loop */
2-
import type { DrizzleSnapshotJSON } from 'drizzle-kit/payload'
2+
import type { DrizzleSnapshotJSON } from 'drizzle-kit/api'
33
import type { CreateMigration } from 'payload/database'
44

55
import fs from 'fs'
@@ -43,12 +43,13 @@ const getDefaultDrizzleSnapshot = (): DrizzleSnapshotJSON => ({
4343
schemas: {},
4444
tables: {},
4545
},
46-
dialect: 'pg',
46+
dialect: 'postgresql',
4747
enums: {},
4848
prevId: '00000000-0000-0000-0000-00000000000',
4949
schemas: {},
50+
sequences: {},
5051
tables: {},
51-
version: '5',
52+
version: '7',
5253
})
5354

5455
export const createMigration: CreateMigration = async function createMigration(
@@ -60,7 +61,7 @@ export const createMigration: CreateMigration = async function createMigration(
6061
fs.mkdirSync(dir)
6162
}
6263

63-
const { generateDrizzleJson, generateMigration } = require('drizzle-kit/payload')
64+
const { generateDrizzleJson, generateMigration } = require('drizzle-kit/api')
6465

6566
const [yyymmdd, hhmmss] = new Date().toISOString().split('T')
6667
const formattedDate = yyymmdd.replace(/\D/g, '')
@@ -76,6 +77,12 @@ export const createMigration: CreateMigration = async function createMigration(
7677

7778
let drizzleJsonBefore = getDefaultDrizzleSnapshot()
7879

80+
if (this.schemaName) {
81+
drizzleJsonBefore.schemas = {
82+
[this.schemaName]: this.schemaName,
83+
}
84+
}
85+
7986
// Get latest migration snapshot
8087
const latestSnapshot = fs
8188
.readdirSync(dir)

packages/db-postgres/src/find/findMany.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FindArgs } from 'payload/database'
22
import type { Field, PayloadRequest, TypeWithID } from 'payload/types'
33

4-
import { inArray, sql } from 'drizzle-orm'
4+
import { inArray, sql, count as sqlCount } from 'drizzle-orm'
55

66
import type { PostgresAdapter } from '../types'
77
import type { ChainedMethods } from './chainMethods'
@@ -143,8 +143,11 @@ export const findMany = async function find({
143143
methods: selectCountMethods,
144144
query: db
145145
.select({
146-
count: sql<number>`count
147-
(DISTINCT ${adapter.tables[tableName].id})`,
146+
count:
147+
selectCountMethods.length > 0
148+
? sql<number>`count
149+
(DISTINCT ${adapter.tables[tableName].id})`
150+
: sqlCount(),
148151
})
149152
.from(table)
150153
.where(where),

packages/db-postgres/src/init.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ export const init: Init = async function init(this: PostgresAdapter) {
1414
if (this.schemaName) {
1515
this.pgSchema = pgSchema(this.schemaName)
1616
} else {
17-
this.pgSchema = { table: pgTable }
17+
this.pgSchema = { enum: pgEnum, table: pgTable }
1818
}
1919

2020
if (this.payload.config.localization) {
21-
this.enums.enum__locales = pgEnum(
21+
this.enums.enum__locales = this.pgSchema.enum(
2222
'_locales',
2323
this.payload.config.localization.locales.map(({ code }) => code) as [string, ...string[]],
2424
)

packages/db-postgres/src/migrate.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export async function migrate(this: PostgresAdapter): Promise<void> {
2727
let latestBatch = 0
2828
let migrationsInDB = []
2929

30-
const hasMigrationTable = await migrationTableExists(this.drizzle)
30+
const hasMigrationTable = await migrationTableExists(this)
3131

3232
if (hasMigrationTable) {
3333
;({ docs: migrationsInDB } = await payload.find({
@@ -80,7 +80,7 @@ export async function migrate(this: PostgresAdapter): Promise<void> {
8080
}
8181

8282
async function runMigrationFile(payload: Payload, migration: Migration, batch: number) {
83-
const { generateDrizzleJson } = require('drizzle-kit/payload')
83+
const { generateDrizzleJson } = require('drizzle-kit/api')
8484

8585
const start = Date.now()
8686
const req = { payload } as PayloadRequest

packages/db-postgres/src/migrateDown.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export async function migrateDown(this: PostgresAdapter): Promise<void> {
4747
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
4848
})
4949

50-
const tableExists = await migrationTableExists(this.drizzle)
50+
const tableExists = await migrationTableExists(this)
5151
if (tableExists) {
5252
await payload.delete({
5353
id: migration.id,

packages/db-postgres/src/migrateRefresh.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function migrateRefresh(this: PostgresAdapter) {
5151
msg: `Migrated down: ${migration.name} (${Date.now() - start}ms)`,
5252
})
5353

54-
const tableExists = await migrationTableExists(this.drizzle)
54+
const tableExists = await migrationTableExists(this)
5555
if (tableExists) {
5656
await payload.delete({
5757
collection: 'payload-migrations',

packages/db-postgres/src/migrateReset.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function migrateReset(this: PostgresAdapter): Promise<void> {
4242
msg: `Migrated down: ${migrationFile.name} (${Date.now() - start}ms)`,
4343
})
4444

45-
const tableExists = await migrationTableExists(this.drizzle)
45+
const tableExists = await migrationTableExists(this)
4646
if (tableExists) {
4747
await payload.delete({
4848
id: migration.id,
@@ -68,7 +68,7 @@ export async function migrateReset(this: PostgresAdapter): Promise<void> {
6868

6969
// Delete dev migration
7070

71-
const tableExists = await migrationTableExists(this.drizzle)
71+
const tableExists = await migrationTableExists(this)
7272
if (tableExists) {
7373
try {
7474
await payload.delete({

packages/db-postgres/src/migrateStatus.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export async function migrateStatus(this: PostgresAdapter): Promise<void> {
1414
})
1515

1616
let existingMigrations = []
17-
const hasMigrationTable = await migrationTableExists(this.drizzle)
17+
const hasMigrationTable = await migrationTableExists(this)
1818

1919
if (hasMigrationTable) {
2020
;({ existingMigrations } = await getMigrations({ payload }))

packages/db-postgres/src/queries/parseParams.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { SQL } from 'drizzle-orm'
33
import type { Field, Operator, Where } from 'payload/types'
44

55
import { and, ilike, isNotNull, isNull, ne, notInArray, or, sql } from 'drizzle-orm'
6+
import { PgUUID } from 'drizzle-orm/pg-core'
67
import { QueryError } from 'payload/errors'
78
import { validOperators } from 'payload/types'
89

@@ -174,6 +175,7 @@ export async function parseParams({
174175
const sanitizedQueryValue = sanitizeQueryValue({
175176
adapter,
176177
field,
178+
isUUID: table?.[columnName] instanceof PgUUID,
177179
operator,
178180
relationOrPath,
179181
val,

packages/db-postgres/src/queries/sanitizeQueryValue.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { APIError } from 'payload/errors'
22
import { type Field, type TabAsField, fieldAffectsData } from 'payload/types'
33
import { createArrayFromCommaDelineated } from 'payload/utilities'
4+
import { validate as uuidValidate } from 'uuid'
45

56
import type { PostgresAdapter } from '../types'
67

78
type SanitizeQueryValueArgs = {
89
adapter: PostgresAdapter
910
field: Field | TabAsField
11+
isUUID: boolean
1012
operator: string
1113
relationOrPath: string
1214
val: any
@@ -15,6 +17,7 @@ type SanitizeQueryValueArgs = {
1517
export const sanitizeQueryValue = ({
1618
adapter,
1719
field,
20+
isUUID,
1821
operator: operatorArg,
1922
relationOrPath,
2023
val,
@@ -64,6 +67,16 @@ export const sanitizeQueryValue = ({
6467

6568
if (field.type === 'number' && typeof formattedValue === 'string') {
6669
formattedValue = Number(val)
70+
71+
if (Number.isNaN(formattedValue)) {
72+
formattedValue = null
73+
}
74+
}
75+
76+
if (isUUID && typeof formattedValue === 'string') {
77+
if (!uuidValidate(val)) {
78+
formattedValue = null
79+
}
6780
}
6881

6982
if (field.type === 'date' && operator !== 'exists') {

0 commit comments

Comments
 (0)