- infos = Information about the reference plugin is in keys below
- infos/author = Klemens Böswirth k.boeswirth+git@gmail.com
- infos/licence = BSD
- infos/needs =
- infos/provides =
- infos/recommends =
- infos/placements = presetstorage
- infos/status = maintained unittest libc writeonly
- infos/metadata = check/reference check/reference/restrict
- infos/description = Plugin for validating singular or recursive references
This plugin serves one single purpose: the validation of references from key to another inside the KDB.
To specify a key as a reference add the metakey check/reference
. Currently the metakey
supports the three values single
, recursive
and alternative
. While the value
alternative
only makes sense in a certain context inside the recursive
mode, the other
two values define to different modes of operation for the plugin.
If a key has the metakey check/reference
with value single
, the plugin reads the value
of the key and produces an error, if the value is not a valid (i.e. resolvable) reference.
If a key has metakey check/reference
with value recursive
, the plugin constructs a
reference graph starting with the marked key. (for the exact construction see below)
In this reference graph each node corresponds to a key in the KDB, while each edge
represents a reference between to keys. The plugin will produce an error, if this graph
is not a directed acyclic graph or contains any invalid references.
The plugin will try to resolve all keys marked with the metakey check/reference
as references.
The only exception to this rule is, if the value of such a key is a valid array name (i.e. #0
,
#_10
, ...). In that case, the plugin will try to resolve the values of the array elements,
directly below the marked key. And treats the marked key as referencing multiple other keys.
The resolution of the references into key names goes as follows:
- If the reference value starts with
./
or../
, it will be interpreted as relative to the current key or the parent of the current key. - If the reference value starts with
@/
, it will be relative to the parent-key used in the call tokdbGet
. - All other values are treated as absolute and interpreted as a keyname directly.
.
and..
will be treated the same way as in Unix paths. However, the plugin will emit warnings, if.
is used anywhere other than before the first slash. Equally using..
after a path segment other than..
itself, will result in a warning. This is because these use cases are redundant and might be (or result in) mistakes. Here are a few examples of what results in warnings, and what doesn't:./system/key
no warningsystem/key
no warningsystem/./key
warning, redundant use of.
../../../key
no warning../key/../otherkey
warning, redundant use of.
The process starts with a key X
, which has the metakey check/reference
set to the value
recursive
. This key X
must be an array key. The basename of X
will be called the refname
.
For each element in the array run the following process:
- Interpret the current key
K
s value as a reference and throw an error, if the reference is not valid. - If there is no node for
K
in the reference graph create one. If there is no node forR
in the reference graph create one. Insert an edge fromK
toR
into the graph. - Find a key
K1
directly belowR
that has therefname
as its basename. Interpret this key as an array if found. For each array element, start the process recursively from 1 and then continue with 4. - Find any key
K2
directly belowR
that has the metakeycheck/reference
set toalternative
. Interpret any such key as an array. For each array element, start the process recursively from 1, but this time using the basename ofK2
(the of the array) as therefname
.
Once the whole process is finished, we will have a graph of the whole reference structure
stemming from X
. This graph can then be check for acyclicity.
Without any additional intervention, the plugin accepts the name of any existing key as valid
reference value. Existing in this context means, the key either has a value or metadata
associated with it. In recursive mode a key is also said to exist, if a key with the current
refname
as a basename exists (has value or metadata) directly below the key in question.
If, however, the key containing the reference value has the check/reference/restrict
metakey
set (even if the value is empty), its value has to be taken into account.
If the value check/reference/restrict
is anything but a valid array-element-name, i.e. a #
followed by n
underscores (_
) and n+1
digits (0-9
), its value will be used directly.
Otherwise check/reference/restrict
has to be a valid array and its elements will be treated
as alternative restriction. Only one of these restriction has to be fulfilled for a reference to
be valid.
Each restriction is first resolved as if it was a reference itself (see Resolution of references). The resolved value is then used as an Elektra-style globbing pattern. For the supported see elektra-globbing.
If a keyname matches the globbing expression it will be considered a valid reference (as long as the key actually exists).
Note: If the restriction is the empty string ""
no keyname will match, meaning
the reference key annotated with this metadata has to be a leaf node in the reference graph,
and therefore cannot have a value (other than the empty string ""
).
# Mount the plugin
sudo kdb mount referencetest.dump user/tests/reference dump reference
# Mark a key as a single reference
kdb setmeta user/tests/reference/singleref check/reference single
# Try setting an invalid reference
kdb set user/tests/reference/singleref user/tests/reference/referred1
# RET: 5
# STDERR: .*Reason: Reference 'user/tests/reference/referred1', set in key 'user/tests/reference/singleref', does not reference an existing key.*
# Create referred key ...
kdb set user/tests/reference/referred1 ""
#> Create a new key user/tests/reference/referred1 with string ""
# ... and try again
kdb set user/tests/reference/singleref user/tests/reference/referred1
#> Set string to "user/tests/reference/referred1"
# Cleanup
kdb rm user/tests/reference/singleref
kdb rm user/tests/reference/referred1
# Unmount the plugin
sudo kdb umount user/tests/reference
The examples directory contains a few examples:
- alternative shows how the
alternative
value ofcheck/reference
gets processed. - complex shows how the plugin can be used together with the spec plugin, to validate complex recursive structures.