@tanstack/db
Version:
A reactive client store for building super fast apps on sync
90 lines (89 loc) • 2.79 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const d2mini = require("@electric-sql/d2mini");
const evaluators = require("./evaluators.cjs");
const joins = require("./joins.cjs");
const groupBy = require("./group-by.cjs");
const orderBy = require("./order-by.cjs");
const select = require("./select.cjs");
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(
d2mini.map(([key, row]) => {
const ret = [key, { [mainTableAlias]: row }];
return ret;
})
);
if (query.join) {
pipeline = joins.processJoinClause(
pipeline,
query,
tables,
mainTableAlias,
allInputs
);
}
if (query.where) {
pipeline = pipeline.pipe(
d2mini.filter(([_key, row]) => {
const result = evaluators.evaluateWhereOnNamespacedRow(
row,
query.where,
mainTableAlias
);
return result;
})
);
}
if (query.groupBy) {
pipeline = groupBy.processGroupBy(pipeline, query, mainTableAlias);
}
if (query.having) {
pipeline = pipeline.pipe(
d2mini.filter(([_key, row]) => {
const result = evaluators.evaluateWhereOnNamespacedRow(
row,
query.having,
mainTableAlias
);
return result;
})
);
}
if (query.orderBy) {
pipeline = orderBy.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 ? select.processSelect(pipeline, query, mainTableAlias, allInputs) : !query.join && !query.groupBy ? pipeline.pipe(
d2mini.map(([key, row]) => [key, row[mainTableAlias]])
) : pipeline;
return resultPipeline;
}
exports.compileQueryPipeline = compileQueryPipeline;
//# sourceMappingURL=pipeline-compiler.cjs.map