UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

89 lines (88 loc) 2.91 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const d2mini = require("@electric-sql/d2mini"); const extractors = require("./extractors.cjs"); const utils = require("./utils.cjs"); const { sum, count, avg, min, max, median, mode } = d2mini.groupByOperators; function processGroupBy(pipeline, query, mainTableAlias) { const groupByColumns = Array.isArray(query.groupBy) ? query.groupBy : [query.groupBy]; const keyExtractor = ([_oldKey, namespacedRow]) => { const key = {}; for (const column of groupByColumns) { if (typeof column === `string` && column.startsWith(`@`)) { const columnRef = column.substring(1); const columnName = columnRef.includes(`.`) ? columnRef.split(`.`)[1] : columnRef; key[columnName] = extractors.extractValueFromNamespacedRow( namespacedRow, columnRef, mainTableAlias ); } } return key; }; const aggregates = {}; if (!query.select) { throw new Error(`SELECT clause is required for GROUP BY`); } for (const item of query.select) { if (typeof item === `object`) { for (const [alias, expr] of Object.entries(item)) { if (typeof expr === `object` && utils.isAggregateFunctionCall(expr)) { const functionName = Object.keys(expr)[0]; const columnRef = expr[functionName]; aggregates[alias] = getAggregateFunction( functionName, columnRef, mainTableAlias ); } } } } if (Object.keys(aggregates).length > 0) { pipeline = pipeline.pipe(d2mini.groupBy(keyExtractor, aggregates)); } return pipeline; } function getAggregateFunction(functionName, columnRef, mainTableAlias) { const valueExtractor = ([_oldKey, namespacedRow]) => { let value; if (typeof columnRef === `string` && columnRef.startsWith(`@`)) { value = extractors.extractValueFromNamespacedRow( namespacedRow, columnRef.substring(1), mainTableAlias ); } else { value = extractors.evaluateOperandOnNamespacedRow( namespacedRow, columnRef, mainTableAlias ); } return typeof value === `number` ? value : 0; }; switch (functionName.toUpperCase()) { case `SUM`: return sum(valueExtractor); case `COUNT`: return count(); // count() doesn't need a value extractor case `AVG`: return avg(valueExtractor); case `MIN`: return min(valueExtractor); case `MAX`: return max(valueExtractor); case `MEDIAN`: return median(valueExtractor); case `MODE`: return mode(valueExtractor); default: throw new Error(`Unsupported aggregate function: ${functionName}`); } } exports.getAggregateFunction = getAggregateFunction; exports.processGroupBy = processGroupBy; //# sourceMappingURL=group-by.cjs.map