[libgda/LIBGDA_5.0] GdaBrowser: improved user experience when starting



commit ace788867c8ad481155562dafb6e49b20af55ca5
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Jan 2 16:48:55 2012 +0100

    GdaBrowser: improved user experience when starting

 tools/browser/auth-dialog.c        |    3 +-
 tools/browser/browser-connection.c |  195 +++++++++++++++++++++++-------------
 tools/browser/login-dialog.c       |   25 ++---
 tools/browser/support.c            |    1 +
 4 files changed, 141 insertions(+), 83 deletions(-)
---
diff --git a/tools/browser/auth-dialog.c b/tools/browser/auth-dialog.c
index dcc28d9..a85633d 100644
--- a/tools/browser/auth-dialog.c
+++ b/tools/browser/auth-dialog.c
@@ -434,7 +434,7 @@ auth_dialog_add_cnc_string (AuthDialog *dialog, const gchar *cnc_string, GError
 	AuthData *ad;
 	ad = g_new0 (AuthData, 1);
 	ad->wrapper = gda_thread_wrapper_new ();
-	/*g_print ("Login dialog: new thread wrapper %p\n", ad->wrapper);*/
+	/*g_print ("Auth dialog: new thread wrapper %p\n", ad->wrapper);*/
 	ad->ext.cnc_string = g_strdup (cnc_string);
 	ad->auth_string = NULL;
 	info = gda_config_get_dsn_info (real_cnc);
@@ -706,7 +706,6 @@ auth_dialog_run (AuthDialog *dialog)
 	}
 
  out:
-	gtk_widget_hide (GTK_WIDGET (dialog));
 	return allopened;
 }
 
diff --git a/tools/browser/browser-connection.c b/tools/browser/browser-connection.c
index a11b09c..18d9725 100644
--- a/tools/browser/browser-connection.c
+++ b/tools/browser/browser-connection.c
@@ -524,6 +524,108 @@ browser_connection_meta_data_changed (BrowserConnection *bcnc)
 	meta_changed_cb (NULL, NULL, NULL, 0, NULL, NULL, bcnc);
 }
 
+static gpointer
+wrapper_have_meta_store_ready (BrowserConnection *bcnc, GError **error)
+{
+	gchar *dict_file_name = NULL;
+	gboolean update_store = FALSE;
+	GdaMetaStore *store;
+	gchar *cnc_string, *cnc_info;
+
+	g_object_get (G_OBJECT (bcnc->priv->cnc),
+		      "dsn", &cnc_info,
+		      "cnc-string", &cnc_string, NULL);
+	dict_file_name = config_info_compute_dict_file_name (cnc_info ? gda_config_get_dsn_info (cnc_info) : NULL,
+							     cnc_string);
+	g_free (cnc_string);
+	if (dict_file_name) {
+		if (BROWSER_IS_VIRTUAL_CONNECTION (bcnc))
+			/* force meta store update in case of virtual connection */
+			update_store = TRUE;
+		else if (! g_file_test (dict_file_name, G_FILE_TEST_EXISTS))
+			update_store = TRUE;
+		store = gda_meta_store_new_with_file (dict_file_name);
+	}
+	else {
+		store = gda_meta_store_new (NULL);
+		if (store)
+			update_store = TRUE;
+	}
+	config_info_update_meta_store_properties (store, bcnc->priv->cnc);
+
+	bcnc->priv->dict_file_name = dict_file_name;
+	g_object_set (G_OBJECT (bcnc->priv->cnc), "meta-store", store, NULL);
+	if (update_store) {
+		gboolean retval;
+		GdaMetaContext context = {"_tables", 0, NULL, NULL};
+		retval = gda_connection_update_meta_store (bcnc->priv->cnc, &context, error);
+		if (!retval) {
+			g_object_unref (store);
+			return NULL;
+		}
+	}
+
+	gboolean retval = TRUE;
+	GdaMetaStruct *mstruct;
+	mstruct = gda_meta_struct_new (store, GDA_META_STRUCT_FEATURE_ALL);
+	MUTEX_LOCK (bcnc);
+	if (bcnc->priv->c_mstruct) {
+		g_object_unref (bcnc->priv->c_mstruct);
+		bcnc->priv->c_mstruct = NULL;
+	}
+	bcnc->priv->mstruct = mstruct;
+	retval = gda_meta_struct_complement_all (mstruct, error);
+	MUTEX_UNLOCK (bcnc);
+
+#ifdef GDA_DEBUG_NO
+	GSList *all, *list;
+	g_print ("%s() %p:\n", __FUNCTION__, bcnc->priv->mstruct);
+	all = gda_meta_struct_get_all_db_objects (bcnc->priv->mstruct);
+	for (list = all; list; list = list->next) {
+		GdaMetaDbObject *dbo = (GdaMetaDbObject *) list->data;
+		g_print ("DBO, Type %d: short=>[%s] schema=>[%s] full=>[%s]\n", dbo->obj_type,
+			 dbo->obj_short_name, dbo->obj_schema, dbo->obj_full_name);
+	}
+	g_slist_free (all);
+#endif
+	bcnc->priv->meta_store_signal =
+		gda_thread_wrapper_connect_raw (bcnc->priv->wrapper, store, "meta-changed",
+						FALSE, FALSE,
+						(GdaThreadWrapperCallback) meta_changed_cb,
+						bcnc);
+	g_object_unref (store);
+	return retval ? (void*) 0x01 : NULL;
+}
+
+typedef struct {
+        guint jid;
+        GMainLoop *loop;
+        GError **error;
+        GdaThreadWrapper *wrapper;
+
+        /* out */
+	gboolean retval;
+} MainloopData;
+
+static gboolean
+check_for_meta_store_ready (MainloopData *data)
+{
+	gpointer retval;
+        GError *lerror = NULL;
+
+        retval = gda_thread_wrapper_fetch_result (data->wrapper, FALSE, data->jid, &lerror);
+        if (retval || (!retval && lerror)) {
+                /* waiting is finished! */
+                data->retval = retval ? TRUE : FALSE;
+                if (lerror)
+                        g_propagate_error (data->error, lerror);
+                g_main_loop_quit (data->loop);
+                return FALSE;
+        }
+        return TRUE;
+}
+
+
 static void
 browser_connection_set_property (GObject *object,
 				 guint param_id,
@@ -553,80 +655,37 @@ browser_connection_set_property (GObject *object,
 								bcnc);
 
 
-			/* meta store */
-			gchar *dict_file_name = NULL;
-			gboolean update_store = FALSE;
-			GdaMetaStore *store;
-			gchar *cnc_string, *cnc_info;
-			
-			g_object_get (G_OBJECT (bcnc->priv->cnc),
-				      "dsn", &cnc_info,
-				      "cnc-string", &cnc_string, NULL);
-			dict_file_name = config_info_compute_dict_file_name (cnc_info ? gda_config_get_dsn_info (cnc_info) : NULL,
-									     cnc_string);
-			g_free (cnc_string);
-			if (dict_file_name) {
-				if (BROWSER_IS_VIRTUAL_CONNECTION (bcnc))
-					/* force meta store update in case of virtual connection */
-					update_store = TRUE;
-				else if (! g_file_test (dict_file_name, G_FILE_TEST_EXISTS))
-					update_store = TRUE;
-				store = gda_meta_store_new_with_file (dict_file_name);
+			/* meta store, open it in a sub thread to avoid locking the GTK thread */
+			gpointer retval;
+			GError *lerror = NULL;
+			guint jid;
+			jid = gda_thread_wrapper_execute (bcnc->priv->wrapper,
+							  (GdaThreadWrapperFunc) wrapper_have_meta_store_ready,
+							  (gpointer) bcnc,
+							  NULL, &lerror);
+			if (jid == 0) {
+				browser_show_error (NULL, _("Error while fetching meta data from the connection: %s"),
+						    lerror->message ? lerror->message : _("No detail"));
+				g_clear_error (&lerror);
 			}
 			else {
-				store = gda_meta_store_new (NULL);
-				if (store)
-					update_store = TRUE;
-			}
-			config_info_update_meta_store_properties (store, bcnc->priv->cnc);
-
-			bcnc->priv->dict_file_name = dict_file_name;
-			g_object_set (G_OBJECT (bcnc->priv->cnc), "meta-store", store, NULL);
-			if (update_store) {
-				GError *lerror = NULL;
-				guint job_id;
-				job_id = gda_thread_wrapper_execute (bcnc->priv->wrapper,
-								     (GdaThreadWrapperFunc) wrapper_meta_store_update,
-								     g_object_ref (bcnc), g_object_unref, &lerror);
-				if (job_id > 0)
-					push_wrapper_job (bcnc, job_id, JOB_TYPE_META_STORE_UPDATE,
-							  _("Getting database schema information"),
-							  NULL, NULL);
-				else if (lerror) {
+				GMainLoop *loop;
+				MainloopData data;
+
+				loop = g_main_loop_new (NULL, FALSE);
+				data.jid = jid;
+				data.loop = loop;
+				data.error = &lerror;
+				data.wrapper = bcnc->priv->wrapper;
+				g_timeout_add (200, (GSourceFunc) check_for_meta_store_ready, &data);
+				g_main_loop_run (loop);
+				g_main_loop_unref (loop);
+				if (!data.retval) {
 					browser_show_error (NULL, _("Error while fetching meta data from the connection: %s"),
 							    lerror->message ? lerror->message : _("No detail"));
-					g_error_free (lerror);
+					g_clear_error (&lerror);
 				}
 			}
-			else {
-				guint job_id;
-				GError *lerror = NULL;
-				GdaMetaStruct *mstruct;
-
-				mstruct = gda_meta_struct_new (store, GDA_META_STRUCT_FEATURE_ALL);
-				bcnc->priv->p_mstruct_list = g_slist_append (bcnc->priv->p_mstruct_list,
-									     mstruct);
-				/*g_print ("%s() Added %p to p_mstruct_list\n", __FUNCTION__, mstruct);*/
-				job_id = gda_thread_wrapper_execute (bcnc->priv->wrapper,
-								     (GdaThreadWrapperFunc) wrapper_meta_struct_sync,
-								     g_object_ref (bcnc), g_object_unref, &lerror);
-				if (job_id > 0)
-					push_wrapper_job (bcnc, job_id, JOB_TYPE_META_STRUCT_SYNC,
-							  _("Analysing database schema"),
-							  NULL, NULL);
-				else if (lerror) {
-					browser_show_error (NULL, _("Error while fetching meta data from the connection: %s"),
-							    lerror->message ? lerror->message : _("No detail"));
-					g_error_free (lerror);
-				}
-				g_object_unref (store);
-				bcnc->priv->meta_store_signal =
-					gda_thread_wrapper_connect_raw (bcnc->priv->wrapper, store, "meta-changed",
-									FALSE, FALSE,
-									(GdaThreadWrapperCallback) meta_changed_cb,
-									bcnc);
-			}
-
                         break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
diff --git a/tools/browser/login-dialog.c b/tools/browser/login-dialog.c
index 719b928..4096608 100644
--- a/tools/browser/login-dialog.c
+++ b/tools/browser/login-dialog.c
@@ -31,7 +31,7 @@ static void login_dialog_class_init (LoginDialogClass * class);
 static void login_dialog_init (LoginDialog *dialog);
 static void login_dialog_dispose (GObject *object);
 
-static GdaConnection *real_open_connection (const GdaDsnInfo *cncinfo, GError **error);
+static GdaConnection *real_open_connection (GdaThreadWrapper *wrapper, const GdaDsnInfo *cncinfo, GError **error);
 
 /* get a pointer to the parents to be able to call their destructor */
 static GObjectClass  *parent_class = NULL;
@@ -40,6 +40,7 @@ struct _LoginDialogPrivate
 {
 	GtkWidget *login;
 	GtkWidget *spinner;
+	GdaThreadWrapper *wrapper;
 };
 
 /* module error */
@@ -168,6 +169,8 @@ login_dialog_dispose (GObject *object)
 	LoginDialog *dialog;
 	dialog = LOGIN_DIALOG (object);
 	if (dialog->priv) {
+		if (dialog->priv->wrapper)
+			g_object_unref (dialog->priv->wrapper);
 		g_free (dialog->priv);
 		dialog->priv = NULL;
 	}
@@ -224,8 +227,11 @@ login_dialog_run (LoginDialog *dialog, gboolean retry, GError **error)
 			const GdaDsnInfo *info;
 			GError *lerror = NULL;
 			
+			if (!dialog->priv->wrapper)
+				dialog->priv->wrapper = gda_thread_wrapper_new ();
+
 			info = gdaui_login_get_connection_information (GDAUI_LOGIN (dialog->priv->login));
-			cnc = real_open_connection (info, &lerror);
+			cnc = real_open_connection (dialog->priv->wrapper, info, &lerror);
 			browser_spinner_stop (BROWSER_SPINNER (dialog->priv->spinner));
 			if (cnc)
 				goto out;
@@ -262,12 +268,6 @@ login_dialog_run (LoginDialog *dialog, gboolean retry, GError **error)
 }
 
 /*
- * Open a connection in a sub thread
- */
-
-static GdaThreadWrapper *wrapper = NULL;
-
-/*
  * executed in a sub thread
  */
 static GdaConnection *
@@ -308,6 +308,7 @@ typedef struct {
 	guint cncid;
 	GMainLoop *loop;
 	GError **error;
+	GdaThreadWrapper *wrapper;
 
 	/* out */
 	GdaConnection *cnc;
@@ -318,7 +319,7 @@ check_for_cnc (MainloopData *data)
 {
 	GdaConnection *cnc;
 	GError *lerror = NULL;
-	cnc = gda_thread_wrapper_fetch_result (wrapper, FALSE, data->cncid, &lerror);
+	cnc = gda_thread_wrapper_fetch_result (data->wrapper, FALSE, data->cncid, &lerror);
 	if (cnc || (!cnc && lerror)) {
 		/* waiting is finished! */
 		data->cnc = cnc;
@@ -340,15 +341,12 @@ check_for_cnc (MainloopData *data)
  * Returns: a new #GdaConnection, or %NULL if an error occurred
  */
 static GdaConnection *
-real_open_connection (const GdaDsnInfo *cncinfo, GError **error)
+real_open_connection (GdaThreadWrapper *wrapper, const GdaDsnInfo *cncinfo, GError **error)
 {
 	
 	GdaDsnInfo *info;
 	guint cncid;
 
-	if (!wrapper)
-		wrapper = gda_thread_wrapper_new ();
-
 	info = g_new0 (GdaDsnInfo, 1);
 	if (cncinfo->name)
 		info->name = g_strdup (cncinfo->name);
@@ -376,6 +374,7 @@ real_open_connection (const GdaDsnInfo *cncinfo, GError **error)
 	data.error = error;
 	data.loop = loop;
 	data.cnc = NULL;
+	data.wrapper = wrapper;
 
 	g_timeout_add (200, (GSourceFunc) check_for_cnc, &data);
 	g_main_loop_run (loop);
diff --git a/tools/browser/support.c b/tools/browser/support.c
index 6ca1d37..a156f73 100644
--- a/tools/browser/support.c
+++ b/tools/browser/support.c
@@ -56,6 +56,7 @@ browser_connection_open (GError **error)
 		browser_core_take_window (nbwin);
 		browser_core_take_connection (bcnc);
 	}
+	gtk_widget_destroy (GTK_WIDGET (dialog));
 	return bcnc;
 }
 



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