[libgda: 1/5] DB: Convenient API to get GdaDbTable and GdaDbView
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda: 1/5] DB: Convenient API to get GdaDbTable and GdaDbView
- Date: Thu, 6 Jan 2022 16:41:40 +0000 (UTC)
commit da078d70740231db4df409bf8b612396d2c9fbcf
Author: Pavlo Solntsev <p sun fun gmail com>
Date: Mon Aug 3 22:42:36 2020 -0500
DB: Convenient API to get GdaDbTable and GdaDbView
See https://gitlab.gnome.org/GNOME/libgda/-/issues/223
libgda/gda-db-base.c | 46 ++++++++---
libgda/gda-db-catalog.c | 159 ++++++++++++++++++++++++++++++-------
libgda/gda-db-catalog.h | 9 +++
tests/db/check-db-base.c | 41 ++++++++++
tests/db/check-db-catalog.c | 63 +++++++++++++++
tests/test-ddl-modifiable-sqlite.c | 2 +
6 files changed, 280 insertions(+), 40 deletions(-)
---
diff --git a/libgda/gda-db-base.c b/libgda/gda-db-base.c
index 6c1344b20..45d768c1b 100644
--- a/libgda/gda-db-base.c
+++ b/libgda/gda-db-base.c
@@ -319,9 +319,11 @@ gda_db_base_set_name (GdaDbBase *self,
* @a: first #GdaDbBase object
* @b: second #GdaDbBase object
*
- * Compares two objects similar to g_strcmp().
+ * Compares two objects similar to g_strcmp(). In general, catalog and schema can be %NULL. In this case
+ * those pairs are ignored. If we represent a full name as catalog.schema.name then two objects
+ * null.null.customer and main.main.customer are identical.
*
- * Returns: 0 if catalog, schema and name are the same
+ * Returns: 0 if two objects are identical or -1 or 1 otherwise.
*
* Since: 6.0
*/
@@ -336,17 +338,41 @@ gda_db_base_compare (GdaDbBase *a,
else if (a && !b)
return 1;
- gint res = g_strcmp0 (gda_db_base_get_name(a), gda_db_base_get_name(b));
+ const gchar *a_catalog = gda_db_base_get_catalog (a);
+ const gchar *b_catalog = gda_db_base_get_catalog (b);
- if (!res)
- {
- res = g_strcmp0 (gda_db_base_get_catalog(a), gda_db_base_get_catalog(b));
+ const gchar *a_schema = gda_db_base_get_schema (a);
+ const gchar *b_schema = gda_db_base_get_schema (b);
+
+ const gchar *a_name = gda_db_base_get_name (a);
+ const gchar *b_name = gda_db_base_get_name (b);
- if (!res)
- return g_strcmp0(gda_db_base_get_schema(a), gda_db_base_get_schema(b));
+ gint res;
+
+ res = g_strcmp0 (a_name, b_name);
+ if (a_name && b_name)
+ {
+ if (a_schema && b_schema)
+ {
+ res = g_strcmp0 (a_schema, b_schema);
+ if (a_catalog && b_catalog)
+ {
+ return g_strcmp0 (a_catalog, b_catalog);
+ }
+ else
+ {
+ return res;
+ }
+ }
else
- return res;
+ {
+ return res;
+ }
}
else
- return res;
+ {
+ return res;
+ }
+
+ return -1;
}
diff --git a/libgda/gda-db-catalog.c b/libgda/gda-db-catalog.c
index 04d590aa6..a5b4324c4 100644
--- a/libgda/gda-db-catalog.c
+++ b/libgda/gda-db-catalog.c
@@ -552,14 +552,20 @@ gda_db_catalog_get_views (GdaDbCatalog *self)
/**
* gda_db_catalog_get_table:
* @self: a #GdaDbCatalog object
+ * @catalog (nullable): catalog name or %NULL
+ * @schema (nullable): schema name or %NULL
* @name: table name
*
- * Convenient function to return a table based on name
+ * Convenient function to get a table based on @name. The coller is responsible
+ * for calling gda_db_catalog_parse_cnc() before calling this function.
*
- * Returns: table as #GdaDbTable or %NULL
+ * Returns: (transfer none): table as #GdaDbTable or %NULL if the table is not found. The
+ * returned pointer should not be freed and belongs to the @self.
+ *
+ * Since: 6.2
*
*/
-const GdaDbTable*
+GdaDbTable *
gda_db_catalog_get_table (GdaDbCatalog *self,
const gchar *catalog,
const gchar *schema,
@@ -568,55 +574,132 @@ gda_db_catalog_get_table (GdaDbCatalog *self,
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (name, NULL);
+ GdaDbBase *iobj;
+ GList *it;
+
GdaDbCatalogPrivate *priv = gda_db_catalog_get_instance_private (self);
- GdaDbBase *iobj = gda_db_base_new ();
+ iobj = gda_db_base_new ();
gda_db_base_set_names (iobj, catalog, schema, name);
- GList *it = NULL;
-
for (it = priv->mp_tables; it; it = it->next)
- if (!gda_db_base_compare (iobj,GDA_DB_BASE(it->data)))
- {
- g_object_unref (iobj);
- return GDA_DB_TABLE(it->data);
- }
+ {
+ if (!gda_db_base_compare (GDA_DB_BASE (it->data), iobj)) {
+ if (iobj)
+ g_object_unref (iobj);
+
+ return GDA_DB_TABLE (it->data);
+ }
+ }
+
+ if (iobj)
+ g_object_unref (iobj);
- g_object_unref (iobj);
return NULL;
}
/**
* gda_db_catalog_get_view:
* @self: a #GdaDbCatalog object
- * @name: view name
+ * @catalog: a catalog name or %NULL
+ * @schema: a schema name or %NULL
+ * @name: view name. Can't be %NULL
+ *
+ * Convenient function to get a view based on name. The coller is responsible
+ * for calling gda_db_catalog_parse_cnc() before calling this function. This
+ * code is equivalent to the following code:
*
- * Convenient function to return a view based on name.
+ * |[<!-- language="C" -->
+ * GdaDbBase *iobj;
+ * GList *it;
*
- * Returns: table as #GdaDbView or %NULL if the view is not found.
+ * GdaDbCatalogPrivate *priv = gda_db_catalog_get_instance_private (self);
+ *
+ * if (gda_db_catalog_parse_cnc (self, error))
+ * return NULL;
+ *
+ * iobj = gda_db_base_new ();
+ * gda_db_base_set_names (iobj, catalog, schema, name);
+ *
+ * for (it = priv->mp_views; it; it = it->next)
+ * {
+ * if (!gda_db_base_compare (iobj, GDA_DB_BASE (it->data)))
+ * {
+ * if (iobj)
+ * g_object_unref (iobj);
+ *
+ * return GDA_DB_VIEW (it->data);
+ * }
+ * }
+ *
+ * if (iobj)
+ * g_object_unref (iobj);
+ *
+ * return NULL;
+ * ]|
+ * Returns: (transfer none): View as #GdaDbView or %NULL if the view is not found. The returned
+ * pointer should not be freed and belongs to @self
+ *
+ * Since: 6.0
*
*/
-const GdaDbView*
+GdaDbView*
gda_db_catalog_get_view (GdaDbCatalog *self,
const gchar *catalog,
const gchar *schema,
const gchar *name)
{
- GdaDbCatalogPrivate *priv = gda_db_catalog_get_instance_private (self);
+ g_return_val_if_fail (self, NULL);
+ g_return_val_if_fail (name, NULL);
- GList *it = NULL;
+ GdaDbBase *iobj;
+ GList *it;
+
+ GdaDbCatalogPrivate *priv = gda_db_catalog_get_instance_private (self);
- GdaDbBase *iobj = gda_db_base_new ();
- gda_db_base_set_names (iobj,catalog,schema,name);
+ iobj = gda_db_base_new ();
+ gda_db_base_set_names (iobj, catalog, schema, name);
for (it = priv->mp_views; it; it = it->next)
- if (!gda_db_base_compare (iobj, GDA_DB_BASE(it)))
- {
- g_object_unref (iobj);
- return GDA_DB_VIEW(it);
- }
+ {
+ if (schema && catalog)
+ {
+ if (!gda_db_base_compare (iobj, GDA_DB_BASE (it->data)))
+ {
+ if (iobj)
+ g_object_unref (iobj);
+
+ return GDA_DB_VIEW (it->data);
+ }
+ }
+ else if (schema && !catalog)
+ {
+ if (!g_strcmp0 (schema,
+ gda_db_base_get_schema (GDA_DB_BASE (it->data)))
+ && !g_strcmp0 (name,
+ gda_db_base_get_name (GDA_DB_BASE (it->data))))
+ {
+ if (iobj)
+ g_object_unref (iobj);
+
+ return GDA_DB_VIEW (it->data);
+ }
+ }
+ else if (!schema && !catalog)
+ {
+ if (!g_strcmp0 (name, gda_db_base_get_name (GDA_DB_BASE (it->data))))
+ {
+ if (iobj)
+ g_object_unref (iobj);
+
+ return GDA_DB_VIEW (it->data);
+ }
+ }
+ }
+
+ if (iobj)
+ g_object_unref (iobj);
- g_object_unref (iobj);
return NULL;
}
@@ -683,15 +766,18 @@ _gda_db_table_new_from_meta (GdaMetaDbObject *obj)
* Returns: New instance of #GdaDbView
*/
static GdaDbView*
-_gda_db_view_new_from_meta (GdaMetaView *view)
+_gda_db_view_new_from_meta (GdaMetaDbObject *obj)
{
- if (!view)
+ if (!obj)
return gda_db_view_new ();
GdaDbView *dbview = gda_db_view_new ();
- gda_db_view_set_defstring (dbview,view->view_def);
- gda_db_view_set_replace (dbview,view->is_updatable);
+ gda_db_base_set_names (GDA_DB_BASE (dbview), obj->obj_catalog,
+ obj->obj_schema, obj->obj_name);
+
+ gda_db_view_set_defstring (dbview, obj->extra.meta_view.view_def);
+ gda_db_view_set_replace (dbview, obj->extra.meta_view.is_updatable);
return dbview;
}
@@ -744,6 +830,9 @@ gda_db_catalog_parse_cnc (GdaDbCatalog *self,
GSList *it = NULL;
+ gint ntables = 0;
+ gint nviews = 0;
+
for (it=dblist; it; it = it->next)
{
if(GDA_META_DB_OBJECT(it->data)->obj_type == GDA_META_DB_TABLE)
@@ -753,17 +842,27 @@ gda_db_catalog_parse_cnc (GdaDbCatalog *self,
continue;
priv->mp_tables = g_list_append (priv->mp_tables,table);
+ ntables++;
continue;
}
if(GDA_META_DB_OBJECT(it->data)->obj_type == GDA_META_DB_VIEW)
{
GdaDbView *view = _gda_db_view_new_from_meta (it->data);
+
+ if (!view)
+ continue;
+
+ g_print ("%s:%d Found %s view\n", __FILE__, __LINE__, gda_db_base_get_full_name(GDA_DB_BASE
(view)));
priv->mp_views = g_list_append (priv->mp_views, view);
+ nviews++;
continue;
}
}
+#ifdef GDA_DEBUG
+ g_print ("Tables: %d total, Views: %d total\n", ntables, nviews);
+#endif
g_slist_free (dblist);
g_object_unref (mstruct);
return TRUE;
diff --git a/libgda/gda-db-catalog.h b/libgda/gda-db-catalog.h
index 239777b6a..312e3a2b1 100644
--- a/libgda/gda-db-catalog.h
+++ b/libgda/gda-db-catalog.h
@@ -106,6 +106,15 @@ gboolean gda_db_catalog_write_to_path (GdaDbCatalog *self,
gboolean gda_db_catalog_validate_file_from_path (const gchar *xmlfile,
GError **error);
+GdaDbTable *gda_db_catalog_get_table (GdaDbCatalog *self,
+ const gchar *catalog,
+ const gchar *schema,
+ const gchar *name);
+
+GdaDbView *gda_db_catalog_get_view (GdaDbCatalog *self,
+ const gchar *catalog,
+ const gchar *schema,
+ const gchar *name);
G_END_DECLS
#endif /* GDA_DB_CATALOG_H */
diff --git a/tests/db/check-db-base.c b/tests/db/check-db-base.c
index 38315c57c..c59260cb1 100644
--- a/tests/db/check-db-base.c
+++ b/tests/db/check-db-base.c
@@ -30,6 +30,11 @@ typedef struct {
GdaDbBase *obj;
}BaseFixture;
+typedef struct {
+ GdaDbBase *obja;
+ GdaDbBase *objb;
+} TestBaseCompare;
+
static void
test_db_base_start (BaseFixture *self,
G_GNUC_UNUSED gconstpointer user_data)
@@ -38,6 +43,25 @@ test_db_base_start (BaseFixture *self,
}
+static void
+test_db_base_compare_start (TestBaseCompare *self,
+ G_GNUC_UNUSED gconstpointer user_data)
+{
+ self->obja = gda_db_base_new ();
+ self->objb = gda_db_base_new();
+}
+
+static void
+test_db_base_compare_finish (TestBaseCompare *self,
+ G_GNUC_UNUSED gconstpointer user_data)
+{
+ if (self->obja)
+ g_object_unref (self->obja);
+
+ if (self->objb)
+ g_object_unref (self->objb);
+}
+
static void
test_db_base_finish (BaseFixture *self,
G_GNUC_UNUSED gconstpointer user_data)
@@ -46,6 +70,16 @@ test_db_base_finish (BaseFixture *self,
g_object_unref (self->obj);
}
+static void
+test_db_base_compare_run1 (TestBaseCompare *self,
+ G_GNUC_UNUSED gconstpointer user_data)
+{
+ gda_db_base_set_name (self->obja, "name_a");
+ gda_db_base_set_name (self->objb, "name_b");
+
+ g_assert_cmpint (gda_db_base_compare (self->obja, self->objb), ==, 0);
+}
+
static void
test_db_base_run1 (BaseFixture *self,
G_GNUC_UNUSED gconstpointer user_data)
@@ -225,5 +259,12 @@ main (gint argc,
test_db_base_run5,
test_db_base_finish);
+ g_test_add ("/test-db/base-compare",
+ TestBaseCompare,
+ NULL,
+ test_db_base_compare_start,
+ test_db_base_compare_run1,
+ test_db_base_compare_finish);
+
return g_test_run();
}
diff --git a/tests/db/check-db-catalog.c b/tests/db/check-db-catalog.c
index dba5b5715..f2ff229eb 100644
--- a/tests/db/check-db-catalog.c
+++ b/tests/db/check-db-catalog.c
@@ -54,6 +54,7 @@ typedef struct {
GdaDbColumn *column_ts;
GdaDbColumn *column_state;
GdaDbTable *table;
+ GdaDbView *view;
} DbCatalogCnc;
typedef struct {
@@ -119,6 +120,8 @@ test_db_catalog_start_db (DbCatalogCnc *self,
gchar* dbname = g_strdup_printf ("DB_DIR=.;DB_NAME=db_types_%d", g_random_int ());
+ g_print ("Will use DB: %s\n", dbname);
+
self->cnc = gda_connection_new_from_string ("SQLite",
dbname,
NULL,
@@ -177,6 +180,17 @@ test_db_catalog_start_db (DbCatalogCnc *self,
open_res = gda_db_catalog_perform_operation (self->catalog,NULL);
g_assert_true (open_res);
+
+ self->view = gda_db_view_new ();
+
+ gda_db_base_set_name (GDA_DB_BASE (self->view), "myview");
+ gda_db_view_set_defstring (self->view, "SELECT name FROM dntypes");
+ gda_db_view_set_istemp (self->view, FALSE);
+
+ open_res = gda_ddl_modifiable_create (GDA_DDL_MODIFIABLE (self->view),
+ self->cnc, NULL, NULL);
+
+ g_assert_true (open_res);
}
static void
@@ -202,6 +216,7 @@ test_db_catalog_finish_db (DbCatalogCnc *self,
g_object_unref (self->column_ctime);
g_object_unref (self->column_ts);
g_object_unref (self->table);
+ g_object_unref (self->view);
}
static void
@@ -531,6 +546,47 @@ test_db_catalog_constraint_finish (DbCheckCatallog *self,
gda_connection_close (self->cnc, NULL);
}
+static void
+test_db_catalog_get_objects (DbCatalogCnc *self,
+ G_GNUC_UNUSED gconstpointer user_data)
+{
+ GdaDbTable *copy_table;
+ GdaDbView *copy_view;
+ GError *error = NULL;
+ gboolean res;
+ const gchar *name1;
+ const gchar *name2;
+ /* Creating a view to work with */
+
+ /* view has been created */
+
+ res = gda_db_catalog_parse_cnc (self->catalog, &error);
+
+ g_assert_true (res);
+ g_assert_null (error);
+
+ copy_table = gda_db_catalog_get_table (self->catalog, NULL, NULL,
+ gda_db_base_get_name (GDA_DB_BASE (self->table)));
+
+ g_assert_nonnull (copy_table);
+
+ name1 = gda_db_base_get_name (GDA_DB_BASE (copy_table));
+ name2 = gda_db_base_get_name (GDA_DB_BASE (self->table));
+
+ g_assert_cmpstr (name1, ==, name2);
+
+ const gchar *view_name = gda_db_base_get_name (GDA_DB_BASE (self->view));
+
+ copy_view = gda_db_catalog_get_view (self->catalog, NULL, NULL, view_name);
+
+ g_assert_nonnull (copy_view);
+
+ name1 = gda_db_base_get_name (GDA_DB_BASE (copy_view));
+ name2 = gda_db_base_get_name (GDA_DB_BASE (self->view));
+
+ g_assert_cmpstr (name1, ==, name2);
+}
+
gint
main (gint argc,
gchar *argv[])
@@ -580,5 +636,12 @@ main (gint argc,
test_db_catalog_constraint_run,
test_db_catalog_constraint_finish);
+ g_test_add ("/test-db/catalog-get-objects",
+ DbCatalogCnc,
+ NULL,
+ test_db_catalog_start_db,
+ test_db_catalog_get_objects,
+ test_db_catalog_finish_db);
+
return g_test_run();
}
diff --git a/tests/test-ddl-modifiable-sqlite.c b/tests/test-ddl-modifiable-sqlite.c
index 3b59f7d45..60ec5458a 100644
--- a/tests/test-ddl-modifiable-sqlite.c
+++ b/tests/test-ddl-modifiable-sqlite.c
@@ -51,6 +51,8 @@ test_ddl_modifiable_start (TestObjectFixture *fixture,
gchar *dbname = g_strdup_printf("DB_DIR=.;DB_NAME=%s_%d", DB_TEST_BASE, g_random_int ());
+ g_print ("Will use DB: %s\n", dbname);
+
fixture->cnc = gda_connection_open_from_string (PROVIDER_NAME,
dbname,
NULL,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]