@quereus/quereus 2.9.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +224 -222
- package/dist/src/core/database-assertions.d.ts +36 -16
- package/dist/src/core/database-assertions.d.ts.map +1 -1
- package/dist/src/core/database-assertions.js +222 -118
- package/dist/src/core/database-assertions.js.map +1 -1
- package/dist/src/core/database-transaction.d.ts +96 -13
- package/dist/src/core/database-transaction.d.ts.map +1 -1
- package/dist/src/core/database-transaction.js +294 -35
- package/dist/src/core/database-transaction.js.map +1 -1
- package/dist/src/core/database-watchers.d.ts +58 -0
- package/dist/src/core/database-watchers.d.ts.map +1 -0
- package/dist/src/core/database-watchers.js +206 -0
- package/dist/src/core/database-watchers.js.map +1 -0
- package/dist/src/core/database.d.ts +78 -5
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +120 -20
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/statement.d.ts +9 -0
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +29 -0
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/core/table-handle.d.ts +45 -0
- package/dist/src/core/table-handle.d.ts.map +1 -0
- package/dist/src/core/table-handle.js +54 -0
- package/dist/src/core/table-handle.js.map +1 -0
- package/dist/src/func/builtins/conversion.d.ts.map +1 -1
- package/dist/src/func/builtins/conversion.js +12 -1
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +22 -8
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/generation.d.ts.map +1 -1
- package/dist/src/func/builtins/generation.js +26 -1
- package/dist/src/func/builtins/generation.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +5 -1
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json-tvf.d.ts.map +1 -1
- package/dist/src/func/builtins/json-tvf.js +16 -2
- package/dist/src/func/builtins/json-tvf.js.map +1 -1
- package/dist/src/func/builtins/schema.d.ts +4 -0
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +270 -11
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/registration.d.ts +19 -1
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +8 -3
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +12 -4
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/assertion-classifier.d.ts +71 -0
- package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -0
- package/dist/src/planner/analysis/assertion-classifier.js +286 -0
- package/dist/src/planner/analysis/assertion-classifier.js.map +1 -0
- package/dist/src/planner/analysis/assertion-hoist-cache.d.ts +34 -0
- package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -0
- package/dist/src/planner/analysis/assertion-hoist-cache.js +119 -0
- package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -0
- package/dist/src/planner/analysis/binding-extractor.d.ts +58 -0
- package/dist/src/planner/analysis/binding-extractor.d.ts.map +1 -0
- package/dist/src/planner/analysis/binding-extractor.js +110 -0
- package/dist/src/planner/analysis/binding-extractor.js.map +1 -0
- package/dist/src/planner/analysis/change-scope.d.ts +184 -0
- package/dist/src/planner/analysis/change-scope.d.ts.map +1 -0
- package/dist/src/planner/analysis/change-scope.js +825 -0
- package/dist/src/planner/analysis/change-scope.js.map +1 -0
- package/dist/src/planner/analysis/check-extraction.d.ts +29 -0
- package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -0
- package/dist/src/planner/analysis/check-extraction.js +420 -0
- package/dist/src/planner/analysis/check-extraction.js.map +1 -0
- package/dist/src/planner/analysis/constraint-extractor.d.ts +47 -7
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +169 -92
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/analysis/partial-unique-extraction.d.ts +68 -0
- package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -0
- package/dist/src/planner/analysis/partial-unique-extraction.js +347 -0
- package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -0
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts +14 -0
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -0
- package/dist/src/planner/analysis/predicate-conjuncts.js +31 -0
- package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -0
- package/dist/src/planner/analysis/predicate-shape.d.ts +52 -0
- package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -0
- package/dist/src/planner/analysis/predicate-shape.js +119 -0
- package/dist/src/planner/analysis/predicate-shape.js.map +1 -0
- package/dist/src/planner/analysis/sat-checker.d.ts +43 -0
- package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -0
- package/dist/src/planner/analysis/sat-checker.js +393 -0
- package/dist/src/planner/analysis/sat-checker.js.map +1 -0
- package/dist/src/planner/building/table.d.ts.map +1 -1
- package/dist/src/planner/building/table.js +1 -1
- package/dist/src/planner/building/table.js.map +1 -1
- package/dist/src/planner/framework/characteristics.d.ts +10 -1
- package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
- package/dist/src/planner/framework/characteristics.js +24 -5
- package/dist/src/planner/framework/characteristics.js.map +1 -1
- package/dist/src/planner/framework/pass.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.js +46 -16
- package/dist/src/planner/framework/pass.js.map +1 -1
- package/dist/src/planner/framework/physical-utils.d.ts +0 -9
- package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
- package/dist/src/planner/framework/physical-utils.js +0 -31
- package/dist/src/planner/framework/physical-utils.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.d.ts +25 -0
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +75 -8
- package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
- package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/alias-node.js +6 -1
- package/dist/src/planner/nodes/alias-node.js.map +1 -1
- package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/asof-scan-node.js +17 -3
- package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.js +19 -9
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +10 -6
- package/dist/src/planner/nodes/distinct-node.js.map +1 -1
- package/dist/src/planner/nodes/empty-relation-node.d.ts +27 -0
- package/dist/src/planner/nodes/empty-relation-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/empty-relation-node.js +61 -0
- package/dist/src/planner/nodes/empty-relation-node.js.map +1 -0
- package/dist/src/planner/nodes/filter.d.ts.map +1 -1
- package/dist/src/planner/nodes/filter.js +65 -5
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts +1 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.js +8 -6
- package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +12 -9
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-utils.d.ts +24 -1
- package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-utils.js +86 -0
- package/dist/src/planner/nodes/join-utils.js.map +1 -1
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +6 -1
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.js +19 -9
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.js +5 -2
- package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +1 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +186 -4
- package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +75 -30
- package/dist/src/planner/nodes/project-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts +24 -2
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +101 -1
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.d.ts +9 -1
- package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.js +21 -0
- package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
- package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/returning-node.js +64 -28
- package/dist/src/planner/nodes/returning-node.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts +1 -0
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +12 -0
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js +15 -0
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
- package/dist/src/planner/nodes/single-row.js +3 -1
- package/dist/src/planner/nodes/single-row.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +10 -3
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +8 -8
- package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +3 -3
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +26 -8
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/table-function-call.d.ts +4 -1
- package/dist/src/planner/nodes/table-function-call.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-function-call.js +224 -14
- package/dist/src/planner/nodes/table-function-call.js.map +1 -1
- package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-node.js +9 -2
- package/dist/src/planner/nodes/window-node.js.map +1 -1
- package/dist/src/planner/optimizer-tuning.d.ts +29 -1
- package/dist/src/planner/optimizer-tuning.d.ts.map +1 -1
- package/dist/src/planner/optimizer-tuning.js +3 -0
- package/dist/src/planner/optimizer-tuning.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +187 -0
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +22 -7
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +30 -0
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -0
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +116 -0
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -0
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +7 -7
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +18 -16
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-elimination.d.ts +56 -0
- package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-join-elimination.js +326 -0
- package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -0
- package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js +10 -2
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts +20 -0
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +181 -0
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +46 -0
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +156 -0
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts +30 -0
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +60 -0
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts +45 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +210 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts +29 -0
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js +161 -0
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js.map +1 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +39 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +91 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -0
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts +35 -0
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -0
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +74 -0
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -0
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts +27 -0
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -0
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +103 -0
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -0
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +1 -25
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
- package/dist/src/planner/scopes/global.js +2 -2
- package/dist/src/planner/scopes/global.js.map +1 -1
- package/dist/src/planner/type-utils.d.ts.map +1 -1
- package/dist/src/planner/type-utils.js +11 -0
- package/dist/src/planner/type-utils.js.map +1 -1
- package/dist/src/planner/util/fd-utils.d.ts +245 -0
- package/dist/src/planner/util/fd-utils.d.ts.map +1 -0
- package/dist/src/planner/util/fd-utils.js +1416 -0
- package/dist/src/planner/util/fd-utils.js.map +1 -0
- package/dist/src/planner/util/ind-utils.d.ts +79 -0
- package/dist/src/planner/util/ind-utils.d.ts.map +1 -0
- package/dist/src/planner/util/ind-utils.js +146 -0
- package/dist/src/planner/util/ind-utils.js.map +1 -0
- package/dist/src/planner/util/key-utils.d.ts +75 -14
- package/dist/src/planner/util/key-utils.d.ts.map +1 -1
- package/dist/src/planner/util/key-utils.js +234 -57
- package/dist/src/planner/util/key-utils.js.map +1 -1
- package/dist/src/runtime/delta-executor.d.ts +134 -0
- package/dist/src/runtime/delta-executor.d.ts.map +1 -0
- package/dist/src/runtime/delta-executor.js +382 -0
- package/dist/src/runtime/delta-executor.js.map +1 -0
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +52 -16
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-assertion.js +3 -2
- package/dist/src/runtime/emit/create-assertion.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +40 -13
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.js +1 -1
- package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
- package/dist/src/runtime/emit/empty-relation.d.ts +5 -0
- package/dist/src/runtime/emit/empty-relation.d.ts.map +1 -0
- package/dist/src/runtime/emit/empty-relation.js +11 -0
- package/dist/src/runtime/emit/empty-relation.js.map +1 -0
- package/dist/src/runtime/foreign-key-actions.d.ts +16 -0
- package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
- package/dist/src/runtime/foreign-key-actions.js +81 -1
- package/dist/src/runtime/foreign-key-actions.js.map +1 -1
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +2 -0
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/schema/assertion.d.ts +8 -0
- package/dist/src/schema/assertion.d.ts.map +1 -1
- package/dist/src/schema/change-events.d.ts +5 -1
- package/dist/src/schema/change-events.d.ts.map +1 -1
- package/dist/src/schema/change-events.js.map +1 -1
- package/dist/src/schema/function.d.ts +65 -1
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js +31 -0
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/manager.d.ts +33 -0
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +95 -4
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
- package/dist/src/schema/rename-rewriter.js +303 -102
- package/dist/src/schema/rename-rewriter.js.map +1 -1
- package/dist/src/schema/table.d.ts +21 -2
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +17 -8
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +32 -0
- package/dist/src/types/temporal-types.js.map +1 -1
- package/dist/src/vtab/events.d.ts +9 -0
- package/dist/src/vtab/events.d.ts.map +1 -1
- package/dist/src/vtab/events.js +19 -0
- package/dist/src/vtab/events.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +24 -5
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.d.ts +2 -1
- package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.js +32 -1
- package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database.watch infrastructure — registration, post-commit firing,
|
|
3
|
+
* schema-change invalidation, and txn-id minting.
|
|
4
|
+
*
|
|
5
|
+
* Watchers are the second consumer of `DeltaExecutor`. Unlike assertions,
|
|
6
|
+
* they run **after** commit (the change log is still alive, the
|
|
7
|
+
* connections have all committed), and handler errors are logged but
|
|
8
|
+
* never roll the commit back.
|
|
9
|
+
*/
|
|
10
|
+
import { type SqlValue } from '../common/types.js';
|
|
11
|
+
import type { ChangeScope, Subscription, WatchHandler } from '../planner/analysis/change-scope.js';
|
|
12
|
+
import type { Database } from './database.js';
|
|
13
|
+
/**
|
|
14
|
+
* Database internals the watcher manager needs. Mirrors
|
|
15
|
+
* `AssertionEvaluatorContext` — keeps the manager testable without the
|
|
16
|
+
* full `Database`.
|
|
17
|
+
*/
|
|
18
|
+
export interface WatcherManagerContext {
|
|
19
|
+
readonly schemaManager: Database['schemaManager'];
|
|
20
|
+
readonly optimizer: Database['optimizer'];
|
|
21
|
+
getChangedBaseTables(): Set<string>;
|
|
22
|
+
getChangedTuples(base: string, columnIndices: readonly number[], pkIndices: readonly number[]): SqlValue[][];
|
|
23
|
+
registerCaptureSpec(baseTable: string, spec: {
|
|
24
|
+
extraColumns: ReadonlySet<number>;
|
|
25
|
+
}): () => void;
|
|
26
|
+
_findTable(tableName: string, schemaName?: string): ReturnType<Database['_findTable']>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Manages all `Database.watch` subscriptions for a single `Database`.
|
|
30
|
+
*/
|
|
31
|
+
export declare class WatcherManager {
|
|
32
|
+
private readonly ctx;
|
|
33
|
+
private readonly executor;
|
|
34
|
+
private readonly active;
|
|
35
|
+
private nextTxnIdCounter;
|
|
36
|
+
private currentTxnId;
|
|
37
|
+
private unsubscribeSchemaChanges;
|
|
38
|
+
constructor(ctx: WatcherManagerContext);
|
|
39
|
+
private subscribeToSchemaChanges;
|
|
40
|
+
/**
|
|
41
|
+
* Register a watcher. Validates the scope synchronously, registers
|
|
42
|
+
* capture demand, and produces a `Subscription` handle whose
|
|
43
|
+
* `unsubscribe()` releases all resources.
|
|
44
|
+
*/
|
|
45
|
+
watch(scope: ChangeScope, handler: WatchHandler): Subscription;
|
|
46
|
+
/** Fire all subscriptions impacted by the current commit. Errors from
|
|
47
|
+
* any single subscription's apply are logged and swallowed.
|
|
48
|
+
*
|
|
49
|
+
* Must be called by the TransactionManager after a successful commit
|
|
50
|
+
* but before the change log is cleared. */
|
|
51
|
+
runPostCommit(): Promise<void>;
|
|
52
|
+
dispose(): void;
|
|
53
|
+
private disposeActive;
|
|
54
|
+
private invalidateForTable;
|
|
55
|
+
private mintTxnId;
|
|
56
|
+
private nextNonce;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=database-watchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-watchers.d.ts","sourceRoot":"","sources":["../../../src/core/database-watchers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQ/D,OAAO,KAAK,EACX,WAAW,EAEX,YAAY,EACZ,YAAY,EACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE1C,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,EAAE,EAAE,CAAC;IAC7G,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,MAAM,IAAI,CAAC;IAChG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;CACvF;AAcD;;GAEG;AACH,qBAAa,cAAc;IAOd,OAAO,CAAC,QAAQ,CAAC,GAAG;IANhC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,wBAAwB,CAA6B;gBAEhC,GAAG,EAAE,qBAAqB;IAevD,OAAO,CAAC,wBAAwB;IAUhC;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;IAmD9D;;;;gDAI4C;IACtC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAepC,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;CAKjB"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database.watch infrastructure — registration, post-commit firing,
|
|
3
|
+
* schema-change invalidation, and txn-id minting.
|
|
4
|
+
*
|
|
5
|
+
* Watchers are the second consumer of `DeltaExecutor`. Unlike assertions,
|
|
6
|
+
* they run **after** commit (the change log is still alive, the
|
|
7
|
+
* connections have all committed), and handler errors are logged but
|
|
8
|
+
* never roll the commit back.
|
|
9
|
+
*/
|
|
10
|
+
import { createLogger } from '../common/logger.js';
|
|
11
|
+
import { QuereusError } from '../common/errors.js';
|
|
12
|
+
import { StatusCode } from '../common/types.js';
|
|
13
|
+
import { DeltaExecutor, subscriptionFromChangeScope, } from '../runtime/delta-executor.js';
|
|
14
|
+
const log = createLogger('core:watchers');
|
|
15
|
+
const warnLog = log.extend('warn');
|
|
16
|
+
/**
|
|
17
|
+
* Manages all `Database.watch` subscriptions for a single `Database`.
|
|
18
|
+
*/
|
|
19
|
+
export class WatcherManager {
|
|
20
|
+
ctx;
|
|
21
|
+
executor;
|
|
22
|
+
active = new Map();
|
|
23
|
+
nextTxnIdCounter = 0;
|
|
24
|
+
currentTxnId = '';
|
|
25
|
+
unsubscribeSchemaChanges = null;
|
|
26
|
+
constructor(ctx) {
|
|
27
|
+
this.ctx = ctx;
|
|
28
|
+
const executorCtx = {
|
|
29
|
+
getChangedBaseTables: () => ctx.getChangedBaseTables(),
|
|
30
|
+
getChangedTuples: (base, cols, pk) => ctx.getChangedTuples(base, cols, pk),
|
|
31
|
+
getRowCount: (base) => {
|
|
32
|
+
const [schemaName, tableName] = base.split('.');
|
|
33
|
+
const table = ctx._findTable(tableName, schemaName);
|
|
34
|
+
return table?.estimatedRows;
|
|
35
|
+
},
|
|
36
|
+
deltaPerRowFallbackRatio: ctx.optimizer.tuning.deltaPerRowFallbackRatio,
|
|
37
|
+
};
|
|
38
|
+
this.executor = new DeltaExecutor(executorCtx);
|
|
39
|
+
this.subscribeToSchemaChanges();
|
|
40
|
+
}
|
|
41
|
+
subscribeToSchemaChanges() {
|
|
42
|
+
const notifier = this.ctx.schemaManager.getChangeNotifier();
|
|
43
|
+
this.unsubscribeSchemaChanges = notifier.addListener((event) => {
|
|
44
|
+
if (event.type === 'table_removed' || event.type === 'table_modified') {
|
|
45
|
+
const fqName = `${event.schemaName}.${event.objectName}`.toLowerCase();
|
|
46
|
+
this.invalidateForTable(fqName);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Register a watcher. Validates the scope synchronously, registers
|
|
52
|
+
* capture demand, and produces a `Subscription` handle whose
|
|
53
|
+
* `unsubscribe()` releases all resources.
|
|
54
|
+
*/
|
|
55
|
+
watch(scope, handler) {
|
|
56
|
+
if (scope.unboundParameters.length > 0) {
|
|
57
|
+
throw new QuereusError(`watch: scope has unbound parameters [${scope.unboundParameters.join(', ')}]; call bindParameters(scope, params) first`, StatusCode.MISUSE);
|
|
58
|
+
}
|
|
59
|
+
const id = mintSubscriptionId(scope, this.nextNonce());
|
|
60
|
+
const tables = new Set();
|
|
61
|
+
for (const w of scope.watches) {
|
|
62
|
+
tables.add(`${w.table.schema}.${w.table.table}`.toLowerCase());
|
|
63
|
+
}
|
|
64
|
+
const helperCtx = {
|
|
65
|
+
resolveTable: (qname) => {
|
|
66
|
+
const table = this.ctx._findTable(qname.table, qname.schema);
|
|
67
|
+
if (!table)
|
|
68
|
+
return undefined;
|
|
69
|
+
return {
|
|
70
|
+
columnIndexMap: table.columnIndexMap,
|
|
71
|
+
pkIndices: table.primaryKeyDefinition.map(d => d.index),
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
registerCaptureSpec: (base, spec) => this.ctx.registerCaptureSpec(base, spec),
|
|
75
|
+
getCurrentTxnId: () => this.currentTxnId,
|
|
76
|
+
};
|
|
77
|
+
const { subscription, captureDisposers } = subscriptionFromChangeScope(scope, handler, id, helperCtx);
|
|
78
|
+
const disposeFromExecutor = this.executor.register(subscription);
|
|
79
|
+
const entry = {
|
|
80
|
+
id,
|
|
81
|
+
tables,
|
|
82
|
+
disposeFromExecutor,
|
|
83
|
+
captureDisposers,
|
|
84
|
+
disposed: false,
|
|
85
|
+
};
|
|
86
|
+
this.active.set(id, entry);
|
|
87
|
+
const isDead = scope.watches.length === 0
|
|
88
|
+
&& scope.nonDeterministicSources.length === 0;
|
|
89
|
+
if (isDead) {
|
|
90
|
+
warnLog('Registered dead subscription %s (no watches and no non-deterministic sources)', id);
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
id,
|
|
94
|
+
unsubscribe: () => this.disposeActive(entry),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Fire all subscriptions impacted by the current commit. Errors from
|
|
98
|
+
* any single subscription's apply are logged and swallowed.
|
|
99
|
+
*
|
|
100
|
+
* Must be called by the TransactionManager after a successful commit
|
|
101
|
+
* but before the change log is cleared. */
|
|
102
|
+
async runPostCommit() {
|
|
103
|
+
if (this.active.size === 0)
|
|
104
|
+
return;
|
|
105
|
+
this.currentTxnId = this.mintTxnId();
|
|
106
|
+
try {
|
|
107
|
+
await this.executor.runAll();
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
// subscriptionFromChangeScope swallows handler errors; this catch
|
|
111
|
+
// is defensive — if the kernel itself throws (e.g. a missing PK
|
|
112
|
+
// triggers a fallback log), don't propagate into the commit path.
|
|
113
|
+
log('Post-commit watcher run threw: %O', err);
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
this.currentTxnId = '';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
dispose() {
|
|
120
|
+
if (this.unsubscribeSchemaChanges) {
|
|
121
|
+
this.unsubscribeSchemaChanges();
|
|
122
|
+
this.unsubscribeSchemaChanges = null;
|
|
123
|
+
}
|
|
124
|
+
for (const entry of [...this.active.values()]) {
|
|
125
|
+
this.disposeActive(entry);
|
|
126
|
+
}
|
|
127
|
+
this.executor.disposeAll();
|
|
128
|
+
}
|
|
129
|
+
disposeActive(entry) {
|
|
130
|
+
if (entry.disposed)
|
|
131
|
+
return;
|
|
132
|
+
entry.disposed = true;
|
|
133
|
+
this.active.delete(entry.id);
|
|
134
|
+
entry.disposeFromExecutor();
|
|
135
|
+
for (const d of entry.captureDisposers) {
|
|
136
|
+
try {
|
|
137
|
+
d();
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
log('Capture-spec disposer for %s threw: %O', entry.id, err);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
entry.captureDisposers.length = 0;
|
|
144
|
+
}
|
|
145
|
+
invalidateForTable(fqName) {
|
|
146
|
+
const toDispose = [];
|
|
147
|
+
for (const entry of this.active.values()) {
|
|
148
|
+
if (entry.tables.has(fqName))
|
|
149
|
+
toDispose.push(entry);
|
|
150
|
+
}
|
|
151
|
+
for (const entry of toDispose) {
|
|
152
|
+
warnLog('Invalidating subscription %s due to schema change on %s', entry.id, fqName);
|
|
153
|
+
this.disposeActive(entry);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
mintTxnId() {
|
|
157
|
+
this.nextTxnIdCounter += 1;
|
|
158
|
+
return `txn:${this.nextTxnIdCounter}`;
|
|
159
|
+
}
|
|
160
|
+
nextNonce() {
|
|
161
|
+
// Plain Math.random is fine here — we only need uniqueness within a
|
|
162
|
+
// process, not crypto-grade entropy.
|
|
163
|
+
return Math.random().toString(36).slice(2, 10);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Hash a scope into a stable id. The id mixes a canonical serialization
|
|
168
|
+
* of the watch shape (so two subscriptions for the same scope hash to
|
|
169
|
+
* the same prefix) with a random nonce (so the id is unique per
|
|
170
|
+
* registration). Format: `watch:<base32-hash>:<nonce>`.
|
|
171
|
+
*/
|
|
172
|
+
function mintSubscriptionId(scope, nonce) {
|
|
173
|
+
const canonical = canonicalizeScope(scope);
|
|
174
|
+
const hash = djb2Base32(canonical);
|
|
175
|
+
return `watch:${hash}:${nonce}`;
|
|
176
|
+
}
|
|
177
|
+
function canonicalizeScope(scope) {
|
|
178
|
+
const parts = [];
|
|
179
|
+
for (const w of scope.watches) {
|
|
180
|
+
parts.push(`${w.table.schema}.${w.table.table}`);
|
|
181
|
+
parts.push(w.columns === 'all' ? '*' : [...w.columns].sort().join(','));
|
|
182
|
+
parts.push(JSON.stringify(w.scope));
|
|
183
|
+
}
|
|
184
|
+
for (const n of scope.nonDeterministicSources)
|
|
185
|
+
parts.push(JSON.stringify(n));
|
|
186
|
+
for (const p of scope.unboundParameters)
|
|
187
|
+
parts.push(String(p));
|
|
188
|
+
return parts.join('|');
|
|
189
|
+
}
|
|
190
|
+
/** djb2 hash → 6 base32 chars. Fast, no crypto guarantees needed. */
|
|
191
|
+
function djb2Base32(s) {
|
|
192
|
+
let h = 5381;
|
|
193
|
+
for (let i = 0; i < s.length; i++) {
|
|
194
|
+
h = ((h << 5) + h + s.charCodeAt(i)) | 0;
|
|
195
|
+
}
|
|
196
|
+
const u = h >>> 0;
|
|
197
|
+
const alphabet = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
198
|
+
let out = '';
|
|
199
|
+
let n = u;
|
|
200
|
+
for (let i = 0; i < 6; i++) {
|
|
201
|
+
out = alphabet[n & 31] + out;
|
|
202
|
+
n = n >>> 5;
|
|
203
|
+
}
|
|
204
|
+
return out;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=database-watchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-watchers.js","sourceRoot":"","sources":["../../../src/core/database-watchers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EACN,aAAa,EACb,2BAA2B,GAI3B,MAAM,8BAA8B,CAAC;AAUtC,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AA6BnC;;GAEG;AACH,MAAM,OAAO,cAAc;IAOG;IANZ,QAAQ,CAAgB;IACxB,MAAM,GAAG,IAAI,GAAG,EAA8B,CAAC;IACxD,gBAAgB,GAAG,CAAC,CAAC;IACrB,YAAY,GAAG,EAAE,CAAC;IAClB,wBAAwB,GAAwB,IAAI,CAAC;IAE7D,YAA6B,GAA0B;QAA1B,QAAG,GAAH,GAAG,CAAuB;QACtD,MAAM,WAAW,GAAyB;YACzC,oBAAoB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,oBAAoB,EAAE;YACtD,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YAC1E,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrB,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChD,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBACpD,OAAO,KAAK,EAAE,aAAa,CAAC;YAC7B,CAAC;YACD,wBAAwB,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,wBAAwB;SACvE,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACjC,CAAC;IAEO,wBAAwB;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;QAC5D,IAAI,CAAC,wBAAwB,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAwB,EAAE,EAAE;YACjF,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACvE,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,CAAC;gBACvE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACjC,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAkB,EAAE,OAAqB;QAC9C,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,YAAY,CACrB,wCAAwC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,6CAA6C,EACvH,UAAU,CAAC,MAAM,CACjB,CAAC;QACH,CAAC;QAED,MAAM,EAAE,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,SAAS,GAAuC;YACrD,YAAY,EAAE,CAAC,KAAoB,EAAoC,EAAE;gBACxE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC7D,IAAI,CAAC,KAAK;oBAAE,OAAO,SAAS,CAAC;gBAC7B,OAAO;oBACN,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,SAAS,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;iBACvD,CAAC;YACH,CAAC;YACD,mBAAmB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7E,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY;SACxC,CAAC;QAEF,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;QACtG,MAAM,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEjE,MAAM,KAAK,GAAuB;YACjC,EAAE;YACF,MAAM;YACN,mBAAmB;YACnB,gBAAgB;YAChB,QAAQ,EAAE,KAAK;SACf,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAE3B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;eACrC,KAAK,CAAC,uBAAuB,CAAC,MAAM,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,+EAA+E,EAAE,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO;YACN,EAAE;YACF,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;SAC5C,CAAC;IACH,CAAC;IAED;;;;gDAI4C;IAC5C,KAAK,CAAC,aAAa;QAClB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,kEAAkE;YAClE,gEAAgE;YAChE,kEAAkE;YAClE,GAAG,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACxB,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACnC,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;QACtC,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAEO,aAAa,CAAC,KAAyB;QAC9C,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO;QAC3B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC7B,KAAK,CAAC,mBAAmB,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;YACxC,IAAI,CAAC;gBAAC,CAAC,EAAE,CAAC;YAAC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBAAC,GAAG,CAAC,wCAAwC,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAAC,CAAC;QAC3F,CAAC;QACD,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC;IACnC,CAAC;IAEO,kBAAkB,CAAC,MAAc;QACxC,MAAM,SAAS,GAAyB,EAAE,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,yDAAyD,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACrF,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAEO,SAAS;QAChB,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC3B,OAAO,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACvC,CAAC;IAEO,SAAS;QAChB,oEAAoE;QACpE,qCAAqC;QACrC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChD,CAAC;CACD;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,KAAkB,EAAE,KAAa;IAC5D,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,SAAS,IAAI,IAAI,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAkB;IAC5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,qEAAqE;AACrE,SAAS,UAAU,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,QAAQ,GAAG,kCAAkC,CAAC;IACpD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,GAAG,GAAG,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;QAC7B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
|
@@ -21,6 +21,9 @@ import { type LogicalType } from '../types/logical-type.js';
|
|
|
21
21
|
import { type DatabaseDataChangeEvent, type DatabaseSchemaChangeEvent, type DataChangeSubscriptionOptions, type SchemaChangeSubscriptionOptions } from './database-events.js';
|
|
22
22
|
import { type TransactionManagerContext } from './database-transaction.js';
|
|
23
23
|
import { type AssertionEvaluatorContext } from './database-assertions.js';
|
|
24
|
+
import { type WatcherManagerContext } from './database-watchers.js';
|
|
25
|
+
import type { ChangeScope, Subscription, WatchHandler } from '../planner/analysis/change-scope.js';
|
|
26
|
+
import { Table } from './table-handle.js';
|
|
24
27
|
/** Result from _buildPlan containing both the plan tree and its schema dependencies. */
|
|
25
28
|
export interface BuildPlanResult {
|
|
26
29
|
plan: BlockNode;
|
|
@@ -30,7 +33,7 @@ export interface BuildPlanResult {
|
|
|
30
33
|
* Represents a connection to an Quereus database (in-memory in this port).
|
|
31
34
|
* Manages schema, prepared statements, virtual tables, and functions.
|
|
32
35
|
*/
|
|
33
|
-
export declare class Database implements TransactionManagerContext, AssertionEvaluatorContext {
|
|
36
|
+
export declare class Database implements TransactionManagerContext, AssertionEvaluatorContext, WatcherManagerContext {
|
|
34
37
|
readonly schemaManager: SchemaManager;
|
|
35
38
|
readonly declaredSchemaManager: DeclaredSchemaManager;
|
|
36
39
|
private isOpen;
|
|
@@ -53,6 +56,8 @@ export declare class Database implements TransactionManagerContext, AssertionEva
|
|
|
53
56
|
private readonly transactionManager;
|
|
54
57
|
/** Assertion evaluation */
|
|
55
58
|
private readonly assertionEvaluator;
|
|
59
|
+
/** Post-commit watcher dispatch */
|
|
60
|
+
private readonly watcherManager;
|
|
56
61
|
/** Per-database collation registry — comparator + optional key normalizer.
|
|
57
62
|
* The normalizer is required for index participation; comparator-only
|
|
58
63
|
* collations may still be used in ORDER BY but cannot back a compound index. */
|
|
@@ -62,6 +67,19 @@ export declare class Database implements TransactionManagerContext, AssertionEva
|
|
|
62
67
|
getChangedBaseTables(): Set<string>;
|
|
63
68
|
/** Get changed PK tuples for a specific base table */
|
|
64
69
|
getChangedKeyTuples(base: string): SqlValue[][];
|
|
70
|
+
/**
|
|
71
|
+
* Get changed value tuples projected onto `columnIndices` for a specific
|
|
72
|
+
* base table. The columns must have been registered for capture via
|
|
73
|
+
* `registerCaptureSpec` (PK columns are always captured implicitly).
|
|
74
|
+
*/
|
|
75
|
+
getChangedTuples(base: string, columnIndices: readonly number[], pkIndices: readonly number[]): SqlValue[][];
|
|
76
|
+
/**
|
|
77
|
+
* Register projection capture demand for a base table. Returns a dispose
|
|
78
|
+
* handle that removes the spec when called.
|
|
79
|
+
*/
|
|
80
|
+
registerCaptureSpec(baseTable: string, spec: {
|
|
81
|
+
extraColumns: ReadonlySet<number>;
|
|
82
|
+
}): () => void;
|
|
65
83
|
/**
|
|
66
84
|
* Prepares an SQL statement for execution.
|
|
67
85
|
*
|
|
@@ -339,10 +357,13 @@ export declare class Database implements TransactionManagerContext, AssertionEva
|
|
|
339
357
|
getInstructionTracer(): InstructionTracer | undefined;
|
|
340
358
|
_queueDeferredConstraintRow(baseTable: string, constraintName: string, row: Row, descriptor: RowDescriptor, evaluator: (ctx: RuntimeContext) => OutputValue, connectionId?: string, contextRow?: Row, contextDescriptor?: RowDescriptor): void;
|
|
341
359
|
runDeferredRowConstraints(): Promise<void>;
|
|
342
|
-
/** Public API used by DML emitters to record changes
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
360
|
+
/** Public API used by DML emitters to record changes. The full row plus
|
|
361
|
+
* PK column indices are passed so the change capture can project the
|
|
362
|
+
* columns that any active DeltaExecutor subscription has registered
|
|
363
|
+
* demand for. */
|
|
364
|
+
_recordInsert(baseTable: string, newRow: Row, pkIndices: readonly number[]): void;
|
|
365
|
+
_recordDelete(baseTable: string, oldRow: Row, pkIndices: readonly number[]): void;
|
|
366
|
+
_recordUpdate(baseTable: string, oldRow: Row, newRow: Row, pkIndices: readonly number[]): void;
|
|
346
367
|
/** Create a named savepoint, returning its depth index */
|
|
347
368
|
_createSavepoint(name: string): number;
|
|
348
369
|
/** Release a named savepoint (merges layers down to target), returns target depth */
|
|
@@ -397,6 +418,36 @@ export declare class Database implements TransactionManagerContext, AssertionEva
|
|
|
397
418
|
* @returns A Statement with debug capabilities.
|
|
398
419
|
*/
|
|
399
420
|
prepareDebug(sql: string, debug: DebugOptions): Statement;
|
|
421
|
+
/**
|
|
422
|
+
* Returns a public handle to a table for inspection and per-table event
|
|
423
|
+
* subscription. Returns `undefined` if the table does not exist or its
|
|
424
|
+
* owning module is not registered.
|
|
425
|
+
*
|
|
426
|
+
* The returned {@link Table} is a snapshot: its `schema` reference is
|
|
427
|
+
* frozen at acquisition time. If the table is dropped or recreated, the
|
|
428
|
+
* handle keeps the original schema, but no further events for that name
|
|
429
|
+
* will arrive. Re-acquire after schema changes if you need fresh state.
|
|
430
|
+
*
|
|
431
|
+
* After {@link Database.close}, the handle's event emitter reference
|
|
432
|
+
* remains valid (the module instance outlives the database) but the
|
|
433
|
+
* database-level aggregator is unhooked, so local subscriptions on the
|
|
434
|
+
* module emitter still fire only as long as the module itself remains
|
|
435
|
+
* active.
|
|
436
|
+
*
|
|
437
|
+
* @param schemaName The schema name ('main', 'temp', or an attached
|
|
438
|
+
* schema). Pass `undefined` to use the current default schema.
|
|
439
|
+
* @param tableName The table name (case-insensitive resolution).
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* ```typescript
|
|
443
|
+
* const table = db.getTable('main', 'users');
|
|
444
|
+
* const tableEmitter = table?.getEventEmitter();
|
|
445
|
+
* const off = tableEmitter?.onDataChange?.((event) => {
|
|
446
|
+
* if (event.tableName === 'users') console.log(event);
|
|
447
|
+
* });
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
getTable(schemaName: string | undefined, tableName: string): Table | undefined;
|
|
400
451
|
/**
|
|
401
452
|
* Disconnects and removes all active connections.
|
|
402
453
|
* Called during database close.
|
|
@@ -404,5 +455,27 @@ export declare class Database implements TransactionManagerContext, AssertionEva
|
|
|
404
455
|
private disconnectAllConnections;
|
|
405
456
|
private checkOpen;
|
|
406
457
|
runGlobalAssertions(): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Subscribe to changes described by a {@link ChangeScope}.
|
|
460
|
+
*
|
|
461
|
+
* The watcher fires its handler **after** a transaction commits (mirrors
|
|
462
|
+
* assertion COMMIT eval), once per commit, with all matching watches in
|
|
463
|
+
* a single {@link WatchEvent}. Handler errors are caught and logged —
|
|
464
|
+
* they do not roll the commit back (assertions own that contract).
|
|
465
|
+
*
|
|
466
|
+
* Validation is synchronous:
|
|
467
|
+
* - Throws if `scope.unboundParameters` is non-empty (caller must
|
|
468
|
+
* `bindParameters(scope, params)` first).
|
|
469
|
+
* - Throws if any referenced table or column does not exist in the
|
|
470
|
+
* current schema.
|
|
471
|
+
*
|
|
472
|
+
* If the table or any column the scope mentions is later dropped or
|
|
473
|
+
* altered, the subscription is **invalidated and disposed**; re-subscribe
|
|
474
|
+
* to continue watching.
|
|
475
|
+
*
|
|
476
|
+
* @returns A {@link Subscription} handle whose `unsubscribe()` is
|
|
477
|
+
* idempotent and releases capture-spec demand.
|
|
478
|
+
*/
|
|
479
|
+
watch(scope: ChangeScope, handler: WatchHandler): Subscription;
|
|
407
480
|
}
|
|
408
481
|
//# sourceMappingURL=database.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,OAAO,EAAuD,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGpH,OAAO,KAAK,GAAG,MAAM,kBAAkB,CAAC;AAIxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAG5E,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK5D,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAsB,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,9 @@ import { wrapAsyncIterator } from '../util/async-iterator.js';
|
|
|
32
32
|
import { DatabaseEventEmitter, } from './database-events.js';
|
|
33
33
|
import { TransactionManager } from './database-transaction.js';
|
|
34
34
|
import { AssertionEvaluator } from './database-assertions.js';
|
|
35
|
+
import { WatcherManager } from './database-watchers.js';
|
|
36
|
+
import { tryGetEventEmitter } from '../vtab/events.js';
|
|
37
|
+
import { Table } from './table-handle.js';
|
|
35
38
|
const log = createLogger('core:database');
|
|
36
39
|
const errorLog = log.extend('error');
|
|
37
40
|
/** Parse a comma-separated schema path string into an array of trimmed, non-empty names. */
|
|
@@ -41,19 +44,6 @@ function parseSchemaPath(pathString) {
|
|
|
41
44
|
const parts = pathString.split(',').map(s => s.trim()).filter(s => s.length > 0);
|
|
42
45
|
return parts.length > 0 ? parts : undefined;
|
|
43
46
|
}
|
|
44
|
-
/** Extract a VTableEventEmitter from a module if it supports one. */
|
|
45
|
-
function tryGetEventEmitter(module) {
|
|
46
|
-
const asSource = module;
|
|
47
|
-
if (typeof asSource.getEventEmitter !== 'function')
|
|
48
|
-
return undefined;
|
|
49
|
-
const emitter = asSource.getEventEmitter();
|
|
50
|
-
if (!emitter || typeof emitter !== 'object')
|
|
51
|
-
return undefined;
|
|
52
|
-
const typed = emitter;
|
|
53
|
-
if (typeof typed.onDataChange !== 'function' && typeof typed.onSchemaChange !== 'function')
|
|
54
|
-
return undefined;
|
|
55
|
-
return emitter;
|
|
56
|
-
}
|
|
57
47
|
/**
|
|
58
48
|
* Represents a connection to an Quereus database (in-memory in this port).
|
|
59
49
|
* Manages schema, prepared statements, virtual tables, and functions.
|
|
@@ -81,6 +71,8 @@ export class Database {
|
|
|
81
71
|
transactionManager;
|
|
82
72
|
/** Assertion evaluation */
|
|
83
73
|
assertionEvaluator;
|
|
74
|
+
/** Post-commit watcher dispatch */
|
|
75
|
+
watcherManager;
|
|
84
76
|
/** Per-database collation registry — comparator + optional key normalizer.
|
|
85
77
|
* The normalizer is required for index participation; comparator-only
|
|
86
78
|
* collations may still be used in ORDER BY but cannot back a compound index. */
|
|
@@ -103,6 +95,7 @@ export class Database {
|
|
|
103
95
|
// Initialize transaction manager and assertion evaluator
|
|
104
96
|
this.transactionManager = new TransactionManager(this);
|
|
105
97
|
this.assertionEvaluator = new AssertionEvaluator(this);
|
|
98
|
+
this.watcherManager = new WatcherManager(this);
|
|
106
99
|
// Set up option change listeners
|
|
107
100
|
this.setupOptionListeners();
|
|
108
101
|
}
|
|
@@ -128,6 +121,21 @@ export class Database {
|
|
|
128
121
|
getChangedKeyTuples(base) {
|
|
129
122
|
return this.transactionManager.getChangedKeyTuples(base);
|
|
130
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Get changed value tuples projected onto `columnIndices` for a specific
|
|
126
|
+
* base table. The columns must have been registered for capture via
|
|
127
|
+
* `registerCaptureSpec` (PK columns are always captured implicitly).
|
|
128
|
+
*/
|
|
129
|
+
getChangedTuples(base, columnIndices, pkIndices) {
|
|
130
|
+
return this.transactionManager.getChangedTuples(base, columnIndices, pkIndices);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Register projection capture demand for a base table. Returns a dispose
|
|
134
|
+
* handle that removes the spec when called.
|
|
135
|
+
*/
|
|
136
|
+
registerCaptureSpec(baseTable, spec) {
|
|
137
|
+
return this.transactionManager.registerCaptureSpec(baseTable, spec);
|
|
138
|
+
}
|
|
131
139
|
/** @internal Set up listeners for option changes */
|
|
132
140
|
setupOptionListeners() {
|
|
133
141
|
// Register core database options with their change handlers
|
|
@@ -668,6 +676,8 @@ export class Database {
|
|
|
668
676
|
this.statements.clear();
|
|
669
677
|
// Clean up assertion evaluator (unsubscribe schema change listener, clear plan cache)
|
|
670
678
|
this.assertionEvaluator.dispose();
|
|
679
|
+
// Clean up watcher manager (dispose all subscriptions + schema listener)
|
|
680
|
+
this.watcherManager.dispose();
|
|
671
681
|
// Clear schemas, ensuring VTabs are potentially disconnected
|
|
672
682
|
// This will also call destroy on VTabs via SchemaManager.clearAll -> schema.clearTables -> schemaManager.dropTable
|
|
673
683
|
this.schemaManager.clearAll();
|
|
@@ -991,15 +1001,18 @@ export class Database {
|
|
|
991
1001
|
_inCoordinatedCommit() {
|
|
992
1002
|
return this.transactionManager.isInCoordinatedCommit();
|
|
993
1003
|
}
|
|
994
|
-
/** Public API used by DML emitters to record changes
|
|
995
|
-
|
|
996
|
-
|
|
1004
|
+
/** Public API used by DML emitters to record changes. The full row plus
|
|
1005
|
+
* PK column indices are passed so the change capture can project the
|
|
1006
|
+
* columns that any active DeltaExecutor subscription has registered
|
|
1007
|
+
* demand for. */
|
|
1008
|
+
_recordInsert(baseTable, newRow, pkIndices) {
|
|
1009
|
+
this.transactionManager.recordInsert(baseTable, newRow, pkIndices);
|
|
997
1010
|
}
|
|
998
|
-
_recordDelete(baseTable,
|
|
999
|
-
this.transactionManager.recordDelete(baseTable,
|
|
1011
|
+
_recordDelete(baseTable, oldRow, pkIndices) {
|
|
1012
|
+
this.transactionManager.recordDelete(baseTable, oldRow, pkIndices);
|
|
1000
1013
|
}
|
|
1001
|
-
_recordUpdate(baseTable,
|
|
1002
|
-
this.transactionManager.recordUpdate(baseTable,
|
|
1014
|
+
_recordUpdate(baseTable, oldRow, newRow, pkIndices) {
|
|
1015
|
+
this.transactionManager.recordUpdate(baseTable, oldRow, newRow, pkIndices);
|
|
1003
1016
|
}
|
|
1004
1017
|
/** Create a named savepoint, returning its depth index */
|
|
1005
1018
|
_createSavepoint(name) {
|
|
@@ -1163,6 +1176,48 @@ export class Database {
|
|
|
1163
1176
|
_findTable(tableName, dbName) {
|
|
1164
1177
|
return this.schemaManager.findTable(tableName, dbName);
|
|
1165
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Returns a public handle to a table for inspection and per-table event
|
|
1181
|
+
* subscription. Returns `undefined` if the table does not exist or its
|
|
1182
|
+
* owning module is not registered.
|
|
1183
|
+
*
|
|
1184
|
+
* The returned {@link Table} is a snapshot: its `schema` reference is
|
|
1185
|
+
* frozen at acquisition time. If the table is dropped or recreated, the
|
|
1186
|
+
* handle keeps the original schema, but no further events for that name
|
|
1187
|
+
* will arrive. Re-acquire after schema changes if you need fresh state.
|
|
1188
|
+
*
|
|
1189
|
+
* After {@link Database.close}, the handle's event emitter reference
|
|
1190
|
+
* remains valid (the module instance outlives the database) but the
|
|
1191
|
+
* database-level aggregator is unhooked, so local subscriptions on the
|
|
1192
|
+
* module emitter still fire only as long as the module itself remains
|
|
1193
|
+
* active.
|
|
1194
|
+
*
|
|
1195
|
+
* @param schemaName The schema name ('main', 'temp', or an attached
|
|
1196
|
+
* schema). Pass `undefined` to use the current default schema.
|
|
1197
|
+
* @param tableName The table name (case-insensitive resolution).
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* ```typescript
|
|
1201
|
+
* const table = db.getTable('main', 'users');
|
|
1202
|
+
* const tableEmitter = table?.getEventEmitter();
|
|
1203
|
+
* const off = tableEmitter?.onDataChange?.((event) => {
|
|
1204
|
+
* if (event.tableName === 'users') console.log(event);
|
|
1205
|
+
* });
|
|
1206
|
+
* ```
|
|
1207
|
+
*/
|
|
1208
|
+
getTable(schemaName, tableName) {
|
|
1209
|
+
this.checkOpen();
|
|
1210
|
+
const tableSchema = this.schemaManager.getTable(schemaName, tableName);
|
|
1211
|
+
if (!tableSchema)
|
|
1212
|
+
return undefined;
|
|
1213
|
+
const moduleName = tableSchema.vtabModuleName;
|
|
1214
|
+
if (!moduleName)
|
|
1215
|
+
return undefined;
|
|
1216
|
+
const moduleInfo = this.schemaManager.getModule(moduleName);
|
|
1217
|
+
if (!moduleInfo)
|
|
1218
|
+
return undefined;
|
|
1219
|
+
return new Table(tableSchema, moduleName, moduleInfo.module);
|
|
1220
|
+
}
|
|
1166
1221
|
/** @internal */
|
|
1167
1222
|
_findFunction(funcName, nArg) {
|
|
1168
1223
|
return this.schemaManager.findFunction(funcName, nArg);
|
|
@@ -1214,6 +1269,21 @@ export class Database {
|
|
|
1214
1269
|
errorLog(`Error starting transaction on newly registered connection ${connection.connectionId}: %O`, error);
|
|
1215
1270
|
// Don't throw here - just log the error to avoid breaking connection registration
|
|
1216
1271
|
}
|
|
1272
|
+
// Replay the active savepoint stack onto this connection so subsequent
|
|
1273
|
+
// release/rollback-to broadcasts targeting earlier depths are in-range.
|
|
1274
|
+
// Without this, modules that register connections lazily (memory, isolation,
|
|
1275
|
+
// any vtab whose connection appears on first read/write) see an empty stack
|
|
1276
|
+
// while the DB broadcasts depths > 0 — silently no-op'ing on a real depth.
|
|
1277
|
+
const activeDepth = this.transactionManager.getActiveSavepointDepth();
|
|
1278
|
+
for (let depth = 0; depth < activeDepth; depth++) {
|
|
1279
|
+
try {
|
|
1280
|
+
await connection.createSavepoint(depth);
|
|
1281
|
+
}
|
|
1282
|
+
catch (error) {
|
|
1283
|
+
errorLog(`Error replaying savepoint depth ${depth} on newly registered connection ${connection.connectionId}: %O`, error);
|
|
1284
|
+
// Continue replaying remaining depths — see comment above on registration robustness.
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1217
1287
|
}
|
|
1218
1288
|
else if (this.transactionManager.isEvaluatingDeferredConstraints()) {
|
|
1219
1289
|
log(`Skipped transaction begin on connection ${connection.connectionId} (evaluating deferred constraints)`);
|
|
@@ -1303,6 +1373,36 @@ export class Database {
|
|
|
1303
1373
|
async runGlobalAssertions() {
|
|
1304
1374
|
await this.assertionEvaluator.runGlobalAssertions();
|
|
1305
1375
|
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Subscribe to changes described by a {@link ChangeScope}.
|
|
1378
|
+
*
|
|
1379
|
+
* The watcher fires its handler **after** a transaction commits (mirrors
|
|
1380
|
+
* assertion COMMIT eval), once per commit, with all matching watches in
|
|
1381
|
+
* a single {@link WatchEvent}. Handler errors are caught and logged —
|
|
1382
|
+
* they do not roll the commit back (assertions own that contract).
|
|
1383
|
+
*
|
|
1384
|
+
* Validation is synchronous:
|
|
1385
|
+
* - Throws if `scope.unboundParameters` is non-empty (caller must
|
|
1386
|
+
* `bindParameters(scope, params)` first).
|
|
1387
|
+
* - Throws if any referenced table or column does not exist in the
|
|
1388
|
+
* current schema.
|
|
1389
|
+
*
|
|
1390
|
+
* If the table or any column the scope mentions is later dropped or
|
|
1391
|
+
* altered, the subscription is **invalidated and disposed**; re-subscribe
|
|
1392
|
+
* to continue watching.
|
|
1393
|
+
*
|
|
1394
|
+
* @returns A {@link Subscription} handle whose `unsubscribe()` is
|
|
1395
|
+
* idempotent and releases capture-spec demand.
|
|
1396
|
+
*/
|
|
1397
|
+
watch(scope, handler) {
|
|
1398
|
+
this.checkOpen();
|
|
1399
|
+
return this.watcherManager.watch(scope, handler);
|
|
1400
|
+
}
|
|
1401
|
+
/** @internal Invoked by the TransactionManager after a successful commit
|
|
1402
|
+
* and before the change log is cleared. */
|
|
1403
|
+
async runPostCommitWatchers() {
|
|
1404
|
+
await this.watcherManager.runPostCommit();
|
|
1405
|
+
}
|
|
1306
1406
|
/** @internal Invalidate cached assertion plan (called on DROP ASSERTION) */
|
|
1307
1407
|
invalidateAssertionCache(name) {
|
|
1308
1408
|
this.assertionEvaluator.invalidateAssertion(name);
|