@paroicms/server
Version:
The ParoiCMS server
109 lines • 4.47 kB
JavaScript
import { getRegularDocumentTypeByName } from "@paroicms/internal-anywhere-lib";
import { dbAnyLanguage } from "../context.js";
export function applyRegularChildrenSortingOnQuery(siteContext, options) {
const { query, parentDocumentType, leftJoinDocument, orderByAsString } = options;
const orderBy = options.orderBy ??
toOrderByOrManual(options.regularChildrenSorting ?? parentDocumentType.regularChildrenSorting);
if (!orderBy)
return { ordered: false };
const orderPropertiesMap = makeMapOfOrderProperties(siteContext, parentDocumentType.regularChildren);
const orderByQ = orderByAsString ? makeOrderByAsStringQuery() : query;
if (orderBy === "manual") {
query.leftJoin("PaOrderedNode as o", "o.nodeId", "l.id");
orderByQ.orderBy("o.orderNum", "asc").orderBy("l.id", "asc");
}
else {
let index = 0;
for (const { fieldName, direction } of orderBy) {
if (fieldName === "title") {
if (leftJoinDocument) {
query.leftJoin("PaDocument as d", {
"d.nodeId": "s.nodeId",
"d.language": "s.language",
});
}
orderByQ.orderBy("d.title", direction);
}
else if (fieldName === "publishDate") {
orderByQ.orderBy("l.publishDate", 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 = `f${index}.val`;
}
else if (dataType === "number" || dataType === "currency") {
orderByField = `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`]: "s.nodeId",
[`f${index}.language`]: localized
? "s.language"
: siteContext.cn.raw("?", [dbAnyLanguage]),
});
orderByQ.orderByRaw(`${orderByField} ${direction}`);
}
++index;
}
}
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 toOrderByOrManual(regularChildrenSorting) {
if (!regularChildrenSorting)
return;
if (regularChildrenSorting === "manual")
return "manual";
return regularChildrenSorting.map(([fieldName, direction]) => ({ fieldName, direction }));
}
//# sourceMappingURL=child-ordering-query.js.map