From 2e086d95d97c8bfb42dd189ca277f79d8e4c0837 Mon Sep 17 00:00:00 2001 From: Dan Ribbens Date: Wed, 6 Sep 2023 16:25:52 -0400 Subject: [PATCH] chore: working simple where --- packages/db-postgres/src/find.ts | 16 +++-- .../src/queries/buildAndOrConditions.ts | 7 +-- .../db-postgres/src/queries/buildQuery.ts | 16 ++--- .../src/queries/getTableColumnFromPath.ts | 63 +++++++++---------- .../db-postgres/src/queries/parseParams.ts | 35 +++++------ src/collections/operations/find.ts | 2 +- test/postgres/int.spec.ts | 13 +++- 7 files changed, 76 insertions(+), 76 deletions(-) diff --git a/packages/db-postgres/src/find.ts b/packages/db-postgres/src/find.ts index 083bf16e33..343ac77f60 100644 --- a/packages/db-postgres/src/find.ts +++ b/packages/db-postgres/src/find.ts @@ -55,8 +55,10 @@ export const find: Find = async function find( // initial query const selectQuery = this.db.selectDistinct(selectFields) - .from(table) - .orderBy(orderBy.order(orderBy.column)); + .from(table); + if (orderBy.order && orderBy.column) { + selectQuery.orderBy(orderBy.order(orderBy.column)); + } const findManyArgs = buildFindManyArgs({ adapter: this, @@ -85,10 +87,12 @@ export const find: Find = async function find( } else { findManyArgs.where = where; // orderBy will only be set if a complex sort is needed on a relation - if (sort[0] === '-') { - findManyArgs.orderBy = desc(this.tables[tableName][sort.substring(1)]); - } else { - findManyArgs.orderBy = asc(this.tables[tableName][sort]); + if (sort) { + if (sort[0] === '-') { + findManyArgs.orderBy = desc(this.tables[tableName][sort.substring(1)]); + } else { + findManyArgs.orderBy = asc(this.tables[tableName][sort]); + } } } diff --git a/packages/db-postgres/src/queries/buildAndOrConditions.ts b/packages/db-postgres/src/queries/buildAndOrConditions.ts index 61486d91ce..b19de75960 100644 --- a/packages/db-postgres/src/queries/buildAndOrConditions.ts +++ b/packages/db-postgres/src/queries/buildAndOrConditions.ts @@ -8,11 +8,10 @@ import { BuildQueryJoins } from './buildQuery'; export async function buildAndOrConditions({ joins, where, - collectionSlug, - globalSlug, adapter, locale, fields, + tableName, }: { joins: BuildQueryJoins, where: Where[], @@ -21,6 +20,7 @@ export async function buildAndOrConditions({ adapter: PostgresAdapter locale?: string, fields: Field[], + tableName: string, }): Promise { const completedConditions = []; // Loop over all AND / OR operations and add them to the AND / OR query param @@ -33,11 +33,10 @@ export async function buildAndOrConditions({ const result = await parseParams({ joins, where: condition, - collectionSlug, - globalSlug, adapter, locale, fields, + tableName, }); if (Object.keys(result).length > 0) { completedConditions.push(result); diff --git a/packages/db-postgres/src/queries/buildQuery.ts b/packages/db-postgres/src/queries/buildQuery.ts index 6a223ecea5..fe673e377c 100644 --- a/packages/db-postgres/src/queries/buildQuery.ts +++ b/packages/db-postgres/src/queries/buildQuery.ts @@ -49,7 +49,10 @@ const buildQuery = async function buildQuery({ orderBy.order = asc; } - const tableColumns = getTableColumnFromPath({ + const { + table: sortTable, + columnName: sortTableColumnName, + } = getTableColumnFromPath({ adapter, collectionPath: sortPath, fields, @@ -59,13 +62,6 @@ const buildQuery = async function buildQuery({ tableName, }); - const lastTableColumn = tableColumns[tableColumns.length - 1]; - const { - table: sortTable, - columnName: sortTableColumnName, - } = lastTableColumn; - // } = tableColumns[tableColumns.length - 1]; - orderBy.column = sortTable[sortTableColumnName]; } @@ -74,12 +70,10 @@ const buildQuery = async function buildQuery({ if (Object.keys(incomingWhere).length > 0) { where = await parseParams({ adapter, - collectionSlug: '', - columnPrefix: '', - globalSlug: '', fields, joins, locale, + tableName, where: incomingWhere, }); } diff --git a/packages/db-postgres/src/queries/getTableColumnFromPath.ts b/packages/db-postgres/src/queries/getTableColumnFromPath.ts index 9dbad0ba90..0d32364cec 100644 --- a/packages/db-postgres/src/queries/getTableColumnFromPath.ts +++ b/packages/db-postgres/src/queries/getTableColumnFromPath.ts @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign */ -import { Field, fieldAffectsData, TabAsField, tabHasName } from 'payload/dist/fields/config/types'; +import { Field, FieldAffectingData, fieldAffectsData, TabAsField, tabHasName } from 'payload/dist/fields/config/types'; import toSnakeCase from 'to-snake-case'; import { and, eq } from 'drizzle-orm'; import { APIError } from 'payload/errors'; @@ -11,6 +11,7 @@ type TableColumn = { table: GenericTable columnName: string collectionPath: string + field: FieldAffectingData } type Args = { @@ -22,7 +23,6 @@ type Args = { locale?: string pathSegments: string[] tableName: string - tableColumns?: TableColumn[] } /** * Transforms path to table and column name @@ -38,8 +38,7 @@ export const getTableColumnFromPath = ({ locale, pathSegments, tableName, - tableColumns = [], -}: Args): TableColumn[] => { +}: Args): TableColumn => { const fieldPath = pathSegments[0]; const field = flattenFields(fields as Field[]) .find((fieldToFind) => fieldAffectsData(fieldToFind) && fieldToFind.name === fieldPath) as Field | TabAsField; @@ -48,7 +47,7 @@ export const getTableColumnFromPath = ({ if (field) { switch (field.type) { case 'tabs': { - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath, columnPrefix, @@ -60,13 +59,11 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - tableColumns, - })); - break; + }); } case 'tab': { if (tabHasName(field)) { - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath, columnPrefix: `${columnPrefix}${field.name}_`, @@ -75,9 +72,9 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - })); + }); } - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath, columnPrefix, @@ -86,8 +83,7 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - })); - break; + }); } case 'group': { @@ -95,7 +91,7 @@ export const getTableColumnFromPath = ({ newTableName = `${tableName}_locales`; joins[tableName] = eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID); } - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath, columnPrefix: `${columnPrefix}${field.name}_`, @@ -104,8 +100,7 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - })); - break; + }); } case 'array': { @@ -118,7 +113,7 @@ export const getTableColumnFromPath = ({ } else { joins[newTableName] = eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID); } - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath, fields: field.fields as Field[], @@ -126,8 +121,7 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - })); - break; + }); } case 'blocks': { @@ -152,7 +146,7 @@ export const getTableColumnFromPath = ({ } else { throw new APIError('Not supported'); } - tableColumns = tableColumns.concat(getTableColumnFromPath({ + return getTableColumnFromPath({ adapter, collectionPath: pathSegments.slice(1) .join('.'), @@ -161,8 +155,7 @@ export const getTableColumnFromPath = ({ locale, pathSegments: pathSegments.slice(1), tableName: newTableName, - })); - break; + }); } default: { @@ -178,21 +171,23 @@ export const getTableColumnFromPath = ({ // case 'richText': // case 'select': // case 'point': - if (locale && fieldAffectsData(field) && field.localized && adapter.payload.config.localization) { - newTableName = `${tableName}_locales`; - joins[newTableName] = and( - eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID), - eq(adapter.tables[newTableName]._locale, locale), - ); + if (fieldAffectsData(field)) { + if (locale && field.localized && adapter.payload.config.localization) { + newTableName = `${tableName}_locales`; + joins[newTableName] = and( + eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID), + eq(adapter.tables[newTableName]._locale, locale), + ); + } + return { + collectionPath, + field, + table: adapter.tables[newTableName], + columnName: `${columnPrefix}${field.name}`, + }; } - tableColumns.push({ - collectionPath, - table: adapter.tables[newTableName], - columnName: `${columnPrefix}${fieldAffectsData(field) ? field.name : pathSegments[0]}`, - }); } } - return tableColumns; } throw new APIError(`Cannot find field for path at ${fieldPath}`); diff --git a/packages/db-postgres/src/queries/parseParams.ts b/packages/db-postgres/src/queries/parseParams.ts index 152a412c2c..3e9b6da756 100644 --- a/packages/db-postgres/src/queries/parseParams.ts +++ b/packages/db-postgres/src/queries/parseParams.ts @@ -4,33 +4,30 @@ import { Operator, Where } from 'payload/types'; import { Field } from 'payload/dist/fields/config/types'; import { validOperators } from 'payload/dist/types/constants'; import { and, SQL } from 'drizzle-orm'; -import { buildSearchParam } from './buildSearchParams'; import { buildAndOrConditions } from './buildAndOrConditions'; import { PostgresAdapter } from '../types'; import { operatorMap } from './operatorMap'; import { BuildQueryJoins } from './buildQuery'; +import { getTableColumnFromPath } from './getTableColumnFromPath'; type Args = { joins: BuildQueryJoins where: Where - collectionSlug?: string - globalSlug?: string adapter: PostgresAdapter locale: string + tableName: string, fields: Field[] - columnPrefix: string } export async function parseParams({ joins, where, - collectionSlug, - globalSlug, adapter, locale, fields, - columnPrefix, + tableName, }: Args): Promise { let result: SQL; + const constraints: SQL[] = []; if (typeof where === 'object') { // We need to determine if the whereKey is an AND, OR, or a schema path @@ -45,11 +42,10 @@ export async function parseParams({ if (Array.isArray(condition)) { const builtConditions = await buildAndOrConditions({ joins, - collectionSlug, fields, - globalSlug, adapter, locale, + tableName, where: condition, }); if (builtConditions.length > 0) result = operatorMap[conditionOperator](result, ...builtConditions); @@ -61,23 +57,26 @@ export async function parseParams({ if (typeof pathOperators === 'object') { for (const operator of Object.keys(pathOperators)) { if (validOperators.includes(operator as Operator)) { - result = and(await buildSearchParam({ - joins, - collectionSlug, - globalSlug, + const tableColumn = getTableColumnFromPath({ adapter, - locale, + collectionPath: relationOrPath, fields, - incomingPath: relationOrPath, - val: pathOperators[operator], - operator, - })); + joins, + locale, + pathSegments: relationOrPath.split('.'), + tableName, + }); + constraints.push(operatorMap[operator](tableColumn.table[tableColumn.columnName], where[relationOrPath][operator])); } } } } } } + if (constraints.length > 0) { + result = and(result, ...constraints); + } + return result; } diff --git a/src/collections/operations/find.ts b/src/collections/operations/find.ts index 5b52f9710a..d6d7c351f5 100644 --- a/src/collections/operations/find.ts +++ b/src/collections/operations/find.ts @@ -160,7 +160,7 @@ async function find>( where: fullWhere, page: sanitizedPage, limit: sanitizedLimit, - sort: sort.replace(/__/gi, '.'), + sort: sort ? sort.replace(/__/gi, '.') : undefined, locale, pagination, req, diff --git a/test/postgres/int.spec.ts b/test/postgres/int.spec.ts index c459d0701b..b65e9d9fab 100644 --- a/test/postgres/int.spec.ts +++ b/test/postgres/int.spec.ts @@ -415,8 +415,17 @@ describe('Postgres', () => { collection: 'posts', sort: '-slug', }); - expect(pages[0].fullName).toEqual('second'); - expect(pages[1].fullName).toEqual('first'); + expect(pages[0].tableName).toEqual('second'); + expect(pages[1].tableName).toEqual('first'); + }); + it('find where', async () => { + const { docs: people } = await payload.find({ + collection: 'people', + where: { + fullName: { equals: 'Dan Ribbens' }, + }, + }); + expect(people).toHaveLength(1); }); });