--- /dev/null
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <json.h>
+#include <ejdb/ejdb.h>
+#include <sqlite3.h>
+
+static EJDB *jb;
+
+int main(int ac, char* av[])
+{
+#ifdef WITH_SQLITE
+ sqlite3 *sqlite;
+ sqlite3_stmt *sqlite_insert_event;
+ sqlite3_stmt *sqlite_insert;
+ char *sqliteErr;
+ int rc;
+ sqlite3_int64 rowid;
+#endif
+ struct json_tokener *tok;
+ enum json_tokener_error jerr;
+ json_object *o;
+ struct stat s;
+ int fd;
+ const char *input, *i;
+ int input_len,il;
+
+#ifdef WITH_EJDB
+ EJCOLL *coll;
+ jb = ejdbnew();
+ if (!ejdbopen(jb, "journal", JBOWRITER | JBOCREAT | JBOTRUNC)) {
+ perror("ejdbopen");
+ return -1;
+ }
+
+ coll = ejdbcreatecoll(jb, "log", NULL);
+#endif
+
+#ifdef WITH_SQLITE
+ rc = sqlite3_open(":memory:", &sqlite);
+ if (rc != 0) {
+ fprintf(stderr, "Can't open in-memory database: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_close(sqlite);
+ return -1;
+ }
+
+ rc = sqlite3_exec(sqlite,
+ "CREATE TABLE journal "
+ "(key TEXT, value TEXT, event INTEGER)"
+ ";", NULL, 0, &sqliteErr);
+ if (rc != SQLITE_OK) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+
+#ifdef WITH_SQLITE_INDEXED
+ rc = sqlite3_exec(sqlite,
+ "CREATE INDEX idx_key "
+ "ON journal (key)"
+ ";", NULL, 0, &sqliteErr);
+ if (rc != SQLITE_OK) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+
+ rc = sqlite3_exec(sqlite,
+ "CREATE INDEX idx_value "
+ "ON journal (value)"
+ ";", NULL, 0, &sqliteErr);
+ if (rc != SQLITE_OK) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+#endif
+
+ rc = sqlite3_prepare(sqlite,
+ "INSERT INTO journal "
+ "(key, value, event) VALUES "
+ "(\"__EVENT__\", NULL, NULL)"
+ ";", -1, &sqlite_insert_event, NULL);
+ if (rc != SQLITE_OK) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+
+ rc = sqlite3_prepare(sqlite,
+ "INSERT INTO journal "
+ "(key, value, event) VALUES "
+ "(?, ?, ?)",
+ -1, &sqlite_insert, NULL);
+ if (rc != SQLITE_OK) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+#endif
+
+ if (stat(av[1], &s) < 0) {
+ perror("stat");
+ return -1;
+ }
+ il = input_len = s.st_size;
+
+ if ((fd = open(av[1], O_RDONLY)) < 0) {
+ perror("open");
+ return -1;
+ }
+
+ i = input = mmap(NULL, input_len, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (input == NULL) {
+ perror("mmap");
+ return -1;
+ }
+
+ tok = json_tokener_new();
+ while ((uintptr_t)i < (uintptr_t)input + input_len) {
+ int val_type;
+ char *val_type_str, *str;
+ bson bsrec;
+ bson_oid_t oid;
+
+ do {
+ o = json_tokener_parse_ex(tok, i, il);
+ } while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
+
+ if (jerr != json_tokener_success) {
+ fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
+ return -1;
+ }
+ printf("c:%d i:%p t:%d\n", tok->char_offset, i, json_object_get_type(o));
+
+#ifdef WITH_EJDB
+ bson_init(&bsrec);
+#endif
+#ifdef WITH_SQLITE
+ rc = sqlite3_step(sqlite_insert_event);
+ if (rc != SQLITE_DONE) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+ rowid = sqlite3_last_insert_rowid(sqlite);
+#endif
+ json_object_object_foreach(o, key, val) {
+ printf("key: \"%s\", type of val: ", key);
+ fflush(stdout);
+ val_type = json_object_get_type(val);
+
+ switch (val_type) {
+ case json_type_null:
+ val_type_str = "val is NULL";
+ break;
+
+ case json_type_boolean:
+ val_type_str = "val is a boolean";
+ break;
+
+ case json_type_double:
+ val_type_str = "val is a double";
+ break;
+
+ case json_type_int:
+ val_type_str = "val is an integer";
+ break;
+
+ case json_type_string:
+ val_type_str = "val is a string";
+ str = (char *) json_object_get_string(val);
+#ifdef WITH_EJDB
+ bson_append_string(&bsrec, key, str);
+#endif
+#ifdef WITH_SQLITE
+ sqlite3_bind_text(sqlite_insert, 1, key, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(sqlite_insert, 2, str, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_int64(sqlite_insert, 3, rowid);
+ rc = sqlite3_step(sqlite_insert);
+ if (rc != SQLITE_DONE) {
+ fprintf(stderr, "SQL Error: %s\n", sqlite3_errmsg(sqlite));
+ sqlite3_free(sqliteErr);
+ return -1;
+ }
+#endif
+ break;
+
+ case json_type_object:
+ val_type_str = "val is an object";
+ break;
+
+ case json_type_array:
+ val_type_str = "val is an array";
+ break;
+ }
+
+ printf("%s", val_type_str);
+
+ if (str)
+ printf("\t->\t\"%s\"", str);
+
+ printf("\n");
+ str = NULL;
+#ifdef WITH_SQLITE
+ sqlite3_reset(sqlite_insert);
+#endif
+ }
+#ifdef WITH_EJDB
+ bson_finish(&bsrec);
+ ejdbsavebson(coll, &bsrec, &oid);
+ bson_destroy(&bsrec);
+#endif
+#ifdef WITH_SQLITE
+ sqlite3_reset(sqlite_insert_event);
+#endif
+ //json_object_put(o);
+ i += tok->char_offset;
+ il -= tok->char_offset;
+ }
+
+#ifdef WITH_SQLITE
+ //sqlite3_close(sqlite);
+#endif
+
+#ifdef WITH_EJDB
+ ejdbclose(jb);
+ ejdbdel(jb);
+#endif
+ return 0;
+}