Bier.Introspection (bier v0.1.0)

Copy Markdown View Source

Database introspection.

Queries pg_catalog for the relations (tables and views) exposed across the configured db_schemas, along with their columns, primary keys, and foreign keys. Foreign keys are needed by the request pipeline for resource embedding.

The result is a map keyed by {schema, relation} so the router/controller can resolve a request target in constant time:

%{
  {"test", "items"} => %Bier.Introspection.Relation{
    schema: "test",
    name: "items",
    kind: :table | :view,
    columns: [%{name: "id", type: "bigint", pk?: true, notnull?: true, default: ...}, ...],
    primary_key: ["id"],
    foreign_keys: [%{columns: ["client_id"], ref_schema: "test", ref_relation: "clients", ref_columns: ["id"], constraint: "..."}]
  },
  ...
}

Summary

Functions

Introspect callable /rpc/<fn> functions across schemas.

Introspect custom media-type handlers across schemas.

Whether the postgis extension is installed in the database.

Per-role access map for openapi-mode = follow-privileges.

Introspects schemas over the given Postgrex connection.

Returns the COMMENT on schema, or nil.

Types

t()

@type t() :: %{optional({String.t(), String.t()}) => Bier.Introspection.Relation.t()}

Functions

functions(conn, schemas)

@spec functions(conn :: term(), schemas :: [String.t()]) :: %{
  optional({String.t(), String.t()}) => [map()]
}

Introspect callable /rpc/<fn> functions across schemas.

Returns a map keyed by {schema, function_name} whose value is the list of overloads for that name (PostgREST dispatches an overloaded RPC by the supplied argument names). Each overload carries:

  • args — ordered IN/INOUT/VARIADIC parameters with name, type, mode (:in | :inout | :variadic), variadic?, and has_default? (derived from pronargdefaults vs the trailing input args).
  • out_args — OUT/INOUT/TABLE columns (the result shape for record returns).
  • ret_kind / ret_schema / ret_relation / ret_type — return shape.
  • volatility:immutable | :stable | :volatile (GET is rejected for a volatile proc, which runs in a read-only transaction).

  • single_unnamed? — a single unnamed scalar/json IN parameter binds the raw request body positionally rather than as named args.

media_handlers(conn, schemas)

@spec media_handlers(conn :: term(), schemas :: [String.t()]) :: [map()]

Introspect custom media-type handlers across schemas.

PostgREST models a custom media type as a DOMAIN whose name is the MIME string, and a handler as an aggregate whose transition state type is that domain. The aggregate's first argument type is the relation (or anyelement) the handler applies to. Returns a list of handler maps.

postgis?(conn)

@spec postgis?(conn :: term()) :: boolean()

Whether the postgis extension is installed in the database.

Gates the built-in application/geo+json producer: its rendering relies on PostGIS's ST_AsGeoJSON, so without the extension the media type is not offered (a geo+json Accept then yields 406 PGRST107).

privileges(conn, schemas, role)

@spec privileges(conn :: term(), schemas :: [String.t()], role :: String.t()) :: %{
  relations: map(),
  functions: map()
}

Per-role access map for openapi-mode = follow-privileges.

Returns %{relations: %{{schema, name} => %{select?, insert?, update?, delete?}}, functions: %{{schema, name} => %{execute?}}}. PostgreSQL resolves role membership, so a role inherits grants from roles it belongs to. Functions are aggregated across overloads (execute? is true when ANY overload is callable).

run(conn, schemas, extra_search_path \\ [])

@spec run(conn :: term(), schemas :: [String.t()], extra_search_path :: [String.t()]) ::
  t()

Introspects schemas over the given Postgrex connection.

extra_search_path is db-extra-search-path. It widens exactly one thing: where a computed field's function may live (see query_computed/3). Every other query — relations, columns, foreign keys, callable /rpc/ routines — stays scoped to schemas, so an extra-path schema never becomes part of the exposed API surface.

Returns a map keyed by {schema, relation}.

schema_comment(conn, schema)

@spec schema_comment(conn :: term(), schema :: String.t()) :: String.t() | nil

Returns the COMMENT on schema, or nil.