@tanstack/db
Version:
A reactive client store for building super fast apps on sync
90 lines (89 loc) • 2.65 kB
JavaScript
import { map, filter } from "@electric-sql/d2mini";
import { evaluateWhereOnNamespacedRow } from "./evaluators.js";
import { processJoinClause } from "./joins.js";
import { processGroupBy } from "./group-by.js";
import { processOrderBy } from "./order-by.js";
import { processSelect } from "./select.js";
function compileQueryPipeline(query, inputs) {
const allInputs = { ...inputs };
if (query.with && query.with.length > 0) {
for (const withQuery of query.with) {
if (!withQuery.as) {
throw new Error(`WITH query must have an "as" property`);
}
if (allInputs[withQuery.as]) {
throw new Error(`CTE with name "${withQuery.as}" already exists`);
}
const withQueryWithoutWith = { ...withQuery, with: void 0 };
const compiledWithQuery = compileQueryPipeline(
withQueryWithoutWith,
allInputs
);
allInputs[withQuery.as] = compiledWithQuery;
}
}
const tables = {};
const mainTableAlias = query.as || query.from;
const input = allInputs[query.from];
if (!input) {
throw new Error(`Input for table "${query.from}" not found in inputs map`);
}
tables[mainTableAlias] = input;
let pipeline = input.pipe(
map(([key, row]) => {
const ret = [key, { [mainTableAlias]: row }];
return ret;
})
);
if (query.join) {
pipeline = processJoinClause(
pipeline,
query,
tables,
mainTableAlias,
allInputs
);
}
if (query.where) {
pipeline = pipeline.pipe(
filter(([_key, row]) => {
const result = evaluateWhereOnNamespacedRow(
row,
query.where,
mainTableAlias
);
return result;
})
);
}
if (query.groupBy) {
pipeline = processGroupBy(pipeline, query, mainTableAlias);
}
if (query.having) {
pipeline = pipeline.pipe(
filter(([_key, row]) => {
const result = evaluateWhereOnNamespacedRow(
row,
query.having,
mainTableAlias
);
return result;
})
);
}
if (query.orderBy) {
pipeline = processOrderBy(pipeline, query, mainTableAlias);
} else if (query.limit !== void 0 || query.offset !== void 0) {
throw new Error(
`LIMIT and OFFSET require an ORDER BY clause to ensure deterministic results`
);
}
const resultPipeline = query.select ? processSelect(pipeline, query, mainTableAlias, allInputs) : !query.join && !query.groupBy ? pipeline.pipe(
map(([key, row]) => [key, row[mainTableAlias]])
) : pipeline;
return resultPipeline;
}
export {
compileQueryPipeline
};
//# sourceMappingURL=pipeline-compiler.js.map