[libgda/LIBGDA_4.0] SQLite provider: better BLOB handling regarding transactions
- From: Vivien Malerba <vivien src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.0] SQLite provider: better BLOB handling regarding transactions
- Date: Tue, 29 Sep 2009 19:33:25 +0000 (UTC)
commit cfdadb54200e6098cd938d3ba93b3cf428c3a41c
Author: Vivien Malerba <malerba gnome-db org>
Date: Tue Sep 22 21:41:06 2009 +0200
SQLite provider: better BLOB handling regarding transactions
Start a transaction before reading any BLOB from an SQLite
database, and don't start a transaction when using a BLOB as a
variable
libgda/sqlite/gda-sqlite-blob-op.c | 27 +++++++++++++-
libgda/sqlite/gda-sqlite-blob-op.h | 5 ++-
libgda/sqlite/gda-sqlite-provider.c | 64 ++++++++++-------------------------
libgda/sqlite/gda-sqlite.h | 3 +-
4 files changed, 48 insertions(+), 51 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-blob-op.c b/libgda/sqlite/gda-sqlite-blob-op.c
index ceaa4b1..9ae0e8f 100644
--- a/libgda/sqlite/gda-sqlite-blob-op.c
+++ b/libgda/sqlite/gda-sqlite-blob-op.c
@@ -110,15 +110,33 @@ 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,
- const gchar *column_name, sqlite3_int64 rowid)
+_gda_sqlite_blob_op_new (SqliteConnectionData *cdata,
+ const gchar *db_name, const gchar *table_name,
+ const gchar *column_name, sqlite3_int64 rowid)
{
GdaSqliteBlobOp *bop = NULL;
int rc;
sqlite3_blob *sblob;
gchar *db, *table;
gboolean free_strings = TRUE;
+ gboolean transaction_started = FALSE;
g_return_val_if_fail (table_name, NULL);
g_return_val_if_fail (column_name, NULL);
@@ -131,11 +149,16 @@ _gda_sqlite_blob_op_new (SqliteConnectionData *cdata, const gchar *db_name, cons
else if (! _split_identifier_string (g_strdup (table_name), &db, &table))
return NULL;
+ if (! check_transaction_started (cdata->gdacnc, &transaction_started))
+ return NULL;
+
rc = sqlite3_blob_open (cdata->connection, db ? db : "main", table, column_name, rowid,
1, /* Read & Write */
&(sblob));
if (rc != SQLITE_OK) {
/*g_print ("ERROR: %s\n", sqlite3_errmsg (cdata->connection));*/
+ if (transaction_started)
+ gda_connection_rollback_transaction (cdata->gdacnc, NULL, NULL);
goto out;
}
diff --git a/libgda/sqlite/gda-sqlite-blob-op.h b/libgda/sqlite/gda-sqlite-blob-op.h
index 48d6aca..306bb2c 100644
--- a/libgda/sqlite/gda-sqlite-blob-op.h
+++ b/libgda/sqlite/gda-sqlite-blob-op.h
@@ -47,8 +47,9 @@ struct _GdaSqliteBlobOpClass {
};
GType _gda_sqlite_blob_op_get_type (void) G_GNUC_CONST;
-GdaBlobOp *_gda_sqlite_blob_op_new (SqliteConnectionData *cdata, const gchar *db_name, const gchar *table_name,
- const gchar *column_name, sqlite3_int64 rowid);
+GdaBlobOp *_gda_sqlite_blob_op_new (SqliteConnectionData *cdata,
+ const gchar *db_name, const gchar *table_name,
+ const gchar *column_name, sqlite3_int64 rowid);
G_END_DECLS
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index aba7563..62fc831 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -610,6 +610,8 @@ gda_sqlite_provider_open_connection (GdaServerProvider *provider, GdaConnection
}
cdata = g_new0 (SqliteConnectionData, 1);
+ cdata->gdacnc = cnc;
+ g_object_add_weak_pointer (G_OBJECT (cnc), (gpointer*) &(cdata->gdacnc));
if (filename)
cdata->file = filename;
@@ -1023,6 +1025,7 @@ gda_sqlite_provider_begin_transaction (GdaServerProvider *provider, GdaConnectio
status = FALSE;
}
+ /*g_print ("%s(%p) => %s\n", __FUNCTION__, cnc, status ? "TRUE" : "FALSE");*/
return status;
}
@@ -1057,6 +1060,7 @@ gda_sqlite_provider_commit_transaction (GdaServerProvider *provider, GdaConnecti
status = FALSE;
}
+ /*g_print ("%s(%p) => %s\n", __FUNCTION__, cnc, status ? "TRUE" : "FALSE");*/
return status;
}
@@ -1092,6 +1096,7 @@ gda_sqlite_provider_rollback_transaction (GdaServerProvider *provider,
status = FALSE;
}
+ /*g_print ("%s(%p) => %s\n", __FUNCTION__, cnc, status ? "TRUE" : "FALSE");*/
return status;
}
@@ -2103,23 +2108,6 @@ fill_blob_data (GdaConnection *cnc, GdaSet *params,
return NULL;
}
-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;
-}
-
-
/*
* Execute statement request
*/
@@ -2257,7 +2245,6 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
GdaConnectionEvent *event = NULL;
int i;
GSList *blobs_list = NULL; /* list of PendingBlob structures */
- gboolean transaction_started = FALSE;
for (i = 1, list = _GDA_PSTMT (ps)->param_ids; list; list = list->next, i++) {
const gchar *pname = (gchar *) list->data;
@@ -2354,21 +2341,16 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
GdaBlob *blob = (GdaBlob*) gda_value_get_blob (value);
const gchar *str = NULL;
- /* Start a transaction if necessary */
- if (!check_transaction_started (cnc, &transaction_started))
- str = _("Cannot start transaction");
- else {
- /* force reading the complete BLOB into memory */
- if (blob->op)
- blob_len = gda_blob_op_get_length (blob->op);
- else
- blob_len = ((GdaBinary*) blob)->binary_length;
- if (blob_len < 0)
- str = _("Can't get BLOB's length");
- else if (blob_len >= G_MAXINT)
- str = _("BLOB is too big");
- }
-
+ /* force reading the complete BLOB into memory */
+ if (blob->op)
+ blob_len = gda_blob_op_get_length (blob->op);
+ else
+ blob_len = ((GdaBinary*) blob)->binary_length;
+ if (blob_len < 0)
+ str = _("Can't get BLOB's length");
+ else if (blob_len >= G_MAXINT)
+ str = _("BLOB is too big");
+
if (str) {
event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
gda_connection_event_set_description (event, str);
@@ -2465,8 +2447,6 @@ 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 (cnc, NULL, NULL);
return NULL;
}
@@ -2496,8 +2476,6 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
if (allow_noparam)
g_object_set (data_model, "auto-reset", TRUE, NULL);
pending_blobs_free_list (blobs_list);
- if (transaction_started)
- gda_connection_commit_transaction (cnc, NULL, NULL);
return data_model;
}
else {
@@ -2521,8 +2499,6 @@ 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 (cnc, NULL, NULL);
return NULL;
}
else {
@@ -2532,8 +2508,6 @@ 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 (cnc, NULL, NULL);
return NULL;
}
}
@@ -2545,8 +2519,6 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
sqlite3_reset (ps->sqlite_stmt);
if (new_ps)
g_object_unref (ps);
- if (transaction_started)
- gda_connection_rollback_transaction (cnc, NULL, NULL);
return NULL;
}
@@ -2588,8 +2560,6 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
sqlite3_reset (ps->sqlite_stmt);
if (new_ps)
g_object_unref (ps);
- if (transaction_started)
- gda_connection_commit_transaction (cnc, NULL, NULL);
return set;
}
}
@@ -2803,7 +2773,9 @@ gda_sqlite_free_cnc_data (SqliteConnectionData *cdata)
{
if (!cdata)
return;
-
+
+ if (cdata->gdacnc)
+ g_object_remove_weak_pointer (G_OBJECT (cdata->gdacnc), (gpointer*) &(cdata->gdacnc));
if (cdata->connection)
sqlite3_close (cdata->connection);
g_free (cdata->file);
diff --git a/libgda/sqlite/gda-sqlite.h b/libgda/sqlite/gda-sqlite.h
index c9f3237..30aa7c2 100644
--- a/libgda/sqlite/gda-sqlite.h
+++ b/libgda/sqlite/gda-sqlite.h
@@ -1,5 +1,5 @@
/* GDA SQLite provider
- * Copyright (C) 1998 - 2008 The GNOME Foundation.
+ * Copyright (C) 1998 - 2009 The GNOME Foundation.
*
* AUTHORS:
* Rodrigo Moya <rodrigo gnome-db org>
@@ -41,6 +41,7 @@
* Provider's specific connection data
*/
typedef struct {
+ GdaConnection *gdacnc;
sqlite3 *connection;
gchar *file;
GHashTable *types; /* key = type name, value = GType */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]