[libgda] GdaBrowser: handle transactions



commit 2a33fe89dbc40bfe68240815145b4c0d9ddceb7b
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Sep 13 15:17:14 2009 +0200

    GdaBrowser: handle transactions

 tools/browser/browser-connection.c                 |   69 ++++++++++-
 tools/browser/browser-connection.h                 |   11 ++-
 tools/browser/browser-stock-icons.c                |    5 +-
 tools/browser/browser-stock-icons.h                |    3 +
 tools/browser/data/Makefile.am                     |    3 +
 .../hicolor_actions_24x24_transaction-begin.png    |  Bin 0 -> 1046 bytes
 .../hicolor_actions_24x24_transaction-commit.png   |  Bin 0 -> 1153 bytes
 .../hicolor_actions_24x24_transaction-rollback.png |  Bin 0 -> 904 bytes
 tools/browser/doc/gda-browser-sections.txt         |    4 +
 tools/browser/doc/tmpl/browser-connection.sgml     |    9 ++
 tools/browser/main.c                               |    1 +
 tools/browser/query-exec/query-exec-perspective.c  |  131 ++++++++++++++++++--
 12 files changed, 224 insertions(+), 12 deletions(-)
---
diff --git a/tools/browser/browser-connection.c b/tools/browser/browser-connection.c
index 6deda85..b29fe04 100644
--- a/tools/browser/browser-connection.c
+++ b/tools/browser/browser-connection.c
@@ -113,10 +113,11 @@ enum {
 	BUSY,
 	META_CHANGED,
 	FAV_CHANGED,
+	TRANSACTION_STATUS_CHANGED,
 	LAST_SIGNAL
 };
 
-gint browser_connection_signals [LAST_SIGNAL] = { 0, 0, 0 };
+gint browser_connection_signals [LAST_SIGNAL] = { 0, 0, 0, 0 };
 
 GType
 browser_connection_get_type (void)
@@ -176,10 +177,19 @@ browser_connection_class_init (BrowserConnectionClass *klass)
                               NULL, NULL,
                               g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
                               0);
+	browser_connection_signals [TRANSACTION_STATUS_CHANGED] =
+		g_signal_new ("transaction-status-changed",
+                              G_TYPE_FROM_CLASS (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (BrowserConnectionClass, transaction_status_changed),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
+                              0);
 
 	klass->busy = NULL;
 	klass->meta_changed = NULL;
 	klass->favorites_changed = NULL;
+	klass->transaction_status_changed = NULL;
 
 	object_class->dispose = browser_connection_dispose;
 }
@@ -231,6 +241,12 @@ fav_changed_cb (BrowserFavorites *bfav, BrowserConnection *bcnc)
 }
 
 static void
+transaction_status_changed_cb (GdaConnection *cnc, BrowserConnection *bcnc)
+{
+	g_signal_emit (bcnc, browser_connection_signals [TRANSACTION_STATUS_CHANGED], 0);
+}
+
+static void
 browser_connection_dispose (GObject *object)
 {
 	BrowserConnection *bcnc;
@@ -260,8 +276,12 @@ browser_connection_dispose (GObject *object)
 			g_object_unref (bcnc->priv->p_mstruct);
 		if (bcnc->priv->p_mstruct_mutex)
 			g_mutex_free (bcnc->priv->p_mstruct_mutex);
-		if (bcnc->priv->cnc)
+		if (bcnc->priv->cnc) {
+			g_signal_handlers_disconnect_by_func (bcnc->priv->cnc,
+							      G_CALLBACK (transaction_status_changed_cb),
+							      bcnc);
 			g_object_unref (bcnc->priv->cnc);
+		}
 		if (bcnc->priv->parser)
 			g_object_unref (bcnc->priv->parser);
 		if (bcnc->priv->variables) {
@@ -411,6 +431,8 @@ browser_connection_new (GdaConnection *cnc)
 
 	bcnc = BROWSER_CONNECTION (g_object_new (BROWSER_TYPE_CONNECTION, NULL));
 	bcnc->priv->cnc = g_object_ref (cnc);
+	g_signal_connect (cnc, "transaction-status-changed",
+			  G_CALLBACK (transaction_status_changed_cb), bcnc);
 
 	/* meta store */
 	gchar *dict_file_name = NULL;
@@ -650,6 +672,49 @@ browser_connection_get_transaction_status (BrowserConnection *bcnc)
 }
 
 /**
+ * browser_connection_begin
+ * @bcnc: a #BrowserConnection
+ * @error: a place to store errors, or %NULL
+ *
+ * Begins a transaction
+ */
+gboolean
+browser_connection_begin (BrowserConnection *bcnc, GError **error)
+{
+	g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), FALSE);
+	return gda_connection_begin_transaction (bcnc->priv->cnc, NULL,
+						 GDA_TRANSACTION_ISOLATION_UNKNOWN, error);
+}
+
+/**
+ * browser_connection_commit
+ * @bcnc: a #BrowserConnection
+ * @error: a place to store errors, or %NULL
+ *
+ * Commits a transaction
+ */
+gboolean
+browser_connection_commit (BrowserConnection *bcnc, GError **error)
+{
+	g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), FALSE);
+	return gda_connection_commit_transaction (bcnc->priv->cnc, NULL, error);
+}
+
+/**
+ * browser_connection_rollback
+ * @bcnc: a #BrowserConnection
+ * @error: a place to store errors, or %NULL
+ *
+ * Rolls back a transaction
+ */
+gboolean
+browser_connection_rollback (BrowserConnection *bcnc, GError **error)
+{
+	g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), FALSE);
+	return gda_connection_rollback_transaction (bcnc->priv->cnc, NULL, error);
+}
+
+/**
  * browser_connection_get_favorites
  * @bcnc: a #BrowserConnection
  *
diff --git a/tools/browser/browser-connection.h b/tools/browser/browser-connection.h
index 90a51df..e351106 100644
--- a/tools/browser/browser-connection.h
+++ b/tools/browser/browser-connection.h
@@ -51,6 +51,7 @@ struct _BrowserConnectionClass
 	void                    (*busy) (BrowserConnection *bcnc, gboolean is_busy, const gchar *reason);
 	void                    (*meta_changed) (BrowserConnection *bcnc, GdaMetaStruct *mstruct);
 	void                    (*favorites_changed) (BrowserConnection *bcnc);
+	void                    (*transaction_status_changed) (BrowserConnection *bcnc);
 };
 
 GType               browser_connection_get_type               (void) G_GNUC_CONST;
@@ -64,7 +65,6 @@ void                browser_connection_update_meta_data       (BrowserConnection
 GdaMetaStruct      *browser_connection_get_meta_struct        (BrowserConnection *bcnc);
 GdaMetaStore       *browser_connection_get_meta_store         (BrowserConnection *bcnc);
 const gchar        *browser_connection_get_dictionary_file    (BrowserConnection *bcnc);
-GdaTransactionStatus *browser_connection_get_transaction_status (BrowserConnection *bcnc);
 
 BrowserFavorites   *browser_connection_get_favorites          (BrowserConnection *bcnc);
 
@@ -84,6 +84,15 @@ GObject            *browser_connection_execution_get_result   (BrowserConnection
 							       guint exec_id,
 							       GdaSet **last_insert_row, GError **error);
 
+/*
+ * transactions
+ */
+GdaTransactionStatus *browser_connection_get_transaction_status (BrowserConnection *bcnc);
+gboolean              browser_connection_begin (BrowserConnection *bcnc, GError **error);
+gboolean              browser_connection_commit (BrowserConnection *bcnc, GError **error);
+gboolean              browser_connection_rollback (BrowserConnection *bcnc, GError **error);
+
+
 G_END_DECLS
 
 #endif
diff --git a/tools/browser/browser-stock-icons.c b/tools/browser/browser-stock-icons.c
index ad31171..5ba962d 100644
--- a/tools/browser/browser-stock-icons.c
+++ b/tools/browser/browser-stock-icons.c
@@ -42,8 +42,11 @@ browser_stock_icons_init (void)
 
 	static const GtkStockItem items[] =
 	{
-		{ BROWSER_STOCK_HISTORY,	N_("History"),		0, 0, NULL },
+		{ BROWSER_STOCK_HISTORY,   N_("History"),		0, 0, NULL },
 		{ BROWSER_STOCK_BOOKMARKS, N_("Bookmarks"),	0, 0, NULL },
+		{ BROWSER_STOCK_BEGIN, N_("Begin"),	0, 0, NULL },
+		{ BROWSER_STOCK_COMMIT, N_("Commit"),	0, 0, NULL },
+		{ BROWSER_STOCK_ROLLBACK, N_("Rollback"),	0, 0, NULL },
 	};
 
 	factory = gtk_icon_factory_new ();
diff --git a/tools/browser/browser-stock-icons.h b/tools/browser/browser-stock-icons.h
index 0691e94..2ade8cf 100644
--- a/tools/browser/browser-stock-icons.h
+++ b/tools/browser/browser-stock-icons.h
@@ -24,6 +24,9 @@ G_BEGIN_DECLS
 
 #define BROWSER_STOCK_HISTORY         "history-view"
 #define BROWSER_STOCK_BOOKMARKS       "bookmark-view"
+#define BROWSER_STOCK_BEGIN           "transaction-begin"
+#define BROWSER_STOCK_COMMIT          "transaction-commit"
+#define BROWSER_STOCK_ROLLBACK        "transaction-rollback"
 
 /* Named icons defined in fd.o Icon Naming Spec */
 #define STOCK_NEW_WINDOW           "window-new"
diff --git a/tools/browser/data/Makefile.am b/tools/browser/data/Makefile.am
index d8fc4ab..675f0ca 100644
--- a/tools/browser/data/Makefile.am
+++ b/tools/browser/data/Makefile.am
@@ -14,6 +14,9 @@ private_icons = \
 	hicolor_actions_22x22_history-view.png \
 	hicolor_actions_24x24_bookmark-view.png \
 	hicolor_actions_24x24_history-view.png \
+	hicolor_actions_24x24_transaction-begin.png \
+	hicolor_actions_24x24_transaction-commit.png \
+	hicolor_actions_24x24_transaction-rollback.png \
 	hicolor_actions_32x32_bookmark-view.png \
 	hicolor_actions_32x32_history-view.png \
 	hicolor_actions_scalable_bookmark-view.svg \
diff --git a/tools/browser/data/hicolor_actions_24x24_transaction-begin.png b/tools/browser/data/hicolor_actions_24x24_transaction-begin.png
new file mode 100644
index 0000000..b552ca3
Binary files /dev/null and b/tools/browser/data/hicolor_actions_24x24_transaction-begin.png differ
diff --git a/tools/browser/data/hicolor_actions_24x24_transaction-commit.png b/tools/browser/data/hicolor_actions_24x24_transaction-commit.png
new file mode 100644
index 0000000..76bf2f7
Binary files /dev/null and b/tools/browser/data/hicolor_actions_24x24_transaction-commit.png differ
diff --git a/tools/browser/data/hicolor_actions_24x24_transaction-rollback.png b/tools/browser/data/hicolor_actions_24x24_transaction-rollback.png
new file mode 100644
index 0000000..4681dcf
Binary files /dev/null and b/tools/browser/data/hicolor_actions_24x24_transaction-rollback.png differ
diff --git a/tools/browser/doc/gda-browser-sections.txt b/tools/browser/doc/gda-browser-sections.txt
index 678f2a8..873089f 100644
--- a/tools/browser/doc/gda-browser-sections.txt
+++ b/tools/browser/doc/gda-browser-sections.txt
@@ -154,6 +154,10 @@ browser_connection_create_parser
 browser_connection_render_pretty_sql
 browser_connection_execute_statement
 browser_connection_execution_get_result
+<SUBSECTION>
+browser_connection_begin
+browser_connection_commit
+browser_connection_rollback
 browser_connection_get_transaction_status
 <SUBSECTION Standard>
 BROWSER_CONNECTION
diff --git a/tools/browser/doc/tmpl/browser-connection.sgml b/tools/browser/doc/tmpl/browser-connection.sgml
index a2578cb..b5119d0 100644
--- a/tools/browser/doc/tmpl/browser-connection.sgml
+++ b/tools/browser/doc/tmpl/browser-connection.sgml
@@ -189,3 +189,12 @@ An opened connection
 @Returns: 
 
 
+<!-- ##### FUNCTION browser_connection_get_transaction_status ##### -->
+<para>
+
+</para>
+
+ bcnc: 
+ Returns: 
+
+
diff --git a/tools/browser/main.c b/tools/browser/main.c
index ab9e4d1..00b81bf 100644
--- a/tools/browser/main.c
+++ b/tools/browser/main.c
@@ -138,6 +138,7 @@ main (int argc, char *argv[])
 		}
 	}
 	
+	g_print ("Main THREAD is %p\n", g_thread_self ());
 	if (have_loop)
 		/* application loop */
 		gtk_main ();
diff --git a/tools/browser/query-exec/query-exec-perspective.c b/tools/browser/query-exec/query-exec-perspective.c
index bca6a1b..76649e0 100644
--- a/tools/browser/query-exec/query-exec-perspective.c
+++ b/tools/browser/query-exec/query-exec-perspective.c
@@ -45,6 +45,9 @@ static GObjectClass  *parent_class = NULL;
 struct _QueryExecPerspectivePrivate {
 	GtkWidget *notebook;
 	BrowserWindow *bwin;
+	
+	GtkActionGroup *action_group;
+	gboolean updating_transaction_status;
 };
 
 GType
@@ -104,6 +107,7 @@ static void
 query_exec_perspective_init (QueryExecPerspective *perspective)
 {
 	perspective->priv = g_new0 (QueryExecPerspectivePrivate, 1);
+	perspective->priv->action_group = NULL;
 }
 
 static void nb_switch_page_cb (GtkNotebook *nb, GtkNotebookPage *page, gint page_num,
@@ -112,6 +116,8 @@ static void nb_page_removed_cb (GtkNotebook *nb, GtkNotebookPage *page, gint pag
 			       QueryExecPerspective *perspective);
 static void close_button_clicked_cb (GtkWidget *wid, GtkWidget *page_widget);
 
+static void transaction_status_changed_cb (BrowserConnection *bcnc, QueryExecPerspective *perspective);
+
 /**
  * query_exec_perspective_new
  *
@@ -170,6 +176,10 @@ query_exec_perspective_new (BrowserWindow *bwin)
 	gtk_box_pack_start (GTK_BOX (bpers), paned, TRUE, TRUE, 0);
 	gtk_widget_show_all (paned);
 
+	/* transaction status detection */
+	g_signal_connect (bcnc, "transaction-status-changed",
+			  G_CALLBACK (transaction_status_changed_cb), bpers);
+
 	return bpers;
 }
 
@@ -220,6 +230,9 @@ query_exec_perspective_dispose (GObject *object)
 
 	perspective = QUERY_EXEC_PERSPECTIVE (object);
 	if (perspective->priv) {
+		if (perspective->priv->action_group)
+			g_object_unref (perspective->priv->action_group);
+
 		g_signal_handlers_disconnect_by_func (perspective->priv->notebook,
 						      G_CALLBACK (nb_page_removed_cb), perspective);
 		g_free (perspective->priv);
@@ -259,10 +272,98 @@ query_exec_add_cb (GtkAction *action, BrowserPerspective *bpers)
 	gtk_notebook_set_menu_label (GTK_NOTEBOOK (perspective->priv->notebook), page, tlabel);
 }
 
+static void
+transaction_status_changed_cb (BrowserConnection *bcnc, QueryExecPerspective *perspective)
+{
+	if (!perspective->priv->action_group)
+		return;
+
+	GtkAction *action;
+	gboolean trans_started;
+
+	trans_started = browser_connection_get_transaction_status (bcnc) ? TRUE : FALSE;
+	perspective->priv->updating_transaction_status = TRUE;
+
+	action = gtk_action_group_get_action (perspective->priv->action_group, "QueryExecBegin");
+	gtk_action_set_sensitive (action, !trans_started);
+
+	action = gtk_action_group_get_action (perspective->priv->action_group, "QueryExecCommit");
+	gtk_action_set_sensitive (action, trans_started);
+
+	action = gtk_action_group_get_action (perspective->priv->action_group, "QueryExecRollback");
+	gtk_action_set_sensitive (action, trans_started);
+				      
+	perspective->priv->updating_transaction_status = FALSE;
+}
+
+static void
+transaction_begin_cb (GtkAction *action, BrowserPerspective *bpers)
+{
+	QueryExecPerspective *perspective;
+	BrowserConnection *bcnc;
+
+	perspective = QUERY_EXEC_PERSPECTIVE (bpers);
+	bcnc = browser_window_get_connection (perspective->priv->bwin);
+	if (!perspective->priv->updating_transaction_status) {
+		GError *error = NULL;
+		if (! browser_connection_begin (bcnc, &error)) {
+			browser_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) bpers)),
+					    _("Error starting transaction: %s"),
+					    error && error->message ? error->message : _("No detail"));
+			g_clear_error (&error);
+		}
+	}
+}
+
+static void
+transaction_commit_cb (GtkAction *action, BrowserPerspective *bpers)
+{
+	QueryExecPerspective *perspective;
+	BrowserConnection *bcnc;
+
+	perspective = QUERY_EXEC_PERSPECTIVE (bpers);
+	bcnc = browser_window_get_connection (perspective->priv->bwin);
+	if (!perspective->priv->updating_transaction_status) {
+		GError *error = NULL;
+		if (! browser_connection_commit (bcnc, &error)) {
+			browser_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) bpers)),
+					    _("Error committing transaction: %s"),
+					    error && error->message ? error->message : _("No detail"));
+			g_clear_error (&error);
+		}
+	}
+}
+
+static void
+transaction_rollback_cb (GtkAction *action, BrowserPerspective *bpers)
+{
+	QueryExecPerspective *perspective;
+	BrowserConnection *bcnc;
+
+	perspective = QUERY_EXEC_PERSPECTIVE (bpers);
+	bcnc = browser_window_get_connection (perspective->priv->bwin);
+	if (!perspective->priv->updating_transaction_status) {
+		GError *error = NULL;
+		if (! browser_connection_rollback (bcnc, &error)) {
+			browser_show_error (GTK_WINDOW (gtk_widget_get_toplevel ((GtkWidget*) bpers)),
+					    _("Error rolling back transaction: %s"),
+					    error && error->message ? error->message : _("No detail"));
+			g_clear_error (&error);
+		}
+	}
+}
+
 static GtkActionEntry ui_actions[] = {
-        { "QueryExecMenu", NULL, "_Query", NULL, "QueryExecMenu", NULL },
-        { "QueryExecItem1", STOCK_CONSOLE, "_New editor", NULL, "Open a new query editor",
+        { "QueryExecMenu", NULL, N_("_Query"), NULL, "QueryExecMenu", NULL },
+        { "QueryExecItem1", STOCK_CONSOLE, N_("_New editor"), NULL, N_("Open a new query editor"),
           G_CALLBACK (query_exec_add_cb)},
+        { "QueryExecBegin", BROWSER_STOCK_BEGIN, N_("_Begin"), NULL, N_("Begin a new transaction"),
+          G_CALLBACK (transaction_begin_cb)},
+        { "QueryExecCommit", BROWSER_STOCK_COMMIT, N_("_Commit"), NULL, N_("Commit current transaction"),
+          G_CALLBACK (transaction_commit_cb)},
+        { "QueryExecRollback", BROWSER_STOCK_ROLLBACK, N_("_Rollback"), NULL, N_("Rollback current transaction"),
+          G_CALLBACK (transaction_rollback_cb)},
+
 };
 
 static const gchar *ui_actions_info =
@@ -271,27 +372,41 @@ static const gchar *ui_actions_info =
 	"    <placeholder name='MenuExtension'>"
         "      <menu name='QueryExec' action='QueryExecMenu'>"
         "        <menuitem name='QueryExecItem1' action= 'QueryExecItem1'/>"
+        "        <menuitem name='QueryExecBegin' action= 'QueryExecBegin'/>"
+        "        <menuitem name='QueryExecCommit' action= 'QueryExecCommit'/>"
+        "        <menuitem name='QueryExecRollback' action= 'QueryExecRollback'/>"
         "      </menu>"
 	"    </placeholder>"
         "  </menubar>"
         "  <toolbar name='ToolBar'>"
         "    <separator/>"
         "    <toolitem action='QueryExecItem1'/>"
+        "    <toolitem action='QueryExecBegin'/>"
+        "    <toolitem action='QueryExecCommit'/>"
+        "    <toolitem action='QueryExecRollback'/>"
         "  </toolbar>"
         "</ui>";
 
 static GtkActionGroup *
-query_exec_perspective_get_actions_group (BrowserPerspective *bpers)
+query_exec_perspective_get_actions_group (BrowserPerspective *perspective)
 {
-	GtkActionGroup *agroup;
-	agroup = gtk_action_group_new ("QueryExecActions");
-	gtk_action_group_add_actions (agroup, ui_actions, G_N_ELEMENTS (ui_actions), bpers);
+	QueryExecPerspective *bpers;
+	bpers = QUERY_EXEC_PERSPECTIVE (perspective);
+
+	if (!bpers->priv->action_group) {
+		GtkActionGroup *agroup;
+		agroup = gtk_action_group_new ("QueryExecActions");
+		gtk_action_group_add_actions (agroup, ui_actions, G_N_ELEMENTS (ui_actions), bpers);
+		bpers->priv->action_group = g_object_ref (agroup);
+	}
 	
-	return agroup;
+	transaction_status_changed_cb (browser_window_get_connection (bpers->priv->bwin), bpers);
+
+	return bpers->priv->action_group;
 }
 
 static const gchar *
-query_exec_perspective_get_actions_ui (BrowserPerspective *bpers)
+query_exec_perspective_get_actions_ui (BrowserPerspective *perspective)
 {
 	return ui_actions_info;
 }



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