The kit of a database schema: tables, with columns that have a name, a type and a key (primary or foreign), and foreign keys drawn from a column to a column of the same type.
A table is a node of type "schema-table" whose data is:
%{
"name" => "orders",
"columns" => [
%{"id" => "c1", "name" => "id", "type" => "uuid", "key" => "pk"},
%{"id" => "c2", "name" => "customer_id", "type" => "uuid", "key" => "fk"},
%{"id" => "c3", "name" => "placed_at", "type" => "timestamp", "key" => nil}
]
}Each column has a handle on each side, of the column's family of types
(family/1): an edge joins two columns of one family (integer to
bigint, varchar(64) to text, but not text to uuid), and takes
the sides nearest each other.
A column's handles are its "id" (its name, for a column without one),
so a foreign key stays when people rename the column.
People rename the table and its columns in place, pick a column's type,
set its key, and add and remove columns.
A table of another schema than the one shown (the table a foreign key
points to, in billing) is a stub: data with "external" => true and
its "schema", and only the columns its foreign keys use. It is drawn
faint, with a dashed border and its qualified name (billing.invoices),
its edges dashed, and nobody edits it, even on a canvas they edit:
%{"name" => "invoices", "schema" => "billing", "external" => true,
"columns" => [%{"name" => "id", "type" => "uuid", "key" => "pk"}]}A table may name its "schema" without being a stub; its name shows
qualified too.
In Markdown, a schema is a Mermaid entity relationship diagram: each
table with its columns (uuid id PK), and a foreign key as a
relationship from its table to the table it refers to, named after its
column. from_markdown/1 reads it back, and reads ER diagrams people
write: a relationship becomes an edge from the column it names (else
the table's first column) to the other table's primary key.
Summary
Functions
The column types people pick from.
The family of a column's type: the types whose columns a foreign key
joins. Sizes, precisions and modifiers do not count (varchar(255),
numeric(12,2), int unsigned, timestamp with time zone), nor case.
Functions
@spec column_types() :: [String.t()]
The column types people pick from.
The family of a column's type: the types whose columns a foreign key
joins. Sizes, precisions and modifiers do not count (varchar(255),
numeric(12,2), int unsigned, timestamp with time zone), nor case.
iex> Hakushi.Kits.Schema.family("int4")
"integer"
iex> Hakushi.Kits.Schema.family("character varying(255)")
"text"
iex> Hakushi.Kits.Schema.family("TIMESTAMP WITH TIME ZONE")
"timestamp"The families are integer, decimal, float, text, uuid,
timestamp, date, time, boolean, json and binary. A type of
none of them is a family of its own (its name, in lower case, with
underscores for spaces), so it joins only its own type. Add or change
families with config :hakushi, Hakushi.Kits.Schema, families: %{"geometry" => "geometry", "ltree" => "text"}.