UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

142 lines (141 loc) 5.15 kB
import { map, join, consolidate, filter } from "@electric-sql/d2mini"; import { evaluateConditionOnNamespacedRow } from "./evaluators.js"; import { extractJoinKey } from "./extractors.js"; function processJoinClause(pipeline, query, tables, mainTableAlias, allInputs) { if (!query.join) return pipeline; const input = allInputs[query.from]; for (const joinClause of query.join) { const joinedTableAlias = joinClause.as || joinClause.from; const joinType = joinClause.type === `cross` ? `inner` : joinClause.type; const [mainKeyRef, , joinedKeyRefs] = joinClause.on; const mainPipeline = pipeline.pipe( map(([currentKey, namespacedRow]) => { const mainRow = namespacedRow[mainTableAlias]; const key = extractJoinKey(mainRow, mainKeyRef, mainTableAlias); return [key, [currentKey, namespacedRow]]; }) ); let joinedTableInput; if (allInputs[joinClause.from]) { joinedTableInput = allInputs[joinClause.from]; } else { joinedTableInput = input.graph.newInput(); } tables[joinedTableAlias] = joinedTableInput; const joinedPipeline = joinedTableInput.pipe( map(([currentKey, row]) => { const namespacedRow = { [joinedTableAlias]: row }; const key = extractJoinKey(row, joinedKeyRefs, joinedTableAlias); return [key, [currentKey, namespacedRow]]; }) ); switch (joinType) { case `inner`: pipeline = mainPipeline.pipe( join(joinedPipeline, `inner`), consolidate(), processJoinResults(mainTableAlias, joinedTableAlias, joinClause) ); break; case `left`: pipeline = mainPipeline.pipe( join(joinedPipeline, `left`), consolidate(), processJoinResults(mainTableAlias, joinedTableAlias, joinClause) ); break; case `right`: pipeline = mainPipeline.pipe( join(joinedPipeline, `right`), consolidate(), processJoinResults(mainTableAlias, joinedTableAlias, joinClause) ); break; case `full`: pipeline = mainPipeline.pipe( join(joinedPipeline, `full`), consolidate(), processJoinResults(mainTableAlias, joinedTableAlias, joinClause) ); break; default: pipeline = mainPipeline.pipe( join(joinedPipeline, `inner`), consolidate(), processJoinResults(mainTableAlias, joinedTableAlias, joinClause) ); } } return pipeline; } function processJoinResults(mainTableAlias, joinedTableAlias, joinClause) { return function(pipeline) { return pipeline.pipe( // Process the join result and handle nulls in the same step map((result) => { const [_key, [main, joined]] = result; const mainKey = main == null ? void 0 : main[0]; const mainNamespacedRow = main == null ? void 0 : main[1]; const joinedKey = joined == null ? void 0 : joined[0]; const joinedNamespacedRow = joined == null ? void 0 : joined[1]; if (joinClause.type === `inner` || joinClause.type === `cross`) { if (!mainNamespacedRow || !joinedNamespacedRow) { return void 0; } } if (joinClause.type === `left` && !mainNamespacedRow) { return void 0; } if (joinClause.type === `right` && !joinedNamespacedRow) { return void 0; } const mergedNamespacedRow = {}; if (mainNamespacedRow) { Object.entries(mainNamespacedRow).forEach( ([tableAlias, tableData]) => { mergedNamespacedRow[tableAlias] = tableData; } ); } if (joinedNamespacedRow) { Object.entries(joinedNamespacedRow).forEach( ([tableAlias, tableData]) => { mergedNamespacedRow[tableAlias] = tableData; } ); } else if (joinClause.type === `left` || joinClause.type === `full`) ; if (!mainNamespacedRow && (joinClause.type === `right` || joinClause.type === `full`)) ; const newKey = `[${mainKey},${joinedKey}]`; return [newKey, mergedNamespacedRow]; }), // Filter out undefined results filter((value) => value !== void 0), // Process the ON condition filter(([_key, namespacedRow]) => { if (!joinClause.on || joinClause.type === `cross`) { return true; } if (joinClause.type === `left` && namespacedRow[joinedTableAlias] === void 0) { return true; } if (joinClause.type === `right` && namespacedRow[mainTableAlias] === void 0) { return true; } if (joinClause.type === `full` && (namespacedRow[mainTableAlias] === void 0 || namespacedRow[joinedTableAlias] === void 0)) { return true; } return evaluateConditionOnNamespacedRow( namespacedRow, joinClause.on, mainTableAlias, joinedTableAlias ); }) ); }; } export { processJoinClause, processJoinResults }; //# sourceMappingURL=joins.js.map