Class: ClaudeMemory::Core::FactQueryBuilder
- Inherits:
-
Object
- Object
- ClaudeMemory::Core::FactQueryBuilder
- Defined in:
- lib/claude_memory/core/fact_query_builder.rb
Overview
Query construction logic for fact-related database queries Builds Sequel datasets with appropriate joins and selects Follows Functional Core pattern - pure query building, no execution
Class Method Summary collapse
-
.batch_find_facts(store, fact_ids) ⇒ Hash
Build dataset for batch finding facts with entity joins.
-
.batch_find_receipts(store, fact_ids, include_raw_text: false) ⇒ Hash
Build dataset for batch finding receipts (provenance) with content_items join.
-
.build_facts_dataset(store) ⇒ Sequel::Dataset
Build standard facts dataset with entity join and all necessary columns.
-
.build_receipts_dataset(store, include_raw_text: false) ⇒ Sequel::Dataset
Build standard receipts dataset with content_items join.
-
.fetch_changes(store, since, limit) ⇒ Array<Hash>
Find facts created since a given timestamp.
-
.find_conflicts(store, fact_id) ⇒ Array<Hash>
Find conflicts involving the given fact.
-
.find_fact(store, fact_id) ⇒ Hash?
Find single fact by ID with entity join.
-
.find_fact_by_docid(store, docid) ⇒ Hash?
Find single fact by docid with entity join.
-
.find_provenance_by_content(store, content_id) ⇒ Array<Hash>
Find provenance records for a content item.
-
.find_receipts(store, fact_id, include_raw_text: false) ⇒ Array<Hash>
Find receipts for a single fact.
-
.find_superseded_by(store, fact_id) ⇒ Array<Integer>
Find fact IDs that supersede the given fact.
-
.find_supersedes(store, fact_id) ⇒ Array<Integer>
Find fact IDs that are superseded by the given fact.
Class Method Details
.batch_find_facts(store, fact_ids) ⇒ Hash
Build dataset for batch finding facts with entity joins
13 14 15 16 17 18 19 20 21 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 13 def self.batch_find_facts(store, fact_ids) return {} if fact_ids.empty? results = build_facts_dataset(store) .where(Sequel[:facts][:id] => fact_ids) .all results.each_with_object({}) { |row, hash| hash[row[:id]] = row } end |
.batch_find_receipts(store, fact_ids, include_raw_text: false) ⇒ Hash
Build dataset for batch finding receipts (provenance) with content_items join
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 28 def self.batch_find_receipts(store, fact_ids, include_raw_text: false) return {} if fact_ids.empty? results = build_receipts_dataset(store, include_raw_text: include_raw_text) .where(Sequel[:provenance][:fact_id] => fact_ids) .all results.group_by { |row| row[:fact_id] }.tap do |grouped| # Ensure all requested fact_ids have an entry (empty array if no receipts) fact_ids.each { |id| grouped[id] ||= [] } end end |
.build_facts_dataset(store) ⇒ Sequel::Dataset
Build standard facts dataset with entity join and all necessary columns
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 131 def self.build_facts_dataset(store) store.facts .left_join(:entities, id: :subject_entity_id) .select( Sequel[:facts][:id], Sequel[:facts][:docid], Sequel[:facts][:predicate], Sequel[:facts][:object_literal], Sequel[:facts][:status], Sequel[:facts][:confidence], Sequel[:facts][:valid_from], Sequel[:facts][:valid_to], Sequel[:facts][:created_at], Sequel[:entities][:canonical_name].as(:subject_name), Sequel[:facts][:scope], Sequel[:facts][:project_path] ) end |
.build_receipts_dataset(store, include_raw_text: false) ⇒ Sequel::Dataset
Build standard receipts dataset with content_items join
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 154 def self.build_receipts_dataset(store, include_raw_text: false) columns = [ Sequel[:provenance][:id], Sequel[:provenance][:fact_id], Sequel[:provenance][:quote], Sequel[:provenance][:strength], Sequel[:provenance][:line_start], Sequel[:provenance][:line_end], Sequel[:content_items][:session_id], Sequel[:content_items][:occurred_at] ] columns << Sequel[:content_items][:raw_text] if include_raw_text store.provenance .left_join(:content_items, id: :content_item_id) .select(*columns) end |
.fetch_changes(store, since, limit) ⇒ Array<Hash>
Find facts created since a given timestamp
108 109 110 111 112 113 114 115 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 108 def self.fetch_changes(store, since, limit) store.facts .select(:id, :docid, :subject_entity_id, :predicate, :object_literal, :status, :created_at, :scope, :project_path) .where { created_at >= since } .order(Sequel.desc(:created_at)) .limit(limit) .all end |
.find_conflicts(store, fact_id) ⇒ Array<Hash>
Find conflicts involving the given fact
96 97 98 99 100 101 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 96 def self.find_conflicts(store, fact_id) store.conflicts .select(:id, :fact_a_id, :fact_b_id, :status) .where(Sequel.or(fact_a_id: fact_id, fact_b_id: fact_id)) .all end |
.find_fact(store, fact_id) ⇒ Hash?
Find single fact by ID with entity join
45 46 47 48 49 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 45 def self.find_fact(store, fact_id) build_facts_dataset(store) .where(Sequel[:facts][:id] => fact_id) .first end |
.find_fact_by_docid(store, docid) ⇒ Hash?
Find single fact by docid with entity join
55 56 57 58 59 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 55 def self.find_fact_by_docid(store, docid) build_facts_dataset(store) .where(Sequel[:facts][:docid] => docid) .first end |
.find_provenance_by_content(store, content_id) ⇒ Array<Hash>
Find provenance records for a content item
121 122 123 124 125 126 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 121 def self.find_provenance_by_content(store, content_id) store.provenance .select(:id, :fact_id, :content_item_id, :quote, :strength) .where(content_item_id: content_id) .all end |
.find_receipts(store, fact_id, include_raw_text: false) ⇒ Array<Hash>
Find receipts for a single fact
66 67 68 69 70 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 66 def self.find_receipts(store, fact_id, include_raw_text: false) build_receipts_dataset(store, include_raw_text: include_raw_text) .where(Sequel[:provenance][:fact_id] => fact_id) .all end |
.find_superseded_by(store, fact_id) ⇒ Array<Integer>
Find fact IDs that supersede the given fact
76 77 78 79 80 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 76 def self.find_superseded_by(store, fact_id) store.fact_links .where(to_fact_id: fact_id, link_type: "supersedes") .select_map(:from_fact_id) end |
.find_supersedes(store, fact_id) ⇒ Array<Integer>
Find fact IDs that are superseded by the given fact
86 87 88 89 90 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 86 def self.find_supersedes(store, fact_id) store.fact_links .where(from_fact_id: fact_id, link_type: "supersedes") .select_map(:to_fact_id) end |