Lotus.Schema (Lotus v0.16.4)

Copy Markdown View Source

Schema introspection functionality for Lotus.

Provides functions to list schemas, tables and inspect table schemas across different database adapters (PostgreSQL, MySQL, SQLite, etc.).

Visibility Filtering

All schema and table listing functions automatically apply visibility rules configured in your application:

  • Schema visibility filters which schemas are accessible
  • Table visibility filters which tables within allowed schemas are accessible
  • Built-in security automatically blocks system schemas and tables

Schema visibility takes precedence - if a schema is denied, all tables within it are blocked regardless of table-level rules.

Database-Specific Behavior

  • PostgreSQL: Returns namespaced {schema, table} tuples
  • MySQL: Returns {database, table} tuples (schemas = databases in MySQL)
  • SQLite: Returns table names as strings (schema-less)

Summary

Functions

Gets the schema information for a specific table.

Gets basic statistics about a table.

Lists all relations (tables with schema information) in the given repository.

Lists all visible schemas in the given repository.

Lists all visible tables in the given repository.

Functions

get_table_schema(repo_or_name, table_name, opts \\ [])

@spec get_table_schema(module() | String.t(), String.t(), keyword()) ::
  {:ok, [map()]} | {:error, term()}

Gets the schema information for a specific table.

Returns a list of column definitions with their types and constraints.

Options

  • :schema - Look for table in specific schema
  • :schemas - Search for table in multiple schemas (first match wins)
  • :search_path - Use PostgreSQL search_path to resolve table location
  • :cache - Cache options (profile, ttl_ms, etc.)

Examples

{:ok, schema} = Lotus.Schema.get_table_schema(MyApp.Repo, "users")
# Returns schema for public.users

{:ok, schema} = Lotus.Schema.get_table_schema("postgres", "customers", schema: "reporting")
# Returns schema for reporting.customers

{:ok, schema} = Lotus.Schema.get_table_schema("postgres", "customers", search_path: "reporting, public")
# Finds customers table using search_path resolution

get_table_stats(repo_or_name, table_name, opts \\ [])

@spec get_table_stats(module() | String.t(), String.t(), keyword()) ::
  {:ok, %{row_count: non_neg_integer()}} | {:error, binary()}

Gets basic statistics about a table.

Returns information like row count and table size.

Options

  • :schema - Look for table in specific schema
  • :schemas - Search for table in multiple schemas (first match wins)
  • :search_path - Use PostgreSQL search_path to resolve table location
  • :cache - Cache options (profile, ttl_ms, etc.)

Examples

{:ok, stats} = Lotus.Schema.get_table_stats(MyApp.Repo, "users")
# Returns: %{row_count: 1234}

{:ok, stats} = Lotus.Schema.get_table_stats("postgres", "customers", schema: "reporting")
# Gets stats for reporting.customers

list_relations(repo_or_name, opts \\ [])

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

Lists all relations (tables with schema information) in the given repository.

Similar to list_tables/2 but returns {schema, table} tuples instead of just table names. Useful for UIs that need to display schema information.

Examples

{:ok, relations} = Lotus.Schema.list_relations("postgres", search_path: "reporting, public")
# Returns [{"reporting", "customers"}, {"reporting", "orders"}, {"public", "users"}, ...]

list_schemas(repo_or_name, opts \\ [])

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

Lists all visible schemas in the given repository.

Returns a list of schema names filtered by visibility rules. For databases without schemas (like SQLite), returns an empty list.

Note: Results are automatically filtered by schema visibility rules. System schemas (like pg_catalog) are always blocked for security.

Options

  • :cache - Cache options (profile, ttl_ms, etc.)

Examples

{:ok, schemas} = Lotus.Schema.list_schemas(MyApp.Repo)
# PostgreSQL: ["public", "reporting", ...]  (filtered by visibility)

{:ok, schemas} = Lotus.Schema.list_schemas("mysql")
# MySQL: ["app_production", "analytics_db", ...]  (databases = schemas)

{:ok, schemas} = Lotus.Schema.list_schemas("sqlite")
# SQLite: []  (schema-less database)

list_tables(repo_or_name, opts \\ [])

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

Lists all visible tables in the given repository.

For databases with schemas (like PostgreSQL), returns {schema, table} tuples. For databases without schemas (like SQLite), returns just table names as strings.

Note: Results are automatically filtered by visibility rules:

  1. Schema visibility is checked first - denied schemas block all their tables
  2. Table visibility is then applied to tables in allowed schemas
  3. System tables are always blocked for security

Options

  • :schema - Search in specific schema (e.g., schema: "reporting")
  • :schemas - Search in multiple schemas (e.g., schemas: ["reporting", "public"])
  • :search_path - Use PostgreSQL search_path (e.g., search_path: "reporting, public")
  • :include_views - Include views in results (default: false)

Examples

{:ok, tables} = Lotus.Schema.list_tables(MyApp.Repo)
# PostgreSQL: [{"public", "users"}, {"public", "posts"}, ...]  (filtered by visibility)

{:ok, tables} = Lotus.Schema.list_tables("postgres", search_path: "reporting, public")
# PostgreSQL: [{"reporting", "customers"}, {"reporting", "orders"}, {"public", "users"}, ...]

{:ok, tables} = Lotus.Schema.list_tables("mysql")
# MySQL: [{"app_db", "users"}, {"analytics_db", "reports"}, ...]  (databases = schemas)

{:ok, tables} = Lotus.Schema.list_tables("sqlite")
# SQLite: ["products", "orders", "order_items"]  (schema-less)