[libgda] meta-store: fixed gda_connection_get_meta_store_data_v()
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] meta-store: fixed gda_connection_get_meta_store_data_v()
- Date: Wed, 9 Jan 2019 17:58:42 +0000 (UTC)
commit a13c71553c715a6f3dcb55acb8a7223704ddd9cd
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Wed Jan 9 10:08:46 2019 -0600
meta-store: fixed gda_connection_get_meta_store_data_v()
Optimized and more error details per parameter and requested
meta type.
libgda/gda-connection.c | 308 +++++++++++++++++--------------------
tests/providers/prov-test-common.c | 13 +-
2 files changed, 145 insertions(+), 176 deletions(-)
---
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 44121b921..8d0ed1e65 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -5053,149 +5053,6 @@ meta_key_equal (gconstpointer a, gconstpointer b)
return TRUE;
}
-static GHashTable *
-prepare_meta_statements_hash (void)
-{
- GHashTable *h;
- MetaKey *key;
- GdaStatement *stmt;
- GdaSqlParser *parser = gda_sql_parser_new ();
- const gchar *sql;
-
- gchar **name_array = g_new (gchar *, 1);
- name_array[0] = "name";
-
- gchar **name_col_array = g_new (gchar *, 2);
- name_col_array[0] = "name";
- name_col_array[1] = "field_name";
-
- gchar **name_index_array = g_new (gchar *, 2);
- name_index_array[0] = "name";
- name_index_array[1] = "index_name";
-
- h = g_hash_table_new (meta_key_hash, meta_key_equal);
-
- /* GDA_CONNECTION_META_NAMESPACES */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_NAMESPACES;
- sql = "SELECT schema_name, schema_owner, schema_internal FROM _schemata";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_NAMESPACES;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT schema_name, schema_owner, schema_internal FROM _schemata WHERE
schema_name=##name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- /* GDA_CONNECTION_META_TYPES */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_TYPES;
- sql = "SELECT short_type_name, gtype, comments, synonyms FROM _all_types WHERE NOT internal";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_TYPES;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT short_type_name, gtype, comments, synonyms FROM _all_types WHERE NOT internal AND
short_type_name=##name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- /* GDA_CONNECTION_META_TABLES */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_TABLES;
- sql = "SELECT table_short_name, table_schema, table_full_name, table_owner, table_comments FROM
_tables WHERE table_type LIKE '%TABLE%' AND table_short_name != table_full_name";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_TABLES;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT table_short_name, table_schema, table_full_name, table_owner, table_comments FROM
_tables WHERE table_type LIKE '%TABLE%' AND table_short_name != table_full_name AND
table_short_name=##name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- /* GDA_CONNECTION_META_VIEWS */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_VIEWS;
- sql = "SELECT t.table_short_name, t.table_schema, t.table_full_name, t.table_owner, t.table_comments,
v.view_definition FROM _views as v NATURAL JOIN _tables as t WHERE t.table_short_name != t.table_full_name";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_VIEWS;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT t.table_short_name, t.table_schema, t.table_full_name, t.table_owner, t.table_comments,
v.view_definition FROM _views as v NATURAL JOIN _tables as t WHERE t.table_short_name != t.table_full_name
AND table_short_name=##name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- /* GDA_CONNECTION_META_FIELDS */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_FIELDS;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT c.column_name, c.data_type, c.gtype, c.numeric_precision, c.numeric_scale,
c.is_nullable AS 'Nullable', c.column_default, c.extra FROM _columns as c NATURAL JOIN _tables as t WHERE
t.table_short_name=##name::string ORDER BY c.ordinal_position";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_FIELDS;
- key->nb_filters = 2;
- key->filters = name_col_array;
- sql = "SELECT c.column_name, c.data_type, c.gtype, c.numeric_precision, c.numeric_scale,
c.is_nullable AS 'Nullable', c.column_default, c.extra FROM _columns as c NATURAL JOIN _tables as t WHERE
t.table_short_name=##name::string AND c.column_name = ##field_name::string ORDER BY c.ordinal_position";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- /* GDA_CONNECTION_META_INDEXES */
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_INDEXES;
- key->nb_filters = 1;
- key->filters = name_array;
- sql = "SELECT i.table_name, i.table_schema, i.index_name, d.column_name, d.ordinal_position,
i.index_type FROM _table_indexes as i INNER JOIN _index_column_usage as d ON (d.table_catalog =
i.table_catalog AND d.table_schema = i.table_schema AND d.table_name = i.table_name) INNER JOIN _tables t ON
(t.table_catalog = i.table_catalog AND t.table_schema = i.table_schema AND t.table_name = i.table_name) WHERE
t.table_short_name=##name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- key = g_new0 (MetaKey, 1);
- key->meta_type = GDA_CONNECTION_META_INDEXES;
- key->nb_filters = 2;
- key->filters = name_index_array;
- sql = "SELECT i.table_name, i.table_schema, i.index_name, d.column_name, d.ordinal_position,
i.index_type FROM _table_indexes as i INNER JOIN _index_column_usage as d ON (d.table_catalog =
i.table_catalog AND d.table_schema = i.table_schema AND d.table_name = i.table_name) INNER JOIN _tables t ON
(t.table_catalog = i.table_catalog AND t.table_schema = i.table_schema AND t.table_name = i.table_name) WHERE
t.table_short_name=##name::string AND i.index_name=##index_name::string";
- stmt = gda_sql_parser_parse_string (parser, sql, NULL, NULL);
- if (!stmt)
- g_error ("Could not parse internal statement: %s\n", sql);
- g_hash_table_insert (h, key, stmt);
-
- return h;
-}
-
/**
* gda_connection_get_meta_store_data: (skip)
* @cnc: a #GdaConnection object.
@@ -5295,9 +5152,14 @@ gda_connection_get_meta_store_data_v (GdaConnection *cnc, GdaConnectionMetaType
GdaMetaStore *store;
GdaDataModel *model = NULL;
static GHashTable *stmt_hash = NULL;
- GdaStatement *stmt;
+ GdaStatement *stmt = NULL;
GdaSet *set = NULL;
+ GdaSqlParser *parser;
GList* node;
+ gchar *sql;
+ gboolean fail = FALSE;
+ GError *lerror = NULL;
+ gint nparams = 0;
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
GdaConnectionPrivate *priv = gda_connection_get_instance_private (cnc);
@@ -5311,33 +5173,137 @@ gda_connection_get_meta_store_data_v (GdaConnection *cnc, GdaConnectionMetaType
/* Get or create the GdaMetaStore object */
store = gda_connection_get_meta_store (cnc);
- g_assert (store);
-
- /* fetch the statement */
- MetaKey key;
- gint i;
- if (!stmt_hash)
- stmt_hash = prepare_meta_statements_hash ();
- key.meta_type = meta_type;
- key.nb_filters = g_list_length (filters);
- key.filters = NULL;
- if (key.nb_filters > 0)
- key.filters = g_new (gchar *, key.nb_filters);
- for (node = filters, i = 0;
- node;
- node = node->next, i++) {
- if (!set)
- set = g_object_new (GDA_TYPE_SET, NULL);
+ if (store == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+ _("Internal error: No meta store in connection"));
+ return NULL;
+ }
+ set = GDA_SET (g_object_new (GDA_TYPE_SET, NULL));
+ for (node = filters;
+ node;
+ node = node->next) {
gda_set_add_holder (set, GDA_HOLDER (node->data));
- key.filters[i] = (gchar*) gda_holder_get_id (GDA_HOLDER (node->data));
- }
- stmt = g_hash_table_lookup (stmt_hash, &key);
- g_free (key.filters);
- if (!stmt) {
- g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
- "%s", _("Wrong filter arguments"));
- if (set)
- g_object_unref (set);
+ nparams++;
+ }
+
+ switch (meta_type) {
+ case GDA_CONNECTION_META_NAMESPACES:
+ sql = "SELECT schema_name, schema_owner, schema_internal FROM _schemata";
+ if (nparams > 0) {
+ sql = "SELECT schema_name, schema_owner, schema_internal FROM _schemata WHERE
schema_name=##name::string";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter namespaces"));
+ fail = TRUE;
+ }
+ }
+ break;
+ case GDA_CONNECTION_META_TYPES:
+ sql = "SELECT short_type_name, gtype, comments, synonyms FROM _all_types WHERE NOT internal";
+ if (nparams > 0) {
+ sql = "SELECT short_type_name, gtype, comments, synonyms FROM _all_types WHERE NOT
internal AND short_type_name=##name::string";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter data types"));
+ fail = TRUE;
+ }
+ }
+ break;
+ case GDA_CONNECTION_META_TABLES:
+ sql = "SELECT table_short_name, table_schema, table_full_name, table_owner, table_comments
FROM _tables WHERE table_type LIKE '%TABLE%' AND table_short_name != table_full_name";
+ if (nparams > 0) {
+ sql = "SELECT table_short_name, table_schema, table_full_name, table_owner,
table_comments FROM _tables WHERE table_type LIKE '%TABLE%' AND table_short_name != table_full_name AND
table_short_name=##name::string";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter tables"));
+ fail = TRUE;
+ }
+ }
+ break;
+ case GDA_CONNECTION_META_VIEWS:
+ sql = "SELECT t.table_short_name, t.table_schema, t.table_full_name, t.table_owner,
t.table_comments, v.view_definition FROM _views as v NATURAL JOIN _tables as t WHERE t.table_short_name !=
t.table_full_name";
+ if (nparams > 0) {
+ sql = "SELECT t.table_short_name, t.table_schema, t.table_full_name, t.table_owner,
t.table_comments, v.view_definition FROM _views as v NATURAL JOIN _tables as t WHERE t.table_short_name !=
t.table_full_name AND table_short_name=##name::string";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter views"));
+ fail = TRUE;
+ }
+ }
+ break;
+ case GDA_CONNECTION_META_FIELDS:
+ if (nparams > 0) {
+ sql = "SELECT c.column_name, c.data_type, c.gtype, c.numeric_precision,
c.numeric_scale, c.is_nullable AS 'Nullable', c.column_default, c.extra FROM _columns as c NATURAL JOIN
_tables as t WHERE t.table_short_name=##name::string ORDER BY c.ordinal_position";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter fields"));
+ fail = TRUE;
+ } else if (nparams > 1) {
+ sql = "SELECT c.column_name, c.data_type, c.gtype, c.numeric_precision,
c.numeric_scale, c.is_nullable AS 'Nullable', c.column_default, c.extra FROM _columns as c NATURAL JOIN
_tables as t WHERE t.table_short_name=##name::string AND c.column_name = ##field_name::string ORDER BY
c.ordinal_position";
+ if (gda_set_get_holder (set, "field_name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'field_name' is required to filter fields"));
+ fail = TRUE;
+ }
+ }
+ } else {
+ sql = "";
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameters: 'name' and/or 'field_name' are required to filter
fields"));
+ fail = TRUE;
+ }
+ break;
+ case GDA_CONNECTION_META_INDEXES:
+ if (nparams > 0) {
+ sql = "SELECT i.table_name, i.table_schema, i.index_name, d.column_name,
d.ordinal_position, i.index_type FROM _table_indexes as i INNER JOIN _index_column_usage as d ON
(d.table_catalog = i.table_catalog AND d.table_schema = i.table_schema AND d.table_name = i.table_name) INNER
JOIN _tables t ON (t.table_catalog = i.table_catalog AND t.table_schema = i.table_schema AND t.table_name =
i.table_name) WHERE t.table_short_name=##name::string";
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter indexes"));
+ fail = TRUE;
+ } else if (nparams > 1) {
+ sql = "SELECT i.table_name, i.table_schema, i.index_name, d.column_name,
d.ordinal_position, i.index_type FROM _table_indexes as i INNER JOIN _index_column_usage as d ON
(d.table_catalog = i.table_catalog AND d.table_schema = i.table_schema AND d.table_name = i.table_name) INNER
JOIN _tables t ON (t.table_catalog = i.table_catalog AND t.table_schema = i.table_schema AND t.table_name =
i.table_name) WHERE t.table_short_name=##name::string AND i.index_name=##index_name::string";
+ if (gda_set_get_holder (set, "index_name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'index_name' is required to filter indexes"));
+ fail = TRUE;
+ }
+ }
+ } else {
+ sql = "";
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameters: 'name' and/or 'index_name' are required to filter
indexes"));
+ fail = TRUE;
+ }
+
+ if (nparams > 0) {
+
+ if (gda_set_get_holder (set, "name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'name' is required to filter indexes"));
+ fail = TRUE;
+ } else if (gda_set_get_holder (set, "field_name") == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
+ _("Parameter 'index_name' is required to filter indexes"));
+ fail = TRUE;
+ }
+ }
+ break;
+ }
+ if (sql == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+ _("Invalid meta type to get data from store"));
+ fail = TRUE;
+ }
+ if (fail) {
+ return NULL;
+ }
+ parser = gda_sql_parser_new ();
+ stmt = gda_sql_parser_parse_string (parser, sql, NULL, error);
+ if (stmt == NULL) {
+ g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+ _("Internal error while creating statement to retrieve data: %s"),
+ lerror && lerror->message ? lerror->message : "No internal error reported;
please file an issue to https://gitlab.gnome.org/GNOME/libgda/issues");
+ g_clear_error (&lerror);
return NULL;
}
@@ -5349,7 +5315,7 @@ gda_connection_get_meta_store_data_v (GdaConnection *cnc, GdaConnectionMetaType
stmt, set, error);
if (set)
g_object_unref (set);
-
+
return model;
}
diff --git a/tests/providers/prov-test-common.c b/tests/providers/prov-test-common.c
index 00b19bc42..3cd08919b 100644
--- a/tests/providers/prov-test-common.c
+++ b/tests/providers/prov-test-common.c
@@ -362,7 +362,7 @@ prov_test_common_check_meta_identifiers (gboolean case_sensitive, gboolean updat
if (ops == NULL) {
g_message ("Error while rendering operation to perform: %s",
error && error->message ?
error->message : "No Error was set");
- g_clear_error (error);
+ g_clear_error (&error);
return 1;
}
g_print ("Operation to perform: %s\n", ops);
@@ -444,9 +444,13 @@ prov_test_common_check_meta_identifiers (gboolean case_sensitive, gboolean updat
g_object_unref (data);
/* check fields of table */
- data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_FIELDS, &error, 1,
- "name", value);
- g_assert (data);
+ g_value_set_string ((value2 = gda_value_new (G_TYPE_STRING)), "id");
+ data = gda_connection_get_meta_store_data (cnc, GDA_CONNECTION_META_FIELDS, &error, 2,
+ "name", value, "field_name", value2, NULL);
+ if (data == NULL) {
+ g_message ("Error getting data for fields: %s",
+ error && error->message ? error->message : "No error was set");
+ }
if (gda_data_model_get_n_rows (data) != 1) {
#ifdef CHECK_EXTRA_INFO
g_message ("Getting Meta for Fields: wrong number of rows : %d\n",
@@ -462,7 +466,6 @@ prov_test_common_check_meta_identifiers (gboolean case_sensitive, gboolean updat
}
cvalue = gda_data_model_get_value_at (data, 0, 0, &error);
g_assert (cvalue);
- g_value_set_string ((value2 = gda_value_new (G_TYPE_STRING)), "id");
if (gda_value_compare (value2, cvalue)) {
#ifdef CHECK_EXTRA_INFO
g_message ("Comparing data for returned data in meta data for Fields: expected %s and got
%s\n",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]