diff --git a/lib/db/jdb-iterator.c b/lib/db/jdb-iterator.c
index df8c66919..a7ae51c87 100644
--- a/lib/db/jdb-iterator.c
+++ b/lib/db/jdb-iterator.c
@@ -56,8 +56,6 @@ j_db_iterator_new(JDBSchema* schema, JDBSelector* selector, GError** error)
if (selector)
{
- j_db_selector_finalize(selector, error);
-
iterator->selector = j_db_selector_ref(selector);
if (G_UNLIKELY(!iterator->selector))
diff --git a/meson.build b/meson.build
index b4c686a4f..86e0f27d6 100644
--- a/meson.build
+++ b/meson.build
@@ -537,6 +537,9 @@ julea_test_srcs = files([
'test/core/message.c',
'test/core/semantics.c',
'test/db/db.c',
+ 'test/db/db-entry.c',
+ 'test/db/db-schema.c',
+ 'test/db/db-selector.c',
'test/hdf5/hdf.c',
'test/hdf5/hdf-attribute.c',
'test/hdf5/hdf-dataset.c',
diff --git a/test/core/semantics.c b/test/core/semantics.c
index d59520598..f77f2b9a0 100644
--- a/test/core/semantics.c
+++ b/test/core/semantics.c
@@ -79,9 +79,39 @@ test_semantics_set_get(JSemantics** semantics, G_GNUC_UNUSED gconstpointer data)
J_TEST_TRAP_END;
}
+static void
+test_core_semantics_from_string(void)
+{
+ g_autoptr(JSemantics) semantics = NULL;
+ gint ret;
+ gchar semantics_string[] = "atomicity=operation,consistency=eventual,persistency=network,security=strict";
+
+ J_TEST_TRAP_START;
+
+ semantics = j_semantics_new_from_string(NULL, semantics_string);
+ g_assert_nonnull(semantics);
+ if (g_test_failed())
+ return;
+
+ ret = j_semantics_get(semantics, J_SEMANTICS_ATOMICITY);
+ g_assert_cmpint(ret, ==, J_SEMANTICS_ATOMICITY_OPERATION);
+
+ ret = j_semantics_get(semantics, J_SEMANTICS_CONSISTENCY);
+ g_assert_cmpint(ret, ==, J_SEMANTICS_CONSISTENCY_EVENTUAL);
+
+ ret = j_semantics_get(semantics, J_SEMANTICS_PERSISTENCY);
+ g_assert_cmpint(ret, ==, J_SEMANTICS_PERSISTENCY_NETWORK);
+
+ ret = j_semantics_get(semantics, J_SEMANTICS_SECURITY);
+ g_assert_cmpint(ret, ==, J_SEMANTICS_SECURITY_STRICT);
+
+ J_TEST_TRAP_END;
+}
+
void
test_core_semantics(void)
{
g_test_add_func("/core/semantics/new_ref_unref", test_semantics_new_ref_unref);
g_test_add("/core/semantics/set_get", JSemantics*, NULL, test_semantics_fixture_setup, test_semantics_set_get, test_semantics_fixture_teardown);
+ g_test_add_func("/core/semantics/from_string", test_core_semantics_from_string);
}
diff --git a/test/db/db-entry.c b/test/db/db-entry.c
new file mode 100644
index 000000000..d6e05c2d0
--- /dev/null
+++ b/test/db/db-entry.c
@@ -0,0 +1,404 @@
+/*
+ * JULEA - Flexible storage framework
+ * Copyright (C) 2021 Timm Leon Erxleben
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "test.h"
+
+#define EPS 1e-9
+
+static void
+test_db_entry_new_free(void)
+{
+ guint const n = 100000;
+
+ J_TEST_TRAP_START;
+
+ for (guint i = 0; i < n; i++)
+ {
+ g_autoptr(GError) error = NULL;
+ g_autoptr(JDBEntry) entry = NULL;
+ g_autoptr(JDBSchema) schema = NULL;
+
+ schema = j_db_schema_new("test-ns", "test-schema", &error);
+ g_assert_nonnull(schema);
+ g_assert_no_error(error);
+
+ entry = j_db_entry_new(schema, &error);
+ g_assert_nonnull(entry);
+ g_assert_no_error(error);
+ }
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_entry_insert_update_delete(void)
+{
+ guint const n = 1000;
+
+ gchar const* str = "demo.bp";
+ gint32 si32 = -42;
+ guint32 ui32 = 42;
+ gint64 si64 = -84;
+ guint64 ui64 = 4;
+ gfloat fl32 = 1.337;
+ gdouble fl64 = 42.42;
+ guint8 blob[5] = { 1, 2, 3, 4, 5 };
+ gpointer val;
+ JDBType type;
+ guint64 length;
+
+ g_autoptr(GError) error = NULL;
+ g_autoptr(JBatch) batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+ g_autoptr(JDBEntry) delete_entry = NULL;
+ g_autoptr(JDBEntry) update_entry = NULL;
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JDBSelector) selector = NULL;
+ g_autoptr(JDBIterator) iterator = NULL;
+ gboolean ret;
+
+ J_TEST_TRAP_START;
+
+ schema = j_db_schema_new("test-ns", "test-schema", &error);
+ g_assert_nonnull(schema);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "string-0", J_DB_TYPE_STRING, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "sint32-0", J_DB_TYPE_SINT32, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "uint32-0", J_DB_TYPE_UINT32, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "sint64-0", J_DB_TYPE_SINT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "uint64-0", J_DB_TYPE_UINT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "float32-0", J_DB_TYPE_FLOAT32, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "float64-0", J_DB_TYPE_FLOAT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "blob-0", J_DB_TYPE_BLOB, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_create(schema, batch, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ for (guint i = 0; i < n; i++)
+ {
+ g_autoptr(JDBEntry) entry = NULL;
+
+ entry = j_db_entry_new(schema, &error);
+ g_assert_nonnull(entry);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "string-0", str, strlen(str), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "sint32-0", &si32, sizeof(si32), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "uint32-0", &ui32, sizeof(ui32), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "sint64-0", &si64, sizeof(si64), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "uint64-0", &ui64, sizeof(ui64), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "float32-0", &fl32, sizeof(fl32), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "float64-0", &fl64, sizeof(fl64), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_set_field(entry, "blob-0", blob, sizeof(blob), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ // FIXME Do not pass error, will not exist anymore when batch is executed
+ ret = j_db_entry_insert(entry, batch, NULL);
+ g_assert_true(ret);
+ }
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+
+ // check all written values
+
+ selector = j_db_selector_new(schema, J_DB_SELECTOR_MODE_AND, &error);
+ g_assert_nonnull(selector);
+ g_assert_no_error(error);
+
+ ret = j_db_selector_add_field(selector, "string-0", J_DB_SELECTOR_OPERATOR_EQ, str, strlen(str), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ iterator = j_db_iterator_new(schema, selector, &error);
+ g_assert_nonnull(iterator);
+ g_assert_no_error(error);
+
+ while (j_db_iterator_next(iterator, &error))
+ {
+ g_assert_no_error(error);
+
+ ret = j_db_iterator_get_field(iterator, schema, "string-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpstr((gchar*)val, ==, str);
+ g_assert_cmpint(type, ==, J_DB_TYPE_STRING);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "sint32-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpint(*(gint32*)val, ==, si32);
+ g_assert_cmpint(type, ==, J_DB_TYPE_SINT32);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "uint32-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpuint(*(guint32*)val, ==, ui32);
+ g_assert_cmpint(type, ==, J_DB_TYPE_UINT32);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "sint64-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpint(*(gint64*)val, ==, si64);
+ g_assert_cmpint(type, ==, J_DB_TYPE_SINT64);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "uint64-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpuint(*(guint64*)val, ==, ui64);
+ g_assert_cmpint(type, ==, J_DB_TYPE_UINT64);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "float32-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpfloat(fabs(*(gfloat*)val - fl32), <, EPS);
+ g_assert_cmpint(type, ==, J_DB_TYPE_FLOAT32);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "float64-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpfloat(fabs(*(gdouble*)val - fl64), <, EPS);
+ g_assert_cmpint(type, ==, J_DB_TYPE_FLOAT64);
+ g_free(val);
+
+ ret = j_db_iterator_get_field(iterator, schema, "blob-0", &type, &val, &length, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ g_assert_cmpmem((guint8*)val, length, blob, sizeof(blob));
+ g_assert_cmpint(type, ==, J_DB_TYPE_BLOB);
+ g_free(val);
+ }
+
+ g_error_free(error);
+ error = NULL;
+
+ // update values
+
+ update_entry = j_db_entry_new(schema, &error);
+ g_assert_nonnull(update_entry);
+ g_assert_no_error(error);
+
+ ui32 = 3;
+ ret = j_db_entry_set_field(update_entry, "uint32-0", &ui32, sizeof(ui32), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_update(update_entry, selector, batch, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ // delete new entry
+
+ delete_entry = j_db_entry_new(schema, &error);
+ g_assert_nonnull(delete_entry);
+ g_assert_no_error(error);
+
+ ret = j_db_entry_delete(delete_entry, selector, batch, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ // delete schema
+
+ ret = j_db_schema_delete(schema, batch, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_entry_id(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JDBEntry) entry = NULL;
+ g_autoptr(JBatch) batch = NULL;
+ g_autoptr(GError) error = NULL;
+ gint64 val = 42;
+ g_autofree gpointer id = NULL;
+ guint64 len = 0;
+ gboolean res;
+
+ J_TEST_TRAP_START;
+
+ batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+
+ schema = j_db_schema_new("test-ns", "test", NULL);
+ j_db_schema_add_field(schema, "test-si64", J_DB_TYPE_SINT64, NULL);
+ res = j_db_schema_create(schema, batch, &error);
+ g_assert_true(res);
+
+ entry = j_db_entry_new(schema, NULL);
+ j_db_entry_set_field(entry, "test-si64", &val, sizeof(gint64), NULL);
+
+ res = j_db_entry_insert(entry, batch, &error);
+ g_assert_true(res);
+
+ res = j_batch_execute(batch);
+ g_assert_true(res);
+ g_assert_no_error(error);
+
+ res = j_db_entry_get_id(entry, &id, &len, &error);
+ g_assert_true(res);
+ g_assert_no_error(error);
+
+ res = j_db_schema_delete(schema, batch, &error);
+ g_assert_true(res);
+
+ res = j_batch_execute(batch);
+ g_assert_true(res);
+ g_assert_no_error(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_entry_invalid_insert(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JDBEntry) entry = NULL;
+ g_autoptr(JBatch) batch = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res;
+ gint64 val = 42;
+
+ J_TEST_TRAP_START;
+
+ batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+
+ schema = j_db_schema_new("test-ns", "test", NULL);
+ j_db_schema_add_field(schema, "test-si64", J_DB_TYPE_SINT64, NULL);
+
+ entry = j_db_entry_new(schema, NULL);
+ j_db_entry_set_field(entry, "test-si64", &val, sizeof(gint64), NULL);
+
+ res = j_db_entry_insert(entry, batch, &error);
+ g_assert_true(res);
+
+ res = j_batch_execute(batch);
+ g_assert_false(res);
+ g_assert_nonnull(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_entry_set_nonexistant(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JDBEntry) entry = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res;
+ gint64 val = 42;
+
+ J_TEST_TRAP_START;
+
+ schema = j_db_schema_new("test-ns", "test", NULL);
+ j_db_schema_add_field(schema, "test-si64", J_DB_TYPE_SINT64, NULL);
+ entry = j_db_entry_new(schema, NULL);
+
+ res = j_db_entry_set_field(entry, "not-existant", &val, sizeof(gint64), &error);
+ g_assert_false(res);
+ g_assert_nonnull(error);
+
+ J_TEST_TRAP_END;
+}
+
+void
+test_db_entry(void)
+{
+ g_test_add_func("/db/entry/new_free", test_db_entry_new_free);
+ g_test_add_func("/db/entry/insert_update_delete", test_db_entry_insert_update_delete);
+ g_test_add_func("/db/entry/get_id", test_db_entry_id);
+ g_test_add_func("/db/entry/insert_in_local_schema", test_db_entry_invalid_insert);
+ g_test_add_func("/db/entry/set_non_existing_field", test_db_entry_set_nonexistant);
+}
diff --git a/test/db/db-schema.c b/test/db/db-schema.c
new file mode 100644
index 000000000..a38a1cd8d
--- /dev/null
+++ b/test/db/db-schema.c
@@ -0,0 +1,331 @@
+/*
+ * JULEA - Flexible storage framework
+ * Copyright (C) 2021 Timm Leon Erxleben
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "test.h"
+
+static void
+test_db_schema_new_free(void)
+{
+ guint const n = 100000;
+
+ J_TEST_TRAP_START;
+
+ for (guint i = 0; i < n; i++)
+ {
+ g_autoptr(GError) error = NULL;
+ g_autoptr(JDBSchema) schema = NULL;
+
+ schema = j_db_schema_new("test-ns", "test-schema", &error);
+ g_assert_nonnull(schema);
+ g_assert_no_error(error);
+ }
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_schema_create_delete(void)
+{
+ guint const n = 1000;
+
+ g_autoptr(JBatch) batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+ gboolean ret;
+
+ gchar const* idx_string[] = { "string-0", NULL };
+ gchar const* idx_uint[] = { "uint-0", NULL };
+ gchar const* idx_float[] = { "float-0", NULL };
+
+ J_TEST_TRAP_START;
+
+ for (guint i = 0; i < n; i++)
+ {
+ g_autoptr(GError) error = NULL;
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autofree gchar* name = NULL;
+
+ name = g_strdup_printf("test-schema-%d", i);
+ schema = j_db_schema_new("test-ns", name, &error);
+ g_assert_nonnull(schema);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_field(schema, "string-0", J_DB_TYPE_STRING, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_field(schema, "string-1", J_DB_TYPE_STRING, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_field(schema, "uint-0", J_DB_TYPE_UINT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_field(schema, "uint-1", J_DB_TYPE_UINT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_field(schema, "float-0", J_DB_TYPE_FLOAT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_field(schema, "float-1", J_DB_TYPE_FLOAT64, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ ret = j_db_schema_add_index(schema, idx_string, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_index(schema, idx_uint, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ ret = j_db_schema_add_index(schema, idx_float, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ // FIXME Do not pass error, will not exist anymore when batch is executed
+ ret = j_db_schema_create(schema, batch, NULL);
+ g_assert_true(ret);
+
+ // FIXME Do not pass error, will not exist anymore when batch is executed
+ ret = j_db_schema_delete(schema, batch, NULL);
+ g_assert_true(ret);
+ }
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_invalid_schema_get(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JBatch) batch = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res;
+
+ J_TEST_TRAP_START;
+
+ batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+
+ schema = j_db_schema_new("test-ns", "non-existant", NULL);
+
+ res = j_db_schema_get(schema, batch, &error);
+ g_assert_true(res);
+
+ res = j_batch_execute(batch);
+ g_assert_false(res);
+ g_assert_nonnull(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_invalid_schema_delete(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(JBatch) batch = NULL;
+ g_autoptr(GError) error = NULL;
+ bool ret;
+
+ J_TEST_TRAP_START;
+
+ schema = j_db_schema_new("test-ns", "test", NULL);
+ ret = j_db_schema_add_field(schema, "test-si64", J_DB_TYPE_SINT64, NULL);
+ g_assert_true(ret);
+ batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+ ret = j_db_schema_create(schema, batch, &error);
+ g_assert_true(ret);
+
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ j_db_schema_delete(schema, batch, &error);
+ ret = j_batch_execute(batch);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ j_db_schema_delete(schema, batch, &error);
+ ret = j_batch_execute(batch);
+ g_assert_false(ret);
+ g_assert_nonnull(error);
+
+ J_TEST_TRAP_END;
+
+ g_test_incomplete("Known issue. Similar to #116");
+}
+
+static void
+test_db_schema_equals_different_name(void)
+{
+ g_autoptr(JDBSchema) schema1 = NULL;
+ g_autoptr(JDBSchema) schema2 = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res, equal;
+
+ J_TEST_TRAP_START;
+
+ schema1 = j_db_schema_new("equal", "same1", NULL);
+ schema2 = j_db_schema_new("equal", "same2", NULL);
+
+ res = j_db_schema_equals(schema1, schema2, &equal, &error);
+ g_assert_true(res);
+ g_assert_false(equal);
+ g_assert_no_error(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_schema_equals_same_name_different_fields(void)
+{
+ g_autoptr(JDBSchema) schema1 = NULL;
+ g_autoptr(JDBSchema) schema2 = NULL;
+ g_autoptr(GRand) rnd = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res, equal;
+ gchar field_name[] = "field_dd";
+
+ J_TEST_TRAP_START;
+
+ schema1 = j_db_schema_new("equal", "same", NULL);
+ schema2 = j_db_schema_new("equal", "same", NULL);
+
+ rnd = g_rand_new();
+
+ for (int i = 0; i <= g_rand_int_range(rnd, 1, 100); ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ // generate some random type fields (excluding id type)
+ res = j_db_schema_add_field(schema1, field_name, g_rand_int_range(rnd, 0, 8), NULL);
+ g_assert_true(res);
+ res = j_db_schema_add_field(schema2, field_name, g_rand_int_range(rnd, 0, 8), NULL);
+ g_assert_true(res);
+ }
+
+ res = j_db_schema_equals(schema1, schema2, &equal, &error);
+ g_assert_true(res);
+ g_assert_false(equal);
+ g_assert_no_error(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_schema_equals_same_name_same_fields(void)
+{
+ g_autoptr(JDBSchema) schema1 = NULL;
+ g_autoptr(JDBSchema) schema2 = NULL;
+ g_autoptr(GRand) rnd = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean res, equal;
+ gint field = 0;
+ gchar field_name[] = "field_dd";
+
+ J_TEST_TRAP_START;
+
+ schema1 = j_db_schema_new("equal", "same", NULL);
+ schema2 = j_db_schema_new("equal", "same", NULL);
+
+ rnd = g_rand_new();
+
+ for (int i = 0; i <= g_rand_int_range(rnd, 1, 100); ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ // generate some random type fields (excluding id type)
+ field = g_rand_int_range(rnd, 0, 8);
+ res = j_db_schema_add_field(schema1, field_name, field, NULL);
+ g_assert_true(res);
+ res = j_db_schema_add_field(schema2, field_name, field, NULL);
+ g_assert_true(res);
+ }
+
+ res = j_db_schema_equals(schema1, schema2, &equal, &error);
+ g_assert_true(res);
+ g_assert_true(equal);
+ g_assert_no_error(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_schema_get_all_fields(void)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ g_autoptr(GRand) rnd = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autofree JDBType* res_types = NULL;
+ g_autofree gchar** res_names = NULL;
+ g_autofree JDBType* types = NULL;
+ g_autofree gchar** names = NULL;
+ gchar field_name[] = "field_dd";
+ gint field = 0;
+ guint32 field_count;
+ guint32 res_field_count;
+
+ J_TEST_TRAP_START;
+
+ schema = j_db_schema_new("equal", "same", NULL);
+ rnd = g_rand_new();
+
+ field_count = g_rand_int_range(rnd, 1, 100);
+ types = g_new(JDBType, field_count);
+ names = g_new0(gchar*, field_count);
+
+ for (guint32 i = 0; i < field_count; ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ // generate some random type fields (excluding id type)
+ field = g_rand_int_range(rnd, 0, 8);
+ types[i] = field;
+ names[i] = g_strdup(field_name);
+ g_assert_true(j_db_schema_add_field(schema, field_name, field, NULL));
+ }
+
+ res_field_count = j_db_schema_get_all_fields(schema, &res_names, &res_types, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(res_field_count, ==, field_count);
+
+ for (guint32 i = 0; i < field_count; ++i)
+ {
+ g_assert_cmpstr(names[i], ==, res_names[i]);
+ g_assert_cmpint(types[i], ==, res_types[i]);
+ g_free(names[i]);
+ g_free(res_names[i]);
+ }
+
+ J_TEST_TRAP_END;
+}
+
+void
+test_db_schema(void)
+{
+ g_test_add_func("/db/schema/new_free", test_db_schema_new_free);
+ g_test_add_func("/db/schema/create_delete", test_db_schema_create_delete);
+ g_test_add_func("/db/schema/invalid_get", test_db_invalid_schema_get);
+ g_test_add_func("/db/schema/invalid_delete", test_db_invalid_schema_delete);
+ g_test_add_func("/db/schema/equals_different_name", test_db_schema_equals_different_name);
+ g_test_add_func("/db/schema/equals_same_name_different_fields", test_db_schema_equals_same_name_different_fields);
+ g_test_add_func("/db/schema/equals_same_name_same_fields", test_db_schema_equals_same_name_same_fields);
+ g_test_add_func("/db/schema/get_all_fields", test_db_schema_get_all_fields);
+}
diff --git a/test/db/db-selector.c b/test/db/db-selector.c
new file mode 100644
index 000000000..ea97def90
--- /dev/null
+++ b/test/db/db-selector.c
@@ -0,0 +1,153 @@
+/*
+ * JULEA - Flexible storage framework
+ * Copyright (C) 2021 Timm Leon Erxleben
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "test.h"
+
+static JDBSchema*
+generate_test_schema(gchar const* name)
+{
+ g_autoptr(JDBSchema) schema = NULL;
+ gboolean res;
+ gchar field_name[] = "field_dd";
+
+ schema = j_db_schema_new("test-ns", name, NULL);
+
+ for (int i = 0; i <= 99; ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ res = j_db_schema_add_field(schema, field_name, i % 8, NULL);
+ g_assert_true(res);
+ }
+
+ return j_db_schema_ref(schema);
+}
+
+static void
+test_db_selector_add_field(void)
+{
+ g_autoptr(JDBSchema) schema = generate_test_schema("selector-test");
+ g_autoptr(JDBSelector) selector = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean ret;
+ gchar val[] = "some value";
+ gchar field_name[] = "field_dd";
+
+ J_TEST_TRAP_START;
+
+ selector = j_db_selector_new(schema, J_DB_SELECTOR_MODE_AND, &error);
+ g_assert_nonnull(selector);
+ g_assert_no_error(error);
+
+ for (int i = 0; i < 8; ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ ret = j_db_selector_add_field(selector, field_name, i % 6, val, sizeof(val), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ if (g_test_failed())
+ return;
+ }
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_selector_add_non_existant_field(void)
+{
+ g_autoptr(JDBSchema) schema = generate_test_schema("selector-test");
+ g_autoptr(JDBSelector) selector = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean ret;
+ gchar val[] = "some value";
+
+ J_TEST_TRAP_START;
+
+ selector = j_db_selector_new(schema, J_DB_SELECTOR_MODE_AND, &error);
+ g_assert_nonnull(selector);
+ g_assert_no_error(error);
+
+ ret = j_db_selector_add_field(selector, "field_100", J_DB_SELECTOR_OPERATOR_GT, val, sizeof(val), &error);
+ g_assert_false(ret);
+ g_assert_nonnull(error);
+
+ J_TEST_TRAP_END;
+}
+
+static void
+test_db_selector_add_selector(void)
+{
+ g_autoptr(JDBSchema) schema = generate_test_schema("selector-test");
+ g_autoptr(JDBSelector) selector1 = NULL;
+ g_autoptr(JDBSelector) selector2 = NULL;
+ g_autoptr(GError) error = NULL;
+ gboolean ret;
+ gchar val[] = "some value";
+ gchar field_name[] = "field_dd";
+
+ J_TEST_TRAP_START;
+
+ selector1 = j_db_selector_new(schema, J_DB_SELECTOR_MODE_AND, &error);
+ g_assert_nonnull(selector1);
+ g_assert_no_error(error);
+
+ selector2 = j_db_selector_new(schema, J_DB_SELECTOR_MODE_OR, &error);
+ g_assert_nonnull(selector2);
+ g_assert_no_error(error);
+
+ for (int i = 0; i < 8; ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ ret = j_db_selector_add_field(selector1, field_name, i % 6, val, sizeof(val), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ if (g_test_failed())
+ return;
+ }
+
+ for (int i = 8; i < 25; ++i)
+ {
+ g_snprintf(field_name, sizeof(field_name), "field_%i", i);
+ ret = j_db_selector_add_field(selector2, field_name, i % 6, val, sizeof(val), &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+ if (g_test_failed())
+ return;
+ }
+
+ ret = j_db_selector_add_selector(selector1, selector2, &error);
+ g_assert_true(ret);
+ g_assert_no_error(error);
+
+ J_TEST_TRAP_END;
+}
+
+void
+test_db_selector(void)
+{
+ g_test_add_func("/db/selector/add_field", test_db_selector_add_field);
+ g_test_add_func("/db/selector/add_non_existant_field", test_db_selector_add_non_existant_field);
+ g_test_add_func("/db/selector/add_selector", test_db_selector_add_selector);
+}
diff --git a/test/db/db.c b/test/db/db.c
index 029801ba0..c117a6d3d 100644
--- a/test/db/db.c
+++ b/test/db/db.c
@@ -20,227 +20,14 @@
#include
#include
+#include
#include
#include
#include "test.h"
-static void
-test_db_schema_new_free(void)
-{
- guint const n = 100000;
-
- J_TEST_TRAP_START;
- for (guint i = 0; i < n; i++)
- {
- g_autoptr(GError) error = NULL;
- g_autoptr(JDBSchema) schema = NULL;
-
- schema = j_db_schema_new("test-ns", "test-schema", &error);
- g_assert_nonnull(schema);
- g_assert_no_error(error);
- }
- J_TEST_TRAP_END;
-}
-
-static void
-test_db_schema_create_delete(void)
-{
- guint const n = 1000;
-
- g_autoptr(JBatch) batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
- gboolean ret;
-
- gchar const* idx_string[] = { "string-0", NULL };
- gchar const* idx_uint[] = { "uint-0", NULL };
- gchar const* idx_float[] = { "float-0", NULL };
-
- J_TEST_TRAP_START;
- for (guint i = 0; i < n; i++)
- {
- g_autoptr(GError) error = NULL;
- g_autoptr(JDBSchema) schema = NULL;
- g_autofree gchar* name = NULL;
-
- name = g_strdup_printf("test-schema-%d", i);
- schema = j_db_schema_new("test-ns", name, &error);
- g_assert_nonnull(schema);
- g_assert_no_error(error);
-
- ret = j_db_schema_add_field(schema, "string-0", J_DB_TYPE_STRING, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_field(schema, "string-1", J_DB_TYPE_STRING, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_field(schema, "uint-0", J_DB_TYPE_UINT64, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_field(schema, "uint-1", J_DB_TYPE_UINT64, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_field(schema, "float-0", J_DB_TYPE_FLOAT64, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_field(schema, "float-1", J_DB_TYPE_FLOAT64, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_schema_add_index(schema, idx_string, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_index(schema, idx_uint, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
- ret = j_db_schema_add_index(schema, idx_float, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- /// \todo Do not pass error, will not exist anymore when batch is executed
- ret = j_db_schema_create(schema, batch, NULL);
- g_assert_true(ret);
-
- /// \todo Do not pass error, will not exist anymore when batch is executed
- ret = j_db_schema_delete(schema, batch, NULL);
- g_assert_true(ret);
- }
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
- J_TEST_TRAP_END;
-}
-
-static void
-test_db_entry_new_free(void)
-{
- guint const n = 100000;
-
- J_TEST_TRAP_START;
- for (guint i = 0; i < n; i++)
- {
- g_autoptr(GError) error = NULL;
- g_autoptr(JDBEntry) entry = NULL;
- g_autoptr(JDBSchema) schema = NULL;
-
- schema = j_db_schema_new("test-ns", "test-schema", &error);
- g_assert_nonnull(schema);
- g_assert_no_error(error);
-
- entry = j_db_entry_new(schema, &error);
- g_assert_nonnull(entry);
- g_assert_no_error(error);
- }
- J_TEST_TRAP_END;
-}
-
-static void
-test_db_entry_insert_update_delete(void)
-{
- guint const n = 1000;
-
- gchar const* file = "demo.bp";
- guint64 dim = 4;
-
- g_autoptr(GError) error = NULL;
- g_autoptr(JBatch) batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
- g_autoptr(JDBEntry) delete_entry = NULL;
- g_autoptr(JDBEntry) update_entry = NULL;
- g_autoptr(JDBSchema) schema = NULL;
- g_autoptr(JDBSelector) selector = NULL;
- gboolean ret;
-
- J_TEST_TRAP_START;
- schema = j_db_schema_new("test-ns", "test-schema", &error);
- g_assert_nonnull(schema);
- g_assert_no_error(error);
-
- ret = j_db_schema_add_field(schema, "string-0", J_DB_TYPE_STRING, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_schema_add_field(schema, "uint-0", J_DB_TYPE_UINT64, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_schema_create(schema, batch, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- for (guint i = 0; i < n; i++)
- {
- g_autoptr(JDBEntry) entry = NULL;
-
- entry = j_db_entry_new(schema, &error);
- g_assert_nonnull(entry);
- g_assert_no_error(error);
-
- ret = j_db_entry_set_field(entry, "string-0", file, strlen(file), &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_entry_set_field(entry, "uint-0", &dim, sizeof(dim), &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- /// \todo Do not pass error, will not exist anymore when batch is executed
- ret = j_db_entry_insert(entry, batch, NULL);
- g_assert_true(ret);
- }
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
-
- selector = j_db_selector_new(schema, J_DB_SELECTOR_MODE_AND, &error);
- g_assert_nonnull(selector);
- g_assert_no_error(error);
-
- ret = j_db_selector_add_field(selector, "string-0", J_DB_SELECTOR_OPERATOR_EQ, file, strlen(file), &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- update_entry = j_db_entry_new(schema, &error);
- g_assert_nonnull(update_entry);
- g_assert_no_error(error);
-
- dim = 3;
- ret = j_db_entry_set_field(update_entry, "uint-0", &dim, sizeof(dim), &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_entry_update(update_entry, selector, batch, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- delete_entry = j_db_entry_new(schema, &error);
- g_assert_nonnull(delete_entry);
- g_assert_no_error(error);
-
- ret = j_db_entry_delete(delete_entry, selector, batch, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_db_schema_delete(schema, batch, &error);
- g_assert_true(ret);
- g_assert_no_error(error);
-
- ret = j_batch_execute(batch);
- g_assert_true(ret);
-
- J_TEST_TRAP_END;
-}
+#define EPS 1e-9
static void
schema_create(void)
@@ -425,6 +212,10 @@ entry_update(void)
g_autoptr(JDBSelector) selector = NULL;
g_autoptr(JDBEntry) entry = NULL;
g_autoptr(JBatch) batch = j_batch_new_for_template(J_SEMANTICS_TEMPLATE_DEFAULT);
+ g_autoptr(JDBIterator) it = NULL;
+ gpointer val = NULL;
+ JDBType type;
+ guint64 val_length;
gchar const* file = "demo.bp";
gchar const* name = "temperature";
@@ -464,6 +255,33 @@ entry_update(void)
g_assert_no_error(error);
success = j_batch_execute(batch);
g_assert_true(success);
+
+ // test if values were actually updated
+
+ it = j_db_iterator_new(schema, selector, &error);
+ g_assert_nonnull(it);
+ g_assert_no_error(error);
+
+ while (j_db_iterator_next(it, &error))
+ {
+ g_assert_no_error(error);
+ success = j_db_iterator_get_field(it, schema, "min", &type, &val, &val_length, &error);
+ g_assert_true(success);
+ g_assert_no_error(error);
+ // g_assert_cmpfloat_with_epsilon(*(double*)val, 2.0, EPS);
+ g_assert_cmpfloat(fabs(*(double*)val - 2.0), <, EPS);
+ g_assert_cmpint(type, ==, J_DB_TYPE_FLOAT64);
+ g_assert_cmpuint(val_length, ==, sizeof(gdouble));
+ g_free(val);
+ success = j_db_iterator_get_field(it, schema, "max", &type, &val, &val_length, &error);
+ g_assert_true(success);
+ g_assert_no_error(error);
+ g_assert_cmpfloat(fabs(*(double*)val - 22.0), <, EPS);
+ // g_assert_cmpfloat_with_epsilon(*(double*)val, 22.0, EPS);
+ g_assert_cmpint(type, ==, J_DB_TYPE_FLOAT64);
+ g_assert_cmpuint(val_length, ==, sizeof(gdouble));
+ g_free(val);
+ }
}
static void
@@ -546,10 +364,5 @@ test_db_all(void)
void
test_db_db(void)
{
- /// \todo add more tests
- g_test_add_func("/db/schema/new_free", test_db_schema_new_free);
- g_test_add_func("/db/schema/create_delete", test_db_schema_create_delete);
- g_test_add_func("/db/entry/new_free", test_db_entry_new_free);
- g_test_add_func("/db/entry/insert_update_delete", test_db_entry_insert_update_delete);
g_test_add_func("/db/all", test_db_all);
}
diff --git a/test/test.c b/test/test.c
index 6f598951a..a40966c15 100644
--- a/test/test.c
+++ b/test/test.c
@@ -66,6 +66,9 @@ main(int argc, char** argv)
// DB client
test_db_db();
+ test_db_schema();
+ test_db_entry();
+ test_db_selector();
// Item client
test_item_collection();
diff --git a/test/test.h b/test/test.h
index c10a06535..060a2b8de 100644
--- a/test/test.h
+++ b/test/test.h
@@ -58,6 +58,9 @@ void test_kv_kv_iterator(void);
void test_kv_parallel(void);
void test_db_db(void);
+void test_db_schema(void);
+void test_db_entry(void);
+void test_db_selector(void);
void test_item_collection(void);
void test_item_collection_iterator(void);