\hypertarget{group__kdb}{\section{K\-D\-B}
\label{group__kdb}\index{K\-D\-B@{K\-D\-B}}
}


General methods to access the Key database.  


\subsection*{Functions}
\begin{DoxyCompactItemize}
\item 
K\-D\-B $\ast$ \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open} (Key $\ast$error\-Key)
\begin{DoxyCompactList}\small\item\em Opens the session with the Key database. \end{DoxyCompactList}\item 
int \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close} (K\-D\-B $\ast$handle, Key $\ast$error\-Key)
\item 
int \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get} (K\-D\-B $\ast$handle, Key\-Set $\ast$ks, Key $\ast$parent\-Key)
\begin{DoxyCompactList}\small\item\em Retrieve keys in an atomic and universal way. \end{DoxyCompactList}\item 
int \hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set} (K\-D\-B $\ast$handle, Key\-Set $\ast$ks, Key $\ast$parent\-Key)
\begin{DoxyCompactList}\small\item\em Set keys in an atomic and universal way. \end{DoxyCompactList}\end{DoxyCompactItemize}


\subsection{Detailed Description}
General methods to access the Key database. To use them\-: 
\begin{DoxyCode}
\textcolor{preprocessor}{#include <kdb.h>}
\end{DoxyCode}


The kdb$\ast$() methods are used to access the storage, to get and set \hyperlink{group__keyset}{Key\-Sets }.

They use some backend implementation to know the details about how to access the storage.

One backend consists of multiple plugins. See \hyperlink{group__plugin}{writing a new plugin } for information about how to write a plugin. 

\subsection{Function Documentation}
\hypertarget{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{\index{K\-D\-B@{K\-D\-B}!kdb\-Close@{kdb\-Close}}
\index{kdb\-Close@{kdb\-Close}!KDB@{K\-D\-B}}
\subsubsection[{kdb\-Close}]{\setlength{\rightskip}{0pt plus 5cm}int kdb\-Close (
\begin{DoxyParamCaption}
\item[{K\-D\-B $\ast$}]{handle, }
\item[{Key $\ast$}]{error\-Key}
\end{DoxyParamCaption}
)}}\label{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}
Closes the session with the Key database.

This is the counterpart of \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()}.

You must call this method when you finished your affairs with the key database. You can manipulate Key and Key\-Set objects also after \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()}, but you must not use any kdb$\ast$() call afterwards. You can run \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()} in the atexit() handler.

The {\ttfamily handle} parameter will be finalized and all resources associated to it will be freed. After a \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()}, the {\ttfamily handle} can't be used anymore.

\begin{DoxyPrecond}{Precondition}
The handle must be a valid handle as returned from \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()}

error\-Key must be a valid key, e.\-g. created with \hyperlink{group__key_gad23c65b44bf48d773759e1f9a4d43b89}{key\-New()}
\end{DoxyPrecond}

\begin{DoxyParams}{Parameters}
{\em handle} & contains internal information of \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{opened } key database \\
\hline
{\em error\-Key} & the key which holds error information \\
\hline
\end{DoxyParams}

\begin{DoxyRetVals}{Return values}
{\em 0} & on success \\
\hline
{\em -\/1} & on N\-U\-L\-L pointer \\
\hline
\end{DoxyRetVals}
\hypertarget{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{\index{K\-D\-B@{K\-D\-B}!kdb\-Get@{kdb\-Get}}
\index{kdb\-Get@{kdb\-Get}!KDB@{K\-D\-B}}
\subsubsection[{kdb\-Get}]{\setlength{\rightskip}{0pt plus 5cm}int kdb\-Get (
\begin{DoxyParamCaption}
\item[{K\-D\-B $\ast$}]{handle, }
\item[{Key\-Set $\ast$}]{ks, }
\item[{Key $\ast$}]{parent\-Key}
\end{DoxyParamCaption}
)}}\label{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}


Retrieve keys in an atomic and universal way. 

\begin{DoxyPrecond}{Precondition}
\hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()} must be called before using this method.

The {\ttfamily returned} Key\-Set must be a valid Key\-Set, e.\-g. constructed with \hyperlink{group__keyset_ga671e1aaee3ae9dc13b4834a4ddbd2c3c}{ks\-New()}.
\end{DoxyPrecond}
The {\ttfamily returned} Key\-Set may already contain some keys from previous \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} calls. The new retrieved keys will be appended using \hyperlink{group__keyset_gaa5a1d467a4d71041edce68ea7748ce45}{ks\-Append\-Key()}.

It will fully retrieve, at least, all keys under the {\ttfamily parent\-Key} folder, with all subfolders and their children.

\begin{DoxyNote}{Note}
\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} might retrieve more keys then requested (that are not below parent\-Key). These keys must be passed to calls of \hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set()}, otherwise they will be lost. This stems from the fact that the user has the only copy of the whole configuration and backends only write configuration that was passed to them. For example, if you \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} \char`\"{}system/mountpoint/interest\char`\"{} you will not only get all keys below system/mountpoint/interest, but also all keys below system/mountpoint (if system/mountpoint is a mountpoint as the name suggests, but system/mountpoint/interest is not a mountpoint). Make sure to not touch or remove keys outside the keys of interest, because others may need them!
\end{DoxyNote}
\begin{DoxySeeAlso}{See Also}
\hyperlink{group__keyset_ga6b00cf82b59af4d883a9bad6cf4a4a4a}{ks\-Cut()} for further remarks on that topic.
\end{DoxySeeAlso}
\begin{DoxyParagraph}{Example\-:}

\end{DoxyParagraph}
This example demonstrates the typical usecase within an application (without error handling).


\begin{DoxyCode}
KeySet *myConfig = \hyperlink{group__keyset_ga671e1aaee3ae9dc13b4834a4ddbd2c3c}{ksNew}(0,KS\_END);
Key *pkey = \hyperlink{group__key_gad23c65b44bf48d773759e1f9a4d43b89}{keyNew}(\textcolor{stringliteral}{"system/sw/MyApp"},\hyperlink{group__key_gga91fb3178848bd682000958089abbaf40aa8adb6fcb92dec58fb19410eacfdd403}{KEY\_END});
KDB *handle = \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdbOpen}(pkey);

\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, myConfig, pkey); \textcolor{comment}{// get the config initially}

Key *key = \hyperlink{group__keyset_gad2e30fb6d4739d917c5abb2ac2f9c1a1}{ksLookupByName}(myConfig,\textcolor{stringliteral}{"/sw/MyApp/key"}, 0);
\textcolor{comment}{// check if key is not 0 and work with it...}

\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, myConfig, pkey); \textcolor{comment}{// get the config again}

\hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel} (myConfig); \textcolor{comment}{// delete the in-memory configuration}

\hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdbClose}(handle, pkey); \textcolor{comment}{// no more affairs with the key database.}
\hyperlink{group__key_ga3df95bbc2494e3e6703ece5639be5bb1}{keyDel}(pkey);
\end{DoxyCode}


\begin{DoxyParagraph}{Details\-:}

\end{DoxyParagraph}
If you pass N\-U\-L\-L on any parameter \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} will fail immediately without doing anything.

When a backend fails \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} will return -\/1 with all error and warning information in the {\ttfamily parent\-Key}. The parameter {\ttfamily returned} will not be changed.

\begin{DoxyParagraph}{Updates\-:}

\end{DoxyParagraph}
In the first run of kdb\-Get all keys are retrieved. On subsequent calls only the keys are retrieved where something was changed inside the key database. The other keys stay unchanged in the keyset, even when they were manipulated.

It is your responsibility to save the original keyset if you need it afterwards.

If you must get the same keyset again, e.\-g. in another thread you need to open a second handle to the key database using \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()}.


\begin{DoxyParams}{Parameters}
{\em handle} & contains internal information of \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{opened } key database \\
\hline
{\em parent\-Key} & parent key holds the information which keys should be get (it is possible that more are retrieved) -\/ an invalid name gets all keys \\
\hline
{\em ks} & the (pre-\/initialized) Key\-Set returned with all keys found will not be changed on error or if no update is required \\
\hline
\end{DoxyParams}
\begin{DoxySeeAlso}{See Also}
\hyperlink{group__keyset_gaa34fc43a081e6b01e4120daa6c112004}{ks\-Lookup()}, \hyperlink{group__keyset_gad2e30fb6d4739d917c5abb2ac2f9c1a1}{ks\-Lookup\-By\-Name()} for powerful lookups after the Key\-Set was retrieved 

\hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set()} to save the configuration afterwards and \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()} to finish affairs with the \hyperlink{group__key}{Key} database. 
\end{DoxySeeAlso}

\begin{DoxyRetVals}{Return values}
{\em 1} & if the keys were retrieved successfully \\
\hline
{\em 0} & if there was no update -\/ no changes are made to the keyset then \\
\hline
{\em -\/1} & on failure -\/ no changes are made to the keyset then \\
\hline
\end{DoxyRetVals}
\hypertarget{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{\index{K\-D\-B@{K\-D\-B}!kdb\-Open@{kdb\-Open}}
\index{kdb\-Open@{kdb\-Open}!KDB@{K\-D\-B}}
\subsubsection[{kdb\-Open}]{\setlength{\rightskip}{0pt plus 5cm}K\-D\-B$\ast$ kdb\-Open (
\begin{DoxyParamCaption}
\item[{Key $\ast$}]{error\-Key}
\end{DoxyParamCaption}
)}}\label{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}


Opens the session with the Key database. 

The method will bootstrap itself the following way. The first step is to open the default backend. With it system/elektra/mountpoints will be loaded and all needed libraries and mountpoints will be determined. These libraries for backends will be loaded and with it the {\ttfamily K\-D\-B} datastructure will be initialized.

You must always call this method before retrieving or committing any keys to the database. In the end of the program, after using the key database, you must not forget to \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()}. You can use the atexit () handler for it.

The pointer to the {\ttfamily K\-D\-B} structure returned will be initialized like described above, and it must be passed along on any kdb$\ast$() method your application calls.

Get a {\ttfamily K\-D\-B} handle for every thread using elektra. Don't share the handle across threads, and also not the pointer accessing it\-: 
\begin{DoxyCode}
thread1
\{
        KDB * h;
        h = \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdbOpen}(parent);
        \textcolor{comment}{// fetch keys and work with them}
        \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdbClose}(h, parent);
\}
thread2
\{
        KDB * h;
        h = \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdbOpen}(parent);
        \textcolor{comment}{// fetch keys and work with them}
        \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdbClose}(h, parent);
\}
\end{DoxyCode}


You don't need \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()} if you only want to manipulate plain in-\/memory Key or Key\-Set objects.

\begin{DoxyPrecond}{Precondition}
error\-Key must be a valid key, e.\-g. created with \hyperlink{group__key_gad23c65b44bf48d773759e1f9a4d43b89}{key\-New()}
\end{DoxyPrecond}

\begin{DoxyParams}{Parameters}
{\em error\-Key} & the key which holds errors and warnings which were issued \\
\hline
\end{DoxyParams}
\begin{DoxySeeAlso}{See Also}
\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()}, \hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()} to end all affairs to the \hyperlink{group__key}{Key} database. 
\end{DoxySeeAlso}

\begin{DoxyRetVals}{Return values}
{\em handle} & on success \\
\hline
{\em N\-U\-L\-L} & on failure \\
\hline
\end{DoxyRetVals}
\hypertarget{group__kdb_ga11436b058408f83d303ca5e996832bcf}{\index{K\-D\-B@{K\-D\-B}!kdb\-Set@{kdb\-Set}}
\index{kdb\-Set@{kdb\-Set}!KDB@{K\-D\-B}}
\subsubsection[{kdb\-Set}]{\setlength{\rightskip}{0pt plus 5cm}int kdb\-Set (
\begin{DoxyParamCaption}
\item[{K\-D\-B $\ast$}]{handle, }
\item[{Key\-Set $\ast$}]{ks, }
\item[{Key $\ast$}]{parent\-Key}
\end{DoxyParamCaption}
)}}\label{group__kdb_ga11436b058408f83d303ca5e996832bcf}


Set keys in an atomic and universal way. 

With {\ttfamily parent\-Key} you can only store a part of the given keyset. When other keys also belong to a backend, they will be used too, even when they are above {\ttfamily parent\-Key}.

\begin{DoxyParagraph}{Details\-:}

\end{DoxyParagraph}
If you pass a parent\-Key without a name the whole keyset will be set in an atomic way.

Each key is checked with \hyperlink{group__keytest_gaf247df0de7aca04b32ef80e39ef12950}{key\-Need\-Sync()} before being actually committed. So only changed keys are updated. If no key of a backend needs to be synced any affairs to backends omitted and 0 is returned.

\begin{DoxyParagraph}{Errors\-:}

\end{DoxyParagraph}
If some error occurs, \hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set()} will stop. In this situation the Key\-Set internal cursor will be set on the key that generated the error.

None of the keys are actually commited.

You should present the error message to the user and let the user decide what to do. Possible solutions are\-:
\begin{DoxyItemize}
\item repeat the same kdb\-Set (for temporary errors)
\item remove the key and set it again (for validation or type errors)
\item change the value and try it again (for validation errors)
\item do a kdb\-Get and then (for conflicts ...)
\begin{DoxyItemize}
\item set the same keyset again (in favour of what was set by this user)
\item drop the old keyset (in favour of what was set elsewhere)
\end{DoxyItemize}
\item export the configuration into a file (for unresolvable errors)
\end{DoxyItemize}

\begin{DoxyParagraph}{Example of how this method can be used\-:}

\begin{DoxyCode}
\textcolor{keywordtype}{int} i;
KeySet *myConfig = \hyperlink{group__keyset_ga671e1aaee3ae9dc13b4834a4ddbd2c3c}{ksNew}(0,KS\_END);
Key *parentKey = \hyperlink{group__key_gad23c65b44bf48d773759e1f9a4d43b89}{keyNew}(\textcolor{stringliteral}{"system/sw/MyApp"},\hyperlink{group__key_gga91fb3178848bd682000958089abbaf40aa8adb6fcb92dec58fb19410eacfdd403}{KEY\_END});
KDB *handle = \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdbOpen}(pkey);

\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, ks, parentKey); \textcolor{comment}{// kdbGet needs to be called first!}
KeySet *base = \hyperlink{group__keyset_gac59e4b328245463f1451f68d5106151c}{ksDup}(ks); \textcolor{comment}{// save a copy of original keyset}

\textcolor{comment}{// change the keys within ks}

KeySet *ours = \hyperlink{group__keyset_gac59e4b328245463f1451f68d5106151c}{ksDup}(ks); \textcolor{comment}{// save a copy of our keyset}
\textcolor{keywordtype}{int} ret=\hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdbSet}(handle, ks, parentKey);
\textcolor{keywordflow}{while} (ret == -1) \textcolor{comment}{// as long as we have an error}
\{
        \textcolor{comment}{// We got an error. Warn user.}
        Key *problemKey = \hyperlink{group__keyset_ga4287b9416912c5f2ab9c195cb74fb094}{ksCurrent}(ks);
        \textcolor{comment}{// parentKey has the errorInformation}
        \textcolor{comment}{// problemKey is the faulty key (may be null)}
        \textcolor{keywordtype}{int} userInput = showElektraErrorDialog (parentKey, problemKey);
        \textcolor{keywordflow}{switch} (userInput)
        \{
        \textcolor{keywordflow}{case} INPUT\_USE\_OURS:
                \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, ks, parentKey); \textcolor{comment}{// refresh key database}
                \hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel}(ks);
                ks = ours;
                \textcolor{keywordflow}{break};
        \textcolor{keywordflow}{case} INPUT\_DO\_MERGE:
                \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, ks, parentKey); \textcolor{comment}{// refresh key database}
                KeySet * res=doElektraMerge(ours, ks, base);
                \hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel}(ks);
                ks = res;
                \textcolor{keywordflow}{break};
        \textcolor{keywordflow}{case} INPUT\_USE\_THEIRS:
                \textcolor{comment}{// should always work, we just write what we got}
                \textcolor{comment}{// but to be sure always give the user another way}
                \textcolor{comment}{// to exit the loop}
                \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdbGet}(handle, ks, parentKey); \textcolor{comment}{// refresh key database}
                \textcolor{keywordflow}{break};
        ...
        \}
        ret=\hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdbSet}(handle, ks, parentKey);
\}

\hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel} (ours);
\hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel} (base);
\hyperlink{group__keyset_ga27e5c16473b02a422238c8d970db7ac8}{ksDel} (ks); \textcolor{comment}{// delete the in-memory configuration}

\hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdbClose}(handle, parentKey); \textcolor{comment}{// no more affairs with the key database.}
\hyperlink{group__key_ga3df95bbc2494e3e6703ece5639be5bb1}{keyDel}(parentKey);
\end{DoxyCode}

\end{DoxyParagraph}
show\-Elektra\-Error\-Dialog() and do\-Elektra\-Merge() need to be implemented by the user. For do\-Elektra\-Merge a 3-\/way merge algorithm exists in libelektra-\/tools.

\begin{DoxyPrecond}{Precondition}
\hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} must be called before \hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set()}\-:
\begin{DoxyItemize}
\item initially (after \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()})
\item after conflict errors in \hyperlink{group__kdb_ga11436b058408f83d303ca5e996832bcf}{kdb\-Set()}.
\end{DoxyItemize}
\end{DoxyPrecond}

\begin{DoxyParams}{Parameters}
{\em handle} & contains internal information of \hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{opened } key database \\
\hline
{\em ks} & a Key\-Set which should contain changed keys, otherwise nothing is done \\
\hline
{\em parent\-Key} & holds the information below which key keys should be set, see above \\
\hline
\end{DoxyParams}

\begin{DoxyRetVals}{Return values}
{\em 1} & on success \\
\hline
{\em 0} & if nothing had to be done \\
\hline
{\em -\/1} & on failure \\
\hline
\end{DoxyRetVals}
\begin{DoxySeeAlso}{See Also}
\hyperlink{group__keytest_gaf247df0de7aca04b32ef80e39ef12950}{key\-Need\-Sync()} 

\hyperlink{group__keyset_ga317321c9065b5a4b3e33fe1c399bcec9}{ks\-Next()}, \hyperlink{group__keyset_ga4287b9416912c5f2ab9c195cb74fb094}{ks\-Current()} for iteration over the \hyperlink{group__keyset}{Key\-Set} 

\hyperlink{group__kdb_ga6808defe5870f328dd17910aacbdc6ca}{kdb\-Open()} and \hyperlink{group__kdb_ga28e385fd9cb7ccfe0b2f1ed2f62453a1}{kdb\-Get()} that must be called first 

\hyperlink{group__kdb_gadb54dc9fda17ee07deb9444df745c96f}{kdb\-Close()} that must be called afterwards 
\end{DoxySeeAlso}
