[libgda/LIBGDA_5.0] Improved connections binding handling of strange cases



commit 8cbe4a505cf0d806b02e83f4e91864279824786c
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Jan 8 20:53:29 2012 +0100

    Improved connections binding handling of strange cases

 libgda/sqlite/virtual/gda-vconnection-data-model.c |   90 +++++++++++---------
 libgda/sqlite/virtual/gda-vconnection-hub.c        |    4 +-
 libgda/sqlite/virtual/gda-vprovider-data-model.c   |    8 ++-
 3 files changed, 60 insertions(+), 42 deletions(-)
---
diff --git a/libgda/sqlite/virtual/gda-vconnection-data-model.c b/libgda/sqlite/virtual/gda-vconnection-data-model.c
index f58cb82..ecb5c60 100644
--- a/libgda/sqlite/virtual/gda-vconnection-data-model.c
+++ b/libgda/sqlite/virtual/gda-vconnection-data-model.c
@@ -37,6 +37,8 @@ static void gda_vconnection_data_model_class_init (GdaVconnectionDataModelClass
 static void gda_vconnection_data_model_init       (GdaVconnectionDataModel *cnc, GdaVconnectionDataModelClass *klass);
 static void gda_vconnection_data_model_dispose   (GObject *object);
 
+static gboolean get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gboolean force, GError **error);
+
 enum {
 	VTABLE_CREATED,
 	VTABLE_DROPPED,
@@ -147,8 +149,12 @@ gda_vconnection_data_model_dispose (GObject *object)
 
 	/* free memory */
 	if (cnc->priv) {
+		while (cnc->priv->table_data_list) {
+			GdaVConnectionTableData *td;
+			td = (GdaVConnectionTableData *) cnc->priv->table_data_list->data;
+			get_rid_of_vtable (cnc, td, TRUE, NULL);
+		}
 		gda_connection_close_no_warning ((GdaConnection *) cnc);
-		g_assert (!cnc->priv->table_data_list);
 
 		g_free (cnc->priv);
 		cnc->priv = NULL;
@@ -337,6 +343,44 @@ gda_vconnection_data_model_add (GdaVconnectionDataModel *cnc, GdaVconnectionData
 	return retval;
 }
 
+static gboolean
+get_rid_of_vtable (GdaVconnectionDataModel *cnc, GdaVConnectionTableData *td, gboolean force, GError **error)
+{
+	gchar *str;
+	int rc;
+	char *zErrMsg = NULL;
+	gboolean allok = TRUE;
+
+	SqliteConnectionData *scnc;
+	scnc = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error ((GdaConnection *) cnc, error);
+	if (!scnc && !force)
+		return FALSE;
+
+	if (scnc) {
+		str = g_strdup_printf ("DROP TABLE %s", td->table_name);
+		rc = SQLITE3_CALL (sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
+		g_free (str);
+
+		if (rc != SQLITE_OK) {
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+				     "%s", zErrMsg);
+			SQLITE3_CALL (sqlite3_free) (zErrMsg);
+			allok = FALSE;
+			if (!force)
+				return FALSE;
+		}
+	}
+
+	/* clean the cnc->priv->table_data_list list */
+	cnc->priv->table_data_list = g_slist_remove (cnc->priv->table_data_list, td);
+	g_signal_emit (G_OBJECT (cnc), gda_vconnection_data_model_signals[VTABLE_DROPPED], 0,
+		       td->table_name);
+	/*g_print ("Virtual connection: removed table %s (%p)\n", td->table_name, td->spec->data_model);*/
+	gda_vconnection_data_model_table_data_free (td);
+
+	return allok;
+}
 
 /**
  * gda_vconnection_data_model_remove:
@@ -354,19 +398,9 @@ gda_vconnection_data_model_remove (GdaVconnectionDataModel *cnc, const gchar *ta
 {
 	GdaVConnectionTableData *td;
 
-	gchar *str;
-	int rc;
-	char *zErrMsg = NULL;
-	gboolean retval = TRUE;
-	SqliteConnectionData *scnc;
-
 	g_return_val_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc), FALSE);
 	g_return_val_if_fail (table_name && *table_name, FALSE);
 
-	scnc = (SqliteConnectionData*) gda_connection_internal_get_provider_data_error ((GdaConnection *) cnc, error);
-	if (!scnc) 
-		return FALSE;
-
 	td = gda_vconnection_get_table_data_by_name (cnc, table_name);
 	if (!td) {
 		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
@@ -375,28 +409,7 @@ gda_vconnection_data_model_remove (GdaVconnectionDataModel *cnc, const gchar *ta
 		return FALSE;
 	}
 
-	str = g_strdup_printf ("DROP TABLE %s", td->table_name);
-	rc = SQLITE3_CALL (sqlite3_exec) (scnc->connection, str, NULL, 0, &zErrMsg);
-	g_free (str);
-
-	if (rc != SQLITE_OK) {
-		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
-			     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
-			     "%s", zErrMsg);
-		SQLITE3_CALL (sqlite3_free) (zErrMsg);
-		return FALSE;
-	}
-	else {
-		/* clean the cnc->priv->table_data_list list */
-		cnc->priv->table_data_list = g_slist_remove (cnc->priv->table_data_list, td);
-		g_signal_emit (G_OBJECT (cnc), gda_vconnection_data_model_signals[VTABLE_DROPPED], 0,
-			       td->table_name);
-		/*g_print ("Virtual connection: removed table %s (%p)\n", td->table_name, td->spec->data_model);*/
-		gda_vconnection_data_model_table_data_free (td);
-		return TRUE;
-	}
-
-	return retval;
+	return get_rid_of_vtable (cnc, td, FALSE, error);
 }
 
 /**
@@ -494,20 +507,19 @@ void
 gda_vconnection_data_model_foreach (GdaVconnectionDataModel *cnc, 
 				    GdaVconnectionDataModelFunc func, gpointer data)
 {
-	GSList *list, *next;
+	GSList *copy, *list;
 	g_return_if_fail (GDA_IS_VCONNECTION_DATA_MODEL (cnc));
 	g_return_if_fail (cnc->priv);
 
-	if (!func)
+	if (!func || !cnc->priv->table_data_list)
 		return;
 
-	list = cnc->priv->table_data_list;
-	while (list) {
+	copy = g_slist_copy (cnc->priv->table_data_list);
+	for (list = copy; list; list = list->next) {
 		GdaVConnectionTableData *td = (GdaVConnectionTableData*) list->data;
-		next = list->next;
 		func (td->spec->data_model, td->table_name, data);
-		list = next;
 	}
+	g_slist_free (copy);
 }
 
 /* 
diff --git a/libgda/sqlite/virtual/gda-vconnection-hub.c b/libgda/sqlite/virtual/gda-vconnection-hub.c
index 39c1477..4947823 100644
--- a/libgda/sqlite/virtual/gda-vconnection-hub.c
+++ b/libgda/sqlite/virtual/gda-vconnection-hub.c
@@ -882,7 +882,7 @@ meta_changed_cb (G_GNUC_UNUSED GdaMetaStore *store, GSList *changes, HubConnecti
 		GdaMetaStoreChange *ch = (GdaMetaStoreChange*) list->data;
 		GValue *tsn, *tn;
 
-		/* we are only intsrested in changes occurring in the "_tables" table */
+		/* we are only interested in changes occurring in the "_tables" table */
 		if (!strcmp (ch->table_name, "_tables")) {
 			switch (ch->c_type) {
 			case GDA_META_STORE_ADD: {
@@ -936,6 +936,7 @@ table_add (HubConnection *hc, const GValue *table_name, GError **error)
 	lspec->table_name = gda_value_copy (table_name);
 	lspec->hc = hc;
 	tmp = get_complete_table_name (hc, lspec->table_name);
+	/*g_print ("%s (HC=%p, table_name=%s) name=%s\n", __FUNCTION__, hc, g_value_get_string (table_name), tmp);*/
 	if (!gda_vconnection_data_model_add (GDA_VCONNECTION_DATA_MODEL (hc->hub), (GdaVconnectionDataModelSpec*) lspec,
 					     (GDestroyNotify) local_spec_free, tmp, error)) {
 		g_free (tmp);
@@ -951,6 +952,7 @@ table_remove (HubConnection *hc, const GValue *table_name)
 	gchar *name;
 
 	name = get_complete_table_name (hc, table_name);
+	/*g_print ("%s (HC=%p, table_name=%s) name=%s\n", __FUNCTION__, hc, g_value_get_string (table_name), name);*/
 	gda_vconnection_data_model_remove (GDA_VCONNECTION_DATA_MODEL (hc->hub), name, NULL);
 	g_free (name);
 }
diff --git a/libgda/sqlite/virtual/gda-vprovider-data-model.c b/libgda/sqlite/virtual/gda-vprovider-data-model.c
index 7ca011e..77ce8cd 100644
--- a/libgda/sqlite/virtual/gda-vprovider-data-model.c
+++ b/libgda/sqlite/virtual/gda-vprovider-data-model.c
@@ -350,8 +350,12 @@ static void
 cnc_close_foreach_func (G_GNUC_UNUSED GdaDataModel *model, const gchar *table_name, GdaVconnectionDataModel *cnc)
 {
 	/*g_print ("---- FOREACH: Removing virtual table '%s'\n", table_name);*/
-	if (! gda_vconnection_data_model_remove (cnc, table_name, NULL))
-		g_warning ("Internal GdaVproviderDataModel error");
+	GError *lerror = NULL;
+	if (! gda_vconnection_data_model_remove (cnc, table_name, &lerror)) {
+		g_warning ("Internal GdaVproviderDataModel error: %s",
+			   lerror && lerror->message ? lerror->message : _("No detail"));
+		g_clear_error (&lerror);
+	}
 }
 
 static gboolean



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]