Sublimate.ProjectionData (Sublimate v0.1.0)

Copy Markdown

Describes a projection to the engine: its source and destination tables, join chain, identity column, and the strategy that defines what to derive.

A consumer builds a ProjectionData (usually through a small builder that maps its own config onto this shape) and hands it to Sublimate.Projection to install and run.

Struct fields by type

  • source

    :qualified_source_table, :source_table_alias, :identity_column, :add_identity_column_if_not_exists.

    The identity column is the backbone of a projection. Every projection row is keyed by the source identity, so the engine verifies that the identity column exists before installation.

  • destination

    :qualified_destination_table, :destination_table_unique_index.

    The destination table contains the projection's output. The consumer creates and owns this table; the engine only maintains its contents.

  • deltas

    :qualified_deltas_table, :deltas_table_unique_index.

    The deltas table stores pending changes before they are merged into the destination table. Its column structure is strategy-defined; these fields only identify the database objects managed by the engine.

  • database functions

    :qualified_destination_trigger_fn (the source-table trigger function that maintains the destination), :qualified_insert_merge_deltas_fn (the merge function).

  • database triggers

    :delta_trigger (the source-table trigger), :join_triggers (per-joined-table trigger and function names, keyed by table).

  • strategy

    The :strategy module and its :strategy_data belong together - the strategy is the only thing that interprets its own configuration - so they are set as a pair.

Construction

new/1 transforms the input config into a ProjectionData struct. It resolves qualified table names and the names of database objects managed by the engine, but does not inspect the database.

Schema-dependent work and derived descriptors are deferred to the strategy module's Sublimate.ProjectionStrategy.prepare/3 callback during installation.

Typically, a consumer maps its domain-specific configuration to this shape using a small builder instead of calling new/1 directly. The builder sets :strategy to the implementing module and :strategy_data to that implementation's configuration.

Summary

Types

Input data to generate a ProjectionData struct.

t()

Functions

Transforms a config/0 configuration map into a ProjectionData struct. It resolves qualified table names and the names of database objects managed by the engine.

Types

config()

@type config() :: %{
  destination_table: String.t(),
  identity_column: String.t(),
  source_table: String.t(),
  strategy_data: map(),
  strategy: module(),
  add_identity_column_if_not_exists: boolean() | nil,
  otp_app: atom() | nil
}

Input data to generate a ProjectionData struct.

Config fields

Required fields

  • destination_table

    The name of the destination table, with an optional database schema prefix.

  • identity_column

    The name of the column in the source table that uniquely identifies each row. This column must be of an integer type - a regular integer or a PostgreSQL identity column. Uniqueness must be enforced by a PRIMARY KEY or UNIQUE constraint.

    Will be added atomatically to the source table when missing and field add_identity_column_if_not_exists is true.

  • source_table

    The name of the source table, with an optional database schema prefix.

  • strategy

    The module that implements Sublimate.ProjectionStrategy behaviour.

  • strategy_data

    Data that is unique to the strategy module implementation. For example, with Sublimate it contains a facets configuration.

Optional fields

  • add_identity_column_if_not_exists

    If true, adds an auto-increment identity column to the source table, using the column name provided via field identity_column.

  • otp_app

    The library or application that is calling Sublimate.create_projection_data/1. For example, a Sublimate user is instructed to add to config.exs:

      config :sublimate, repo: MyApp.Repo

    By passing sublimate to otp_app, the value for repo can be read.

join_spec()

@type join_spec() :: %{
  table: String.t(),
  match: String.t(),
  to: String.t(),
  where: String.t() | nil
}

join_triggers()

@type join_triggers() :: %{
  required(String.t()) => %{
    trigger: String.t(),
    trigger_fn: String.t(),
    delete_trigger: String.t()
  }
}

postgrex_options()

@type postgrex_options() :: [timeout: integer() | :infinity, log: boolean()]

t()

@type t() :: %Sublimate.ProjectionData{
  add_identity_column_if_not_exists: boolean() | nil,
  delta_trigger: String.t(),
  deltas_table_unique_index: String.t(),
  destination_table_unique_index: String.t(),
  identity_column: String.t(),
  join_triggers: join_triggers(),
  otp_app: atom(),
  qualified_deltas_table: String.t(),
  qualified_destination_table: String.t(),
  qualified_destination_trigger_fn: String.t(),
  qualified_insert_merge_deltas_fn: String.t(),
  qualified_source_table: String.t(),
  source_table_alias: String.t(),
  strategy: module(),
  strategy_data: map()
}

Functions

new(config)

@spec new(config()) :: t()

Transforms a config/0 configuration map into a ProjectionData struct. It resolves qualified table names and the names of database objects managed by the engine.