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 https://github.com/drizzle-team/drizzle-orm/pull/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: https://github.com/payloadcms/payload/discussions/8996 https://github.com/payloadcms/payload/discussions/8644
This commit is contained in:
@@ -982,88 +982,91 @@ describe('Fields', () => {
|
||||
expect(definitions['version.text']).toEqual(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('point', () => {
|
||||
let doc
|
||||
const point = [7, -7]
|
||||
const localized = [5, -2]
|
||||
const group = { point: [1, 9] }
|
||||
|
||||
beforeEach(async () => {
|
||||
const findDoc = await payload.find({
|
||||
collection: 'point-fields',
|
||||
pagination: false,
|
||||
})
|
||||
;[doc] = findDoc.docs
|
||||
})
|
||||
|
||||
it('should read', async () => {
|
||||
const find = await payload.find({
|
||||
collection: 'point-fields',
|
||||
pagination: false,
|
||||
})
|
||||
|
||||
;[doc] = find.docs
|
||||
|
||||
expect(doc.point).toEqual(pointDoc.point)
|
||||
expect(doc.localized).toEqual(pointDoc.localized)
|
||||
expect(doc.group).toMatchObject(pointDoc.group)
|
||||
})
|
||||
|
||||
it('should create', async () => {
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
})
|
||||
|
||||
expect(doc.point).toEqual(point)
|
||||
expect(doc.localized).toEqual(localized)
|
||||
expect(doc.group).toMatchObject(group)
|
||||
})
|
||||
|
||||
it('should not create duplicate point when unique', async () => {
|
||||
// first create the point field
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
})
|
||||
|
||||
// Now make sure we can't create a duplicate (since 'localized' is a unique field)
|
||||
await expect(() =>
|
||||
payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
}),
|
||||
).rejects.toThrow(Error)
|
||||
|
||||
await expect(async () =>
|
||||
payload.create({
|
||||
collection: 'number-fields',
|
||||
data: {
|
||||
min: 5,
|
||||
},
|
||||
}),
|
||||
).rejects.toThrow('The following field is invalid: min')
|
||||
|
||||
expect(doc.point).toEqual(point)
|
||||
expect(doc.localized).toEqual(localized)
|
||||
expect(doc.group).toMatchObject(group)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
describe('point', () => {
|
||||
let doc
|
||||
const point = [7, -7]
|
||||
const localized = [5, -2]
|
||||
const group = { point: [1, 9] }
|
||||
|
||||
beforeEach(async () => {
|
||||
const findDoc = await payload.find({
|
||||
collection: 'point-fields',
|
||||
pagination: false,
|
||||
})
|
||||
;[doc] = findDoc.docs
|
||||
})
|
||||
|
||||
it('should read', async () => {
|
||||
if (payload.db.name === 'sqlite') {return}
|
||||
const find = await payload.find({
|
||||
collection: 'point-fields',
|
||||
pagination: false,
|
||||
})
|
||||
|
||||
;[doc] = find.docs
|
||||
|
||||
expect(doc.point).toEqual(pointDoc.point)
|
||||
expect(doc.localized).toEqual(pointDoc.localized)
|
||||
expect(doc.group).toMatchObject(pointDoc.group)
|
||||
})
|
||||
|
||||
it('should create', async () => {
|
||||
if (payload.db.name === 'sqlite') {return}
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
})
|
||||
|
||||
expect(doc.point).toEqual(point)
|
||||
expect(doc.localized).toEqual(localized)
|
||||
expect(doc.group).toMatchObject(group)
|
||||
})
|
||||
|
||||
it('should not create duplicate point when unique', async () => {
|
||||
if (payload.db.name === 'sqlite') {return}
|
||||
// first create the point field
|
||||
doc = await payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
})
|
||||
|
||||
// Now make sure we can't create a duplicate (since 'localized' is a unique field)
|
||||
await expect(() =>
|
||||
payload.create({
|
||||
collection: 'point-fields',
|
||||
data: {
|
||||
group,
|
||||
localized,
|
||||
point,
|
||||
},
|
||||
}),
|
||||
).rejects.toThrow(Error)
|
||||
|
||||
await expect(async () =>
|
||||
payload.create({
|
||||
collection: 'number-fields',
|
||||
data: {
|
||||
min: 5,
|
||||
},
|
||||
}),
|
||||
).rejects.toThrow('The following field is invalid: min')
|
||||
|
||||
expect(doc.point).toEqual(point)
|
||||
expect(doc.localized).toEqual(localized)
|
||||
expect(doc.group).toMatchObject(group)
|
||||
})
|
||||
})
|
||||
|
||||
describe('unique indexes', () => {
|
||||
it('should throw validation error saving on unique fields', async () => {
|
||||
const data = {
|
||||
|
||||
Reference in New Issue
Block a user