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.
All functions take a resolved %Lotus.Source.Adapter{} struct. Cache keys
are derived from adapter.name, which is always a string and independent of
the adapter's internal state shape (repo module, keyword list, etc.).
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
adapter = Lotus.Source.resolve!("main", nil)
# Get all columns for a table
{:ok, schema} = SchemaCache.describe_table(adapter, "public", "users")
# => %{"id" => %{type: "uuid", nullable: false, ...}, ...}
# Get specific column type
{:ok, type} = SchemaCache.get_column_type(adapter, "public", "users", "id")
# => "uuid"
# Invalidate cache after migrations
SchemaCache.invalidate(adapter, "public", "users")
Summary
Functions
Get column metadata for a table. Returns map of column_name => column_info. Caches result for subsequent calls.
Get specific column type. Returns the database-native type string.
Invalidate cache for a specific table (useful after migrations).
Warm cache with frequently-used tables on application startup.
Types
Functions
@spec describe_table( adapter :: Lotus.Source.Adapter.t(), 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.describe_table(adapter, "public", "users")
schema["id"]
# => %{type: "uuid", nullable: false, default: nil, primary_key: true}
@spec get_column_type( adapter :: Lotus.Source.Adapter.t(), 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(adapter, "public", "users", "id")
# => "uuid"
SchemaCache.get_column_type(adapter, "public", "users", "nonexistent")
# => :not_found
@spec invalidate( adapter :: Lotus.Source.Adapter.t(), schema :: String.t() | nil, table :: String.t() ) :: :ok
Invalidate cache for a specific table (useful after migrations).
Examples
SchemaCache.invalidate(adapter, "public", "users")
# => :ok
@spec warm_cache( adapter :: Lotus.Source.Adapter.t(), tables :: [{schema :: String.t() | nil, table :: String.t()}] ) :: :ok
Warm cache with frequently-used tables on application startup.
Examples
SchemaCache.warm_cache(adapter, [
{"public", "users"},
{"public", "orders"}
])
# => :ok