Lotus.Storage.SchemaCache (Lotus v0.16.5)

Copy Markdown View Source

Caches table schema metadata for automatic type detection and casting.

Maintains in-memory representation of database schema. Uses Lotus's existing ETS-based cache infrastructure to store table/column metadata and avoid repeated information_schema queries.

Features

  • Table-level caching: Caches all columns for a table together for efficiency
  • TTL-based expiration: Default 5-minute TTL (configurable)
  • Graceful degradation: Falls back to direct schema query if cache unavailable
  • Warm cache support: Preload frequently-used tables on application startup

Usage

# Get all columns for a table
{:ok, schema} = SchemaCache.get_table_schema(MyApp.Repo, "public", "users")
# => %{"id" => %{type: "uuid", nullable: false, ...}, ...}

# Get specific column type
{:ok, type} = SchemaCache.get_column_type(MyApp.Repo, "public", "users", "id")
# => "uuid"

# Invalidate cache after migrations
SchemaCache.invalidate(MyApp.Repo, "public", "users")

Summary

Functions

Get specific column type. Returns the database-native type string.

Get column metadata for a table. Returns map of column_name => column_info. Caches result for subsequent calls.

Invalidate cache for a specific table (useful after migrations).

Warm cache with frequently-used tables on application startup.

Types

column_info()

@type column_info() :: %{
  type: String.t(),
  nullable: boolean(),
  default: term() | nil,
  primary_key: boolean()
}

Functions

get_column_type(repo, schema, table, column)

@spec get_column_type(
  repo :: module(),
  schema :: String.t() | nil,
  table :: String.t(),
  column :: String.t()
) :: {:ok, String.t()} | :not_found

Get specific column type. Returns the database-native type string.

Examples

{:ok, type} = SchemaCache.get_column_type(MyApp.Repo, "public", "users", "id")
# => "uuid"

SchemaCache.get_column_type(MyApp.Repo, "public", "users", "nonexistent")
# => :not_found

get_table_schema(repo, schema, table)

@spec get_table_schema(
  repo :: module(),
  schema :: String.t() | nil,
  table :: String.t()
) :: {:ok, %{required(String.t()) => column_info()}} | {:error, term()}

Get column metadata for a table. Returns map of column_name => column_info. Caches result for subsequent calls.

Examples

{:ok, schema} = SchemaCache.get_table_schema(MyApp.Repo, "public", "users")
schema["id"]
# => %{type: "uuid", nullable: false, default: nil, primary_key: true}

invalidate(repo, schema, table)

@spec invalidate(repo :: module(), schema :: String.t() | nil, table :: String.t()) ::
  :ok

Invalidate cache for a specific table (useful after migrations).

Examples

SchemaCache.invalidate(MyApp.Repo, "public", "users")
# => :ok

warm_cache(repo, tables)

@spec warm_cache(
  repo :: module(),
  tables :: [{schema :: String.t() | nil, table :: String.t()}]
) :: :ok

Warm cache with frequently-used tables on application startup.

Examples

SchemaCache.warm_cache(MyApp.Repo, [
  {"public", "users"},
  {"public", "orders"}
])
# => :ok