imag/doc/src/02000-store.md

178 lines
5.6 KiB
Markdown

# The Store {#sec:thestore}
## File Format {#sec:thestore:fileformat}
The content in the store MUST BE encoded in either Unicode UTF-8 or ASCII.
Each "Entry" (File) MUST HAVE a "Header" component as well as a "Content"
component.
Each "Entry" in the store MUST start with three single dashes ("-") followed
by a newline character, named "initial marker" in the following chapter.
The Header follows the initial marker (@sec:thestore:fileformat:header).
The Header MUST BE followed by a line which contains three single dashes ("-")
and a newline character, called "header-close marker" in the following
chapter.
The content follows the header-close marker (@sec:thestore:fileformat:content).
### Header Format {#sec:thestore:fileformat:header}
The header format MUST BE "TOML".
The sections which MAY or MUST be in the header are defined in the following
chapters.
#### Header section: "imag" {#sec:thestore:fileformat:header:imag}
The header MUST contain a section called "imag", where the automatically by the
program generated data is stored in.
The contents of this section is edited via commandline calls or by the
program implicitely and SHOULD NOT be edited by the user.
This "imag" section MUST contain the following keys
1. A "version" Key. The version stored here is the version of the Store, the
Entry was created with.
The "imag" section MAY contain
1. A section "imag.links" where a module is allowed to store URIs in a flat
list
1. A section "imag.content", used for referring to external content.
The key "uri" is the only one which is required, it refers to external
content.
An explicitely suggested key is "file" for referring to a _local Mirror_ of
the content.
#### Header section: "custom" {#sec:thestore:fileformat:header:custom}
The header MAY contain a section named "custom".
The user is free to store arbitrary data here.
The user is also free to edit this section by either commandline or editor.
#### Module Header section {#sec:thestore:fileformat:header:module}
The header MAY contain a section named after a module.
The corrosponding module is allowed to store arbitrary data in this section.
### Content Format {#sec:thestore:fileformat:content}
The content is the part of the file where the user is free to enter any
textual content.
The content MAY BE rendered as Markdown or other markup format for the users
convenience.
The Store library MUST NOT expect any particular markup format.
### Example {#sec:thestore:fileformat:example}
An example for a file in the store follows.
```
---
[imag]
version = "0.1.0"
[imag.content]
url = "file://home/user/kittens.mpeg"
imag.links = [
"imag://home/user/more_kittens.mpeg"
]
[examplemodule]
arbitrary = data
[custom]
truth = 42
---
This is an example text, written by the user.
```
## File organization {#sec:thestore:fileorganization}
The "Entries" are stored as files in the "Store", which is a directory the
user has access to.
The store MAY exist in the users Home-directory or any other directory the
user has Read-Write-Access to.
The Path of each File is shown as absolute path in this paper, while the root
is always the store directory.
This Path is named "Storepath".
So if the store exists in `/home/user/store/`, a file with the Storepath
`/example.file` is (on the filesystem) located at
`/home/user/store/example.file`.
A Storepath contains predefined parts:
* The module name of the Module the Entry belongs to.
This part is a directory.
* The version (semantic versioning applies) of the module storing the Entry
This part is a postfix to the filename
The pattern for the storepath is
```
/<module name>/<optional sub-folders>/<file name>~<sem version>
```
So if a Module named "ExampleModule" with version "0.1" stores a file in the
Store, the Storepath for a file with the name "example" is
"/ExampleModule/example~0.1".
Any number of subdirectories MAY BE used, so creating folder hierarchies is
possible and valid.
A file "example" for a module "module" in version "0.1" would be stored in
sub-folders like this:
```
/module/some/sub/folder/example~0.1
```
A given file MUST only exist once with the same path.
For example, it is invalid if these files exist at the same time:
* /foo/bar~0.2
* /foo/bar~1.3
To future-proof the System it is thus necessary to create a disambiguation at
the store level. Thus if a library wants to retrieve a file from the Store
it MUST at least accept files from it's current advertised version. It MAY
accept older files and it MAY transform them and resubmit them in the newer
version.
For this there will be an enum returned for each given Entry. It will have these
members:
- `Compatible`, for version matches
- `PossiblyIncompatible`, if the current version is at least a major number
further
- `Incompatible`, if the file is a at least a major number further
## Store path links {#sec:thestore:links}
Linking entries MUST BE version independent.
This means if an entry "a" from a module "A" gets written to the store, it may
link to an entry "b" from a module "B", which is in version "0.1" at the moment.
If the module "B" gets updated, it might update its entries in the store as
well.
The link from the "a" MUST NOT get invalid in this case.
This is accomplished by linking without the version number: So a link for the
entry
```
/module/some/sub/folder/example~0.1
```
is
```
imag://module/some/sub/folder/example
```
As shown in the example, a link to imag-internal entries, the link is prefixed
with a "imag://" identifier.
This prefix is optional.
A link to external content MUST NEVER be prefixed this way.
The path of the internal link MUST NEVER be relative, but always absolute from
the root directory of the store.