This project defines the entity types used in the Semio Database, and in its clients that use the client library such as the Semio CLI.
These entities have properties in common.
- They represent a versioned record in the database. Hence they are always referred to as "records".
- They have the same facets (see
RecordDefn):Private: the original description of the record, as defined by its author. It may contain restricted information, and it is a record that change in time (usually it is the latest), i.e. it isUnfrozen. Its dependencies are described asUnfrozenReferences, which version information can be a looseVersionReq. It can be converted into a GraphQL value for queries.Publicsame asPrivatebut it omits restricted information.Unfrozen: the actual record,PrivateorPublicare views of it.Frozen: a record frozen in a specific version. Its dependencies are described asFrozenReferences, which version information is a specificVersion.Action: the set of operations that can be applied to a record. A record is the result of a sequence of actions applied to an empty shell.
- They have a type information and a type version information.
- They are meant to be serializable and deserializable using that information, so that their inner details do not have to be involved in the database structure.
- They can be referred to with a UUID, but they are not aware their UUID: it is the database that handles that.
- Most record types have a parent. When they have no parent, they are said to be "root" record types.
- They have a name. In combination with parenthood,
names can be used to create unique paths to refer to records.
Semio Client does that with its notion of
Selector.
Each record type corresponds to a mod in this crate and a directory with the same name.
For each version of the record type, a sub-directory is created,
with a mod for each facet inside.
User represents users with access rights to the database.
This is a root record type (no parent),
and may be the parent of any other non-root record type.
It is meant to correspond to users known to the database server,
and with controlled access rights.
Organization represents an organization,
under which other records should be organized.
This is useful to regroup records under the same authority.
Folder represents a folder,
that serves as an intermediary parent to other records,
in order to organize them conveniently.
Enumeration represents an enumeration type,
with EnumerationVariants capable of holding values of any other type.
Each variant has an associated UUID.
Variants are stored as an IndexMap<Uuid, EnumerationVariant> rather
than a plain HashMap. This preserves the insertion order of variants across
serialization/deserialization, which keeps generated YAML record files stable —
a HashMap produces non-deterministic key ordering and causes spurious diffs every
time a module is rebuilt.
Structure represents a structure type,
with StructureFields capable of associating values of any other type
to named and UUID-identified attributes.
Fields are stored as an IndexMap<Uuid, StructureField> for the same
reason as Enumeration.variants above: to guarantee a stable serialization order.
Primitive represents a primitive type,
but it is not a record type.
It is used by record types representing types,
such as Enumeration or Structure.
All records representing types can be referred to using
FrozenTy or UnfrozenTy.
Private and Unfrozen records hold an access control list,
defining which permissions are required to access them.
These are meant to be handled by the database,
so that to reject requests from users who were not granted the permissions.
Implement the Freezer trait to interface with the
freeze methods available for Unfrozen records.
A freezing algorithm is already integrated in the record types,
but it needs a database (or any sort of repository of records)
to look up for matching actual tagged (and therefore Frozen) versions.