Main Page | Modules | Data Structures | File List | Data Fields

Elektra framework for pluggable backends

The tactics to create pluggable backends to libelektra.so. More...

Data Structures

struct  _Key
 The private Key struct. More...
struct  _KeySet
 The private KeySet struct. More...

Enumerations

enum  KDBBackendMethod {
  KDB_BE_OPEN = 1,
  KDB_BE_CLOSE = 1<<1,
  KDB_BE_STATKEY = 1<<2,
  KDB_BE_GETKEY = 1<<3,
  KDB_BE_SETKEY = 1<<4,
  KDB_BE_SETKEYS = 1<<5,
  KDB_BE_RENAME = 1<<6,
  KDB_BE_REMOVEKEY = 1<<7,
  KDB_BE_GETCHILD = 1<<8,
  KDB_BE_MONITORKEY = 1<<9,
  KDB_BE_MONITORKEYS = 1<<10,
  KDB_BE_END = 0
}
 Switches to denote the backend methods. More...

Functions

ssize_t unencode (char *encoded, void *returned)
 Unencodes a buffer of ASCII hexadecimal values into a byte stream.
int kdbNeedsUTF8Conversion ()
 Checks if UTF-8 conversion is needed in current context.
int UTF8Engine (int direction, char **string, size_t *inputOutputByteSize)
 Converts string to (direction = UTF8_TO) and from (direction = UTF8_FROM) UTF-8.
ssize_t encode (void *unencoded, size_t size, char *returned)
 Encodes a buffer of data onto hexadecimal ASCII.
int kdbSetKeys_default (KeySet *ks)
 A high level, probably inefficient implementation for the kdbSetKeys() method.
uint32_t kdbMonitorKeys_default (KeySet *interests, uint32_t diffMask, unsigned long iterations, unsigned sleeptime)
 A high level, probably inefficient, implementation for the kdbMonitorKeys() method.
uint32_t kdbMonitorKey_default (Key *interest, uint32_t diffMask, unsigned long iterations, unsigned sleeptime)
 A high level, probably inefficient, implementation for the kdbMonitorKey() method.
KDBBackend * kdbBackendExport (const char *backendName,...)
 This function must be called by a backend's kdbBackendFactory() to define the backend's methods that will be exported.
size_t strblen (const char *s)
 Calculates the lenght in bytes of a string.
int kdbOpen_backend ()
 Initialize the backend.
int kdbClose_backend ()
 All finalization logic of the backend should go here.
int kdbStatKey_backend (Key *key)
 Implementation for kdbStatKey() method.
int kdbGetKey_backend (Key *key)
 Implementation for kdbGetKey() method.
int kdbSetKey_backend (Key *key)
 Implementation for kdbSetKey() method.
int kdbRename_backend (Key *key, const char *newName)
 Implementation for kdbRename() method.
int kdbRemoveKey_backend (const Key *key)
 Implementation for kdbRemoveKey() method.
ssize_t kdbGetKeyChildKeys_backend (const Key *parentKey, KeySet *returned, unsigned long options)
 Implementation for kdbGetKeyChildKeys() method.
int kdbSetKeys_backend (KeySet *ks)
 Implementation for kdbSetKeys() method.
uint32_t kdbMonitorKeys_backend (KeySet *interests, uint32_t diffMask, unsigned long iterations, unsigned sleep)
 The implementation of this method is optional.
uint32_t kdbMonitorKey_backend (Key *interest, uint32_t diffMask, unsigned long iterations, unsigned sleep)
 The implementation of this method is optional.
KDBBackend * kdbBackendFactory (void)
 All KeyDB methods implemented by the backend can have random names, except kdbBackendFactory().

Detailed Description

The tactics to create pluggable backends to libelektra.so.

Since version 0.4.9, Elektra can dynamically load different key storage backends. Fast jump to kdbBackendExport() to see an example of a backend implementation.

The methods of class KeyDB that are backend dependent are kdbOpen(), kdbClose(), kdbGetKey(), kdbSetKey(), kdbStatKey(), kdbGetKeyChildKeys(), kdbRemove(), kdbRename(). So a backend must reimplement these methods.

And methods that have a builtin default high-level inefficient implementation are kdbSetKeys(), kdbMonitorKey(), kdbMonitorKeys(). So it is suggested to reimplement them too, to make them more efficient.

The other KeyDB methods are higher level. They use the above methods to do their job, and generally don't have to be reimplemented for a different backend.

The backend must implement a method with name kdbBackendFactory() and no parameters, that is responsible of exporting the implementations of libelektra.so backend dependent methods.

The backend implementation must:

#include <kdb.h>
#include <kdbbackend.h>

Better than that, a skeleton of a backend implementation is provided inside Elektra development package or source code tree, and should be used as a base for the implementation.

An elektrified program will use the backend defined by environment variable $KDB_BACKEND, The backend library is dynamically loaded when the program calls kdbOpen(), unless if the program is security/authentication/setuid related, in which it probably uses the more secure kdbOpenDefault() which completely ignores the $KDB_BACKEND environment and will use the "default" named backend defined by the sysadmin. Look at /lib/libelektra-default.so link to see the default backend for your system.

Elektra source code or development package provides a skeleton and Makefile to implement a backend, and we'll document this skeleton here.

A backend is defined by a single name, for example BACKENDNAME, that causes libelektra.so look for its library as libelektra-BACKENDNAME.so.

Elektra source code tree includes several backend implementations (http://germane-software.com/repositories/elektra/trunk/src/backends) that can also be used as a reference.


Enumeration Type Documentation

enum KDBBackendMethod
 

Switches to denote the backend methods.

Used in calls to kdbBackendExport().

Enumeration values:
KDB_BE_OPEN  Next arg is backend for kdbOpen()
KDB_BE_CLOSE  Next arg is backend for kdbClose()
KDB_BE_STATKEY  Next arg is backend for kdbStatKey()
KDB_BE_GETKEY  Next arg is backend for kdbGetKey()
KDB_BE_SETKEY  Next arg is backend for kdbSetKey()
KDB_BE_SETKEYS  Next arg is backend for kdbSetKeys()
KDB_BE_RENAME  Next arg is backend for kdbRename()
KDB_BE_REMOVEKEY  Next arg is backend for kdbRemoveKey()
KDB_BE_GETCHILD  Next arg is backend for kdbGetKeyChildKeys()
KDB_BE_MONITORKEY  Next arg is backend for kdbMonitorKey()
KDB_BE_MONITORKEYS  Next arg is backend for kdbMonitorKeys()
KDB_BE_END  End of arguments

Definition at line 43 of file kdbbackend.h.


Function Documentation

ssize_t unencode char *  encoded,
void *  returned
 

Unencodes a buffer of ASCII hexadecimal values into a byte stream.

The allowed format for the hexadecimal values is just a stream of pairs of plain hex-digits, all together or space-separated.

The returned data won't be bigger than half the size of the source encoded data.

Parameters:
encoded the source of ASCII hexadecimal digits.
returned preallocated destination for the unencoded data.
Returns:
the amount of bytes unencoded, or a negative value and errno is set to KDB_RET_TYPEMISMATCH
See also:
encode()

Definition at line 349 of file libkdb.c.

int kdbNeedsUTF8Conversion  ) 
 

Checks if UTF-8 conversion is needed in current context.

if nl_langinfo() is not available, no conversion is ever needed. If iconv usage is disabled there is no need to check if we need to convert. Furthermore, some systems have nl_langinfo(), but lacks ability to get CODESET through it. Look at the comments by the UTF8Engine() function for more information.

Returns:
0 if not needed, anything else if needed

Definition at line 395 of file libkdb.c.

Referenced by UTF8Engine().

int UTF8Engine int  direction,
char **  string,
size_t *  inputOutputByteSize
 

Converts string to (direction = UTF8_TO) and from (direction = UTF8_FROM) UTF-8.

Since Elektra provides portability for key names and string values between different codesets, you should use this helper in your backend to convert to and from universal UTF-8 strings, when storing key names, values and comments.

If iconv() or nl_langinfo() is not available on your system, or if iconv() usage is disabled (--disable-iconv on build time) simply return 0 immediately.

Parameters:
direction must be UTF8_TO (convert from current non-UTF-8 to UTF-8) or UTF8_FROM (convert from UTF-8 to current non-UTF-8)
string before the call: the string to be converted; after the call: reallocated to carry the converted string
inputOutputByteSize before the call: the size of the string including leading NULL; after the call: the size of the converted string including leading NULL
Returns:
0 on success, -1 otherwise and errno is propagated

Definition at line 428 of file libkdb.c.

References kdbNeedsUTF8Conversion().

ssize_t encode void *  unencoded,
size_t  size,
char *  returned
 

Encodes a buffer of data onto hexadecimal ASCII.

The resulting data is made up of pairs of ASCII hex-digits, space- and newline-separated. This is the counterpart of unencode().

The returned must allocated prior you call this function and won't be bigger than 3 times the size of the source unencoded.

Parameters:
unencoded the source buffer.
size the size of the source buffer in bytes.
returned the preallocated destination for the ASCII-encoded data.
Returns:
the amount of bytes used in the resulting encoded buffer.
See also:
unencode()

Definition at line 504 of file libkdb.c.

Referenced by keyToStreamBasename().

int kdbSetKeys_default KeySet ks  ) 
 

A high level, probably inefficient implementation for the kdbSetKeys() method.

If a backend doesn't want to reimplement this method, this implementation can be used, in which kdbSetKey() will be called for each Key object contained in ks.

See also:
kdbSetKeys(), kdbSetKeys_backend()

Definition at line 961 of file libkdb.c.

References kdbSetKey(), keyNeedsSync(), ksCurrent(), and ksNext().

Referenced by kdbSetKeys().

uint32_t kdbMonitorKeys_default KeySet interests,
uint32_t  diffMask,
unsigned long  iterations,
unsigned  sleeptime
 

A high level, probably inefficient, implementation for the kdbMonitorKeys() method.

If a backend doesn't want to reimplement this method, this implementation can be used.

Definition at line 1199 of file libkdb.c.

References kdbMonitorKey(), ksCurrent(), ksNext(), and _KeySet::size.

Referenced by kdbMonitorKeys().

uint32_t kdbMonitorKey_default Key interest,
uint32_t  diffMask,
unsigned long  iterations,
unsigned  sleeptime
 

A high level, probably inefficient, implementation for the kdbMonitorKey() method.

If a backend doesn't want to reimplement this method, this implementation can be used.

Definition at line 1298 of file libkdb.c.

References KDB_RET_NOCRED, KDB_RET_NOTFOUND, kdbGetKey(), keyCompare(), keyDel(), keyDup(), keyGetNameSize(), and keyNew().

Referenced by kdbMonitorKey().

KDBBackend* kdbBackendExport const char *  backendName,
  ...
 

This function must be called by a backend's kdbBackendFactory() to define the backend's methods that will be exported.

Its job is to organize a libelektra.so's table of virtual methods with pointers to backend dependent methods.

The order and number of arguments are flexible (as keyNew()) to let libelektra.so evolve without breaking its ABI compatibility with backends. So for each method a backend must export, there is a flag defined by KDBBackendMethod. Each flag tells kdbBackendExport() which method comes next. A backend can have no implementation for a few methods that have default inefficient high-level implementations -- kdbSetKeys(), kdbMonitorKey(), kdbMonitorKeys() -- and to use these defaults, simply don't pass anything to kdbBackendExport() about them.

The last parameter must be KDB_BE_END .

Example of a complete backend:
//
// This is my implementation for an Elektra backend storage.
//
// To compile it:
// $ cc -fpic -o myback.o -c myback.c
// $ cc -shared -fpic -o libelektra-myback.so myback.o
// 
// To use it:
// $ export KDB_BACKEND=myback
// $ kdb ls -Rv
//

#include <kdb.h>
#include <kdbbackend.h>

#define BACKENDNAME "my_elektra_backend_implementation"


int kdbOpen_backend() {...}
int kdbClose_backend() {...}
int kdbGetKey_backend(Key *key) {...}
int kdbSetKey_backend(Key *key) {...}

... etc implementations of other methods ...



KDBBackend *kdbBackendFactory(void) {
    return kdbBackendExport(BACKENDNAME,
        KDB_BE_OPEN,          &kdbOpen_backend,
        KDB_BE_CLOSE,         &kdbClose_backend,
        KDB_BE_GETKEY,        &kdbGetKey_backend,
        KDB_BE_SETKEY,        &kdbSetKey_backend,
        KDB_BE_STATKEY,       &kdbStatKey_backend,
        KDB_BE_RENAME,        &kdbRename_backend,
        KDB_BE_REMOVEKEY,     &kdbRemoveKey_backend,
        KDB_BE_GETCHILD,      &kdbGetKeyChildKeys_backend,
        KDB_BE_SETKEYS,       &kdbSetKeys_backend,
        KDB_BE_MONITORKEY,    &kdbMonitorKey_backend,
        KDB_BE_MONITORKEYS,   &kdbMonitorKeys_backend,
        KDB_BE_END);
}
In the example, the *_backend() methods can have other random names, since you'll correctly pass them later to kdbBackendExport().

Parameters:
backendName a simple name for this backend
Returns:
an object that contains all backend informations needed by libelektra.so

Definition at line 1425 of file libkdb.c.

References KDB_BE_CLOSE, KDB_BE_GETCHILD, KDB_BE_GETKEY, KDB_BE_MONITORKEY, KDB_BE_MONITORKEYS, KDB_BE_OPEN, KDB_BE_REMOVEKEY, KDB_BE_RENAME, KDB_BE_SETKEY, KDB_BE_SETKEYS, KDB_BE_STATKEY, and strblen().

Referenced by kdbBackendFactory().

size_t strblen const char *  s  ) 
 

Calculates the lenght in bytes of a string.

This function differs from strlen() because it is Unicode and multibyte chars safe. While strlen() counts characters and ignores the final NULL, strblen() count bytes including the ending NULL.

Returns:
number of bytes used by the string, including the final NULL.

Definition at line 65 of file key.c.

Referenced by commandSet(), kdbBackendExport(), kdbGetKeyByParent(), kdbGetKeyByParentKey(), kdbGetValueByParent(), kdbSetValueByParent(), keyAddBaseName(), keyGetBaseName(), keyGetComment(), keyGetCommentSize(), keyGetFullName(), keyGetFullNameSize(), keyGetFullRootNameSize(), keyGetName(), keyGetNameSize(), keyGetOwner(), keyGetOwnerSize(), keyGetParentNameSize(), keyNameGetBaseNameSize(), keySetBaseName(), keySetComment(), keySetLink(), keySetName(), keySetOwner(), keySetString(), keyToStreamBasename(), ksLookupByName(), ksLookupByValue(), ksToStream(), and parseCommandLine().

int kdbOpen_backend  ) 
 

Initialize the backend.

This is the first method kdbOpenBackend() calls after dynamically loading the backend library.

This method is responsible of:

  • backend's specific configuration gathering
  • all backend's internal structs initialization
  • initial setup of all I/O details such as opening a file, connecting to a database, etc

Returns:
0 on success, anything else otherwise.
See also:
kdbOpenBackend()

kdbOpen()

Definition at line 133 of file template.c.

Referenced by kdbBackendFactory().

int kdbClose_backend  ) 
 

All finalization logic of the backend should go here.

Called prior to unloading the backend dynamic module. Should ensure that no functions or static/global variables from the module will ever be accessed again. Should free any memory that the backend no longer needs. After this call, libelektra.so will unload the backend library, so this is the point to shutdown any affairs with the storage.

Returns:
0 on success, anything else otherwise.
See also:
kdbClose()

Definition at line 154 of file template.c.

Referenced by kdbBackendFactory().

int kdbStatKey_backend Key key  ) 
 

Implementation for kdbStatKey() method.

This method is responsible of:

  • make necessary I/O to retrieve key->name's metadata
  • fill the key struct with its metadata

See also:
kdbStatKey() for expected behavior.

Definition at line 171 of file template.c.

Referenced by kdbBackendFactory().

int kdbGetKey_backend Key key  ) 
 

Implementation for kdbGetKey() method.

This method is responsible of:

  • make necessary I/O to retrieve all key->name's value and metadata
  • fill the key struct with its value and metadata

See also:
kdbGetKey() for expected behavior.

Definition at line 187 of file template.c.

Referenced by kdbBackendFactory().

int kdbSetKey_backend Key key  ) 
 

Implementation for kdbSetKey() method.

This method is responsible of:

  • check the existence of key->name on persistent storage
  • prepare the backend to receive a new or updated key
  • use value and metadata from key to store them in the backend storage
  • fill the key struct with its value and metadata

See also:
kdbSetKey() for expected behavior.

Definition at line 206 of file template.c.

Referenced by kdbBackendFactory().

int kdbRename_backend Key key,
const char *  newName
 

Implementation for kdbRename() method.

See also:
kdbRename() for expected behavior.

Definition at line 219 of file template.c.

Referenced by kdbBackendFactory().

int kdbRemoveKey_backend const Key key  ) 
 

Implementation for kdbRemoveKey() method.

See also:
kdbRemoveKey() for expected behavior.

Definition at line 233 of file template.c.

Referenced by kdbBackendFactory().

ssize_t kdbGetKeyChildKeys_backend const Key parentKey,
KeySet returned,
unsigned long  options
 

Implementation for kdbGetKeyChildKeys() method.

See also:
kdbGetKeyChildKeys() for expected behavior.

Definition at line 247 of file template.c.

References _KeySet::size.

Referenced by kdbBackendFactory().

int kdbSetKeys_backend KeySet ks  ) 
 

Implementation for kdbSetKeys() method.

The implementation of this method is optional, and a builtin, probablly inefficient implementation can be explicitly used when exporting the backend with kdbBackendExport(), using kdbSetKeys_default().

See also:
kdbSetKeys() for expected behavior.

Definition at line 263 of file template.c.

uint32_t kdbMonitorKeys_backend KeySet interests,
uint32_t  diffMask,
unsigned long  iterations,
unsigned  sleep
 

The implementation of this method is optional.

The builtin inefficient implementation will use kdbGetKey() for each key inside interests.

See also:
kdbMonitorKeys() for expected behavior.

Definition at line 277 of file template.c.

Referenced by kdbBackendFactory().

uint32_t kdbMonitorKey_backend Key interest,
uint32_t  diffMask,
unsigned long  iterations,
unsigned  sleep
 

The implementation of this method is optional.

The builtin inefficient implementation will use kdbGetKey() for interest.

See also:
kdbMonitorKey() for expected behavior.

Definition at line 293 of file template.c.

Referenced by kdbBackendFactory().

KDBBackend* kdbBackendFactory void   ) 
 

All KeyDB methods implemented by the backend can have random names, except kdbBackendFactory().

This is the single symbol that will be looked up when loading the backend, and the first method of the backend implementation that will be called.

Its purpose is to "publish" the exported methods for libelektra.so. The implementation inside the provided skeleton is usually enough: simply call kdbBackendExport() with all methods that must be exported.

Returns:
whatever kdbBackendExport() returns
See also:
kdbBackendExport() for an example

kdbOpenBackend()

Definition at line 314 of file template.c.

References KDB_BE_CLOSE, KDB_BE_END, KDB_BE_GETCHILD, KDB_BE_GETKEY, KDB_BE_MONITORKEY, KDB_BE_MONITORKEYS, KDB_BE_OPEN, KDB_BE_REMOVEKEY, KDB_BE_RENAME, KDB_BE_SETKEY, KDB_BE_STATKEY, kdbBackendExport(), kdbClose_backend(), kdbGetKey_backend(), kdbGetKeyChildKeys_backend(), kdbMonitorKey_backend(), kdbMonitorKeys_backend(), kdbOpen_backend(), kdbRemoveKey_backend(), kdbRename_backend(), kdbSetKey_backend(), and kdbStatKey_backend().


Generated on Sun Feb 19 10:05:38 2006 for Elektra Project by  doxygen 1.3.9.1