[libgda] Corrections related to writable GdaDataSelect data model



commit 5a3b7b63a22037242e32d192800e7fd2c158da48
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Jul 6 21:25:35 2009 +0200

    Corrections related to writable GdaDataSelect data model
    
    * GdaDataSelect: correctly handle composed primary keys
    * GdaDataSelect: correctly handle SQL quoted identifiers
    * SQLite provider: time and timestamp corrections
    * GdaConnection: dump variables along with the SQL statement when
      debug mode is set
    * misc corrections

 libgda/gda-connection.c             |   88 ++++++++++++++++++++++++-----------
 libgda/gda-data-select.c            |    5 ++-
 libgda/gda-util.c                   |   25 ++++------
 libgda/sqlite/gda-sqlite-provider.c |   18 +++++--
 samples/WritableSelect/example.c    |    6 +-
 5 files changed, 91 insertions(+), 51 deletions(-)
---
diff --git a/libgda/gda-connection.c b/libgda/gda-connection.c
index 95a0454..a91093d 100644
--- a/libgda/gda-connection.c
+++ b/libgda/gda-connection.c
@@ -157,6 +157,29 @@ static GObjectClass *parent_class = NULL;
 extern GdaServerProvider *_gda_config_sqlite_provider; /* defined in gda-config.c */
 static GdaServerProvider *_gda_thread_wrapper_provider = NULL;
 
+static gint debug_level = -1;
+static void
+dump_exec_params (GdaConnection *cnc, GdaSet *params)
+{
+	if (params && (debug_level & 8)) {
+		GSList *list;
+		g_print ("EVENT> COMMAND: parameters (on cnx %p)\n", cnc);
+		for (list = params->holders; list; list = list->next) {
+			GdaHolder *holder = GDA_HOLDER (list->data);
+			gchar *str;
+			const GValue *value;
+			value = gda_holder_get_value (holder);
+			str = value ? gda_value_stringify (value) : "NULL";
+			g_print ("\t%s: type=>%s, value=>%s\n", gda_holder_get_id (holder),
+				 gda_g_type_to_string (gda_holder_get_g_type (holder)),
+				 str);
+			if (value)
+				g_free (str);
+		}
+	}
+}
+
+
 /*
  * GdaConnection class implementation
  * @klass:
@@ -319,6 +342,29 @@ gda_connection_class_init (GdaConnectionClass *klass)
 	
 	object_class->dispose = gda_connection_dispose;
 	object_class->finalize = gda_connection_finalize;
+
+	/* computing debug level */
+	if (debug_level == -1) {
+		const gchar *str;
+		debug_level = 0;
+		str = getenv ("GDA_CONNECTION_EVENTS_SHOW");
+		if (str) {
+			gchar **array;
+			gint i;
+			array = g_strsplit_set (str, " ,/;:", 0);
+			for (i = 0; i < g_strv_length (array); i++) {
+				if (!g_ascii_strcasecmp (array[i], "notice"))
+					debug_level += 1;
+				else if (!g_ascii_strcasecmp (array[i], "warning"))
+					debug_level += 2;
+				else if (!g_ascii_strcasecmp (array[i], "error"))
+					debug_level += 4;
+				else if (!g_ascii_strcasecmp (array[i], "command"))
+					debug_level += 8;
+			}
+			g_strfreev (array);
+		}
+	}
 }
 
 static void
@@ -1478,50 +1524,28 @@ gda_connection_get_authentication (GdaConnection *cnc)
 void
 gda_connection_add_event (GdaConnection *cnc, GdaConnectionEvent *event)
 {
-	static gint debug = -1;
 	g_return_if_fail (GDA_IS_CONNECTION (cnc));
 	g_return_if_fail (cnc->priv);
 	g_return_if_fail (GDA_IS_CONNECTION_EVENT (event));
 
 	gda_mutex_lock (cnc->priv->mutex);
-	if (debug == -1) {
-		const gchar *str;
-		debug = 0;
-		str = getenv ("GDA_CONNECTION_EVENTS_SHOW");
-		if (str) {
-			gchar **array;
-			gint i;
-			array = g_strsplit_set (str, " ,/;:", 0);
-			for (i = 0; i < g_strv_length (array); i++) {
-				if (!g_ascii_strcasecmp (array[i], "notice"))
-					debug += 1;
-				else if (!g_ascii_strcasecmp (array[i], "warning"))
-					debug += 2;
-				else if (!g_ascii_strcasecmp (array[i], "error"))
-					debug += 4;
-				else if (!g_ascii_strcasecmp (array[i], "command"))
-					debug += 8;
-			}
-			g_strfreev (array);
-		}
-	}
 
 	cnc->priv->events_list = g_list_prepend (cnc->priv->events_list, event);
 
-	if (debug > 0) {
+	if (debug_level > 0) {
 		const gchar *str = NULL;
 		switch (gda_connection_event_get_event_type (event)) {
 		case GDA_CONNECTION_EVENT_NOTICE:
-			if (debug & 1) str = "NOTICE";
+			if (debug_level & 1) str = "NOTICE";
 			break;
 		case GDA_CONNECTION_EVENT_WARNING:
-			if (debug & 2) str = "WARNING";
+			if (debug_level & 2) str = "WARNING";
 			break;
 		case GDA_CONNECTION_EVENT_ERROR:
-			if (debug & 4) str = "ERROR";
+			if (debug_level & 4) str = "ERROR";
 			break;
 		case GDA_CONNECTION_EVENT_COMMAND:
-			if (debug & 8) str = "COMMAND";
+			if (debug_level & 8) str = "COMMAND";
 			break;
 		default:
 			break;
@@ -1902,6 +1926,8 @@ async_stmt_exec_cb (GdaServerProvider *provider, GdaConnection *cnc, guint task_
 			task = CNC_TASK (g_array_index (cnc->priv->waiting_tasks, gpointer, 0));
 			cnc_task_lock (task);
 			task->being_processed = TRUE;
+			
+			dump_exec_params (cnc, task->params);
 			PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, cnc, 
 										 task->stmt, 
 										 task->params, 
@@ -1985,8 +2011,11 @@ gda_connection_async_statement_execute (GdaConnection *cnc, GdaStatement *stmt,
 	if (cnc->priv->waiting_tasks->len == 1) {
 		/* execute statement now as there are no other ones to be executed */
 		GError *lerror = NULL;
+
 		cnc_task_lock (task);
 		task->being_processed = TRUE;
+
+		dump_exec_params (cnc, task->params);
 		PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, cnc, 
 									 task->stmt,
 									 task->params, 
@@ -2184,6 +2213,7 @@ gda_connection_statement_execute_v (GdaConnection *cnc, GdaStatement *stmt, GdaS
 	    ! (model_usage & GDA_STATEMENT_MODEL_CURSOR_FORWARD))
 		model_usage |= GDA_STATEMENT_MODEL_RANDOM_ACCESS;
 
+	dump_exec_params (cnc, params);
 	obj = PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, cnc, stmt, params, 
 								       model_usage, types, last_inserted_row, 
 								       NULL, NULL, NULL, error);
@@ -2439,6 +2469,7 @@ gda_connection_statement_execute_select_fullv (GdaConnection *cnc, GdaStatement
 	    ! (model_usage & GDA_STATEMENT_MODEL_CURSOR_FORWARD))
 		model_usage |= GDA_STATEMENT_MODEL_RANDOM_ACCESS;
 
+	dump_exec_params (cnc, params);
 	model = (GdaDataModel *) PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, 
 											  cnc, stmt, params, model_usage, 
 											  types, NULL, NULL, 
@@ -2500,6 +2531,7 @@ gda_connection_statement_execute_select_full (GdaConnection *cnc, GdaStatement *
 	    ! (model_usage & GDA_STATEMENT_MODEL_CURSOR_FORWARD))
 		model_usage |= GDA_STATEMENT_MODEL_RANDOM_ACCESS;
 
+	dump_exec_params (cnc, params);
 	model = (GdaDataModel *) PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, 
 											  cnc, stmt, params, 
 											  model_usage, col_types, NULL, 
@@ -2562,6 +2594,8 @@ gda_connection_repetitive_statement_execute (GdaConnection *cnc, GdaRepetitiveSt
 	for (list = sets_list; list; list = list->next) {
 		GObject *obj;
 		GError *lerror = NULL;
+
+		dump_exec_params (cnc, (GdaSet*) list->data);
 		obj = PROV_CLASS (cnc->priv->provider_obj)->statement_execute (cnc->priv->provider_obj, cnc, stmt, 
 									       GDA_SET (list->data), 
 									       model_usage, col_types, NULL, 
diff --git a/libgda/gda-data-select.c b/libgda/gda-data-select.c
index fadcd54..e159aa9 100644
--- a/libgda/gda-data-select.c
+++ b/libgda/gda-data-select.c
@@ -1346,7 +1346,8 @@ row_selection_condition_foreach_func (GdaSqlAnyPart *part, gpointer data, GError
 		return TRUE;
 
 	GdaSqlOperation *op = (GdaSqlOperation*) part;
-	if (op->operator_type != GDA_SQL_OPERATOR_TYPE_EQ) {
+	if ((op->operator_type != GDA_SQL_OPERATOR_TYPE_EQ) &&
+	    (op->operator_type != GDA_SQL_OPERATOR_TYPE_AND)) {
 		g_set_error (error, GDA_DATA_SELECT_ERROR, GDA_DATA_SELECT_MODIFICATION_STATEMENT_ERROR,
 			      "%s", _("Invalid unique row condition (ony equal operators are allowed)"));
 		return FALSE;
@@ -3091,6 +3092,8 @@ compute_insert_select_params_mapping (GdaSet *sel_params, GdaSet *ins_values, Gd
 			goto onerror;
 		}
 		g_assert (cdata.colid);
+		if (*(cdata.colid) == '"')
+			gda_sql_identifier_remove_quotes (cdata.colid);
 		/*g_print ("SEL param '%s' <=> column named '%s'\n", cdata.hid, cdata.colid);*/
 		
 		GSList *ins_list;
diff --git a/libgda/gda-util.c b/libgda/gda-util.c
index 4a0e99a..c4595c1 100644
--- a/libgda/gda-util.c
+++ b/libgda/gda-util.c
@@ -831,12 +831,17 @@ gda_compute_unique_table_row_condition (GdaSqlStatementSelect *stsel, GdaMetaTab
 				GdaSqlParamSpec *pspec;
 
 				/* equal condition */
-				op = gda_sql_operation_new (GDA_SQL_ANY_PART (and_cond ? (gpointer)and_cond : (gpointer)expr));
-				op->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
-				if (and_cond) 
-					and_cond->operands = g_slist_append (and_cond->operands, op);
-				else
+				if (and_cond) {
+					opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (and_cond));
+					op = gda_sql_operation_new (GDA_SQL_ANY_PART (opexpr));
+					opexpr->cond = op;
+					and_cond->operands = g_slist_append (and_cond->operands, opexpr);
+				}
+				else {
+					op = gda_sql_operation_new (GDA_SQL_ANY_PART (expr));
 					expr->cond = op;
+				}
+				op->operator_type = GDA_SQL_OPERATOR_TYPE_EQ;
 				/* left operand */
 				opexpr = gda_sql_expr_new (GDA_SQL_ANY_PART (op));
 				g_value_set_string (opexpr->value = gda_value_new (G_TYPE_STRING), tcol->column_name);
@@ -1879,11 +1884,6 @@ gda_parse_iso8601_time (GdaTime *timegda, const gchar *value)
 			ndigits++;
 		}
 
-		while (ndigits < 3) {
-			fraction *= 10;
-			ndigits++;
-		}
-
 		while (fraction > 0 && ndigits > 3) {
 			fraction /= 10;
 			ndigits--;
@@ -1939,11 +1939,6 @@ gda_parse_iso8601_timestamp (GdaTimestamp *timestamp, const gchar *value)
 			ndigits++;
 		}
 
-		while (ndigits < 3) {
-			fraction *= 10;
-			ndigits++;
-		}
-
 		while (fraction > 0 && ndigits > 3) {
 			fraction /= 10;
 			ndigits--;
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 54ae9ee..e46240d 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -1668,7 +1668,7 @@ add_oid_columns (GdaStatement *stmt, GHashTable **out_hash, gint *out_nb_cols_ad
 		else
 			name = target->table_name;
 		
-		if (gda_sql_identifier_needs_quotes (name)) {
+		if ((*name != '"') && gda_sql_identifier_needs_quotes (name)) {
 			gchar *tmp;
 			tmp = gda_sql_identifier_add_quotes (target->table_name);
 			str = g_strdup_printf ("%s.rowid", tmp);
@@ -2375,8 +2375,12 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 			const GdaTime *ts;
 			
 			ts = gda_value_get_time (value);
-			str = g_strdup_printf ("%2d:%2d:%2d.%3ld", 
-					       ts->hour, ts->minute, ts->second, ts->fraction);
+			if (ts->fraction != 0)
+				str = g_strdup_printf ("%02d:%02d:%02d.%ld", 
+						       ts->hour, ts->minute, ts->second, ts->fraction);
+			else
+				str = g_strdup_printf ("%02d:%02d:%02d", 
+						       ts->hour, ts->minute, ts->second);
 			sqlite3_bind_text (ps->sqlite_stmt, i, str, -1, g_free);
 		}
 		else if (G_VALUE_TYPE (value) == G_TYPE_DATE) {
@@ -2393,8 +2397,12 @@ gda_sqlite_provider_statement_execute (GdaServerProvider *provider, GdaConnectio
 			const GdaTimestamp *ts;
 			
 			ts = gda_value_get_timestamp (value);
-			str = g_strdup_printf ("%4d-%02d-%02d %2d:%2d:%2d.%3ld", ts->year, ts->month, ts->day, 
-					       ts->hour, ts->minute, ts->second, ts->fraction);
+			if (ts->fraction != 0)
+				str = g_strdup_printf ("%4d-%02d-%02d %02d:%02d:%02d.%ld", ts->year, ts->month, ts->day, 
+						       ts->hour, ts->minute, ts->second, ts->fraction);
+			else
+				str = g_strdup_printf ("%4d-%02d-%02d %02d:%02d:%02d", ts->year, ts->month, ts->day, 
+						       ts->hour, ts->minute, ts->second);
 			sqlite3_bind_text (ps->sqlite_stmt, i, str, -1, g_free);
 		}
 		else if (G_VALUE_TYPE (value) == GDA_TYPE_NUMERIC) {
diff --git a/samples/WritableSelect/example.c b/samples/WritableSelect/example.c
index 1c0d97b..b3c651b 100644
--- a/samples/WritableSelect/example.c
+++ b/samples/WritableSelect/example.c
@@ -81,11 +81,11 @@ main (int argc, char *argv[])
 	g_object_unref (stmt);
 
 	/*
-	 * remove row 4 (5th row)
+	 * remove row 0 (1st row)
 	 */
 	g_print ("\n\n** Removing row 0\n");
 	if (! gda_data_model_remove_row (model, 0, &error)) {
-		g_print ("Could not remove row 1: %s\n",
+		g_print ("Could not remove row 0: %s\n",
                          error && error->message ? error->message : "No detail");
                 exit (1);
 	}
@@ -104,7 +104,7 @@ main (int argc, char *argv[])
 	g_value_set_string ((name = gda_value_new (G_TYPE_STRING)), "Hiro");
 	list = g_list_append (list, name);
 	if (! gda_data_model_append_values (model, list, &error)) {
-		g_print ("Could add a row: %s\n",
+		g_print ("Could not add a row: %s\n",
                          error && error->message ? error->message : "No detail");
                 exit (1);
 	}



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