SelectoMix.Introspector behaviour (selecto_mix v0.4.2)

Protocol for introspecting different schema sources.

This protocol provides a unified interface for discovering database schema information from different sources:

  • Ecto schema modules (via __schema__/1 callbacks)
  • Direct PostgreSQL connections (via Postgrex and system catalogs)
  • Future: Other database types (MySQL, SQLite, etc.)

Usage

# Ecto schema
{:ok, metadata} = SelectoMix.Introspector.introspect(MyApp.User, [])

# Postgrex connection
{:ok, conn} = Postgrex.start_link(...)
{:ok, metadata} = SelectoMix.Introspector.introspect(
  {:postgrex, conn, "users"},
  []
)

Metadata Format

All introspectors return a standardized metadata map:

%{
  table_name: "users",
  schema: "public",
  fields: [:id, :name, :email, :inserted_at, :updated_at],
  field_types: %{
    id: :integer,
    name: :string,
    email: :string,
    inserted_at: :naive_datetime,
    updated_at: :naive_datetime
  },
  primary_key: :id,  # or [:id, :tenant_id] for composite
  associations: %{
    posts: %{
      type: :has_many,
      ...
    },
    profile: %{
      type: :has_one,
      ...
    }
  },
  columns: %{
    id: %{type: :integer, nullable: false, ...},
    name: %{type: :string, nullable: false, ...},
    ...
  },
  source: :ecto  # or :postgres, :mysql, etc.
}

Summary

Callbacks

Introspect a schema source and return standardized metadata.

Functions

Convenience function that delegates to protocol implementation.

Types

metadata()

@type metadata() :: %{
  table_name: String.t(),
  schema: String.t(),
  fields: [atom()],
  field_types: %{required(atom()) => atom()},
  primary_key: atom() | [atom()] | nil,
  associations: %{required(atom()) => map()},
  columns: %{required(atom()) => map()},
  source: :ecto | :postgres | atom()
}

opts()

@type opts() :: keyword()

source()

@type source() ::
  module()
  | {:db, module(), term(), table_name :: String.t()}
  | {:db, module(), term(), table_name :: String.t(), keyword()}
  | {:postgrex, pid() | atom(), table_name :: String.t()}
  | {:postgrex, pid() | atom(), table_name :: String.t(), schema :: String.t()}

Callbacks

introspect(source, opts)

@callback introspect(source(), opts()) :: {:ok, metadata()} | {:error, term()}

Introspect a schema source and return standardized metadata.

Parameters

  • source - Schema source (Ecto module, Postgrex connection tuple, etc.)
  • opts - Options passed to the specific introspector

Returns

  • {:ok, metadata} - Standardized metadata map
  • {:error, reason} - Error details

Functions

introspect(source, opts \\ [])

Convenience function that delegates to protocol implementation.