MnemosyneEcto.Adapter behaviour (mnemosyne_ecto v0.2.0)

Copy Markdown View Source

Database-specific behaviour for the Mnemosyne Ecto backend.

Each supported database (PostgreSQL + pgvector, SQLite + sqlite-vec) provides an implementation that encapsulates everything that differs between engines: the embedding column type, how embeddings are encoded/decoded, how a vector similarity query is expressed, extension setup, and how the migration version is tracked.

The active adapter is resolved at runtime from the repository's Ecto adapter via for_repo/1, so callers only ever configure a standard Ecto.Repo.

Summary

Callbacks

Creates engine-specific vector indexes for the nodes table. May be a no-op (e.g. SQLite brute-force).

Decodes a stored embedding value (driver struct or list) back into a plain list of floats.

The migration column type for the embedding field given the vector dimensionality.

Encodes an embedding list into the value the driver expects for insert_all. Passthrough for nil.

Reads the currently migrated schema version for the given prefix. Returns 0 when unmigrated.

The Ecto schema module for the nodes table (embedding column type differs per engine).

Persists the migrated schema version for the given prefix (run inside a migration).

Engine-specific setup run before creating tables (e.g. CREATE EXTENSION vector). May be a no-op.

Engine-specific teardown run during a full rollback (e.g. dropping a version table). May be a no-op.

The migration column type used for timestamp columns.

Builds an Ecto.Query returning the limit nearest nodes of type to query_embedding (a plain list), ordered by ascending cosine distance and scoped to the state's tenant/repo.

Functions

Resolves the implementation directly from an Ecto adapter module.

Resolves the MnemosyneEcto.Adapter implementation for the given repo based on its configured Ecto adapter.

Types

state()

@type state() :: map()

Callbacks

create_vector_indexes(table, opts)

@callback create_vector_indexes(table :: atom(), opts :: keyword()) :: any()

Creates engine-specific vector indexes for the nodes table. May be a no-op (e.g. SQLite brute-force).

decode_embedding(term)

@callback decode_embedding(term()) :: [float()] | nil

Decodes a stored embedding value (driver struct or list) back into a plain list of floats.

embedding_column_type(dimensions)

@callback embedding_column_type(dimensions :: pos_integer()) :: atom()

The migration column type for the embedding field given the vector dimensionality.

encode_embedding(arg1)

@callback encode_embedding([float()] | nil) :: term()

Encodes an embedding list into the value the driver expects for insert_all. Passthrough for nil.

migrated_version(repo, prefix)

@callback migrated_version(repo :: Ecto.Repo.t(), prefix :: String.t()) ::
  non_neg_integer()

Reads the currently migrated schema version for the given prefix. Returns 0 when unmigrated.

node_schema()

@callback node_schema() :: module()

The Ecto schema module for the nodes table (embedding column type differs per engine).

set_version(prefix, version)

@callback set_version(prefix :: String.t(), version :: pos_integer()) :: any()

Persists the migrated schema version for the given prefix (run inside a migration).

setup opts

@callback setup(opts :: keyword()) :: any()

Engine-specific setup run before creating tables (e.g. CREATE EXTENSION vector). May be a no-op.

teardown(prefix)

@callback teardown(prefix :: String.t()) :: any()

Engine-specific teardown run during a full rollback (e.g. dropping a version table). May be a no-op.

timestamp_column_type()

@callback timestamp_column_type() :: atom()

The migration column type used for timestamp columns.

vector_search(state, type, query_embedding, limit)

@callback vector_search(
  state(),
  type :: atom(),
  query_embedding :: [float()],
  limit :: non_neg_integer()
) :: Ecto.Query.t()

Builds an Ecto.Query returning the limit nearest nodes of type to query_embedding (a plain list), ordered by ascending cosine distance and scoped to the state's tenant/repo.

Functions

for_ecto_adapter(other)

@spec for_ecto_adapter(module()) :: module()

Resolves the implementation directly from an Ecto adapter module.

for_repo(repo)

@spec for_repo(Ecto.Repo.t()) :: module()

Resolves the MnemosyneEcto.Adapter implementation for the given repo based on its configured Ecto adapter.

Raises ArgumentError for unsupported adapters.