Drops.Relation.Cache (drops_relation v0.1.0)

View Source

Persistent cache for inferred Drops.Relation schemas based on migration file digests.

This module provides efficient caching of schema inference results to avoid redundant database introspection during compilation. The cache persists across application restarts using JSON files and is invalidated automatically when migration files change, ensuring schemas stay in sync with the database structure.

Features

  • JSON file-based persistent caching that survives application restarts
  • Migration digest-based cache invalidation
  • Multi-repository support
  • Graceful fallback when file operations fail

Usage

# Cache a schema explicitly
Drops.Relation.Cache.cache_schema(MyApp.Repo, "users", schema)

# Get cached schema (returns nil if not cached)
schema = Drops.Relation.Cache.get_cached_schema(MyApp.Repo, "users")

# Clear cache for a specific repository
Drops.Relation.Cache.clear_repo_cache(MyApp.Repo)

# Get cached schema or empty schema if not cached
schema = Drops.Relation.Cache.maybe_get_cached_schema(MyApp.Repo, "users")

# Check if cache is enabled
if Drops.Relation.Cache.enabled?() do
  # Cache-specific logic
end

# Warm up cache for specific tables
Drops.Relation.Cache.warm_up(MyApp.Repo, ["users", "posts", "comments"])

Summary

Functions

Manually caches a schema for a specific repository and table.

Clears the entire schema cache.

Clears all cached schemas for a specific repository.

Returns the cache file path for a given repo and table name. Used by relation modules to register the cache file as an external resource.

Forces a refresh of cached schemas for a repository.

Warms up the cache by pre-loading schemas for specified tables.

Functions

cache_schema(repo, table_name, schema)

@spec cache_schema(module(), String.t(), any()) :: :ok | {:error, term()}

Manually caches a schema for a specific repository and table.

This function is used to populate the cache after the application starts and the database becomes available. It's typically called during application startup or after migrations.

Parameters

  • repo - The Ecto repository module
  • table_name - The database table name
  • schema - The schema tuple to cache

clear_all()

@spec clear_all() :: :ok

Clears the entire schema cache.

This removes all cached schemas for all repositories.

clear_repo_cache(repo)

@spec clear_repo_cache(module()) :: :ok

Clears all cached schemas for a specific repository.

This is useful when you know the database structure has changed and want to force re-inference for all tables in a repository.

Parameters

  • repo - The Ecto repository module to clear cache for

Examples

Drops.Relation.Cache.clear_repo_cache(MyApp.Repo)

get_cache_file_path(repo, table_name)

@spec get_cache_file_path(module(), String.t()) :: String.t()

Returns the cache file path for a given repo and table name. Used by relation modules to register the cache file as an external resource.

get_cached_schema(repo, table_name)

@spec get_cached_schema(module(), String.t()) :: any() | nil

get_or_infer(repo, table_name)

@spec get_or_infer(module(), String.t()) :: Drops.Relation.Schema.t()

refresh(repo, table_names \\ nil)

@spec refresh(module(), [String.t()] | nil) :: :ok | {:error, term()}

Forces a refresh of cached schemas for a repository.

This clears the cache for the repository and then optionally warms it up again with the specified table names.

Parameters

  • repo - The Ecto repository module
  • table_names - Optional list of table names to warm up after clearing

Examples

# Just clear the cache
Drops.Relation.Cache.refresh(MyApp.Repo)

# Clear and warm up specific tables
Drops.Relation.Cache.refresh(MyApp.Repo, ["users", "posts"])

warm_up(repo, table_name)

@spec warm_up(module(), String.t()) :: Drops.Relation.Schema.t() | {:error, term()}
@spec warm_up(module(), [String.t()]) ::
  {:ok, [Drops.Relation.Schema.t()]} | {:error, term()}

Warms up the cache by pre-loading schemas for specified tables.

This function infers schemas for the given tables and caches the results. This can be useful during application startup to ensure frequently used schemas are cached.

Parameters

  • repo - The Ecto repository module
  • table_names - List of table names to warm up

Returns

Returns :ok on success, or {:error, reason} if warming up fails.

Examples

# Warm up cache for common tables
Drops.Relation.Cache.warm_up(MyApp.Repo, ["users", "posts", "comments"])