To set up upscaledb: Make sure that you add the include path and library path of upscaledb to your IDE/Makefile!
#include <ups/upscaledb.h>
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
Also declare a helper function which will check upscaledb's return codes and terminate the application in case of an error.
// this helper function will handle unexpected errors.
static void check_error(ups_status_t st, const char *description) {
if (st != UPS_SUCCESS) {
printf(“ERROR %s (%s), terminating\n", description, ups_strerror(st));
exit(-1);
}
}
Our introductory sample will insert a few key/value pairs and then print them with a cursor. Since upscaledb uses a B-Tree as the underlying data structure, the key/value pairs will automatically be sorted.
Another helper function will insert string keys and string values ("records"). We will store the strings including the terminating zero byte.
static void
insert(ups_db_t *db, const char *key, const char *value) {
ups_key_t k = ups_make_key((void *)key, strlen(key) + 1);
ups_record_t r = ups_make_record((void *)record, strlen(record) + 1);
ups_status_t st = ups_db_insert(db, 0, &k, &r, 0);
check_error(st, "ups_db_insert");
}
The next few lines create an Environment with a Database. The Database will not be parameterized, which means that it can store unique, variable length keys with variable length records.
int main() {
ups_status_t st;
ups_env_t *env;
ups_db_t *db;
st = ups_env_create(&env, "test.db", 0, 0664, 0);
check_error(st, "ups_env_create");
st = ups_env_create_db(env, &db, 1, 0, 0);
check_error(st, "ups_env_create_db");
Now we're ready to insert data! We will use our helper function.
insert("one", "first record");
insert("two", "second record");
insert("three", "third record");
insert("four", "fourth record");
insert("five", "fifth record");
The Database contents can now be printed using a cursor.
ups_cursor_t *cursor;
st = ups_cursor_create(&cursor, db, 0, 0);
check_error(st, "ups_cursor_create");
// move to the first key
ups_key_t key = {0};
ups_record_t record = {0};
st = ups_cursor_move(cursor, &key, &record, UPS_CURSOR_FIRST);
check_error(st, "ups_cursor_move first");
// print key, then move to the next and repeat
do {
printf("%s\t=> %s\n", (const char *)key.data, (const char
*)record.data);
st = ups_cursor_move(cursor, &key, &record, UPS_CURSOR_NEXT);
} while (st != UPS_KEY_NOT_FOUND);
Done! Now close the Cursor and the Environment to avoid
any resource leaks. The flag UPS_AUTO_CLEANUP
will automatically close
all open Database handles.
st = ups_cursor_close(cursor);
check_error(st, "ups_cursor_close");
st = ups_env_close(env, UPS_AUTO_CLEANUP);
check_error(st, "ups_env_close");
return 0;
}
We hope you enjoyed your first steps with upscaledb!