Elektra
0.9.0
|
General methods to access the Key database. More...
Functions | |
int | elektraOpenBootstrap (KDB *handle, KeySet *keys, Key *errorKey) |
Bootstrap, first phase with fallback. | |
KDB * | kdbOpen (Key *errorKey) |
Opens the session with the Key database. More... | |
int | kdbClose (KDB *handle, Key *errorKey) |
Closes the session with the Key database. More... | |
int | kdbGet (KDB *handle, KeySet *ks, Key *parentKey) |
Retrieve keys in an atomic and universal way. More... | |
int | kdbSet (KDB *handle, KeySet *ks, Key *parentKey) |
Set keys in an atomic and universal way. More... | |
int | kdbEnsure (KDB *handle, KeySet *contract, Key *parentKey) |
This function can be used the given KDB handle meets certain clauses, specified in contract . More... | |
General methods to access the Key database.
To use them:
The kdb*() methods are used to access the storage, to get and set KeySets.
Parameters common for all these functions are:
KDB uses different backend implementations that know the details about how to access the storage. One backend consists of multiple plugins. See writing a new plugin for information about how to write a plugin. Backends are state-less regarding the configuration (because of that you must pass back the whole configuration for every backend), but have a state for:
For every handle you got from kdbOpen(), for every parentKey with a different name, only the shown state transitions are valid. From a freshly opened KDB, only kdbGet() and kdbClose() are allowed, because otherwise conflicts (error 30) would not be detected.
Once kdbGet() was called (for a specific handle+parentKey), any number of kdbGet() and kdbSet() can be used with this handle respective parentKey, unless kdbSet() had a conflict (error 30) with another application. Every affair with KDB needs to be finished with kdbClose().
The name of the parentKey in kdbOpen() and kdbClose() does not matter.
In the usual case we just have one parentKey and one handle. In these cases we just have to remember to use kdbGet() before kdbSet():
To output warnings, you can use following code:
To output the error, you can use following code:
int kdbClose | ( | KDB * | handle, |
Key * | errorKey | ||
) |
Closes the session with the Key database.
This is the counterpart of kdbOpen().
You must call this method when you finished your affairs with the key database. You can manipulate Key and KeySet objects also after kdbClose(), but you must not use any kdb*() call afterwards.
The handle
parameter will be finalized and all resources associated to it will be freed. After a kdbClose(), the handle
cannot be used anymore.
handle | contains internal information of opened key database |
errorKey | the key which holds error/warning information |
0 | on success |
-1 | on NULL pointer |
int kdbEnsure | ( | KDB * | handle, |
KeySet * | contract, | ||
Key * | parentKey | ||
) |
This function can be used the given KDB handle
meets certain clauses, specified in contract
.
Currently the following clauses are supported:
system/elektra/ensure/plugins/<mountpoint>/<pluginname>
defines the state of the plugin <pluginname>
for the mountpoint <mountpoint>
:unmounted
ensures the plugin is not mounted, at this mountpoint.mounted
ensures the plugin is mounted, at this mountpoint. If the plugin is not mounted, we will try to mount it.remount
always mounts the plugin, at this mountpoint. If it was already mounted, it will me unmounted and mounted again. This can be used to ensure the plugin is mounted with a certain configuration.system/elektra/ensure/plugins/<mountpoint>/<pluginname>/config
are extracted and used as the plugins config KeySet during mounting. system/elektra/ensure/plugins/<mountpoint>/<pluginname>
will be repleced by user
in the keynames. If no keys are given, an empty KeySet is used.There are a few special values for <mountpoint>
:
global
is used to indicate the plugin should (un)mounted as a global plugin. Currently this only supports (un)mounting plugins from/to the subposition maxonce
.parent
is used to indicate the keyname of parentKey
shall be used as the mountpoint.If <mountpoint>
is none of those values, it has to be valid keyname with the slashes escaped. That means it has to start with /
, user
, system
, dir
or spec
.
If <mountpoint>
is NOT global
, currently only unmounted
is supported (not mounted
and remounted
).
NOTE: This function only works properly, if the list plugin is mounted in all global positions. If this is not the case, 1 will be returned, because this is seen as an implicit clause in the contract. Additionally any contract that specifies clauses for the list plugin is rejected as malformed.
handle | contains internal information of opened key database |
contract | KeySet containing the contract described above. This will always be ksDel() ed. Even in error cases. |
parentKey | The parentKey used if the parent special value is used, otherwise only used for error reporting. |
0 | on success |
1 | if clauses of the contract are unmet |
-1 | on NULL pointers, or malformed contract |
int kdbGet | ( | KDB * | handle, |
KeySet * | ks, | ||
Key * | parentKey | ||
) |
Retrieve keys in an atomic and universal way.
handle
must be passed as returned from kdbOpen().returned
KeySet must be a valid KeySet, e.g. constructed with ksNew().parentKey
Key must be a valid Key, e.g. constructed with keyNew().If you pass NULL on any parameter kdbGet() will fail immediately without doing anything.
The returned
KeySet may already contain some keys, e.g. from previous kdbGet() calls. The new retrieved keys will be appended using ksAppendKey().
If not done earlier kdbGet() will fully retrieve all keys under the parentKey
folder recursively (See Optimization below when it will not be done).
When a backend fails kdbGet() will return -1 with all error and warning information in the parentKey
. The parameter returned
will not be changed.
It is your responsibility to save the original keyset if you need it afterwards.
If you want to be sure to get a fresh keyset again, you need to open a second handle to the key database using kdbOpen().
handle | contains internal information of opened key database |
parentKey | is used to add warnings and set an error information. Additionally, its name is a hint which keys should be retrieved (it is possible that more are retrieved, see Note above).
|
ks | the (pre-initialized) KeySet returned with all keys found will not be changed on error or if no update is required |
1 | if the keys were retrieved successfully |
0 | if there was no update - no changes are made to the keyset then |
-1 | on failure - no changes are made to the keyset then |
KDB* kdbOpen | ( | Key * | errorKey | ) |
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 KDB
data structure 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 kdbClose().
The pointer to the KDB
structure returned will be initialized like described above, and it must be passed along on any kdb*() method your application calls.
Get a KDB
handle for every thread using elektra. Don't share the handle across threads, and also not the pointer accessing it:
You don't need kdbOpen() if you only want to manipulate plain in-memory Key or KeySet objects.
errorKey | the key which holds errors and warnings which were issued |
handle | on success |
NULL | on failure |
int kdbSet | ( | KDB * | handle, |
KeySet * | ks, | ||
Key * | parentKey | ||
) |
Set keys in an atomic and universal way.
returned
KeySet must be a valid KeySet, e.g. constructed with ksNew().parentKey
Key must be a valid Key, e.g. constructed with keyNew().If you pass NULL on any parameter kdbSet() will fail immediately without doing anything.
With parentKey
you can give an hint which part of the given keyset is of interest for you. Then you promise to only modify or remove keys below this key. All others would be passed back as they were retrieved by kdbGet().
In case of errors you should present the error message to the user and let the user decide what to do. Possible solutions are:
showElektraErrorDialog() and doElektraMerge() need to be implemented by the user of Elektra. For doElektraMerge a 3-way merge algorithm exists in libelektra-tools.
handle | contains internal information of opened key database |
ks | a KeySet which should contain changed keys, otherwise nothing is done |
parentKey | is used to add warnings and set an error information. Additionally, its name is an hint which keys should be committed (it is possible that more are changed).
|
1 | on success |
0 | if nothing had to be done, no changes in KDB |
-1 | on failure, no changes in KDB |