UNPKG

@tanstack/optimistic

Version:

Core optimistic updates library

92 lines (91 loc) 2.81 kB
import { groupBy, map, groupByOperators } from "@electric-sql/d2ts"; import { extractValueFromNestedRow, evaluateOperandOnNestedRow } from "./extractors.js"; import { isAggregateFunctionCall } from "./utils.js"; const { sum, count, avg, min, max, median, mode } = groupByOperators; function processGroupBy(pipeline, query, mainTableAlias) { const groupByColumns = Array.isArray(query.groupBy) ? query.groupBy : [query.groupBy]; const keyExtractor = (nestedRow) => { 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] = extractValueFromNestedRow( nestedRow, columnRef, mainTableAlias ); } } return key; }; const aggregates = {}; for (const item of query.select) { if (typeof item === `object`) { for (const [alias, expr] of Object.entries(item)) { if (typeof expr === `object` && 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( groupBy(keyExtractor, aggregates), // Convert KeyValue<string, ResultType> to Record<string, unknown> map(([_key, value]) => { return value; }) ); } return pipeline; } function getAggregateFunction(functionName, columnRef, mainTableAlias) { const valueExtractor = (nestedRow) => { let value; if (typeof columnRef === `string` && columnRef.startsWith(`@`)) { value = extractValueFromNestedRow( nestedRow, columnRef.substring(1), mainTableAlias ); } else { value = evaluateOperandOnNestedRow( nestedRow, 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}`); } } export { getAggregateFunction, processGroupBy }; //# sourceMappingURL=group-by.js.map