View Source Vtc.Ecto.Postgres.PgFramestamp.Migrations (vtc v0.17.5)

Migrations for adding framestamp types, functions and constraints to a Postgres database.

Link to this section Summary

Types

Details for an individual migration to support a Postgres type.

The type of object a migration is creating.

Alias for string that indicates the returned value is a raw SQL statement.

SQL value that can be passed as an atom or a string.

Full

Adds raw SQL queries to a migration for creating the database types, associated functions, casts, operators, and operator families.

Pg Constraints

Creates basic constraints for a PgFramestamp / Framestamp database field.

Pg Types

Creates function schema as described by the Configuring Database Objects section above.

Adds framestamp composite type.

Pg Operators

Creates a custom unary :framestamp @ operator.

Creates a custom :framestamp, :framestamp + operator.

Creates a custom :framestamp, :framestamp @+ operator.

Creates a custom :framestamp, :framestamp +@ operator.

Creates a custom :framestamp, :rational / operator.

Creates a custom :framestamp, :framestamp = operator that returns true if the real-world seconds values for both framestamps are equal.

Creates a custom :framestamp, :framestamp > operator.

Creates a custom :framestamp, :framestamp >= operator.

Creates a custom :framestamp, :framestamp < operator.

Creates a custom :framestamp, :framestamp <= operator.

Creates a custom unary :framestamp - operator.

Creates a custom :framestamp, :rational % operator.

Creates a custom :framestamp, :rational * operator.

Creates a custom :framestamp, :framestamp <> operator that returns true if the real-world seconds values for both framestamps are not equal.

Creates a custom :framestamp, :framestamp === operator that returns true if both the real-world seconds values and the framerates for both framestamps are equal.

Creates a custom :framestamp, :framestamp !=== operator that returns true if a and b do not have the same real-world-seconds, framerate playback, or framerate tags.

Creates a custom :framestamp, :framestamp - operator.

Creates a custom :framestamp, :framestamp @- operator.

Creates a custom :framestamp, :framestamp -@ operator.

Pg Operator Classes

Creates a B-tree operator class to support indexing on comparison operations.

Pg Functions

Returns the absolute value of the framestamp.

Creates DIV(:framestamp, :rational) that returns a floored :framestamp to match Postgres' DIV(real, real) behavior.

Converts framestamp to a frame number by the frame's index in the timecode stream, with 0 as SMPTE midnight.

Creates framestamp.__private__minus(value) that backs unary - operator.

Returns the internal framerate value.

Returns the internal real-world seconds value as a rational.

Creates framestamp.with_frames(frames, rate)

Creates framestamp.with_seconds(seconds, rate)

Pg Private Functions

Creates framestamp.__private__add(a, b) that backs the + operator.

Creates framestamp.__private__add_inherit_left(a, b) that backs the @+ operator.

Creates framestamp.__private__add_inherit_right(a, b) that backs the +@ operator.

Creates framestamp.__private__cmp(a, b) used in the PgTimecode b-tree operator class.

Creates framestamp.__private__div(:framestamp, :rational) that backs the / operator.

framestamp.__private__eq(framestamp, framestamp)

Creates framestamp.__private__gt(a, b) that backs the > operator.

Creates framestamp.__private__gte(a, b) that backs the >= operator.

Creates framestamp.__private__lt(a, b) that backs the < operator.

Creates framestamp.__private__lte(a, b) that backs the <= operator.

Creates framestamp.__private__modulo(:framestamp, :rational) that backs the % operator.

Creates framestamp.__private__mult(:framestamp, :rational) that backs the * operator.

Creates framestamp.__private__neq(a, b) that backs the <> operator.

Creates framestamp.__private__simplify(bigint. bigint) function that simplifies a rational value based on two ints. Used at the end of every rational operation to avoid overflows.

Creates framestamp.__private__strict_eq(a, b) that backs the === operator.

Creates framestamp.__private__strict_neq(a, b) that backs the !=== operator.

framestamp.__private__sub(a, b) that backs the - operator.

Creates framestamp.__private__sub_inherit_left(a, b) that backs the @- operator.

Creates framestamp.__private__sub_inherit_right(a, b) that backs the -@ operator.

Functions

Returns the config-qualified name of the function for this type.

Link to this section Types

@type constraint_opt() ::
  {:create_seconds_divisible_by_rate?, boolean()}
  | {:framerate_opts, Vtc.Ecto.Postgres.PgFramerate.Migrations.constraint_opt()}

Option types for create_constraints/2.

@type migration_info() :: {migration_type(), raw_sql(), raw_sql()} | :skip

Details for an individual migration to support a Postgres type.

Either {migration_type, up_command, down_command} or :skip if the migration should be skipped.

@type migration_type() ::
  :schema | :type | :function | :operator | :operator_class | :cast | :other

The type of object a migration is creating.

@type raw_sql() :: String.t()

Alias for string that indicates the returned value is a raw SQL statement.

@type sql_value() :: String.t() | atom()

SQL value that can be passed as an atom or a string.

Link to this section Full

@spec run(include: Keyword.t(atom()), exclude: Keyword.t(atom())) :: :ok

Adds raw SQL queries to a migration for creating the database types, associated functions, casts, operators, and operator families.

This migration includes all migrations under the Pg Types, Pg Operators, Pg Operator Classes, Pg Functions, and Pg Private Functions, headings.

Safe to run multiple times when new functionality is added in updates to this library. Existing values will be skipped.

Individual migration functions return raw sql commands in an {up_command, down_command} tuple.

options

Options

  • include: A list of migration functions to include. If not set, all sub-migrations will be included.

  • exclude: A list of migration functions to exclude. If not set, no sub-migrations will be excluded.

types-created

Types Created

Calling this macro creates the following type definitions:

CREATE TYPE framestamp AS (
  __seconds_n bigint,
  __seconds_d bigint,
  __rate_n bigint,
  __rate_d bigint,
  __rate_tags framerate_tags[]
);

Field Access

framestamp's inner fields are considered semi-private to end-users. For working with the seconds / rate values, see create_func_seconds/0 and create_func_rate/0, which create Postgres functions to act as getter functions for working with inner framestamp data.

schemas-created

Schemas Created

Up to two schemas are created as detailed by the Configuring Database Objects section below.

configuring-database-objects

Configuring Database Objects

To change where supporting functions are created, add the following to your Repo configuration:

config :vtc, Vtc.Test.Support.Repo,
  adapter: Ecto.Adapters.Postgres,
  ...
  vtc: [
    framestamp: [
      functions_schema: :framestamp,
      functions_prefix: "framestamp"
    ]
  ]

Option definitions are as follows:

  • functions_schema: The postgres schema to store framestamp-related custom functions.

  • functions_prefix: A prefix to add before all functions. Defaults to "framestamp" for any function created in the :public schema, and "" otherwise.

private-functions

Private Functions

Some custom function names are prefaced with __private__. These functions should not be called by end-users, as they are not subject to any API stability guarantees.

examples

Examples

defmodule MyMigration do
  use Ecto.Migration

  alias Vtc.Ecto.Postgres.PgFramestamp
  require PgFramestamp.Migrations

  def change do
    PgFramestamp.Migrations.run()
  end
end

Link to this section Pg Constraints

Link to this function

create_constraints(table, field, opts \\ [])

View Source
@spec create_constraints(atom(), atom(), [constraint_opt()]) :: :ok

Creates basic constraints for a PgFramestamp / Framestamp database field.

options

Options

  • create_seconds_divisible_by_rate?: If true, creates {field_name}_seconds_divisible_by_rate constraint (see below). Default: true.

  • framerate_opts: Opts for framerate constraints. See PgFramerate.Migrations.create_constraints/3

constraints-created

Constraints created:

  • {field}_rate_positive: Checks that the playback speed is positive.

  • {field}_rate_ntsc_tags: Checks that both drop and non_drop are not set at the same time.

  • {field}_rate_ntsc_valid: Checks that NTSC framerates are mathematically sound, i.e., that the rate is equal to (round(rate.playback) * 1000) / 1001.

  • {field}_rate_ntsc_drop_valid: Checks that NTSC, drop-frame framerates are valid, i.e, are cleanly divisible by 30_000/1001.

  • {field_name}_seconds_divisible_by_rate: Checks that the seconds value of the framestamp is cleanly divisible by the rate.playback value.

examples

Examples

create table("my_table", primary_key: false) do
  add(:id, :uuid, primary_key: true, null: false)
  add(:a, Framestamp.type())
  add(:b, Framestamp.type())
end

PgRational.migration_add_field_constraints(:my_table, :a)
PgRational.migration_add_field_constraints(:my_table, :b)

Link to this section Pg Types

Link to this function

create_function_schemas()

View Source
@spec create_function_schemas() :: migration_info()

Creates function schema as described by the Configuring Database Objects section above.

Link to this function

create_type_framestamp()

View Source
@spec create_type_framestamp() :: migration_info()

Adds framestamp composite type.

fields

Fields

  • __seconds_n: bigint. Numerator of the real-world seconds this frame occurred at, as a rational value.

  • __seconds_d: bigint. Denominator of the real-world seconds this frame occurred at, as a rational value.

  • __rate_n: bigint. Numerator of the real-world playback speed of this frame's media stream.

  • __rate_d: bigint. Denominator of the real-world playback speed of this frame's media stream.

  • __rate_tags[]: Information about the format this framestamp was parsed from, to support lossless round-trips.

Link to this section Pg Operators

@spec create_op_abs() :: migration_info()

Creates a custom unary :framestamp @ operator.

Returns the absolute value of the framestamp.

@spec create_op_add() :: migration_info()

Creates a custom :framestamp, :framestamp + operator.

Adds a to b.

raises: data_exception if a and b do not have the same framerate.

Link to this function

create_op_add_inherit_left()

View Source
@spec create_op_add_inherit_left() :: migration_info()

Creates a custom :framestamp, :framestamp @+ operator.

Adds a to b. If a and b do not have the same framerate, result will inherit a's rate and round seconds to the nearest whole-frame.

Link to this function

create_op_add_inherit_right()

View Source
@spec create_op_add_inherit_right() :: migration_info()

Creates a custom :framestamp, :framestamp +@ operator.

Adds a to b. If a and b do not have the same framerate, result will inherit b's rate and round seconds to the nearest whole-frame.

Link to this function

create_op_div_rational()

View Source
@spec create_op_div_rational() :: migration_info()

Creates a custom :framestamp, :rational / operator.

Just like Framestamp.div/3, a's the internal seconds value will be rounded to the nearest whole-frame to ensure data integrity.

Unlike Framestamp.div/3, the result is rounded to the closest frame, rather than truncating ala integer division.

@spec create_op_eq() :: migration_info()

Creates a custom :framestamp, :framestamp = operator that returns true if the real-world seconds values for both framestamps are equal.

@spec create_op_gt() :: migration_info()

Creates a custom :framestamp, :framestamp > operator.

@spec create_op_gte() :: migration_info()

Creates a custom :framestamp, :framestamp >= operator.

@spec create_op_lt() :: migration_info()

Creates a custom :framestamp, :framestamp < operator.

@spec create_op_lte() :: migration_info()

Creates a custom :framestamp, :framestamp <= operator.

@spec create_op_minus() :: migration_info()

Creates a custom unary :framestamp - operator.

Flips the sign of value. Equivalent to value * -1.

Link to this function

create_op_modulo_rational()

View Source
@spec create_op_modulo_rational() :: migration_info()

Creates a custom :framestamp, :rational % operator.

Just like Framestamp.rem/3, this operation is done on the frame count representation of the Framestamp, which is then used as the basis of a new framestamp.

Link to this function

create_op_mult_rational()

View Source
@spec create_op_mult_rational() :: migration_info()

Creates a custom :framestamp, :rational * operator.

Just like Framestamp.mult/3, a's the internal seconds value will be rounded to the nearest whole-frame to ensure data integrity.

@spec create_op_neq() :: migration_info()

Creates a custom :framestamp, :framestamp <> operator that returns true if the real-world seconds values for both framestamps are not equal.

@spec create_op_strict_eq() :: migration_info()

Creates a custom :framestamp, :framestamp === operator that returns true if both the real-world seconds values and the framerates for both framestamps are equal.

@spec create_op_strict_neq() :: migration_info()

Creates a custom :framestamp, :framestamp !=== operator that returns true if a and b do not have the same real-world-seconds, framerate playback, or framerate tags.

@spec create_op_sub() :: migration_info()

Creates a custom :framestamp, :framestamp - operator.

Subtracts a from b.

raises: data_exception if a and b do not have the same framerate.

Link to this function

create_op_sub_inherit_left()

View Source
@spec create_op_sub_inherit_left() :: migration_info()

Creates a custom :framestamp, :framestamp @- operator.

Subtracts a from b. If a and b do not have the same framerate, result will inherit a's rate and round seconds to the nearest whole-frame.

Link to this function

create_op_sub_inherit_right()

View Source
@spec create_op_sub_inherit_right() :: migration_info()

Creates a custom :framestamp, :framestamp -@ operator.

Subtracts a from b. If a and b do not have the same framerate, result will inherit b's rate and round seconds to the nearest whole-frame.

Link to this section Pg Operator Classes

@spec create_op_class_btree() :: migration_info()

Creates a B-tree operator class to support indexing on comparison operations.

Link to this section Pg Functions

@spec create_func_abs() :: migration_info()

Returns the absolute value of the framestamp.

Link to this function

create_func_floor_div_rational()

View Source
@spec create_func_floor_div_rational() :: migration_info()

Creates DIV(:framestamp, :rational) that returns a floored :framestamp to match Postgres' DIV(real, real) behavior.

Just like Framestamp.div/3, this operation is done on the frame count representation of the Framestamp, which is then used as the basis of a new framestamp.

@spec create_func_frames() :: migration_info()

Converts framestamp to a frame number by the frame's index in the timecode stream, with 0 as SMPTE midnight.

Equivalent to Framestamp.frames/2 with :round set to trunc.

@spec create_func_minus() :: migration_info()

Creates framestamp.__private__minus(value) that backs unary - operator.

Flips the sign of value. Equivalent to value * -1.

@spec create_func_rate() :: migration_info()

Returns the internal framerate value.

@spec create_func_seconds() :: migration_info()

Returns the internal real-world seconds value as a rational.

@spec create_func_sign() :: migration_info()

Returns:

  • -1 if the framestamp's seconds value is less than0/1.
  • 0 if the framestamp's seconds value is 0/1.
  • 1 if the framestamp's seconds value is greater than0/1.
Link to this function

create_func_with_frames()

View Source
@spec create_func_with_frames() :: migration_info()

Creates framestamp.with_frames(frames, rate)

Constructs a framestamp for the given frame count. When passed to framestamp.frames/1, the returned value will yield frames.

Link to this function

create_func_with_seconds()

View Source
@spec create_func_with_seconds() :: migration_info()

Creates framestamp.with_seconds(seconds, rate)

Constructs a framestamp for the given real-world seconds, rounded to the nearest whole-frame based on rate. When passed to framestamp.seconds/1, the returned value will yield the rounded seconds.

Link to this section Pg Private Functions

@spec create_func_add() :: migration_info()

Creates framestamp.__private__add(a, b) that backs the + operator.

Adds a to b.

raises: data_exception if a and b do not have the same framerate.

Link to this function

create_func_add_inherit_left()

View Source
@spec create_func_add_inherit_left() :: migration_info()

Creates framestamp.__private__add_inherit_left(a, b) that backs the @+ operator.

Adds a to b. If a and b do not have the same framerate, result will inherit a's rate and round seconds to the nearest whole-frame.

Link to this function

create_func_add_inherit_right()

View Source
@spec create_func_add_inherit_right() :: migration_info()

Creates framestamp.__private__add_inherit_right(a, b) that backs the +@ operator.

Adds a to b. If a and b do not have the same framerate, result will inherit b's rate and round seconds to the nearest whole-frame.

@spec create_func_cmp() :: migration_info()

Creates framestamp.__private__cmp(a, b) used in the PgTimecode b-tree operator class.

Link to this function

create_func_div_rational()

View Source
@spec create_func_div_rational() :: migration_info()

Creates framestamp.__private__div(:framestamp, :rational) that backs the / operator.

Just like Framestamp.div/3, a's the internal seconds field will be rounded to the nearest whole-frame to ensure data integrity.

Unlike Framestamp.div/3, the result is rounded to the closest frame, rather than truncating ala integer division.

@spec create_func_eq() :: migration_info()

framestamp.__private__eq(framestamp, framestamp)

Backs the = operator.

@spec create_func_gt() :: migration_info()

Creates framestamp.__private__gt(a, b) that backs the > operator.

@spec create_func_gte() :: migration_info()

Creates framestamp.__private__gte(a, b) that backs the >= operator.

@spec create_func_lt() :: migration_info()

Creates framestamp.__private__lt(a, b) that backs the < operator.

@spec create_func_lte() :: migration_info()

Creates framestamp.__private__lte(a, b) that backs the <= operator.

Link to this function

create_func_modulo_rational()

View Source
@spec create_func_modulo_rational() :: migration_info()

Creates framestamp.__private__modulo(:framestamp, :rational) that backs the % operator.

Just like Framestamp.rem/3, this operation is done on the frame count representation of the Framestamp, which is then used as the basis of a new framestamp.

Link to this function

create_func_mult_rational()

View Source
@spec create_func_mult_rational() :: migration_info()

Creates framestamp.__private__mult(:framestamp, :rational) that backs the * operator.

Just like Framestamp.mult/3, a's the internal seconds field will be rounded to the nearest whole-frame to ensure data integrity.

@spec create_func_neq() :: migration_info()

Creates framestamp.__private__neq(a, b) that backs the <> operator.

@spec create_func_simplify() :: migration_info()

Creates framestamp.__private__simplify(bigint. bigint) function that simplifies a rational value based on two ints. Used at the end of every rational operation to avoid overflows.

@spec create_func_strict_eq() :: migration_info()

Creates framestamp.__private__strict_eq(a, b) that backs the === operator.

Checks that both the seconds value AND the framerate are equivalent.

Link to this function

create_func_strict_neq()

View Source
@spec create_func_strict_neq() :: migration_info()

Creates framestamp.__private__strict_neq(a, b) that backs the !=== operator.

Checks if either the seconds value OR the framerate are not equivalent.

@spec create_func_sub() :: migration_info()

framestamp.__private__sub(a, b) that backs the - operator.

Subtracts a from b.

raises: data_exception if a and b do not have the same framerate.

Link to this function

create_func_sub_inherit_left()

View Source
@spec create_func_sub_inherit_left() :: migration_info()

Creates framestamp.__private__sub_inherit_left(a, b) that backs the @- operator.

Subtracts a from b. If a and b do not have the same framerate, result will inherit a's rate and round seconds to the nearest whole-frame.

Link to this function

create_func_sub_inherit_right()

View Source
@spec create_func_sub_inherit_right() :: migration_info()

Creates framestamp.__private__sub_inherit_right(a, b) that backs the -@ operator.

Subtracts a from b. If a and b do not have the same framerate, result will inherit b's rate and round seconds to the nearest whole-frame.

Link to this section Functions

@spec function(atom(), Ecto.Repo.t()) :: String.t()

Returns the config-qualified name of the function for this type.