[libgda] Fixed bug in Sqlite provider with INSERT and blobs



commit 7763c2440f4b9fa9e94563047709e400984448b2
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Sep 26 13:21:01 2010 +0200

    Fixed bug in Sqlite provider with INSERT and blobs

 libgda/sqlite/gda-sqlite-provider.c |   92 ++++++++++++++++++++++++++++++-----
 1 files changed, 80 insertions(+), 12 deletions(-)
---
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 0f03de0..da70ec0 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -57,6 +57,7 @@
 
 #define FILE_EXTENSION ".db"
 static GStaticRecMutex cnc_mutex = G_STATIC_REC_MUTEX_INIT;
+static gchar *get_table_nth_column_name (GdaConnection *cnc, const gchar *table_name, gint pos);
 
 /* TMP */
 typedef struct {
@@ -64,11 +65,12 @@ typedef struct {
 	gchar   *db;
 	gchar   *table;
 	gchar   *column;
+	gboolean free_column; /* set to %TRUE if @column has been dynamically allocated */
 	GdaBlob *blob;
 } PendingBlob;
 
 static PendingBlob*
-make_pending_blob (GdaStatement *stmt, GdaHolder *holder, GError **error)
+make_pending_blob (GdaConnection *cnc, GdaStatement *stmt, GdaHolder *holder, GError **error)
 {
 	PendingBlob *pb = NULL;
 	GdaSqlStatement *sqlst;
@@ -111,16 +113,37 @@ make_pending_blob (GdaStatement *stmt, GdaHolder *holder, GError **error)
 		}
 		GdaSqlField *field;
 		field = g_slist_nth_data (istmt->fields_list, pos);
-		if (!field) {
+		if (field) {
+			pb = g_new0 (PendingBlob, 1);
+			pb->table = istmt->table->table_name;
+			pb->column = field->field_name;
+			pb->free_column = FALSE;
+		}
+		else if (istmt->fields_list) {
 			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
-				     _("Parameter '%s' does not correspond to a table's column"),
+				     _("No column name to associate to parameter '%s'"),
 				     hname);
 			goto out;
 		}
-		pb = g_new0 (PendingBlob, 1);
-		pb->table = istmt->table->table_name;
-		pb->column = field->field_name;
+		else {
+			gchar *fname;
+			fname = get_table_nth_column_name (cnc, istmt->table->table_name, pos);
+			if (fname) {
+				pb = g_new0 (PendingBlob, 1);
+				pb->table = istmt->table->table_name;
+				pb->column = fname;
+				pb->free_column = TRUE;
+			}
+			else {
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+					     _("No column name to associate to parameter '%s'"),
+					     hname);
+				goto out;
+			}
+		}
+	
 		break;
 	}
 	case GDA_SQL_STATEMENT_UPDATE: {
@@ -148,16 +171,36 @@ make_pending_blob (GdaStatement *stmt, GdaHolder *holder, GError **error)
 		}
 		GdaSqlField *field;
 		field = g_slist_nth_data (ustmt->fields_list, pos);
-		if (!field) {
+		if (field) {
+			pb = g_new0 (PendingBlob, 1);
+			pb->table = ustmt->table->table_name;
+			pb->column = field->field_name;
+			pb->free_column = FALSE;
+		}
+		if (ustmt->fields_list) {
 			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
-				     _("Parameter '%s' does not correspond to a table's column"),
+				     _("No column name to associate to parameter '%s'"),
 				     hname);
 			goto out;
 		}
-		pb = g_new0 (PendingBlob, 1);
-		pb->table = ustmt->table->table_name;
-		pb->column = field->field_name;
+		else {
+			gchar *fname;
+			fname = get_table_nth_column_name (cnc, ustmt->table->table_name, pos);
+			if (fname) {
+				pb = g_new0 (PendingBlob, 1);
+				pb->table = ustmt->table->table_name;
+				pb->column = fname;
+				pb->free_column = TRUE;
+			}
+			else {
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
+					     _("No column name to associate to parameter '%s'"),
+					     hname);
+				goto out;
+			}
+		}
 		break;
 	}
 	default:
@@ -185,6 +228,8 @@ pending_blobs_free_list (GSList *blist)
 		PendingBlob *pb = (PendingBlob*) l->data;
 		if (pb->stmt)
 			gda_sql_statement_free (pb->stmt);
+		if (pb->free_column)
+			g_free (pb->column);
 		g_free (pb);
 	}
 
@@ -340,6 +385,29 @@ static gchar *internal_sql[] = {
 	"ROLLBACK TRANSACTION ##name::string"
 };
 
+static gchar *
+get_table_nth_column_name (GdaConnection *cnc, const gchar *table_name, gint pos)
+{
+	static GdaSet *params_set = NULL;
+	GdaDataModel *model;
+	gchar *fname = NULL;
+
+	g_assert (table_name);
+	params_set = gda_set_new_inline (1, "tblname", G_TYPE_STRING, table_name);
+	model = gda_connection_statement_execute_select (cnc,
+							 internal_stmt[INTERNAL_PRAGMA_TABLE_INFO],
+							 params_set, NULL);
+	g_object_unref (params_set);
+	if (model) {
+		const GValue *cvalue;
+		cvalue = gda_data_model_get_value_at (model, 1, pos, NULL);
+		if (cvalue)
+			fname = g_value_dup_string (cvalue);
+		g_object_unref (model);
+	}
+	return fname;
+}
+
 /*
  * GdaSqliteProvider class implementation
  */
@@ -2632,7 +2700,7 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 
 			PendingBlob *pb;
 			GError *lerror = NULL;
-			pb = make_pending_blob (stmt, h, &lerror);
+			pb = make_pending_blob (cnc, stmt, h, &lerror);
 			if (!pb) {
 				event = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR);
 				gda_connection_event_set_description (event, 



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