querying localized relationship field

This commit is contained in:
Dan Ribbens
2023-09-12 12:29:00 -04:00
parent 61098f96a8
commit 33c15afa79
4 changed files with 45 additions and 27 deletions

View File

@@ -30,6 +30,7 @@ export const find: Find = async function find(
let hasPrevPage: boolean;
let hasNextPage: boolean;
let pagingCounter: number;
let selectDistinctResult;
const {
where,
@@ -74,14 +75,16 @@ export const find: Find = async function find(
}
Object.entries(joins)
.forEach(([joinTable, condition]) => {
selectQuery.leftJoin(this.tables[joinTable.split('.')[0]], condition);
if (joinTable) {
selectQuery.leftJoin(this.tables[joinTable], condition);
}
});
const sql = await selectQuery.toSQL();
const result = await selectQuery
selectDistinctResult = await selectQuery
.offset((page - 1) * limit)
.limit(limit === 0 ? undefined : limit);
if (result.length === 0) {
if (selectDistinctResult.length === 0) {
return {
docs: [],
totalDocs: 0,
@@ -96,11 +99,14 @@ export const find: Find = async function find(
};
}
// set the id in an object for sorting later
result.forEach(({ id }, i) => {
selectDistinctResult.forEach(({ id }, i) => {
orderedIDMap[id as (number | string)] = i;
});
const findWhere = Object.keys(orderedIDMap);
findManyArgs.where = inArray(this.tables[tableName].id, Object.keys(orderedIDMap));
} else {
findManyArgs.limit = limitArg === 0 ? undefined : limitArg;
findManyArgs.offset = (page - 1) * limitArg;
if (where) {
findManyArgs.where = where;
}
@@ -116,17 +122,22 @@ export const find: Find = async function find(
const findPromise = this.db.query[tableName].findMany(findManyArgs);
if (pagination !== false) {
const countResult = await this.db.select({ count: sql<number>`count(*)` })
if (pagination !== false || selectDistinctResult.length > limit) {
const selectCount = this.db.select({ count: sql<number>`count(*)` })
.from(table)
.where(where);
Object.entries(joins)
.forEach(([joinTable, condition]) => {
if (joinTable) {
selectCount.leftJoin(this.tables[joinTable], condition);
}
});
const countResult = await selectCount;
totalDocs = Number(countResult[0].count);
totalPages = typeof limit === 'number' ? Math.ceil(totalDocs / limit) : 1;
hasPrevPage = page > 1;
hasNextPage = totalPages > page;
pagingCounter = ((page - 1) * limit) + 1;
findManyArgs.limit = limitArg === 0 ? undefined : limitArg;
findManyArgs.offset = (page - 1) * limitArg;
}
const rawDocs = await findPromise;

View File

@@ -67,12 +67,11 @@ const buildQuery = async function buildQuery({
tableName,
});
// TODO: add to selectFields
orderBy.column = sortTable[sortTableColumnName];
if (orderBy.column) {
selectFields.sort = orderBy.column;
}
orderBy.column = sortTable[sortTableColumnName];
}
let where: SQL;

View File

@@ -74,6 +74,7 @@ export const getTableColumnFromPath = ({
adapter,
collectionPath,
columnPrefix,
constraints,
fields: field.tabs.map((tab) => ({
...tab,
type: 'tab',
@@ -91,6 +92,7 @@ export const getTableColumnFromPath = ({
adapter,
collectionPath,
columnPrefix: `${columnPrefix}${field.name}_`,
constraints,
fields: field.fields as Field[],
joins,
locale,
@@ -103,6 +105,7 @@ export const getTableColumnFromPath = ({
adapter,
collectionPath,
columnPrefix,
constraints,
fields: field.fields as Field[],
joins,
locale,
@@ -121,6 +124,7 @@ export const getTableColumnFromPath = ({
adapter,
collectionPath,
columnPrefix: `${columnPrefix}${field.name}_`,
constraints,
fields: field.fields as Field[],
joins,
locale,
@@ -143,6 +147,7 @@ export const getTableColumnFromPath = ({
return getTableColumnFromPath({
adapter,
collectionPath,
constraints,
fields: field.fields as Field[],
joins,
locale,
@@ -161,28 +166,35 @@ export const getTableColumnFromPath = ({
case 'upload': {
let relationshipFields;
const relationTableName = `${tableName}_relationships`;
const newCollectionPath = pathSegments.slice(1).join('.');
// Join in the relationships table
joins[relationTableName] = eq(adapter.tables[tableName].id, adapter.tables[relationTableName].parent);
selectFields[`${relationTableName}.path`] = adapter.tables[relationTableName].path;
constraints.push({
columnName: 'path',
table: adapter.tables[relationTableName],
value: field.name,
});
if (typeof field.relationTo === 'string') {
newTableName = `${toSnakeCase(field.relationTo)}`;
// parent to relationship join table
relationshipFields = adapter.payload.collections[field.relationTo].config.fields;
joins[`${newTableName}.${pathSegments.join('.')}`] = eq(adapter.tables[newTableName].id, adapter.tables[`${toSnakeCase(tableName)}_relationships`][`${toSnakeCase(field.relationTo)}ID`]);
joins[newTableName] = eq(adapter.tables[newTableName].id, adapter.tables[`${toSnakeCase(tableName)}_relationships`][`${field.relationTo}ID`]);
} else {
throw new APIError('Not supported');
}
return getTableColumnFromPath({
adapter,
collectionPath: newCollectionPath,
constraints,
fields: relationshipFields,
joins,
locale,
pathSegments: pathSegments.slice(1),
tableName: newTableName,
selectFields,
});
}
@@ -204,8 +216,7 @@ export const getTableColumnFromPath = ({
newTableName = `${tableName}_locales`;
joins[newTableName] = eq(adapter.tables[tableName].id, adapter.tables[newTableName]._parentID);
}
selectFields[`${tableName}.${field.name}`] = adapter.tables[tableName][field.name];
selectFields[`${newTableName}.${field.name}`] = adapter.tables[newTableName][field.name];
return {
columnName: `${columnPrefix}${field.name}`,

View File

@@ -69,7 +69,7 @@ export async function parseParams({
if (typeof pathOperators === 'object') {
for (const operator of Object.keys(pathOperators)) {
if (validOperators.includes(operator as Operator)) {
const { field, table, columnName, constraints } = getTableColumnFromPath({
const { field, table, columnName, constraints: queryConstraints } = getTableColumnFromPath({
adapter,
collectionPath: relationOrPath,
fields,
@@ -86,16 +86,13 @@ export async function parseParams({
val: where[relationOrPath][operator],
});
// if (joinKey && joinConstraints.length > 0) {
// // eslint-disable-next-line no-param-reassign
// joins[joinKey] = and(
// ...joinConstraints,
// operatorMap[operator](table[columnName], queryValue),
// );
// } else {
// nothing was added to joins, did not use constraints
// }
queryConstraints.forEach(({
table: constraintTable,
columnName: col,
value,
}) => {
constraints.push(operatorMap.equals(constraintTable[col], value));
});
constraints.push(operatorMap[operator](table[columnName], queryValue));
}
}