Skip to content

Commit 0a15388

Browse files
authored
feat(db-postgres): add point field support (#9078)
### What? Adds full support for the point field to Postgres and Vercel Postgres adapters through the Postgis extension. Fully the same API as with MongoDB, including support for `near`, `within` and `intersects` operators. Additionally, exposes to adapter args: * `tablesFilter`https://orm.drizzle.team/docs/drizzle-kit-push#including-tables-schemas-and-extensions. * `extensions` list of extensions to create, for example `['vector', 'pg_search']`, `postgis` is created automatically if there's any point field ### Why? It's essential to support that field type, especially if the postgres adapter should be out of beta on 3.0 stable. ### How? * Bumps `drizzle-orm` to `0.36.1` and `drizzle-kit` to `0.28.0` as we need this change drizzle-team/drizzle-orm#3141 * Uses its functions to achieve querying functionality, for example the `near` operator works through `ST_DWithin` or `intersects` through `ST_Intersects`. * Removes MongoDB condition from all point field tests, but keeps for SQLite Resolves these discussions: #8996 #8644
1 parent a421503 commit 0a15388

Some content is hidden

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

44 files changed

+855
-372
lines changed

.github/workflows/main.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,19 @@ jobs:
208208
AWS_SECRET_ACCESS_KEY: localstack
209209
AWS_REGION: us-east-1
210210

211+
services:
212+
postgres:
213+
image: ${{ (startsWith(matrix.database, 'postgres') ) && 'postgis/postgis:16-3.4' || '' }}
214+
env:
215+
# must specify password for PG Docker container image, see: https://registry.hub.docker.com/_/postgres?tab=description&page=1&name=10
216+
POSTGRES_USER: ${{ env.POSTGRES_USER }}
217+
POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
218+
POSTGRES_DB: ${{ env.POSTGRES_DB }}
219+
ports:
220+
- 5432:5432
221+
# needed because the postgres container does not provide a healthcheck
222+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
223+
211224
steps:
212225
- uses: actions/checkout@v4
213226
with:
@@ -232,15 +245,6 @@ jobs:
232245
- name: Start LocalStack
233246
run: pnpm docker:start
234247

235-
- name: Start PostgreSQL
236-
uses: CasperWA/postgresql-action@v1.2
237-
with:
238-
postgresql version: '14' # See https://hub.docker.com/_/postgres for available versions
239-
postgresql db: ${{ env.POSTGRES_DB }}
240-
postgresql user: ${{ env.POSTGRES_USER }}
241-
postgresql password: ${{ env.POSTGRES_PASSWORD }}
242-
if: startsWith(matrix.database, 'postgres')
243-
244248
- name: Install Supabase CLI
245249
uses: supabase/setup-cli@v1
246250
with:
@@ -253,10 +257,6 @@ jobs:
253257
supabase start
254258
if: matrix.database == 'supabase'
255259

256-
- name: Wait for PostgreSQL
257-
run: sleep 30
258-
if: startsWith(matrix.database, 'postgres')
259-
260260
- name: Configure PostgreSQL
261261
run: |
262262
psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/$POSTGRES_DB" -c "CREATE ROLE runner SUPERUSER LOGIN;"

docs/database/overview.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ You should prefer a relational DB like Postgres or SQLite if:
6767

6868
## Payload Differences
6969

70-
It's important to note that nearly every Payload feature is available in all of our officially supported Database Adapters, including [Localization](../configuration/localization), [Arrays](../fields/array), [Blocks](../fields/blocks), etc. The only thing that is not supported in Postgres yet is the [Point Field](/docs/fields/point), but that should be added soon.
70+
It's important to note that nearly every Payload feature is available in all of our officially supported Database Adapters, including [Localization](../configuration/localization), [Arrays](../fields/array), [Blocks](../fields/blocks), etc. The only thing that is not supported in SQLite yet is the [Point Field](/docs/fields/point), but that should be added soon.
7171

7272
It's up to you to choose which database you would like to use based on the requirements of your project. Payload has no opinion on which database you should ultimately choose.

docs/fields/point.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const MyPointField: Field = {
2828

2929
<Banner type="warning">
3030
<strong>Important:</strong>
31-
The Point Field is currently only supported in MongoDB.
31+
The Point Field currently is not supported in SQLite.
3232
</Banner>
3333

3434
## Config

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@
132132
"create-payload-app": "workspace:*",
133133
"cross-env": "7.0.3",
134134
"dotenv": "16.4.5",
135-
"drizzle-kit": "0.26.2",
136-
"drizzle-orm": "0.35.1",
135+
"drizzle-kit": "0.28.0",
136+
"drizzle-orm": "0.36.1",
137137
"escape-html": "^1.0.3",
138138
"execa": "5.1.1",
139139
"form-data": "3.0.1",

packages/db-mongodb/src/models/buildSchema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ const fieldToSchemaMap: Record<string, FieldSchemaGenerator> = {
353353
type: {
354354
type: String,
355355
enum: ['Point'],
356+
...(typeof field.defaultValue !== 'undefined' && {
357+
default: 'Point',
358+
}),
356359
},
357360
coordinates: {
358361
type: [Number],

packages/db-postgres/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@
5050
"@payloadcms/drizzle": "workspace:*",
5151
"@types/pg": "8.10.2",
5252
"console-table-printer": "2.12.1",
53-
"drizzle-kit": "0.26.2",
54-
"drizzle-orm": "0.35.1",
53+
"drizzle-kit": "0.28.0",
54+
"drizzle-orm": "0.36.1",
5555
"pg": "8.11.3",
5656
"prompts": "2.4.2",
5757
"to-snake-case": "1.0.0",

packages/db-postgres/src/connect.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ export const connect: Connect = async function connect(
100100
process.exit(1)
101101
}
102102

103+
await this.createExtensions()
104+
103105
// Only push schema if not in production
104106
if (
105107
process.env.NODE_ENV !== 'production' &&

packages/db-postgres/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
convertPathToJSONTraversal,
3737
countDistinct,
3838
createDatabase,
39+
createExtensions,
3940
createJSONQuery,
4041
createMigration,
4142
defaultDrizzleSnapshot,
@@ -75,15 +76,22 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
7576
adapterSchema = { enum: pgEnum, table: pgTable }
7677
}
7778

79+
const extensions = (args.extensions ?? []).reduce((acc, name) => {
80+
acc[name] = true
81+
return acc
82+
}, {})
83+
7884
return createDatabaseAdapter<PostgresAdapter>({
7985
name: 'postgres',
8086
afterSchemaInit: args.afterSchemaInit ?? [],
8187
beforeSchemaInit: args.beforeSchemaInit ?? [],
8288
createDatabase,
89+
createExtensions,
8390
defaultDrizzleSnapshot,
8491
disableCreateDatabase: args.disableCreateDatabase ?? false,
8592
drizzle: undefined,
8693
enums: {},
94+
extensions,
8795
features: {
8896
json: true,
8997
},
@@ -106,6 +114,7 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
106114
sessions: {},
107115
tableNameMap: new Map<string, string>(),
108116
tables: {},
117+
tablesFilter: args.tablesFilter,
109118
transactionOptions: args.transactionOptions || undefined,
110119
versionsSuffix: args.versionsSuffix || '_v',
111120

packages/db-postgres/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type Args = {
2929
* @default false
3030
*/
3131
disableCreateDatabase?: boolean
32+
extensions?: string[]
3233
idType?: 'serial' | 'uuid'
3334
localesSuffix?: string
3435
logger?: DrizzleConfig['logger']
@@ -46,6 +47,7 @@ export type Args = {
4647
* @experimental This only works when there are not other tables or enums of the same name in the database under a different schema. Awaiting fix from Drizzle.
4748
*/
4849
schemaName?: string
50+
tablesFilter?: string[]
4951
transactionOptions?: false | PgTransactionConfig
5052
versionsSuffix?: string
5153
}
@@ -60,10 +62,12 @@ declare module 'payload' {
6062
extends Omit<Args, 'idType' | 'logger' | 'migrationDir' | 'pool'>,
6163
DrizzleAdapter {
6264
afterSchemaInit: PostgresSchemaHook[]
65+
6366
beforeSchemaInit: PostgresSchemaHook[]
6467
beginTransaction: (options?: PgTransactionConfig) => Promise<null | number | string>
6568
drizzle: PostgresDB
6669
enums: Record<string, GenericEnum>
70+
extensions: Record<string, boolean>
6771
/**
6872
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
6973
* Used for returning properly formed errors from unique fields
@@ -88,6 +92,7 @@ declare module 'payload' {
8892
schema: Record<string, unknown>
8993
schemaName?: Args['schemaName']
9094
tableNameMap: Map<string, string>
95+
tablesFilter?: string[]
9196
versionsSuffix?: string
9297
}
9398
}

packages/db-sqlite/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
"@libsql/client": "0.14.0",
4949
"@payloadcms/drizzle": "workspace:*",
5050
"console-table-printer": "2.12.1",
51-
"drizzle-kit": "0.26.2",
52-
"drizzle-orm": "0.35.1",
51+
"drizzle-kit": "0.28.0",
52+
"drizzle-orm": "0.36.1",
5353
"prompts": "2.4.2",
5454
"to-snake-case": "1.0.0",
5555
"uuid": "9.0.0"

0 commit comments

Comments
 (0)