Drops.Relation.Schema (drops_relation v0.1.0)

View Source

Represents schema metadata for a relation.

This struct stores all extracted metadata about a relation including primary keys, foreign keys, field information, and indices. It serves as a central container for schema information used for automatic Ecto schema generation and query compilation.

Structure

  • source - The database table name
  • fields - List of field definitions with types and metadata
  • primary_key - Primary key information
  • foreign_keys - List of foreign key relationships
  • indices - List of database indices

Access Behavior

The schema implements the Access behavior, allowing field lookup by name:

schema[:email]  # Returns the email field
schema[:id]     # Returns the id field

Usage with Relation Modules

Schemas are automatically created when you define a relation module and are accessible via the schema/0 function:

defmodule MyApp.Users do
  use Drops.Relation, repo: MyApp.Repo

  schema("users", infer: true)
end

# Access the relation's schema
schema = MyApp.Users.schema()

# Inspect schema metadata
schema.source        # => :users
schema.fields        # => [%Field{name: :id, type: :integer}, ...]
schema.primary_key   # => %PrimaryKey{fields: [:id]}

# Access specific fields
email_field = schema[:email]
id_field = schema[:id]

# Get field information
email_field.type     # => :string
email_field.meta     # => %{type: :varchar, ...}

Field Access Examples

# Check if a field exists
if schema[:email] do
  IO.puts("Email field exists with type: " <> to_string(schema[:email].type))
end

# Get all field names
field_names = Enum.map(schema.fields, & &1.name)
# => [:id, :name, :email, :active, :inserted_at, :updated_at]

# Filter fields by type
string_fields = Enum.filter(schema.fields, &(&1.type == :string))

Summary

Functions

Finds a field by name in the schema.

Merges two schemas, with the right schema taking precedence for conflicts.

Creates a new Schema struct with the provided metadata.

Access

Access behavior implementation for fetching fields by name.

Access behavior implementation for updating fields.

Access behavior implementation for removing fields.

Types

field_metadata()

@type field_metadata() :: %{name: atom(), type: atom(), type: term(), source: atom()}

t()

@type t() :: %Drops.Relation.Schema{
  fields: [Drops.Relation.Schema.Field.t()],
  foreign_keys: [Drops.Relation.Schema.ForeignKey.t()],
  indices: [Drops.Relation.Schema.Index.t()],
  primary_key: Drops.Relation.Schema.PrimaryKey.t() | nil,
  source: atom()
}

Functions

find_field(schema, field_name)

@spec find_field(t(), atom()) :: Drops.Relation.Schema.Field.t() | nil

Finds a field by name in the schema.

Examples

iex> field = Drops.Relation.Schema.find_field(schema, :email)
iex> field.name
:email

merge(left, right)

@spec merge(t(), t()) :: t()

Merges two schemas, with the right schema taking precedence for conflicts.

Parameters

  • left - The base schema
  • right - The schema to merge into the base, takes precedence

Returns

A merged Drops.Relation.Schema.t() struct.

Examples

iex> left = Drops.Relation.Schema.new(:users, pk, [], [field1], [])
iex> right = Drops.Relation.Schema.new(:users, pk, [], [field2], [])
iex> merged = Drops.Relation.Schema.merge(left, right)
iex> length(merged.fields)
2

new(source)

@spec new(atom()) :: t()
@spec new(map()) :: t()

Creates a new Schema struct with the provided metadata.

Parameters

  • source - The table name
  • primary_key - Primary key information
  • foreign_keys - List of foreign key relationships
  • fields - List of field metadata
  • indices - Index information

new(source, fields, rest \\ [])

@spec new(atom(), [Drops.Relation.Schema.Field.t()], keyword()) :: t()

new(source, primary_key, foreign_keys, fields, indices \\ [])

primary_key?(map, field)

project(schema, fields)

@spec project(t(), [atom()]) :: t()

Access

fetch(schema, key)

Access behavior implementation for fetching fields by name.

Examples

iex> schema[:email]  # Returns the email field
iex> schema[:id]     # Returns the id field

get_and_update(schema, key, function)

Access behavior implementation for updating fields.

Examples

iex> get_and_update(schema, :email, fn field -> {field, %{field | type: :string}} end)

pop(schema, key)

Access behavior implementation for removing fields.

Examples

iex> pop(schema, :email)  # Removes and returns the email field