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 149 |
# 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[:facts][:last_recalled_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
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/claude_memory/core/fact_query_builder.rb', line 155 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 |