UNPKG

@paroicms/server

Version:
117 lines 4.89 kB
import { getRegularDocumentTypeByName } from "@paroicms/internal-anywhere-lib"; import { dbAnyLanguage } from "../context.js"; export function applyRegularChildrenSortingOnQuery(siteContext, options) { const { query, parentDocumentType, leftJoinDocument, orderByAsString, useAggregates } = options; const sorting = options.sorting ?? options.regularChildrenSorting ?? parentDocumentType.regularChildrenSorting; if (!sorting) return { ordered: false }; const orderPropertiesMap = makeMapOfOrderProperties(siteContext, parentDocumentType.regularChildren); const orderByQ = orderByAsString ? makeOrderByAsStringQuery() : query; if (sorting === "manual") { query.leftJoin("PaOrderedNode as o", "o.nodeId", "n.id"); orderByQ.orderBy("o.orderNum", "asc"); } else { let index = 0; for (const { fieldName, direction } of sorting) { if (fieldName === "title") { if (leftJoinDocument) { query.leftJoin("PaDocument as d", { "d.nodeId": "l.nodeId", "d.language": "l.language", }); } const orderByField = useAggregates ? "max(d.title)" : "d.title"; orderByQ.orderByRaw(`${orderByField} ${direction}`); } else if (fieldName === "publishDate") { orderByQ.orderBy("n.publishDate", direction); } else if (fieldName === "updatedAt") { const orderByField = useAggregates ? "max(l.updatedAt)" : "l.updatedAt"; orderByQ.orderByRaw(`${orderByField} ${direction}`); } else { const orderProperties = orderPropertiesMap.get(fieldName); if (!orderProperties) throw new Error(`unknown field '${fieldName}'`); const { dataType, localized } = orderProperties; let orderByField; if (dataType === "string" || dataType === "boolean") { orderByField = useAggregates ? `max(f${index}.val)` : `f${index}.val`; } else if (dataType === "number" || dataType === "currency") { orderByField = useAggregates ? `max(cast(f${index}.val as float))` : `cast(f${index}.val as float)`; } else { throw new Error(`invalid data type '${dataType}'`); } query.leftJoin(`PaFieldVarchar as f${index}`, { [`f${index}.field`]: siteContext.cn.raw("?", [fieldName]), [`f${index}.nodeId`]: "l.nodeId", [`f${index}.language`]: localized ? "l.language" : siteContext.cn.raw("?", [dbAnyLanguage]), }); orderByQ.orderByRaw(`${orderByField} ${direction}`); } ++index; } } orderByQ.orderBy("n.id", getDefaultIdDirection(sorting)); return { ordered: true, orderBy: orderByAsString ? orderByQ.getAsString() : undefined, }; } function makeMapOfOrderProperties(siteContext, children) { const orderProperties = new Map(); for (const child of children ?? []) { const documentType = getRegularDocumentTypeByName(siteContext.siteSchema, child); for (const field of documentType.fields ?? []) { if (field.storedAs !== "varchar") continue; const prev = orderProperties.get(field.name); if (prev) { if (prev.dataType !== field.dataType) { throw new Error(`Cannot order on '${field.name}': inconsistent data types '${prev.dataType}' and '${field.dataType}'`); } if (prev.localized !== field.localized) { throw new Error(`Cannot order on '${field.name}': inconsistent localized`); } } else { orderProperties.set(field.name, { dataType: field.dataType, localized: field.localized }); } } } return orderProperties; } function makeOrderByAsStringQuery() { const arr = []; const query = { orderBy(column, direction) { arr.push(`${column} ${direction}`); return query; }, orderByRaw(raw) { arr.push(raw); return query; }, getAsString() { return arr.join(", "); }, }; return query; } function getDefaultIdDirection(sorting) { if (sorting === "manual") return "asc"; if (sorting.length === 0) return "asc"; const first = sorting[0]; return first.direction; } //# sourceMappingURL=child-ordering-query.js.map