Compare commits

...

1 Commits

Author SHA1 Message Date
Sasha
4ffe520165 better test for all 2025-02-21 01:44:26 +02:00
4 changed files with 45 additions and 10 deletions

View File

@@ -18,6 +18,7 @@ import {
} from 'drizzle-orm' } from 'drizzle-orm'
type OperatorKeys = type OperatorKeys =
| 'all'
| 'and' | 'and'
| 'contains' | 'contains'
| 'equals' | 'equals'
@@ -36,6 +37,7 @@ type OperatorKeys =
export type Operators = Record<OperatorKeys, (column: Column, value: SQLWrapper | unknown) => SQL> export type Operators = Record<OperatorKeys, (column: Column, value: SQLWrapper | unknown) => SQL>
export const operatorMap: Operators = { export const operatorMap: Operators = {
all: inArray,
and, and,
contains: ilike, contains: ilike,
equals: eq, equals: eq,
@@ -48,8 +50,6 @@ export const operatorMap: Operators = {
less_than_equal: lte, less_than_equal: lte,
like: ilike, like: ilike,
not_equals: ne, not_equals: ne,
// TODO: support this
// all: all,
not_in: notInArray, not_in: notInArray,
or, or,
} }

View File

@@ -1,7 +1,8 @@
import type { SQL, Table } from 'drizzle-orm' import type { SQL, Table } from 'drizzle-orm'
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
import type { FlattenedField, Operator, Where } from 'payload' import type { FlattenedField, Operator, Where } from 'payload'
import { and, isNotNull, isNull, ne, notInArray, or, sql } from 'drizzle-orm' import { and, count, eq, inArray, isNotNull, isNull, ne, notInArray, or, sql } from 'drizzle-orm'
import { PgUUID } from 'drizzle-orm/pg-core' import { PgUUID } from 'drizzle-orm/pg-core'
import { QueryError } from 'payload' import { QueryError } from 'payload'
import { validOperatorSet } from 'payload/shared' import { validOperatorSet } from 'payload/shared'
@@ -166,7 +167,7 @@ export function parseParams({
let formattedValue = val let formattedValue = val
if (adapter.name === 'sqlite' && operator === 'equals' && !isNaN(val)) { if (adapter.name === 'sqlite' && operator === 'equals' && !isNaN(val)) {
formattedValue = val formattedValue = val
} else if (['in', 'not_in'].includes(operator) && Array.isArray(val)) { } else if (['all', 'in', 'not_in'].includes(operator) && Array.isArray(val)) {
formattedValue = `(${val.map((v) => `${v}`).join(',')})` formattedValue = `(${val.map((v) => `${v}`).join(',')})`
} else { } else {
formattedValue = `'${operatorKeys[operator].wildcard}${val}${operatorKeys[operator].wildcard}'` formattedValue = `'${operatorKeys[operator].wildcard}${val}${operatorKeys[operator].wildcard}'`
@@ -355,6 +356,24 @@ export function parseParams({
break break
} }
if (operator === 'all' && Array.isArray(queryValue)) {
const db = adapter.drizzle as LibSQLDatabase
constraints.push(
eq(
sql`${db
.select({
count: count(),
})
.from(table)
.where(inArray(resolvedColumn, queryValue))}`,
queryValue.length,
),
)
break
}
constraints.push(adapter.operators[queryOperator](resolvedColumn, queryValue)) constraints.push(adapter.operators[queryOperator](resolvedColumn, queryValue))
} }
} }

View File

@@ -26,6 +26,7 @@ export const allDatabaseAdapters = {
pool: { pool: {
connectionString: process.env.POSTGRES_URL || 'postgres://127.0.0.1:5432/payloadtests', connectionString: process.env.POSTGRES_URL || 'postgres://127.0.0.1:5432/payloadtests',
}, },
logger: true
})`, })`,
'postgres-custom-schema': ` 'postgres-custom-schema': `
import { postgresAdapter } from '@payloadcms/db-postgres' import { postgresAdapter } from '@payloadcms/db-postgres'

View File

@@ -552,7 +552,7 @@ describe('Relationships', () => {
}) })
// all operator is not supported in Postgres yet for any fields // all operator is not supported in Postgres yet for any fields
mongoIt('should query using "all" by hasMany relationship field', async () => { it('should query using "all" by hasMany relationship field', async () => {
const movie1 = await payload.create({ const movie1 = await payload.create({
collection: 'movies', collection: 'movies',
data: {}, data: {},
@@ -562,7 +562,7 @@ describe('Relationships', () => {
data: {}, data: {},
}) })
await payload.create({ const director1 = await payload.create({
collection: 'directors', collection: 'directors',
data: { data: {
name: 'Quentin Tarantino', name: 'Quentin Tarantino',
@@ -570,10 +570,10 @@ describe('Relationships', () => {
}, },
}) })
await payload.create({ const director2 = await payload.create({
collection: 'directors', collection: 'directors',
data: { data: {
name: 'Quentin Tarantino', name: 'Quentin Tarantino Junior',
movies: [movie2.id], movies: [movie2.id],
}, },
}) })
@@ -583,13 +583,28 @@ describe('Relationships', () => {
depth: 0, depth: 0,
where: { where: {
movies: { movies: {
all: [movie1.id], in: [movie1.id],
}, },
}, },
}) })
// eslint-disable-next-line jest/no-standalone-expect // process.exit(0)
expect(query1.totalDocs).toStrictEqual(1) expect(query1.totalDocs).toStrictEqual(1)
expect(query1.docs[0].id).toBe(director1.id)
const query2 = await payload.find({
collection: 'directors',
depth: 0,
where: {
movies: {
all: [movie1.id, movie2.id],
},
},
})
expect(query2.totalDocs).toStrictEqual(1)
expect(query2.docs[0].id).toBe(director1.id)
}) })
it('should sort by a property of a hasMany relationship', async () => { it('should sort by a property of a hasMany relationship', async () => {