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; +}