UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

84 lines (67 loc) 2.64 kB
const { DRAFT_COLUMNS_MAP } = require('../constants/draft') const _getStaticOrders = req => { const { target: entity, query } = req const ordersFromKeys = [] if (req.target._isSingleton || query.SELECT.limit) { const keys = [...(entity.keys || [])].filter(k => !k.isAssociation).map(k => k.name) for (const key of keys) { if (!(key in DRAFT_COLUMNS_MAP)) { ordersFromKeys.push({ by: { '=': key }, implicit: true }) } } } if (entity.query && entity.query.SELECT && entity.query.SELECT.orderBy) { const orderBy = entity.query.SELECT.orderBy const ordersFromView = orderBy.map(keyName => ({ by: { '=': keyName.ref[keyName.ref.length - 1] }, desc: keyName.sort === 'desc' })) return [...ordersFromView, ...ordersFromKeys] } return ordersFromKeys } const _addDefaultSortOrder = (req, select) => { // "static orders" = the orders not from the query options let staticOrders = _getStaticOrders(req) // remove defaultOrder if not part of group by const groupBy = select?.groupBy || select?.from?.SELECT?.groupBy if (groupBy?.length > 0) staticOrders = staticOrders.filter(d => groupBy.some(e => e.ref[0] === d.by['='])) if (!staticOrders.length) return if (select?.from?.SELECT?.groupBy?.length > 0) select = select.from.SELECT select.orderBy = select.orderBy ?? [] select.orderBy.push( ...staticOrders .filter(d => !select.orderBy.find(o => o.ref && o.ref.join('_') === d.by['='])) .map(d => { const orderByRef = { ref: [d.by['=']], sort: d.desc ? 'desc' : 'asc' } if (d.implicit) orderByRef.implicit = true return orderByRef }) ) } const containsAggregation = column => { if (column.func) return true if (column.xpr) return column.xpr.some(xpr => containsAggregation(xpr)) return false } /** * 1. query options --> already set in req.query * 2. orders from view * 3. orders from keys if singleton or limit is set * * @param req */ const handle_sorting = function (req) { if (!req.query || !req.query.SELECT || req.query.SELECT.one) return let select = req.query.SELECT // do not sort for /$count queries or queries only using aggregations if (select.columns?.length && select.columns.every(col => containsAggregation(col))) return _addDefaultSortOrder(req, select) // also apply default sort to bottom-most sub-query if (select.from?.SELECT) { while (select.from.SELECT) select = select.from.SELECT _addDefaultSortOrder(req, select) } } module.exports = () => handle_sorting module.exports.commonGenericSorting = handle_sorting // needed in lean draft