Tutorial

From Elektra Initiative

We assume you have elektra 0.7.0 or later installed properly. See Get to download and install it. GetStartedMounting explains how to set LD_LIBRARY_PATH and PATH, shows some kdb commands and explains how to mount backends.

Contents

Hello World

First we try to write a Hello World Program with elektra, to make sure that it compiles smoothly.

#include <kdb.h>
#include <stdio.h>

int main(void)
{
	Key *k = keyNew("user/hello", KEY_VALUE, "Hello World", KEY_END);
	printf ("%s\n", (char*)keyValue(k));
	keyDel (k);

	return 0;
}

This Code is also under examples/hello.c. But I advice you to type it yourself to get know of it.

This is the standard C hello world modified by using a key. Key is one of the three datastructures used in Elektra, see Elektra API for detailed information.

To compile it run:

gcc `pkg-config --libs --cflags elektra` -ansi -pedantic -std=c99 -o hello hello.c

Note: These (`) are backticks, not apostrophes (')!


Possible errors

pkg-config errors will lead to something like:

hello.c:2:17: error: kdb.h: Datei oder Verzeichnis nicht gefunden
hello.c: In function ‘main’:
hello.c:6: error: ‘Key’ undeclared (first use in this function)
hello.c:6: error: (Each undeclared identifier is reported only once
hello.c:6: error: for each function it appears in.)
hello.c:6: error: ‘k’ undeclared (first use in this function)
hello.c:6: error: ‘KEY_VALUE’ undeclared (first use in this function)
hello.c:6: error: ‘KEY_END’ undeclared (first use in this function)
hello.c:7: warning: incompatible implicit declaration of built-in function ‘printf’
hello.c:7: warning: cast to pointer from integer of different size

meaning that your installation is broken. Make sure that pkg-config find its lib/pkgconfig/elektra.pc file. You can do that by setting PKG_CONFIG_PATH.

pkg-config --libs --cflags elektra

should print a correct -I -L and -l values.

./hello: error while loading shared libraries: libelektra.so.1: cannot open shared object file: No such file or directory

Your linking is not correct! Please make sure pkg-config --libs --cflags elektra prints out the place where you installed the library.

The LD_LIBRARY_PATH is not set correctly. Please make sure that libelektra.so.1 is placed in /lib, /usr/lib or /usr/local/lib or in any directory in the : separated list of LD_LIBRARY_PATH

Package elektra was not found in the pkg-config search path.
Perhaps you should add the directory containing `elektra.pc'
to the PKG_CONFIG_PATH environment variable
No package 'elektra' found
/tmp/ccAjplcD.o: In function `main':
hello.c:(.text+0x31): undefined reference to `keyNew'
hello.c:(.text+0x3f): undefined reference to `keyValue'
hello.c:(.text+0x52): undefined reference to `keyDel'
collect2: ld gab 1 als Ende-Status zurück

PKG_CONFIG_PATH has to be set to the pkgconfig directory, e.g.:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

recap

We learned that Key objects can exist independently. keyValue is a void* pointer because it can hold any data (binary or string).

Kdb Hello World

Now we modify the application to get access to the KDB (Key Data Base).

First we set something we want to get with our program:

kdb set user/hello "Hello World"

If it says:

sh: kdb: command not found

Please make sure kdb is installed in /bin, /usr/bin or any directory in the : separated list of PATH. See GetStartedMounting.

Now lets code (you find it in examples/hellokdb.c):

#include <kdb.h>
#include <stdio.h>

int main(void)
{
	Key *k = keyNew ("user/hello", KEY_END);
	KDB *handle = kdbOpen();

	if (kdbGetKey (handle, k) == -1) printf ("could not get key\n");
	else printf ("%s\n", (char*) keyValue(k));
	kdbClose (handle);
	keyDel (k);

	return 0;
}

When "could not get key" is printed obviously it could not find the key, make sure you set it with kdb first. Of course you can write your own little program to set it, kdbSetKey will help you :-)


Small Application

This section contains a walkthrough to a small real world program. This Code is also under examples/small.c. Its not long compared to its flexibility, more to that later.

#include <stdlib.h>
#include <stdio.h>
#include <kdb.h>

void BailOut (char * msg)
{
	fprintf (stderr, "%s\n", msg);
	exit (1);
}

int main(void)
{
	KDB * h;
	KeySet * myConfig = ksNew(0);
	Key    * myKey;
	char   * myValue;

	/* Open the Key Database */
	if (!(h = kdbOpen()))
		BailOut ("Could not open Key Database");

	/* Get the hello world keyset */
	if (kdbGetByName(h, myConfig, "/", 0) == -1)
		BailOut ("Could not get Keys");

	/* Find the key in the keyset */
	if ((myKey = ksLookupByName (myConfig, "/hello", 0)) == NULL)
		BailOut ("Could not Lookup Key");

	/* Get the value of the key */
	if ((myValue = (char*) keyValue (myKey)) == NULL)
		BailOut ("Could not get Keyvalue");

	/* Actually print the key */
	printf ("%s\n", myValue);
	/* Close and free KeySet */
	ksDel(myConfig);
	/* Close the Key database */
	kdbClose(h);

	return 0;
}

Now try to compile with: cc `pkg-config --libs --cflags elektra` -ansi -pedantic -o hello hello.c


Could not get Keys: Key is not initialized

This error had to come, because the Key is not there. To do so:

kdb set "user/hello" "Hello World"

If it says:

sh: kdb: command not found

Please make sure kdb is installed in /bin, /usr/bin or any directory in the : separated list of PATH.

Note that this program gets in fact all keys available in your system and user namespace. So if you somewhere mounted a buggy backend it will return with an error. (e.g. common mistake: mount /tmp/hosts and file does not exist)

Could not get Keys: Key was not found

would be printed then (in rc5, hopefully better error message soon!).

You are done once it prints:

user:~$ ./small
Hello World

Line by Line walkthrough

ksNew()

There are functions to create new KeySets and Keys, more on that later. Make sure to always

ksDel()

to leave no memory leaks. In the end of the programm it is pointless though, because the operating system takes care of it anyway. You must not free the keys inside the KeySet, because the KeySet takes care of it.

h = kdbOpen()

One of the first Calls in every elektrized Program will be kdbOpen. It opens the connection to the keydatabase if necessary (e.g. Network or local sockets). The return values of all libelektra functions are 0 on success and -1 on failure.

Here comes another of the most important commands togehter with elektra. This command retrieves all Keys in the user/ top hierachy. All these Keys are stored then efficiently in the KeySet struct.

kdbGetByName(h, myConfig, "/", 0)

Of course you are curious what the 0 at the end is. Here you can add options like

KDBOptions::KDB_O_NORECURSIVE 

Does what you expect to do it;) It does not get all keys recursive.

KDBOptions::KDB_O_INACTIVE 

Will make it not ignore inactive keys. Inactive Keys are Keys with a dot in the beginning like: user/.hidden. Apps will ignore it, you can place backups there without producing a big footprint when starting applications.

KDBOptions::KDB_O_SORT 

This will sort the Keys alphabetically.

if ((myKey = ksLookupByName (myConfig, "/hello", 0)) == NULL)

This function is very powerful, because it cascades of your configuration. That means that system/ and user/ are virtually merged together and the proper value will be taken.

if ((myValue = (char*) keyValue (myKey)) == NULL)

Here you actually get the the value of the key. In it is Hello World, so you are done.

See the Elektra API for detailled information.

Views
MediaWiki