[libgda] GdaBrowser: basic support for virtual connections



commit eac9c0ad7e076a0564b185dbacacac2cfed68f5e
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Oct 12 21:07:59 2009 +0200

    GdaBrowser: basic support for virtual connections

 tools/browser/Makefile.am                |    1 +
 tools/browser/browser-connection.c       |  117 ++++++++++++++++++++++++++++++
 tools/browser/browser-connection.h       |    1 +
 tools/browser/browser-connections-list.c |   42 +++++++++++-
 4 files changed, 160 insertions(+), 1 deletions(-)
---
diff --git a/tools/browser/Makefile.am b/tools/browser/Makefile.am
index d8b19e5..4814fe3 100644
--- a/tools/browser/Makefile.am
+++ b/tools/browser/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS+= . doc
 AM_CPPFLAGS = \
         -I$(top_srcdir) \
         -I$(top_srcdir)/libgda \
+        -I$(top_srcdir)/libgda/sqlite \
         -I$(top_builddir) \
         $(LIBGDA_CFLAGS) \
         $(GTK_CFLAGS) \
diff --git a/tools/browser/browser-connection.c b/tools/browser/browser-connection.c
index d61fd81..d07abb3 100644
--- a/tools/browser/browser-connection.c
+++ b/tools/browser/browser-connection.c
@@ -25,6 +25,7 @@
 #include "marshal.h"
 #include <sql-parser/gda-sql-parser.h>
 #include <libgda/gda-sql-builder.h>
+#include <virtual/libgda-virtual.h>
 
 /* code inclusion */
 #include "../dict-file-name.c"
@@ -497,6 +498,122 @@ browser_connection_new (GdaConnection *cnc)
 	return bcnc;
 }
 
+static GdaThreadWrapper *wrapper = NULL;
+typedef struct {
+        guint cncid;
+        GMainLoop *loop;
+        GError **error;
+
+        /* out */
+        GdaConnection *cnc;
+} MainloopData;
+
+static gboolean
+check_for_cnc (MainloopData *data)
+{
+        GdaConnection *cnc;
+        GError *lerror = NULL;
+        cnc = gda_thread_wrapper_fetch_result (wrapper, FALSE, data->cncid, &lerror);
+        if (cnc || (!cnc && lerror)) {
+                /* waiting is finished! */
+                data->cnc = cnc;
+                if (lerror)
+                        g_propagate_error (data->error, lerror);
+                g_main_loop_quit (data->loop);
+                return FALSE;
+        }
+        return TRUE;
+}
+
+typedef struct {
+	GdaConnection *cnc_to_wrap;
+	const gchar *ns;
+} VirtualConnectionData;
+/*
+ * executed in a sub thread
+ */
+static GdaConnection *
+sub_thread_open_cnc (VirtualConnectionData *vcdata, GError **error)
+{
+#ifndef DUMMY
+	static GdaVirtualProvider *provider = NULL;
+	GdaConnection *virtual, *cnc;
+	if (!provider)
+		provider = gda_vprovider_hub_new ();
+
+	virtual = gda_virtual_connection_open_extended (provider, GDA_CONNECTION_OPTIONS_THREAD_SAFE, NULL);
+	cnc = g_object_get_data (G_OBJECT (virtual), "gda-virtual-connection");
+	if (!gda_vconnection_hub_add (GDA_VCONNECTION_HUB (cnc), vcdata->cnc_to_wrap,
+				      vcdata->ns, error)) {
+		g_object_unref (virtual);
+		return NULL;
+	}
+	else
+		return virtual;
+#else
+        sleep (5);
+        g_set_error (error, 0, 0, "Oooo");
+        return NULL;
+#endif
+}
+/**
+ * browser_connection_new_virtual
+ * @bcnc: a #BrowserConnection
+ * @ns: the namespace for @bcnc's tables
+ * @error: a place to store errors, or %NULL
+ *
+ * Creates a new virtual connection using #BrowserConnection as a starting point.
+ *
+ * To close the new connection, use browser_core_close_connection().
+ *
+ * Returns: a new object
+ */
+BrowserConnection *
+browser_connection_new_virtual (BrowserConnection *bcnc, const gchar *ns, GError **error)
+{
+	g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL);
+
+	if (!wrapper)
+                wrapper = gda_thread_wrapper_new ();
+
+	guint cncid;
+	VirtualConnectionData vcdata;
+
+	vcdata.cnc_to_wrap = bcnc->priv->cnc;
+	vcdata.ns = ns ? ns : bcnc->priv->name;
+	cncid = gda_thread_wrapper_execute (wrapper,
+                                            (GdaThreadWrapperFunc) sub_thread_open_cnc,
+                                            (gpointer) &vcdata,
+                                            (GDestroyNotify) NULL,
+                                            error);
+        if (cncid == 0)
+                return NULL;
+
+	GMainLoop *loop;
+        guint source_id;
+        MainloopData data;
+	
+        loop = g_main_loop_new (NULL, FALSE);
+	data.cncid = cncid;
+        data.error = error;
+        data.loop = loop;
+        data.cnc = NULL;
+
+        source_id = g_timeout_add (200, (GSourceFunc) check_for_cnc, &data);
+        g_main_loop_run (loop);
+        g_main_loop_unref (loop);
+
+        if (data.cnc) {
+		BrowserConnection *nbcnc;
+                g_object_set (data.cnc, "monitor-wrapped-in-mainloop", TRUE, NULL);
+		nbcnc = browser_connection_new (data.cnc);
+		g_object_unref (data.cnc);
+		return nbcnc;
+	}
+	else
+		return NULL;
+}
+
 /**
  * browser_connection_get_name
  * @bcnc: a #BrowserConnection
diff --git a/tools/browser/browser-connection.h b/tools/browser/browser-connection.h
index 7a38d03..49b3025 100644
--- a/tools/browser/browser-connection.h
+++ b/tools/browser/browser-connection.h
@@ -57,6 +57,7 @@ struct _BrowserConnectionClass
 GType               browser_connection_get_type               (void) G_GNUC_CONST;
 
 BrowserConnection  *browser_connection_new                    (GdaConnection *cnc);
+BrowserConnection  *browser_connection_new_virtual            (BrowserConnection *bcnc, const gchar *ns, GError **error);
 const gchar        *browser_connection_get_name               (BrowserConnection *bcnc);
 const GdaDsnInfo   *browser_connection_get_information        (BrowserConnection *bcnc);
 
diff --git a/tools/browser/browser-connections-list.c b/tools/browser/browser-connections-list.c
index ac455c5..28887f6 100644
--- a/tools/browser/browser-connections-list.c
+++ b/tools/browser/browser-connections-list.c
@@ -304,6 +304,35 @@ connection_new_cb (GtkButton *button, BrowserConnectionsList *clist)
 	}
 }
 
+static void
+connection_bind_cb (GtkButton *button, BrowserConnectionsList *clist)
+{
+	GtkTreeSelection *select;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	
+	select = gtk_tree_view_get_selection (clist->priv->treeview);
+	if (gtk_tree_selection_get_selected (select, &model, &iter)) {
+		BrowserConnection *bcnc, *nbcnc;
+		GError *error = NULL;
+		gtk_tree_model_get (model, &iter, COLUMN_BCNC, &bcnc, -1);
+		nbcnc = browser_connection_new_virtual (bcnc, NULL, &error);
+		if (nbcnc) {
+			BrowserWindow *nbwin;
+			nbwin = browser_window_new (nbcnc, NULL);
+			
+			browser_core_take_window (nbwin);
+			browser_core_take_connection (nbcnc);
+		}
+		else {
+			browser_show_error ((GtkWindow*) gtk_widget_get_toplevel ((GtkWidget*) clist),
+					    _("Could not open binding connection: %s"),
+					    error && error->message ? error->message : _("No detail"));
+			g_clear_error (&error);
+		}
+	}
+}
+
 /**
  * browser_connections_list_new
  *
@@ -390,12 +419,23 @@ browser_connections_list_show (void)
 		gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
 		g_signal_connect (button, "clicked",
 				  G_CALLBACK (connection_close_cb), clist);
+		gtk_widget_set_tooltip_text (button, _("Close selected connection"));
 		_clist->priv->close_cnc_button = button;
 
-		button = gtk_button_new_with_label (_("New connection"));
+		button = gtk_button_new_with_label (_("Open"));
 		gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
 		g_signal_connect (button, "clicked",
 				  G_CALLBACK (connection_new_cb), clist);
+		gtk_widget_set_tooltip_text (button, _("Open a new connection"));
+
+		button = gtk_button_new_with_label (_("Bind"));
+		gtk_box_pack_start (GTK_BOX (bbox), button, TRUE, TRUE, 0);
+		g_signal_connect (button, "clicked",
+				  G_CALLBACK (connection_bind_cb), clist);
+		gtk_widget_set_tooltip_text (button, _("Use selected connection to create\n"
+						       "a new binding connection to access data\n"
+						       "from multiple databases at once"));
+
 
 		/* GtkTreeModel and view */
 		GtkListStore *store;



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