@cubicweb/rql-generator
Version:
Helpers to build RQL queries
92 lines • 4.37 kB
JavaScript
import { RQLQuery, } from "@cubicweb/client";
import { filterToRQLQueryRestrictions } from "./utils/filter.js";
import { getGroupByClause, getRelationVariable, getRestrictionsClause, getSelectionClause, getRelationsSchemata, } from "./utils/rql.js";
import { getEntitySchema } from "./utils/schema.js";
/**
* Generates a SELECT RQL query to fetch a list of entities with the given attributes.
*
* @example
* For a BlogEntry entity with the attributes `title`, `content` and relation `entry_of`.
* Requesting the first 10 elements, sorted by ascending `title`.
* ```typescript
* generateSelectEntitiesRQL(
* SCHEMA,
* "BlogEntry",
* {
* limit: 10,
* offset: 0,
* orderBy: [{relationName: "title", ascending: true}],
* resolve: ["title", "content", "entry_of"],
* }
* )
* ```
* produces:
* ```
* Any X, ATTR_TITLE, ATTR_CONTENT, GROUP_CONCAT(REL_ENTRY_OF) GROUPBY X, ATTR_TITLE, ATTR_CONTENT ORDERBY ATTR_TITLE ASC LIMIT 10 OFFSET 0 WHERE X is BlogEntry, X title ATTR_TITLE, X content ATTR_CONTENT, X entry_of REL_ENTRY_OF
* ```
*
* @param schema This CW instance's schema
* @param entityType The type of entity to fetch
* @param rqlQueryListOptions Options to build the RQL query
* @returns An array of RQL queries to fetch entities with the given attributes/relations. The produced {@link ResultSet} contains values for the resolved attributes/relations in the same order as the passed `resolve` option.
*
* @category Getting entities
*/
export function generateSelectEntitiesRQL(schema, entityType, { limit, offset, orderBy, where, relations }) {
const entitySchema = getEntitySchema(schema, entityType);
const filterRql = filterToRQLQueryRestrictions(where, entitySchema);
const { attributes, subjectRelations, objectRelations } = getRelationsSchemata(entitySchema, relations);
const selection = getSelectionClause(attributes, subjectRelations, objectRelations);
const restrictions = getRestrictionsClause(attributes, subjectRelations, objectRelations);
const groupBy = getGroupByClause(attributes, subjectRelations, objectRelations);
const orderByParts = orderBy
? orderBy.map((ob) => {
const rqlVariable = getRelationVariable(ob.relationName, attributes, subjectRelations, objectRelations);
let order = "";
if (ob.ascending) {
order = " ASC";
}
else if (ob.ascending === false // if undefined, order should be ""
) {
order = " DESC";
}
const nullsPolicy = ob.nulls ? ` ${ob.nulls.toUpperCase()}` : "";
return `${rqlVariable}${order}${nullsPolicy}`;
})
: [];
const filters = filterRql.rql !== "" ? `, ${filterRql.rql}` : "";
const restrictionClause = restrictions !== "" ? `, ${restrictions}` : "";
const limitStr = limit !== undefined ? ` LIMIT ${limit}` : "";
const offsetStr = offset !== undefined ? ` OFFSET ${offset}` : "";
const orderByStr = orderByParts.length > 0 ? ` ORDERBY ${orderByParts.join(", ")}` : "";
const requestStr = `Any ${selection} ${groupBy}${orderByStr}${limitStr}${offsetStr} WHERE X is ${entityType}${restrictionClause}${filters}`;
return [new RQLQuery(requestStr, { ...filterRql.params })];
}
/**
* Generates a RQL query to count the number of entities respecting the given filter.
*
* @example
* Counting the number of BlogEntry in a given Blog:
* ```typescript
* generateCountEntitiesRQL(SCHEMA, "BlogEntry", {where: {entry_of: 12498}})
* ```
* produces:
* ```
* Any Count(X) WHERE X is BlogEntry, X entry_of %(entry_of)s
* ```
*
* @param schema This CW instance's schema
* @param entityType The type of entity to count
* @param where A custom filter
* @returns An array of RQL queries to count the number of entities respecting the given filter
*
* @category Getting entities
*/
export function generateCountEntitiesRQL(schema, entityType, { where }) {
const entitySchema = getEntitySchema(schema, entityType);
const filterRql = filterToRQLQueryRestrictions(where, entitySchema);
const filters = filterRql.rql !== "" ? `, ${filterRql.rql}` : "";
const requestStr = `Any Count(X) WHERE X is ${entityType}${filters}`;
return [new RQLQuery(requestStr, { ...filterRql.params })];
}
//# sourceMappingURL=get.js.map