
\begin{DoxyItemize}
\item infos = Information about the reference plugin is in keys below
\item infos/author = Klemens Böswirth \href{mailto:k.boeswirth+git@gmail.com}{\texttt{ k.\+boeswirth+git@gmail.\+com}}
\item infos/licence = BSD
\item infos/needs =
\item infos/provides =
\item infos/recommends =
\item infos/placements = presetstorage
\item infos/status = maintained unittest libc nodep writeonly
\item infos/metadata = check/reference check/reference/restrict check/reference/restrict/\#
\item infos/description = Plugin for validating singular or recursive references
\end{DoxyItemize}\hypertarget{md_src_plugins_reference_README_src_plugins_reference_README_md}{}\doxysection{Introduction}\label{md_src_plugins_reference_README_src_plugins_reference_README_md}
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 {\ttfamily check/reference}. Currently the metakey supports the three values {\ttfamily single}, {\ttfamily recursive} and {\ttfamily alternative}. While the value {\ttfamily alternative} only makes sense in a certain context inside the {\ttfamily recursive} mode, the other two values define to different modes of operation for the plugin.

If a key has the metakey {\ttfamily check/reference} with value {\ttfamily 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 {\ttfamily check/reference} with value {\ttfamily 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.\hypertarget{md_src_plugins_reference_README_autotoc_md472}{}\doxysection{Installation}\label{md_src_plugins_reference_README_autotoc_md472}
See \mbox{\hyperlink{doc_INSTALL_md}{installation}}. The package is called {\ttfamily libelektra5-\/experimental}.\hypertarget{md_src_plugins_reference_README_autotoc_md473}{}\doxysubsection{Resolution of References}\label{md_src_plugins_reference_README_autotoc_md473}
The plugin will try to resolve all keys marked with the metakey {\ttfamily 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. {\ttfamily \#0}, {\ttfamily \#\+\_\+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\+:


\begin{DoxyItemize}
\item If the reference value starts with {\ttfamily ./} or {\ttfamily ../}, it will be interpreted as relative to the current key or the parent of the current key.
\item If the reference value starts with {\ttfamily @/}, it will be relative to the parent-\/key used in the call to {\ttfamily kdb\+Get}.
\item All other values are treated as absolute and interpreted as a keyname directly.
\item {\ttfamily .} and {\ttfamily ..} will be treated the same way as in Unix paths. However, the plugin will emit warnings, if {\ttfamily .} is used anywhere other than before the first slash. Equally using {\ttfamily ..} after a path segment other than {\ttfamily ..} 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\textquotesingle{}t\+:
\begin{DoxyItemize}
\item {\ttfamily ./system\+:/key} no warning
\item {\ttfamily system\+:/key} no warning
\item {\ttfamily system\+:/./key} warning, redundant use of {\ttfamily .}
\item {\ttfamily ../../../key} no warning
\item {\ttfamily ../key/../otherkey}warning, redundant use of {\ttfamily .}
\end{DoxyItemize}
\end{DoxyItemize}\hypertarget{md_src_plugins_reference_README_autotoc_md474}{}\doxysubsection{Construction of the Reference Graph}\label{md_src_plugins_reference_README_autotoc_md474}
The process starts with a key {\ttfamily X}, which has the metakey {\ttfamily check/reference} set to the value {\ttfamily recursive}. This key {\ttfamily X} must be an array key. The basename of {\ttfamily X} will be called the {\ttfamily refname}. For each element in the array run the following process\+:


\begin{DoxyEnumerate}
\item Interpret the current key {\ttfamily K}s value as a reference and throw an error, if the reference is not valid.
\item If there is no node for {\ttfamily K} in the reference graph create one. If there is no node for {\ttfamily R} in the reference graph create one. Insert an edge from {\ttfamily K} to {\ttfamily R} into the graph.
\item Find a key {\ttfamily K1} directly below {\ttfamily R} that has the {\ttfamily refname} 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.
\item Find any key {\ttfamily K2} directly below {\ttfamily R} that has the metakey {\ttfamily check/reference} set to {\ttfamily alternative}. Interpret any such key as an array. For each array element, start the process recursively from 1, but this time using the basename of {\ttfamily K2} (the of the array) as the {\ttfamily refname}.
\end{DoxyEnumerate}

Once the whole process is finished, we will have a graph of the whole reference structure stemming from {\ttfamily X}. This graph can then be check for acyclicity.\hypertarget{md_src_plugins_reference_README_autotoc_md475}{}\doxysubsection{Restriction of References}\label{md_src_plugins_reference_README_autotoc_md475}
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 {\ttfamily 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 {\ttfamily check/reference/restrict} metakey set (even if the value is empty), its value has to be taken into account.

If the value {\ttfamily check/reference/restrict} is anything but a valid array-\/element-\/name, i.\+e. a {\ttfamily \#} followed by {\ttfamily n} underscores ({\ttfamily \+\_\+}) and {\ttfamily n+1} digits ({\ttfamily 0-\/9}), its value will be used directly. Otherwise {\ttfamily 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 \href{\#resolution-of-references}{\texttt{ 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 {\ttfamily \char`\"{}\char`\"{}} {\bfseries{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 {\ttfamily \char`\"{}\char`\"{}}).\hypertarget{md_src_plugins_reference_README_autotoc_md476}{}\doxysection{Usage}\label{md_src_plugins_reference_README_autotoc_md476}

\begin{DoxyCode}{0}
\DoxyCodeLine{\# Mount the plugin}
\DoxyCodeLine{sudo kdb mount referencetest.dump user:/tests/reference dump reference}
\DoxyCodeLine{}
\DoxyCodeLine{\# Mark a key as a single reference}
\DoxyCodeLine{kdb meta-\/set user:/tests/reference/singleref check/reference single}
\DoxyCodeLine{}
\DoxyCodeLine{\# Try setting an invalid reference}
\DoxyCodeLine{kdb set user:/tests/reference/singleref user:/tests/reference/referred1}
\DoxyCodeLine{\# RET: 5}
\DoxyCodeLine{\# STDERR: .*Reference 'user:/tests/reference/referred1', set in key 'user:/tests/reference/singleref', does not reference an existing key.*}
\DoxyCodeLine{}
\DoxyCodeLine{\# Create referred key ...}
\DoxyCodeLine{kdb set user:/tests/reference/referred1 "{}"{}}
\DoxyCodeLine{\#> Create a new key user:/tests/reference/referred1 with string "{}"{}}
\DoxyCodeLine{}
\DoxyCodeLine{\# ... and try again}
\DoxyCodeLine{kdb set user:/tests/reference/singleref user:/tests/reference/referred1}
\DoxyCodeLine{\#> Set string to "{}user:/tests/reference/referred1"{}}
\DoxyCodeLine{}
\DoxyCodeLine{\# Cleanup}
\DoxyCodeLine{kdb rm user:/tests/reference/singleref}
\DoxyCodeLine{kdb rm user:/tests/reference/referred1}
\DoxyCodeLine{}
\DoxyCodeLine{\# Unmount the plugin}
\DoxyCodeLine{sudo kdb umount user:/tests/reference}

\end{DoxyCode}
\hypertarget{md_src_plugins_reference_README_autotoc_md477}{}\doxysection{Examples}\label{md_src_plugins_reference_README_autotoc_md477}
The examples directory contains a few examples\+:


\begin{DoxyItemize}
\item alternative shows how the {\ttfamily alternative} value of {\ttfamily check/reference} gets processed.
\item complex shows how the plugin can be used together with the spec plugin, to validate complex recursive structures. 
\end{DoxyItemize}