Elektra: kdb::KDB Class Reference

Elektra 0.8.24

Public Member Functions | List of all members
kdb::KDB Class Reference

Constructs a class KDB. More...

`#include <kdb.hpp>`

Inherited by kdb::tools::merging::MergingKDB.

## Public Member Functions
| KDB ()
| Constructs a class KDB. More...
| KDB (Key &errorKey)
| Constructs a class KDB. More...
virtual void | open (Key &errorKey)
| Open the database. More...
virtual void | close () throw ()
| Close the database. More...
virtual void | close (Key &errorKey) throw ()
| Close the database. More...
virtual int | get (KeySet &returned, std::string const &keyname)
| Get all keys below keyname inside returned. More...
virtual int | get (KeySet &returned, Key &parentKey)
| Get all keys below parentKey inside returned. More...
virtual int | set (KeySet &returned, std::string const &keyname)
| Set all keys below keyname. More...
virtual int | set (KeySet &returned, Key &parentKey)
| Set all keys below parentKey. More...

## Detailed Description

Constructs a class KDB.

Exceptions

  KDBException | if database could not be opened

Opens the session with the Key database.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

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:

void thread1 (void)
{
Key * parent = keyNew ("/app/part1", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}
void thread2 (void)
{
Key * parent = keyNew ("/app/part2", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}

You don't need kdbOpen() if you only want to manipulate plain in-memory Key or KeySet objects.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

Parameters

  errorKey | the key which holds errors and warnings which were issued

See also
  kdbGet(), kdbClose() to end all affairs to the Key database.

Return values

  handle | on success
  NULL | on failure

Access to the key database.

Invariant
  the object holds a valid connection to the key database or is empty

## Constructor & Destructor Documentation

## ◆ KDB() [1/2]

kdb::KDB::KDB | ( |  | ) |
| inline

Constructs a class KDB.

Exceptions

  KDBException | if database could not be opened

Opens the session with the Key database.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

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:

void thread1 (void)
{
Key * parent = keyNew ("/app/part1", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}
void thread2 (void)
{
Key * parent = keyNew ("/app/part2", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}

You don't need kdbOpen() if you only want to manipulate plain in-memory Key or KeySet objects.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

Parameters

  errorKey | the key which holds errors and warnings which were issued

See also
  kdbGet(), kdbClose() to end all affairs to the Key database.

Return values

  handle | on success
  NULL | on failure

## ◆ KDB() [2/2]

kdb::KDB::KDB | ( | Key & | errorKey | ) |
| inlineexplicit

Constructs a class KDB.

Parameters

  errorKey | is useful if you want to get the warnings in the successful case, when no exception is thrown.

Exceptions

  KDBException | if database could not be opened

Opens the session with the Key database.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

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:

void thread1 (void)
{
Key * parent = keyNew ("/app/part1", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}
void thread2 (void)
{
Key * parent = keyNew ("/app/part2", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}

You don't need kdbOpen() if you only want to manipulate plain in-memory Key or KeySet objects.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

Parameters

  errorKey | the key which holds errors and warnings which were issued

See also
  kdbGet(), kdbClose() to end all affairs to the Key database.

Return values

  handle | on success
  NULL | on failure

## Member Function Documentation

## ◆ close() [1/2]

void kdb::KDB::close | ( |  | ) |
throw | ( |
| ) |  |
| inlinevirtual

Close the database.

The return value does not matter because its only a null pointer check.

Closes the session with the Key database.

Precondition
  The handle must be a valid handle as returned from kdbOpen()
  errorKey must be a valid key, e.g. created with keyNew()

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.

Parameters

  handle | contains internal information of opened key database
  errorKey | the key which holds error/warning information

Return values

  0 | on success
  -1 | on NULL pointer

## ◆ close() [2/2]

void kdb::KDB::close | ( | Key & | errorKey | ) |
throw | ( |
| ) |  |
| inlinevirtual

Close the database.

The return value does not matter because its only a null pointer check.

Parameters

  errorKey | is useful if you want to get the warnings

Closes the session with the Key database.

Precondition
  The handle must be a valid handle as returned from kdbOpen()
  errorKey must be a valid key, e.g. created with keyNew()

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.

Parameters

  handle | contains internal information of opened key database
  errorKey | the key which holds error/warning information

Return values

  0 | on success
  -1 | on NULL pointer

## ◆ get() [1/2]

int kdb::KDB::get | ( | KeySet & | returned,
|  | std::string const & | keyname
| ) |  |
| inlinevirtual

Get all keys below keyname inside returned.

Retrieve keys in an atomic and universal way.

Precondition
  The `handle` must be passed as returned from kdbOpen().
  The `returned` KeySet must be a valid KeySet, e.g. constructed with ksNew().
  The `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).

Note
  kdbGet() might retrieve more keys than requested (that are not below parentKey). These keys must be passed to calls of kdbSet(), 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 kdbGet() "system/mountpoint/interest" 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!

Example:
  This example demonstrates the typical usecase within an application (without error handling).

#include <kdb.h>
#include <stdio.h>
int main (void)
{
KeySet * myConfig = ksNew (0, KS_END);
// for error handling see kdbget_error.c
// clang-format off
Key * key = keyNew ("/sw/tests/myapp/#0/current/", KEY_END);
KDB * handle = kdbOpen (key);
kdbGet (handle, myConfig, key);
Key * result = ksLookupByName (myConfig, "/sw/tests/myapp/#0/current/testkey1", 0);
// clang-format on
keyDel (key);
const char * key_name = keyName (result);
const char * key_value = keyString (result);
const char * key_comment = keyString (keyGetMeta (result, "comment"));
printf ("key: %s value: %s comment: %s\n", key_name, key_value, key_comment);
ksDel (myConfig); // delete the in-memory configuration
// maybe you want kdbSet() myConfig here
kdbClose (handle, 0); // no more affairs with the key database.
}

When a backend fails kdbGet() will return -1 with all error and warning information in the `parentKey`. The parameter `returned` will not be changed.

Optimization:
  In the first run of kdbGet all requested (or more) keys are retrieved. On subsequent calls only the keys are retrieved where something was changed inside the key database. The other keys stay in the KeySet returned as passed.

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().

Parameters

  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). cascading keys (starting with /) will retrieve the same path in all namespaces / will retrieve all keys
  ks | the (pre-initialized) KeySet returned with all keys found will not be changed on error or if no update is required

See also
  ksLookup(), ksLookupByName() for powerful lookups after the KeySet was retrieved
  kdbOpen() which needs to be called before
  kdbSet() to save the configuration afterwards and kdbClose() to finish affairs with the Key database.

Return values

  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

#include <kdb.hpp>
#include <keyio.hpp>
using namespace kdb;
int main ()
{
KeySet config;
KDB kdb;
kdb.get (config, "/sw/MyApp");
Key k = config.lookup ("/sw/MyApp/mykey");
if (k)
{
std::cout << k << " is " << k.get<int> () << std::endl;
}
else
{
std::cerr << "No key found" << std::endl;
return 1;
}
}

Parameters

  returned | the keyset where the keys will be in
  keyname | the root keyname which should be used to get keys below it

Return values

  0 | if no key was updated
  1 | if user or system keys were updated
  2 | if user and system keys were updated

Exceptions

  KDBException | if there were problems with the database

See also
  KDB::get (KeySet & returned, Key & parentKey)

Reimplemented in kdb::tools::merging::MergingKDB.

## ◆ get() [2/2]

int kdb::KDB::get | ( | KeySet & | returned,
|  | Key & | parentKey
| ) |  |
| inlinevirtual

Get all keys below parentKey inside returned.

Retrieve keys in an atomic and universal way.

Precondition
  The `handle` must be passed as returned from kdbOpen().
  The `returned` KeySet must be a valid KeySet, e.g. constructed with ksNew().
  The `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).

Note
  kdbGet() might retrieve more keys than requested (that are not below parentKey). These keys must be passed to calls of kdbSet(), 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 kdbGet() "system/mountpoint/interest" 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!

Example:
  This example demonstrates the typical usecase within an application (without error handling).

#include <kdb.h>
#include <stdio.h>
int main (void)
{
KeySet * myConfig = ksNew (0, KS_END);
// for error handling see kdbget_error.c
// clang-format off
Key * key = keyNew ("/sw/tests/myapp/#0/current/", KEY_END);
KDB * handle = kdbOpen (key);
kdbGet (handle, myConfig, key);
Key * result = ksLookupByName (myConfig, "/sw/tests/myapp/#0/current/testkey1", 0);
// clang-format on
keyDel (key);
const char * key_name = keyName (result);
const char * key_value = keyString (result);
const char * key_comment = keyString (keyGetMeta (result, "comment"));
printf ("key: %s value: %s comment: %s\n", key_name, key_value, key_comment);
ksDel (myConfig); // delete the in-memory configuration
// maybe you want kdbSet() myConfig here
kdbClose (handle, 0); // no more affairs with the key database.
}

When a backend fails kdbGet() will return -1 with all error and warning information in the `parentKey`. The parameter `returned` will not be changed.

Optimization:
  In the first run of kdbGet all requested (or more) keys are retrieved. On subsequent calls only the keys are retrieved where something was changed inside the key database. The other keys stay in the KeySet returned as passed.

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().

Parameters

  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). cascading keys (starting with /) will retrieve the same path in all namespaces / will retrieve all keys
  ks | the (pre-initialized) KeySet returned with all keys found will not be changed on error or if no update is required

See also
  ksLookup(), ksLookupByName() for powerful lookups after the KeySet was retrieved
  kdbOpen() which needs to be called before
  kdbSet() to save the configuration afterwards and kdbClose() to finish affairs with the Key database.

Return values

  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

Parameters

  returned | the keyset where the keys will be in
  parentKey | the parentKey of returned

Return values

  0 | if no key was updated
  1 | if user or system keys were updated
  2 | if user and system keys were updated

Exceptions

  KDBException | if there were problems with the database

Reimplemented in kdb::tools::merging::MergingKDB.

## ◆ open()

void kdb::KDB::open | ( | Key & | errorKey | ) |
| inlinevirtual

Open the database.

Parameters

  errorKey | is useful if you want to get the warnings in the successful case, when no exception is thrown.

Opens the session with the Key database.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

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:

void thread1 (void)
{
Key * parent = keyNew ("/app/part1", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}
void thread2 (void)
{
Key * parent = keyNew ("/app/part2", KEY_CASCADING_NAME, KEY_END);
KDB * h = kdbOpen (parent);
// fetch keys and work with them
kdbClose (h, parent);
}

You don't need kdbOpen() if you only want to manipulate plain in-memory Key or KeySet objects.

Precondition
  errorKey must be a valid key, e.g. created with keyNew()

Parameters

  errorKey | the key which holds errors and warnings which were issued

See also
  kdbGet(), kdbClose() to end all affairs to the Key database.

Return values

  handle | on success
  NULL | on failure

## ◆ set() [1/2]

int kdb::KDB::set | ( | KeySet & | returned,
|  | std::string const & | keyname
| ) |  |
| inlinevirtual

Set all keys below keyname.

If the keyname of the parentKey is invalid (e.g. empty) all keys will be set.

Set keys in an atomic and universal way.

Precondition
  kdbGet() must be called before kdbSet():
  - initially (after kdbOpen())
  - after conflict errors in kdbSet().
  The `returned` KeySet must be a valid KeySet, e.g. constructed with ksNew().
  The `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().

Errors
  If some error occurs:
  - kdbSet() will leave the KeySet's * internal cursor on the key that generated the error.
  - Error information will be written into the metadata of the parent key.
  - None of the keys are actually committed in this situation, i.e. no configuration file will be modified.

In case of errors you should present the error message to the user and let the user decide what to do. Possible solutions are:

- remove the problematic key and use kdbSet() again (for validation or type errors)
- change the value of the problematic key and use kdbSet() again (for validation errors)
- do a kdbGet() (for conflicts, i.e. error 30) and then
  - set the same keyset again (in favour of what was set by this user)
  - drop the old keyset (in favour of what was set from another application)
  - merge the original, your own and the other keyset
- export the configuration into a file (for unresolvable errors)
- repeat the same kdbSet might be of limited use if the user does not explicitly request it, because temporary errors are rare and its unlikely that they fix themselves (e.g. disc full, permission problems)

Optimization
  Each key is checked with keyNeedSync() before being actually committed. If no key of a backend needs to be synced any affairs to backends are omitted and 0 is returned.

KeySet * myConfig = ksNew (0, KS_END);
Key * parentKey = keyNew ("system/sw/MyApp", KEY_END);
KDB * handle = kdbOpen (parentKey);
kdbGet (handle, myConfig, parentKey); // kdbGet needs to be called first!
KeySet * base = ksDup (myConfig); // save a copy of original keyset
// change the keys within myConfig
KeySet * ours = ksDup (myConfig); // save a copy of our keyset
KeySet * theirs; // needed for 3-way merging
int ret = kdbSet (handle, myConfig, parentKey);
while (ret == -1) // as long as we have an error
{
// We got an error. Warn user.
Key * problemKey = ksCurrent (myConfig);
// parentKey has the errorInformation
// problemKey is the faulty key (may be null)
int userInput = showElektraErrorDialog (parentKey, problemKey);
switch (userInput)
{
case INPUT_USE_OURS:
kdbGet (handle, myConfig, parentKey); // refresh key database
ksDel (myConfig);
myConfig = ours;
break;
case INPUT_DO_MERGE:
theirs = ksDup (ours);
kdbGet (handle, theirs, parentKey); // refresh key database
KeySet * res = doElektraMerge (ours, theirs, base);
ksDel (theirs);
myConfig = res;
break;
case INPUT_USE_THEIRS:
// should always work, we just write what we got
// but to be sure always give the user another way
// to exit the loop
kdbGet (handle, myConfig, parentKey); // refresh key database
break;
// other cases ...
}
ret = kdbSet (handle, myConfig, parentKey);
}
ksDel (ours);
ksDel (base);
ksDel (myConfig); // delete the in-memory configuration
kdbClose (handle, parentKey); // no more affairs with the key database.
keyDel (parentKey);

showElektraErrorDialog() and doElektraMerge() need to be implemented by the user of Elektra. For doElektraMerge a 3-way merge algorithm exists in libelektra-tools.

Parameters

  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). cascading keys (starting with /) will set the path in all namespaces / will commit all keys metanames will be rejected (error 104) empty/invalid (error 105)

Return values

  1 | on success
  0 | if nothing had to be done, no changes in KDB
  -1 | on failure, no changes in KDB

See also
  keyNeedSync()
  ksCurrent() contains the error Key
  kdbOpen() and kdbGet() that must be called first
  kdbClose() that must be called afterwards

Return values

  0 | if no key was updated
  1 | if user or system keys were updated
  2 | if user and system keys were updated

Parameters

  returned | the keyset where the keys will be in
  keyname | the keyname below the names should be set

Exceptions

  KDBException | if there were problems with the database

## ◆ set() [2/2]

int kdb::KDB::set | ( | KeySet & | returned,
|  | Key & | parentKey
| ) |  |
| inlinevirtual

Set all keys below parentKey.

If the keyname of the parentKey is invalid (e.g. empty) all keys will be set.

Set keys in an atomic and universal way.

Precondition
  kdbGet() must be called before kdbSet():
  - initially (after kdbOpen())
  - after conflict errors in kdbSet().
  The `returned` KeySet must be a valid KeySet, e.g. constructed with ksNew().
  The `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().

Errors
  If some error occurs:
  - kdbSet() will leave the KeySet's * internal cursor on the key that generated the error.
  - Error information will be written into the metadata of the parent key.
  - None of the keys are actually committed in this situation, i.e. no configuration file will be modified.

In case of errors you should present the error message to the user and let the user decide what to do. Possible solutions are:

- remove the problematic key and use kdbSet() again (for validation or type errors)
- change the value of the problematic key and use kdbSet() again (for validation errors)
- do a kdbGet() (for conflicts, i.e. error 30) and then
  - set the same keyset again (in favour of what was set by this user)
  - drop the old keyset (in favour of what was set from another application)
  - merge the original, your own and the other keyset
- export the configuration into a file (for unresolvable errors)
- repeat the same kdbSet might be of limited use if the user does not explicitly request it, because temporary errors are rare and its unlikely that they fix themselves (e.g. disc full, permission problems)

Optimization
  Each key is checked with keyNeedSync() before being actually committed. If no key of a backend needs to be synced any affairs to backends are omitted and 0 is returned.

KeySet * myConfig = ksNew (0, KS_END);
Key * parentKey = keyNew ("system/sw/MyApp", KEY_END);
KDB * handle = kdbOpen (parentKey);
kdbGet (handle, myConfig, parentKey); // kdbGet needs to be called first!
KeySet * base = ksDup (myConfig); // save a copy of original keyset
// change the keys within myConfig
KeySet * ours = ksDup (myConfig); // save a copy of our keyset
KeySet * theirs; // needed for 3-way merging
int ret = kdbSet (handle, myConfig, parentKey);
while (ret == -1) // as long as we have an error
{
// We got an error. Warn user.
Key * problemKey = ksCurrent (myConfig);
// parentKey has the errorInformation
// problemKey is the faulty key (may be null)
int userInput = showElektraErrorDialog (parentKey, problemKey);
switch (userInput)
{
case INPUT_USE_OURS:
kdbGet (handle, myConfig, parentKey); // refresh key database
ksDel (myConfig);
myConfig = ours;
break;
case INPUT_DO_MERGE:
theirs = ksDup (ours);
kdbGet (handle, theirs, parentKey); // refresh key database
KeySet * res = doElektraMerge (ours, theirs, base);
ksDel (theirs);
myConfig = res;
break;
case INPUT_USE_THEIRS:
// should always work, we just write what we got
// but to be sure always give the user another way
// to exit the loop
kdbGet (handle, myConfig, parentKey); // refresh key database
break;
// other cases ...
}
ret = kdbSet (handle, myConfig, parentKey);
}
ksDel (ours);
ksDel (base);
ksDel (myConfig); // delete the in-memory configuration
kdbClose (handle, parentKey); // no more affairs with the key database.
keyDel (parentKey);

showElektraErrorDialog() and doElektraMerge() need to be implemented by the user of Elektra. For doElektraMerge a 3-way merge algorithm exists in libelektra-tools.

Parameters

  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). cascading keys (starting with /) will set the path in all namespaces / will commit all keys metanames will be rejected (error 104) empty/invalid (error 105)

Return values

  1 | on success
  0 | if nothing had to be done, no changes in KDB
  -1 | on failure, no changes in KDB

See also
  keyNeedSync()
  ksCurrent() contains the error Key
  kdbOpen() and kdbGet() that must be called first
  kdbClose() that must be called afterwards

Return values

  0 | if no key was updated
  1 | if user or system keys were updated
  2 | if user and system keys were updated

Parameters

  returned | the keyset where the keys are passed to the user
  parentKey | the parentKey of returned

Exceptions

  KDBException | if there were problems with the database

The documentation for this class was generated from the following file:

- kdb.hpp