abstract class Memo::Queries

Overview

Abstract query interface for database-backend-specific SQL.

Each backend (SQLite, PostgreSQL) implements all query methods with SQL native to that backend. This avoids placeholder translation and keeps SQL explicit per backend.

Direct Known Subclasses

Defined in:

memo/queries/base.cr

Constructors

Class Method Summary

Instance Method Summary

Constructor Detail

def self.for(db : DB::Database, connection_string : String) : Queries #

[View source]
def self.new(db : DBHandle) #

[View source]

Class Method Detail

def self.register_pg(&factory : DB::Database -> Queries) #

[View source]

Instance Method Detail

abstract def add_meta(key : String, value : String) : Nil #

Set a meta value unless the key already has one


[View source]
abstract def chunk_content_ids(source_id : Int64) : Array(Int64) #

The texts a source's chunks were cut from


[View source]
abstract def chunk_states(source_id : Int64, service_id : Int64) : Array(Tuple(Int64 | Nil, Int64 | Nil, Int64 | Nil, String, Bool)) #

Per chunk of a source: {content_id, pair_id, parent_id, source_type, whether its hash has an embedding, with a stored vector, for the service}


[View source]
abstract def clear_completed_queue : Int32 #

[View source]
abstract def clear_completed_queue_texts : Nil #

Drop the text of finished items (from before memo did so itself)


[View source]
abstract def clear_default_service : Nil #

[View source]
abstract def clear_query_cache(service_id : Int64) : Nil #

[View source]
abstract def clear_queue : Int32 #

[View source]
abstract def complete_queue_item(id : Int64, text : String, processed_at : Int64) : Bool #

The mark_queue_* methods take the item's text as it was read, and do nothing if it has changed since: the source was queued again, and the newer text still needs embedding. Mark the item done if it still holds text (nothing changed it since it was read). Returns whether it did.


[View source]
abstract def count_chunks_by_hash(hash : Bytes) : Int64 #

[View source]
abstract def count_chunks_for_service(service_id : Int64) : Int64 #

[View source]
abstract def count_embeddings_for_service(service_id : Int64) : Int64 #

[View source]
abstract def count_files : Int64 #

[View source]
abstract def count_query_cache(service_id : Int64) : Int64 #

[View source]
abstract def count_service_chunks(service_id : Int64) : Int64 #

[View source]
abstract def count_service_embeddings(service_id : Int64) : Int64 #

[View source]
abstract def count_service_sources(service_id : Int64) : Int64 #

[View source]
abstract def count_services : Int64 #

[View source]
abstract def count_vectors(service_id : Int64) : Int64 #

[View source]
abstract def count_vocab(service_id : Int64) : Int64 #

[View source]
def db : DBHandle #

[View source]
abstract def delete_chunks(hash : Bytes, source_id : Int64, source_type : String) : Int32 #

[View source]
abstract def delete_chunks(hash : Bytes, source_id : Int64) : Int32 #

[View source]
abstract def delete_embeddings_by_hash(hash : Bytes) : Nil #

[View source]
abstract def delete_embeddings_by_service(service_id : Int64) : Nil #

[View source]
abstract def delete_file(source_id : Int64) : Int64 #

[View source]
abstract def delete_index_data(service_id : Int64) : Nil #

Remove a service's vectors, journal entries and journal state


[View source]
abstract def delete_queue_item(source_id : Int64) : Nil #

[View source]
abstract def delete_service(id : Int64) : Nil #

[View source]
abstract def delete_service_chunks(service_id : Int64) : Nil #

Delete the chunks whose embeddings only this service has


[View source]
abstract def delete_source_blob(source_type : String, external_id : Bytes) : Int64 #

[View source]
abstract def delete_source_by_id(internal_id : Int64) : Int64 #

[View source]
abstract def delete_source_int(source_type : String, external_id : Int64) : Int64 #

[View source]
abstract def delete_source_text(source_type : String, external_id : String) : Int64 #

[View source]
abstract def delete_vector(embedding_id : Int64) : Nil #

[View source]
abstract def delete_vocab(service_id : Int64) : Nil #

[View source]
abstract def embedded_hashes(hashes : Array(Bytes), service_id : Int64) : Set(Bytes) #

Which of hashes have an embedding for the service with a stored vector (one without has been lost: embed it again)


[View source]
abstract def embedding_ids_for_hash(hash : Bytes) : Array(Tuple(Int64, Int64)) #

{embedding id, service id} for every service's embedding of a hash


[View source]
abstract def embedding_ids_without_vectors(service_id : Int64) : Array(Int64) #

[View source]
abstract def enqueue(source_id : Int64, text : String, created_at : Int64) : Nil #

[View source]
abstract def fetch_search_results(service_id : Int64, params : Array(DB::Any), where_clauses : Array(String), text_join : String, fts_join : String, rowids : Array(Int64), include_text : Bool, per_embedding : Int32) : Array(Tuple(UInt64, Int64, Bytes, String, Int64, Int64 | Nil, String | Nil, Bytes | Nil, Int64 | Nil, Int64 | Nil, String | Nil, Bytes | Nil, Int64 | Nil, Int64 | Nil, String | Nil, Bytes | Nil, Int32 | Nil, Int32, Int32, Int32, String | Nil)) #

The chunks of rowids' embeddings that pass the filter clauses, at most per_embedding of each. An embedding is shared by every chunk with its text, so its other chunks may belong to sources the filters exclude.


[View source]
abstract def files_under(prefix : String) : Array(Tuple(Int64, String)) #

{source_id, path} of the files whose path starts with prefix


[View source]
abstract def filter_candidates(service_id : Int64, params : Array(DB::Any), where_clauses : Array(String), text_join : String, fts_join : String, candidate_ids : Array(Int64)) : Set(UInt64) #

Which of candidate_ids pass the filter clauses (looked up by id, so the cost depends on the number of candidates, not the collection)


[View source]
abstract def find_content_id(hash : Bytes) : Int64 | Nil #

[View source]
abstract def find_service_id(name : String) : Int64 | Nil #

[View source]
abstract def find_source_blob(source_type : String, external_id : Bytes) : Int64 | Nil #

[View source]
abstract def find_source_blob_any_type(external_id : Bytes) : Int64 | Nil #

[View source]
abstract def find_source_int(source_type : String, external_id : Int64) : Int64 | Nil #

[View source]
abstract def find_source_int_any_type(external_id : Int64) : Int64 | Nil #

[View source]
abstract def find_source_text(source_type : String, external_id : String) : Int64 | Nil #

[View source]
abstract def find_source_text_any_type(external_id : String) : Int64 | Nil #

[View source]
abstract def for_connection(cnn : DB::Connection) : Queries #

Same queries, run on one connection (for use inside a transaction).


[View source]
abstract def get_all_texts : Array(String) #

Every source's stored text (a text shared by several, once for each)


[View source]
abstract def get_chunk_hashes(source_id : Int64, source_type : String | Nil) : Array(Bytes) #

[View source]
abstract def get_chunk_id(source_id : Int64, offset : Int32 | Nil) : Int64 #

[View source]
abstract def get_chunks_for_reindex(source_type : String, service_id : Int64) : Array(Tuple(Int64, Int64 | Nil, String | Nil, Int64 | Nil, Int64 | Nil)) #

[View source]
abstract def get_default_service : ServiceProvider::Info | Nil #

[View source]
abstract def get_embedding_rowid(hash : Bytes, service_id : Int64) : Int64 #

[View source]
abstract def get_embedding_rowid?(hash : Bytes, service_id : Int64) : Int64 | Nil #

[View source]
abstract def get_existing_words(service_id : Int64, words : Array(String)) : Set(String) #

[View source]
abstract def get_file_by_hash(hash : Bytes) : Files::FileRecord | Nil #

[View source]
abstract def get_file_by_path(path : String) : Files::FileRecord | Nil #

[View source]
abstract def get_file_by_source(source_id : Int64) : Files::FileRecord | Nil #

[View source]
abstract def get_index_state(service_id : Int64) : Tuple(Int64, Bool) | Nil #

{pruned_through, vectors_backfilled}


[View source]
abstract def get_meta(key : String) : String | Nil #

[View source]
abstract def get_pending_queue(limit : Int32) : Array(Tuple(Int64, Int64, String)) #

[View source]
abstract def get_query_cache(query : String, service_id : Int64) : Tuple(Bytes, Int32) | Nil #

[View source]
abstract def get_queue_attempts(id : Int64) : Int32 | Nil #

nil once the item is gone (its source deleted)


[View source]
abstract def get_queue_item(source_id : Int64) : Tuple(Int64, String) | Nil #

[View source]
abstract def get_recent_query_cache(service_id : Int64, limit : Int32) : Array(Tuple(String, Bytes, Int32)) #

[View source]
abstract def get_service_by_format_model(format : String, model : String) : Tuple(Int64, String, String | Nil, String, Int32, Int32, Float64) | Nil #

[View source]
abstract def get_service_by_name(name : String) : Tuple(Int64, String, String | Nil, String, Int32, Int32, Float64) | Nil #

[View source]
abstract def get_service_info(id : Int64) : ServiceProvider::Info | Nil #

[View source]
abstract def get_service_info_by_name(name : String) : ServiceProvider::Info | Nil #

[View source]
abstract def get_service_tokens_per_byte(service_id : Int64) : Float64 | Nil #

[View source]
abstract def get_source_external(internal_id : Int64) : Tuple(String, Int64 | Nil, String | Nil, Bytes | Nil) | Nil #

[View source]
abstract def get_source_text(source_id : Int64) : String | Nil #

A source's latest text (nil if not stored)


[View source]
abstract def get_texts_for_reindex(source_type : String) : Array(Tuple(Int64, Int64 | Nil, Int64 | Nil, String)) #

[View source]
abstract def get_tokens_per_byte(service_id : Int64) : Float64 | Nil #

[View source]
abstract def get_vector(embedding_id : Int64, service_id : Int64) : Bytes | Nil #

[View source]
abstract def get_vocab(service_id : Int64, &block : DB::ResultSet -> ) : Nil #

[View source]
abstract def increment_match_count(chunk_ids : Array(Int64)) : Nil #

[View source]
abstract def increment_read_count(chunk_ids : Array(Int64)) : Nil #

[View source]
abstract def index_changes_since(service_id : Int64, seq : Int64) : Array(Int64) #

Distinct embedding ids logged after seq


[View source]
abstract def index_removals_between(service_id : Int64, after : Int64, through : Int64) : Array(Int64) #

Embeddings logged for the service after after and through through that it no longer has (no row, no vector): removals


[View source]
abstract def insert_chunk_ignore(hash : Bytes, source_id : Int64, source_type : String, content_id : Int64 | Nil, pair_id : Int64 | Nil, parent_id : Int64 | Nil, offset : Int32 | Nil, size : Int32, created_at : Int64) : Int64 #

[View source]
abstract def insert_embedding_ignore(hash : Bytes, service_id : Int64, token_count : Int32, created_at : Int64) : Int64 #

[View source]
abstract def insert_service(name : String, format : String, base_url : String | Nil, model : String, dimensions : Int32, max_tokens : Int32, created_at : Int64) : Int64 #

[View source]
abstract def insert_service_full(name : String, format : String, base_url : String | Nil, model : String, dimensions : Int32, max_tokens : Int32, is_default : Int32, created_at : Int64) : Int64 #

Insert service with is_default and return ID (for ServiceProvider.create)


[View source]
abstract def insert_source(source_type : String, created_at : Int64) : Int64 #

[View source]
abstract def insert_source_blob(source_type : String, external_id : Bytes, created_at : Int64) : Int64 | Nil #

[View source]
abstract def insert_source_int(source_type : String, external_id : Int64, created_at : Int64) : Int64 | Nil #

Insert a source unless one with this id exists (another writer may have added it since the caller looked). Returns its id, or nil if it existed.


[View source]
abstract def insert_source_text(source_type : String, external_id : String, created_at : Int64) : Int64 | Nil #

[View source]
abstract def legacy_texts_after(source_id : Int64, limit : Int32) : Array(Tuple(Int64, String, Bytes | Nil)) #

memo_texts rows (databases from before 0.13): {source_id, content, content_hash}


[View source]
abstract def list_files(limit : Int32, offset : Int32) : Array(Files::FileRecord) #

[View source]
abstract def list_services : Array(ServiceProvider::Info) #

[View source]
abstract def list_services_by_format(format : String) : Array(ServiceProvider::Info) #

[View source]
abstract def list_sources(source_type : String, limit : Int32, offset : Int32) : Array(Tuple(Int64, Int64 | Nil, String | Nil, Bytes | Nil)) #

[View source]
abstract def load_embedding_rowids(service_id : Int64, source_type : String, external_ids : Array(Int64)) : Array(Tuple(Int64, Int64)) #

[View source]
abstract def log_index_change(service_id : Int64, embedding_id : Int64) : Nil #

[View source]
abstract def mark_queue_failed(id : Int64, text : String, error_message : String | Nil, attempts : Int32, processed_at : Int64) : Nil #

[View source]
abstract def mark_queue_retry(id : Int64, text : String, attempts : Int32, error_message : String | Nil) : Nil #

[View source]
abstract def max_index_log_seq(service_id : Int64) : Int64 #

[View source]
abstract def prune_index_log(service_id : Int64, through : Int64) : Nil #

[View source]
abstract def prune_query_cache(service_id : Int64, count : Int64) : Nil #

[View source]
abstract def queue_stats : Tuple(Int64, Int64) #

[View source]
abstract def release_content(content_id : Int64) : Nil #

Delete a text unless a source or chunk still points at it


[View source]
abstract def search_filtered_rowids(service_id : Int64, params : Array(DB::Any), where_clauses : Array(String), text_join : String, fts_join : String) : Set(UInt64) #

[View source]
abstract def service_exists?(id : Int64) : Bool #

[View source]
abstract def set_chunks_content(source_id : Int64, content_id : Int64) : Nil #

[View source]
abstract def set_default_service(id : Int64) : Nil #

[View source]
abstract def set_index_pruned_through(service_id : Int64, seq : Int64) : Nil #

[View source]
abstract def set_meta(key : String, value : String) : Nil #

[View source]
abstract def set_source_content(source_id : Int64, content_id : Int64 | Nil) : Nil #

[View source]
abstract def set_vectors_backfilled(service_id : Int64) : Nil #

[View source]
abstract def source_content_id(source_id : Int64) : Int64 | Nil #

[View source]
abstract def update_file_path(source_id : Int64, path : String) : Nil #

[View source]
abstract def update_service(id : Int64, updates : Array(String), params : Array(DB::Any)) : Int64 #

[View source]
abstract def update_tokens_per_byte(tokens_per_byte : Float64, service_id : Int64) : Nil #

[View source]
abstract def update_word_frequency(count : Int32, word : String, service_id : Int64) : Nil #

[View source]
abstract def upsert_content(hash : Bytes, content : String | Nil, created_at : Int64) : Int64 #

The id of the text with this hash, storing it if new. content nil stores the hash alone.


[View source]
abstract def upsert_file(source_id : Int64, path : String, content_hash : Bytes, mtime : Int64, size : Int64, created_at : Int64) : Nil #

[View source]
abstract def upsert_query_cache(query : String, service_id : Int64, embedding : Bytes, token_count : Int32, created_at : Int64) : Nil #

[View source]
abstract def upsert_vector(embedding_id : Int64, service_id : Int64, vector : Bytes) : Nil #

[View source]
abstract def upsert_vocab(word : String, service_id : Int64, embedding : Bytes, frequency : Int32, created_at : Int64) : Nil #

[View source]
abstract def vectors_after(service_id : Int64, after_id : Int64, limit : Int32) : Array(Tuple(Int64, Bytes)) #

Up to limit {embedding id, vector} pairs with ids above after_id, in id order


[View source]