diff --git a/.gitignore b/.gitignore
index cb23bd25..d0bf915d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,8 @@ test/sophia-test
test/sophia-benchmark
sophia.h
sophia.c
+example/crud
+example/transaction
+example/batch
+example/cursor
+example/snapshot
diff --git a/example/README.md b/example/README.md
new file mode 100644
index 00000000..ace26b8e
--- /dev/null
+++ b/example/README.md
@@ -0,0 +1,9 @@
+
+
+
+
+
+ sophia - a modern embeddable transactional key-value storage
+
+ (examples)
+
diff --git a/example/batch.c b/example/batch.c
new file mode 100644
index 00000000..e8270855
--- /dev/null
+++ b/example/batch.c
@@ -0,0 +1,65 @@
+
+/*
+ * sophia database
+ * sphia.org
+ *
+ * Copyright (c) Dmitry Simonenko
+ * BSD License
+*/
+
+#include
+#include
+#include
+#include
+
+#include
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ /*
+ * Do fast atomic write of 100 inserts.
+ */
+
+ /* open or create environment and database */
+ void *env = sp_env();
+ sp_setstring(env, "sophia.path", "_test", 0);
+ sp_setstring(env, "db", "test", 0);
+ void *db = sp_getobject(env, "db.test");
+ int rc = sp_open(env);
+ if (rc == -1)
+ goto error;
+
+ /* create batch object */
+ void *batch = sp_batch(db);
+
+ /* insert 100 keys */
+ uint32_t key = 0;
+ while (key < 100) {
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ rc = sp_set(batch, o);
+ if (rc == -1)
+ goto error;
+ key++;
+ }
+
+ /* write batch */
+ rc = sp_commit(batch);
+ if (rc == -1)
+ goto error;
+
+ /* finish work */
+ sp_destroy(env);
+ return 0;
+
+error:;
+ int size;
+ char *error = sp_getstring(env, "sophia.error", &size);
+ printf("error: %s\n", error);
+ free(error);
+ sp_destroy(env);
+ return 1;
+}
diff --git a/example/crud.c b/example/crud.c
new file mode 100644
index 00000000..27a9eea9
--- /dev/null
+++ b/example/crud.c
@@ -0,0 +1,80 @@
+
+/*
+ * sophia database
+ * sphia.org
+ *
+ * Copyright (c) Dmitry Simonenko
+ * BSD License
+*/
+
+#include
+#include
+#include
+#include
+
+#include
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ /*
+ * Do set, get, delete operations. (see transaction.c)
+ */
+
+ /* open or create environment and database */
+ void *env = sp_env();
+ sp_setstring(env, "sophia.path", "_test", 0);
+ sp_setstring(env, "db", "test", 0);
+ void *db = sp_getobject(env, "db.test");
+ int rc = sp_open(env);
+ if (rc == -1)
+ goto error;
+
+ /* set */
+ uint32_t key = 1;
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ sp_setstring(o, "value", &key, sizeof(key));
+ rc = sp_set(db, o);
+ if (rc == -1)
+ goto error;
+
+ /* get */
+ o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ o = sp_get(db, o);
+ if (o) {
+ /* ensure key and value are correct */
+ int size;
+ char *ptr = sp_getstring(o, "key", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ ptr = sp_getstring(o, "value", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ sp_destroy(o);
+ }
+
+ /* delete */
+ o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ rc = sp_delete(db, o);
+ if (rc == -1)
+ goto error;
+
+ /* finish work */
+ sp_destroy(env);
+ return 0;
+
+error:;
+ int size;
+ char *error = sp_getstring(env, "sophia.error", &size);
+ printf("error: %s\n", error);
+ free(error);
+ sp_destroy(env);
+ return 1;
+}
diff --git a/example/cursor.c b/example/cursor.c
new file mode 100644
index 00000000..63a5fc99
--- /dev/null
+++ b/example/cursor.c
@@ -0,0 +1,77 @@
+
+/*
+ * sophia database
+ * sphia.org
+ *
+ * Copyright (c) Dmitry Simonenko
+ * BSD License
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ /*
+ * Do cursor iteration.
+ */
+
+ /* open or create environment and database */
+ void *env = sp_env();
+ sp_setstring(env, "sophia.path", "_test", 0);
+ sp_setstring(env, "db", "test", 0);
+ void *db = sp_getobject(env, "db.test");
+ int rc = sp_open(env);
+ if (rc == -1)
+ goto error;
+
+ /* insert 10 keys */
+ uint32_t key = 0;
+ while (key < 10) {
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ rc = sp_set(db, o);
+ if (rc == -1)
+ goto error;
+ key++;
+ }
+
+ /* create cursor and do forward iteration */
+ void *cursor = sp_cursor(env);
+ void *o = sp_object(db);
+ while ((o = sp_get(cursor, o))) {
+ printf("%"PRIu32"\n", *(uint32_t*)sp_getstring(o, "key", NULL));
+ }
+ sp_destroy(cursor);
+
+ printf("\n");
+
+ /* create cursor and do backward iteration */
+ cursor = sp_cursor(env);
+ o = sp_object(db);
+ sp_setstring(o, "order", "<", 0);
+ while ((o = sp_get(cursor, o))) {
+ printf("%"PRIu32"\n", *(uint32_t*)sp_getstring(o, "key", NULL));
+ }
+ sp_destroy(cursor);
+
+ /* finish work */
+ sp_destroy(env);
+ return 0;
+
+error:;
+ int size;
+ char *error = sp_getstring(env, "sophia.error", &size);
+ printf("error: %s\n", error);
+ free(error);
+ sp_destroy(env);
+ return 1;
+}
diff --git a/example/makefile b/example/makefile
new file mode 100644
index 00000000..759f2896
--- /dev/null
+++ b/example/makefile
@@ -0,0 +1,32 @@
+
+# sophia examples
+#
+
+all: validate clean set-get-delete transaction batch cursor snapshot
+validate:
+ @if [ ! -f ../sophia.o ]; then \
+ echo "Please build sophia first."; \
+ echo ""; \
+ exit 1; \
+ fi
+set-get-delete:
+ gcc crud.c ../libsophia.a -I../ -pedantic -std=c99 -Wall -Wextra -pthread -g -o crud
+transaction:
+ gcc transaction.c ../libsophia.a -I../ -pedantic -std=c99 -Wall -Wextra -pthread -g -o transaction
+batch:
+ gcc batch.c ../libsophia.a -I../ -pedantic -std=c99 -Wall -Wextra -pthread -g -o batch
+cursor:
+ gcc cursor.c ../libsophia.a -I../ -pedantic -std=c99 -Wall -Wextra -pthread -g -o cursor
+snapshot:
+ gcc snapshot.c ../libsophia.a -I../ -pedantic -std=c99 -Wall -Wextra -pthread -g -o snapshot
+clean:
+ @rm -rf _test
+ @rm -f crud
+ @rm -f transaction
+ @rm -f batch
+ @rm -f cursor
+ @rm -f snapshot
+
+.PHONY: all validate clean
+
+# vim: syntax=make
diff --git a/example/snapshot.c b/example/snapshot.c
new file mode 100644
index 00000000..7a10f89e
--- /dev/null
+++ b/example/snapshot.c
@@ -0,0 +1,93 @@
+
+/*
+ * sophia database
+ * sphia.org
+ *
+ * Copyright (c) Dmitry Simonenko
+ * BSD License
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ /* open or create environment and database */
+ void *env = sp_env();
+ sp_setstring(env, "sophia.path", "_test", 0);
+ sp_setstring(env, "db", "test", 0);
+ void *db = sp_getobject(env, "db.test");
+ int rc = sp_open(env);
+ if (rc == -1)
+ goto error;
+
+ /* insert 10 keys */
+ uint32_t key = 0;
+ while (key < 10) {
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ sp_setstring(o, "value", &key, sizeof(key));
+ rc = sp_set(db, o);
+ if (rc == -1)
+ goto error;
+ key++;
+ }
+
+ /* create snapshot */
+ sp_setstring(env, "snapshot", "test", 0);
+ void *snapshot = sp_getobject(env, "snapshot.test");
+
+ /* update previous 10 keys */
+ key = 0;
+ while (key < 10) {
+ uint32_t value = 123;
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ sp_setstring(o, "value", &value, sizeof(value));
+ rc = sp_set(db, o);
+ if (rc == -1)
+ goto error;
+ key++;
+ }
+
+ /* read keys from snapshot (see old versions) */
+ key = 0;
+ while (key < 10) {
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ o = sp_get(snapshot, o);
+ if (o) {
+ int size;
+ char *ptr = sp_getstring(o, "key", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ ptr = sp_getstring(o, "value", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ sp_destroy(o);
+ }
+ key++;
+ }
+
+ /* finish work */
+ sp_destroy(env);
+ return 0;
+
+error:;
+ int size;
+ char *error = sp_getstring(env, "sophia.error", &size);
+ printf("error: %s\n", error);
+ free(error);
+ sp_destroy(env);
+ return 1;
+}
diff --git a/example/transaction.c b/example/transaction.c
new file mode 100644
index 00000000..1fc596a4
--- /dev/null
+++ b/example/transaction.c
@@ -0,0 +1,92 @@
+
+/*
+ * sophia database
+ * sphia.org
+ *
+ * Copyright (c) Dmitry Simonenko
+ * BSD License
+*/
+
+#include
+#include
+#include
+#include
+
+#include
+
+int main(int argc, char *argv[])
+{
+ (void)argc;
+ (void)argv;
+
+ /*
+ * Do set, get, delete operations in transaction.
+ *
+ * The only difference between crud.c is that
+ * first argument to sp_set(), sp_get() and sp_delete() is
+ * an transaction object (not database).
+ */
+
+ /* open or create environment and database */
+ void *env = sp_env();
+ sp_setstring(env, "sophia.path", "_test", 0);
+ sp_setstring(env, "db", "test", 0);
+ void *db = sp_getobject(env, "db.test");
+ int rc = sp_open(env);
+ if (rc == -1)
+ goto error;
+
+ /* begin transaction */
+ void *tx = sp_begin(env);
+
+ /* set */
+ uint32_t key = 1;
+ void *o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ sp_setstring(o, "value", &key, sizeof(key));
+ rc = sp_set(tx, o);
+ if (rc == -1)
+ goto error;
+
+ /* get */
+ o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ o = sp_get(tx, o);
+ if (o) {
+ /* ensure key and value are correct */
+ int size;
+ char *ptr = sp_getstring(o, "key", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ ptr = sp_getstring(o, "value", &size);
+ assert(size == sizeof(uint32_t));
+ assert(*(uint32_t*)ptr == key);
+
+ sp_destroy(o);
+ }
+
+ /* delete */
+ o = sp_object(db);
+ sp_setstring(o, "key", &key, sizeof(key));
+ rc = sp_delete(tx, o);
+ if (rc == -1)
+ goto error;
+
+ /* commit transaction */
+ rc = sp_commit(tx);
+ if (rc == -1)
+ goto error;
+
+ /* finish work */
+ sp_destroy(env);
+ return 0;
+
+error:;
+ int size;
+ char *error = sp_getstring(env, "sophia.error", &size);
+ printf("error: %s\n", error);
+ free(error);
+ sp_destroy(env);
+ return 1;
+}