View Source Vtc.Ecto.Postgres.PgFramestamp.Range (vtc v0.13.11)
Defines a custom Range type for dealing with Framestamp ranges.
The new range types are defined as follows:
CREATE TYPE framestamp_range AS RANGE (
subtype = framestamp,
subtype_diff = framestamp_range_private.subtype_diff
canonical = framestamp_range_private.canonicalization
);
Framestamp ranges can be created in SQL expressions like so:
SELECT framestamp_range(stamp_1, stamp_2, '[)')
Framestamp fastranges can be created in SQL expressions like so:
SELECT framestamp_fastrange(stamp_1, stamp_2)
Indexing
framestamp_range
is currently VERY slow when using a GiST index, consider using a framestamp_fastrange instead.
canonicalization
Canonicalization
Postgres framestamp_range
values are ALWAYS coerced to exclusive out ranges. That
means that even if a Framestamp.Range has :out_type
set to
:inclusive
when it is sent to the database, it will come back from the database
with :out_type
set to :exclusive
, and the :out
field will be adjusted
accordingly.
Further, when a Range operation, like a union, would result in an in and out point with different framerates, the higher rate will always be selected.
This unlike the application behavior of Vtc.Framestamp.Range
, which always inherets
the rate of the value that apears on the left side. This behavior may be updated to
match Vtc's application behavior in the future.
framestamp-fast-range
Framestamp Fast Range
In addition to framestamp_range
, a framestamp_fastrange
type is defined as well:
CREATE TYPE framestamp_fastrange AS RANGE (
subtype = double precision,
subtype_diff = float8mi
);
Fast ranges are meant to support GiST indexing, as in most cases, framestamp_range
will be VERY slow to index.
Frame-accurate
Unlike
framestamp_range
,framestamp_fastrange
is NOT frame-accurate and should not be used where frame-accuracy is desired or required.
field-migrations
Field migrations
You can create framestamp_range
fields during a migration like so:
alias Vtc.Framerate
create table("framestamp_ranges") do
add(:a, Framestamp.Range.type())
add(:b, Framestamp.Range.type())
end
Framestamp.Range re-exports the Ecto.Type
implementation
of this module, and can be used any place this module would be used.
schema-fields
Schema fields
Then in your schema module:
defmodule MyApp.FramestampRanges do
@moduledoc false
use Ecto.Schema
alias Vtc.Framestamp
@type t() :: %__MODULE__{
a: Framestamp.Range.t(),
b: Framestamp.Range.t()
}
schema "rationals_01" do
field(:a, Framestamp.Range)
field(:b, Framestamp.Range)
end
changesets
Changesets
With the above setup, changesets should just work:
def changeset(schema, attrs) do
schema
|> Changeset.cast(attrs, [:a, :b])
|> Changeset.validate_required([:a, :b])
end
Framestamp.Range values can be cast from the following values in changesets:
- Framerate structs.
fragments
Fragments
Framerate values must be explicitly cast using type/2:
stamp_in = Framestamp.with_frames!("01:00:00:00", Rates.f23_98())
stamp_out = Framestamp.with_frames!("02:00:00:00", Rates.f23_98())
stamp_range = Framestamp.new!(stamp_in, stamp_out)
query = Query.from(
f in fragment("SELECT ? as r", type(^stamp_range, Framerate.Range)), select: f.r
)
Link to this section Summary
Types
Type of the raw composite value that will be sent to / received from the database.
Functions
Callback implementation for Ecto.Type.embed_as/1
.
Callback implementation for Ecto.Type.equal?/2
.
The database type for PgFramerate.
Link to this section Types
@type db_record() :: %Postgrex.Range{ lower: Vtc.Ecto.Postgres.PgFramestamp.db_record(), lower_inclusive: boolean(), upper: Vtc.Ecto.Postgres.PgFramestamp.db_record(), upper_inclusive: boolean() }
Type of the raw composite value that will be sent to / received from the database.
Link to this section Functions
Callback implementation for Ecto.Type.embed_as/1
.
Callback implementation for Ecto.Type.equal?/2
.
@spec type() :: atom()
The database type for PgFramerate.
Can be used in migrations as the fields type.