UNPKG

@cubicweb/rql-generator

Version:

Helpers to build RQL queries

92 lines 4.37 kB
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