[libgda] SQLite: don't leave a transaction started when inserting a BLOB



commit 5668d3ad8245598cc2c2747af6594121fbca4227
Author: Vivien Malerba <malerba gnome-db org>
Date:   Fri Sep 17 18:52:41 2010 +0200

    SQLite: don't leave a transaction started when inserting a BLOB

 libgda/sqlite/gda-sqlite-blob-op.c  |   19 ++-----------------
 libgda/sqlite/gda-sqlite-provider.c |   34 ++++++++++++++++++++++++++++++++++
 libgda/sqlite/gda-sqlite-util.c     |   16 ++++++++++++++++
 libgda/sqlite/gda-sqlite-util.h     |    2 ++
 4 files changed, 54 insertions(+), 17 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-blob-op.c b/libgda/sqlite/gda-sqlite-blob-op.c
index 24d7b3f..77afc11 100644
--- a/libgda/sqlite/gda-sqlite-blob-op.c
+++ b/libgda/sqlite/gda-sqlite-blob-op.c
@@ -25,6 +25,7 @@
 #include <libgda/libgda.h>
 #include "gda-sqlite.h"
 #include "gda-sqlite-blob-op.h"
+#include "gda-sqlite-util.h"
 #include <sql-parser/gda-sql-parser.h>
 
 struct _GdaSqliteBlobOpPrivate {
@@ -114,22 +115,6 @@ gda_sqlite_blob_op_finalize (GObject * object)
 	parent_class->finalize (object);
 }
 
-static gboolean
-check_transaction_started (GdaConnection *cnc, gboolean *out_started)
-{
-        GdaTransactionStatus *trans;
-
-        trans = gda_connection_get_transaction_status (cnc);
-        if (!trans) {
-		if (!gda_connection_begin_transaction (cnc, NULL,
-						       GDA_TRANSACTION_ISOLATION_UNKNOWN, NULL))
-			return FALSE;
-		else
-			*out_started = TRUE;
-	}
-	return TRUE;
-}
-
 GdaBlobOp *
 _gda_sqlite_blob_op_new (SqliteConnectionData *cdata,
 			 const gchar *db_name, const gchar *table_name,
@@ -153,7 +138,7 @@ _gda_sqlite_blob_op_new (SqliteConnectionData *cdata,
 	else if (! _split_identifier_string (g_strdup (table_name), &db, &table))
 		return NULL;
 
-	if (! check_transaction_started (cdata->gdacnc, &transaction_started))
+	if (! _gda_sqlite_check_transaction_started (cdata->gdacnc, &transaction_started, NULL))
 		return NULL;
 
 	rc = SQLITE3_CALL (sqlite3_blob_open) (cdata->connection, db ? db : "main",
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 8259188..0f03de0 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -2752,6 +2752,32 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 	else {
                 int status, changes;
                 sqlite3 *handle;
+		gboolean transaction_started = FALSE;
+
+		if (blobs_list) {
+			GError *lerror = NULL;
+			if (! _gda_sqlite_check_transaction_started (cdata->gdacnc,
+								     &transaction_started, &lerror)) {
+				const gchar *errmsg = _("Could not start transaction to create BLOB");
+				event = gda_connection_point_available_event (cnc,
+									      GDA_CONNECTION_EVENT_ERROR);
+				if (lerror) {
+					gda_connection_event_set_description (event,
+									      lerror && lerror->message ?
+									      lerror->message : errmsg);
+					g_propagate_error (error, lerror);
+				}
+				else {
+					gda_connection_event_set_description (event, errmsg);
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+						     GDA_SERVER_PROVIDER_STATEMENT_EXEC_ERROR, "%s", errmsg);
+				}
+				if (new_ps)
+					g_object_unref (ps);
+				pending_blobs_free_list (blobs_list);
+				return NULL;
+			}
+		}
 
                 /* actually execute the command */
                 handle = SQLITE3_CALL (sqlite3_db_handle) (ps->sqlite_stmt);
@@ -2770,6 +2796,8 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 				if (new_ps)
 					g_object_unref (ps);
 				pending_blobs_free_list (blobs_list);
+				if (transaction_started)
+					gda_connection_rollback_transaction (cdata->gdacnc, NULL, NULL);
 				return NULL;
                         }
 			else {
@@ -2779,6 +2807,8 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 				if (new_ps)
 					g_object_unref (ps);
 				pending_blobs_free_list (blobs_list);
+				if (transaction_started)
+					gda_connection_rollback_transaction (cdata->gdacnc, NULL, NULL);
 				return NULL;
 			}
                 }
@@ -2790,8 +2820,12 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 				SQLITE3_CALL (sqlite3_reset) (ps->sqlite_stmt);
 				if (new_ps)
 					g_object_unref (ps);
+				if (transaction_started)
+					gda_connection_rollback_transaction (cdata->gdacnc, NULL, NULL);
 				return NULL;
 			}
+			else if (transaction_started)
+				gda_connection_commit_transaction (cdata->gdacnc, NULL, NULL);
 			
 			gchar *str = NULL;
 			gboolean count_changes = FALSE;
diff --git a/libgda/sqlite/gda-sqlite-util.c b/libgda/sqlite/gda-sqlite-util.c
index 567e89a..64045c5 100644
--- a/libgda/sqlite/gda-sqlite-util.c
+++ b/libgda/sqlite/gda-sqlite-util.c
@@ -297,3 +297,19 @@ _gda_sqlite_identifier_quote (GdaServerProvider *provider, GdaConnection *cnc,
 		return g_strdup (id);
 	}
 }
+
+gboolean
+_gda_sqlite_check_transaction_started (GdaConnection *cnc, gboolean *out_started, GError **error)
+{
+	GdaTransactionStatus *trans;
+
+        trans = gda_connection_get_transaction_status (cnc);
+        if (!trans) {
+		if (!gda_connection_begin_transaction (cnc, NULL,
+						       GDA_TRANSACTION_ISOLATION_UNKNOWN, error))
+			return FALSE;
+		else
+			*out_started = TRUE;
+	}
+	return TRUE;
+}
diff --git a/libgda/sqlite/gda-sqlite-util.h b/libgda/sqlite/gda-sqlite-util.h
index 65be387..beea627 100644
--- a/libgda/sqlite/gda-sqlite-util.h
+++ b/libgda/sqlite/gda-sqlite-util.h
@@ -38,6 +38,8 @@ gchar                     *_gda_sqlite_identifier_quote          (GdaServerProvi
 								  const gchar *id,
 								  gboolean meta_store_convention, gboolean force_quotes);
 
+gboolean _gda_sqlite_check_transaction_started (GdaConnection *cnc, gboolean *out_started, GError **error);
+
 G_END_DECLS
 
 #endif



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