libgda r3336 - in trunk: . doc/C doc/C/tmpl libgda libgda/sqlite providers/mysql providers/postgres



Author: vivien
Date: Thu Feb 26 21:46:17 2009
New Revision: 3336
URL: http://svn.gnome.org/viewvc/libgda?rev=3336&view=rev

Log:
2009-02-26  Vivien Malerba <malerba gnome-db org>

	* libgda/libgda.symbols:
	* libgda/gda-row.[ch]: added gda_row_invalidate_value() and gda_row_value_is_valid()
	to be used by database providers' implementations to tag individual values in a GdaRow
	as invalid (either because the value coud not be read or because the value could not
	be intepreted as the requested data type)
	* libgda/sqlite: SQLite provider's improvements:
	  - handle int64 types
	  - fixed a bug when using the '*' in a SELECT to get a blob data
	  - use the new gda_row_invalidate_value() API
	* libgda/gda-data-access-wrapper.c:
	* libgda/gda-data-model-array.c:
	* providers/mysql/gda-mysql-recordset.c:
	* providers/postgres/gda-postgres-recordset.c: use the new gda_row_invalidate_value() API
	* libgda/gda-data-select.c: use the new gda_row_value_is_valid() API
	* libgda/gda-data-model.c: gda_data_model_dump_as_string() and gda_data_model_dump ()
	now display #### when the value of a column can't be obtained and displayed instead
	of undefined result


Modified:
   trunk/ChangeLog
   trunk/doc/C/libgda-4.0-sections.txt
   trunk/doc/C/tmpl/gda-data-select-priv.sgml
   trunk/libgda/gda-data-access-wrapper.c
   trunk/libgda/gda-data-model-array.c
   trunk/libgda/gda-data-model.c
   trunk/libgda/gda-data-select.c
   trunk/libgda/gda-row.c
   trunk/libgda/gda-row.h
   trunk/libgda/libgda.symbols
   trunk/libgda/sqlite/gda-sqlite-provider.c
   trunk/libgda/sqlite/gda-sqlite-recordset.c
   trunk/libgda/sqlite/utils.c
   trunk/providers/mysql/gda-mysql-recordset.c
   trunk/providers/postgres/gda-postgres-recordset.c

Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt	(original)
+++ trunk/doc/C/libgda-4.0-sections.txt	Thu Feb 26 21:46:17 2009
@@ -1387,6 +1387,9 @@
 <SUBSECTION>
 gda_data_model_iter_move_next_default
 gda_data_model_iter_move_prev_default
+<SUBSECTION>
+gda_row_invalidate_value
+gda_row_value_is_valid
 </SECTION>
 
 <SECTION>

Modified: trunk/doc/C/tmpl/gda-data-select-priv.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-data-select-priv.sgml	(original)
+++ trunk/doc/C/tmpl/gda-data-select-priv.sgml	Thu Feb 26 21:46:17 2009
@@ -187,3 +187,22 @@
 @Returns: 
 
 
+<!-- ##### FUNCTION gda_row_invalidate_value ##### -->
+<para>
+
+</para>
+
+ row: 
+ value: 
+
+
+<!-- ##### FUNCTION gda_row_value_is_valid ##### -->
+<para>
+
+</para>
+
+ row: 
+ value: 
+ Returns: 
+
+

Modified: trunk/libgda/gda-data-access-wrapper.c
==============================================================================
--- trunk/libgda/gda-data-access-wrapper.c	(original)
+++ trunk/libgda/gda-data-access-wrapper.c	Thu Feb 26 21:46:17 2009
@@ -448,12 +448,11 @@
 	row = gda_row_new (model->priv->nb_cols);
 	for (i = 0; i < model->priv->nb_cols; i++) {
 		GdaHolder *holder;
-
+		GValue *dest;
+		dest = gda_row_get_value (row, i);
 		holder = gda_data_model_iter_get_holder_for_field (model->priv->iter, i);
 		if (holder) {
-			GValue *dest;
 			const GValue *cvalue = gda_holder_get_value (holder);
-			dest = gda_row_get_value (row, i);
 			if (cvalue) {
 				gda_value_reset_with_type (dest, G_VALUE_TYPE ((GValue *) cvalue));
 				gda_value_set_from_value (dest, cvalue);
@@ -461,6 +460,8 @@
 			else
 				gda_value_set_null (dest);
 		}
+		else
+			gda_row_invalidate_value (row, dest);
 	}
 
 	g_hash_table_insert (model->priv->rows, GINT_TO_POINTER (model->priv->iter_row), row);
@@ -493,15 +494,25 @@
 		GdaRow *gda_row;
 
 		gda_row = g_hash_table_lookup (imodel->priv->rows, GINT_TO_POINTER (row));
-		if (gda_row) 
-			return gda_row_get_value (gda_row, col);
+		if (gda_row) {
+			GValue *val = gda_row_get_value (gda_row, col);
+			if (gda_row_value_is_valid (gda_row, val))
+				return val;
+			else
+				return NULL;
+		}
 		else {
 			g_assert (imodel->priv->iter);
 			if (imodel->priv->iter_row < 0) {
 				if (gda_data_model_iter_move_next (imodel->priv->iter)) {
 					gda_row = g_hash_table_lookup (imodel->priv->rows, GINT_TO_POINTER (row));
-					if (row == imodel->priv->iter_row)
-						return gda_row_get_value (gda_row, col);
+					if (row == imodel->priv->iter_row) {
+						GValue *val = gda_row_get_value (gda_row, col);
+						if (gda_row_value_is_valid (gda_row, val))
+							return val;
+						else
+							return NULL;
+					}
 				}
 				else {
 					g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
@@ -529,8 +540,13 @@
 			    ! (imodel->priv->model_access_flags & GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD)) {
 				gda_row = g_hash_table_lookup (imodel->priv->rows, GINT_TO_POINTER (row));
 
-				if (gda_row)
-					return gda_row_get_value (gda_row, col);
+				if (gda_row) {
+					GValue *val = gda_row_get_value (gda_row, col);
+					if (gda_row_value_is_valid (gda_row, val))
+						return val;
+					else
+						return NULL;
+				}
 			}
 			else {
 				/* in this case iter can be moved forward and backward at will => we only
@@ -563,7 +579,11 @@
 					g_array_prepend_val (imodel->priv->rows_buffer_array, gda_row);
 					g_array_prepend_val (imodel->priv->rows_buffer_index, imodel->priv->iter_row);
 				}
-				return gda_row_get_value (gda_row, col);
+				GValue *val = gda_row_get_value (gda_row, col);
+				if (gda_row_value_is_valid (gda_row, val))
+					return val;
+				else
+					return NULL;
 			}
 		}
 	}

Modified: trunk/libgda/gda-data-model-array.c
==============================================================================
--- trunk/libgda/gda-data-model-array.c	(original)
+++ trunk/libgda/gda-data-model-array.c	Thu Feb 26 21:46:17 2009
@@ -542,7 +542,10 @@
 		GValue *field;
 
 		field = gda_row_get_value (fields, col);
-		return (const GValue *) field;
+		if (gda_row_value_is_valid (fields, field))
+			return (const GValue *) field;
+		else
+			return NULL;
 	}
 	else {
 		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ROW_NOT_FOUND_ERROR,

Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c	(original)
+++ trunk/libgda/gda-data-model.c	Thu Feb 26 21:46:17 2009
@@ -1960,6 +1960,7 @@
 real_gda_data_model_dump_as_string (GdaDataModel *model, gboolean dump_attributes, 
 				    gboolean dump_rows, gboolean dump_title, gboolean null_as_empty, GError **error)
 {
+#define ERROR_STRING "####"
 #define MULTI_LINE_NO_SEPARATOR
 
 	gboolean allok = TRUE;
@@ -2043,23 +2044,24 @@
 	for (j = 0; j < n_rows; j++) {
 		for (i = 0; i < n_cols; i++) {
 			if (! dump_attributes) {
-				value = gda_data_model_get_value_at (model, i, j, error);
+				value = gda_data_model_get_value_at (model, i, j, NULL);
 				if (!value) {
-					allok = FALSE;
-					goto out;
+					cols_size [i + col_offset] = MAX (cols_size [i + col_offset], strlen (ERROR_STRING));
 				}
-				str = NULL;
-				if (null_as_empty) {
-					if (!value || gda_value_is_null (value))
-						str = g_strdup ("");
-				}
-				if (!str)
-					str = value ? gda_value_stringify ((GValue*)value) : g_strdup ("_null_");
-				if (str) {
-					gint w;
-					string_get_dimensions (str, &w, NULL);
-					cols_size [i + col_offset] = MAX (cols_size [i + col_offset], w);
-					g_free (str);
+				else {
+					str = NULL;
+					if (null_as_empty) {
+						if (!value || gda_value_is_null (value))
+							str = g_strdup ("");
+					}
+					if (!str)
+						str = value ? gda_value_stringify ((GValue*)value) : g_strdup ("_null_");
+					if (str) {
+						gint w;
+						string_get_dimensions (str, &w, NULL);
+						cols_size [i + col_offset] = MAX (cols_size [i + col_offset], w);
+						g_free (str);
+					}
 				}
 			}
 			else {
@@ -2154,18 +2156,18 @@
 		
 		for (i = 0; i < n_cols; i++) {
 			if (!dump_attributes) {
-				value = gda_data_model_get_value_at (ramodel, i, j, error);
-				if (!value) {
-					allok = FALSE;
-					goto out;
-				}
-				str = NULL;
-				if (null_as_empty) {
-					if (!value || gda_value_is_null (value))
-						str = g_strdup ("");
+				value = gda_data_model_get_value_at (ramodel, i, j, NULL);
+				if (!value)
+					str = g_strdup (ERROR_STRING);
+				else {
+					str = NULL;
+					if (null_as_empty) {
+						if (!value || gda_value_is_null (value))
+							str = g_strdup ("");
+					}
+					if (!str)
+						str = value ? gda_value_stringify ((GValue *)value) : g_strdup ("_null_");
 				}
-				if (!str)
-					str = value ? gda_value_stringify ((GValue *)value) : g_strdup ("_null_");
 			}
 			else {
 				GdaValueAttribute attrs;

Modified: trunk/libgda/gda-data-select.c
==============================================================================
--- trunk/libgda/gda-data-select.c	(original)
+++ trunk/libgda/gda-data-select.c	Thu Feb 26 21:46:17 2009
@@ -1,5 +1,5 @@
 /* GDA library
- * Copyright (C) 2008 The GNOME Foundation.
+ * Copyright (C) 2008 - 2009 The GNOME Foundation.
  *
  * AUTHORS:
  *      Vivien Malerba <malerba gnome-db org>
@@ -1742,7 +1742,12 @@
 	}
 	
 	g_assert (prow);
-	return gda_row_get_value (prow, col);
+
+	GValue *retval = gda_row_get_value (prow, col);
+	if (gda_row_value_is_valid (prow, retval))
+		return retval;
+	else
+		return NULL;
 }
 
 static GdaValueAttribute
@@ -1966,7 +1971,13 @@
 		const GValue *value;
 		GError *error = NULL;
 		value = gda_row_get_value (prow, i);
-		if (! gda_holder_set_value ((GdaHolder*) plist->data, value, &error)) {
+
+		if (!gda_row_value_is_valid (prow, value)) {
+			retval = FALSE;
+			g_warning (_("Could not change iter's value for column %d: %s"), i,
+				   error && error->message ? error->message : _("No detail"));
+		}
+		else if (! gda_holder_set_value ((GdaHolder*) plist->data, value, &error)) {
 			if (gda_holder_get_not_null ((GdaHolder*) plist->data) &&
 			    gda_value_is_null (value)) {
 				gda_holder_set_not_null ((GdaHolder*) plist->data, FALSE);

Modified: trunk/libgda/gda-row.c
==============================================================================
--- trunk/libgda/gda-row.c	(original)
+++ trunk/libgda/gda-row.c	Thu Feb 26 21:46:17 2009
@@ -216,7 +216,7 @@
  * Gets a pointer to a #GValue stored in a #GdaRow.
  *
  * This is a pointer to the internal array of values. Don't try to free
- * or modify it!
+ * or modify it (modifying is reserved to database provider's implementations).
  *
  * Returns: a pointer to the #GValue in the position @num of @row.
  */
@@ -229,6 +229,37 @@
         return & (row->priv->fields[num]);
 }
 
+/**
+ * gda_row_invalidate_value
+ * @row: a #GdaRow
+ * @value: a #GValue belonging to @row (obtained with gda_row_get_value()).
+ * 
+ * Marks @value as being invalid. This method is mainly used by database
+ * providers' implementations to report any error while reading a value from the database.
+ */
+void
+gda_row_invalidate_value (GdaRow *row, GValue *value)
+{
+	gda_value_set_null (value);
+	G_VALUE_TYPE (value) = G_TYPE_NONE;
+}
+
+/**
+ * gda_row_value_is_valid
+ * @row: a #GdaRow.
+ * @value: a #GValue belonging to @row (obtained with gda_row_get_value()).
+ *
+ * Tells if @value has been marked as being invalid by gda_row_invalidate_value().
+ * This method is mainly used by database
+ * providers' implementations to report any error while reading a value from the database.
+ *
+ * Returns: TRUE if @value is valid
+ */
+gboolean
+gda_row_value_is_valid (GdaRow *row, GValue *value)
+{
+	return (G_VALUE_TYPE (value) == G_TYPE_NONE) ? FALSE : TRUE;
+}
 
 /**
  * gda_row_get_length

Modified: trunk/libgda/gda-row.h
==============================================================================
--- trunk/libgda/gda-row.h	(original)
+++ trunk/libgda/gda-row.h	Thu Feb 26 21:46:17 2009
@@ -61,6 +61,12 @@
 gint          gda_row_get_length     (GdaRow *row);
 GValue       *gda_row_get_value      (GdaRow *row, gint num);
 
+/* for database providers mainly */
+void          gda_row_invalidate_value (GdaRow *row, GValue *value);
+gboolean      gda_row_value_is_valid (GdaRow *row, GValue *value);
+
+
+
 G_END_DECLS
 
 #endif

Modified: trunk/libgda/libgda.symbols
==============================================================================
--- trunk/libgda/libgda.symbols	(original)
+++ trunk/libgda/libgda.symbols	Thu Feb 26 21:46:17 2009
@@ -467,7 +467,9 @@
 	gda_row_get_length
 	gda_row_get_type
 	gda_row_get_value
+	gda_row_invalidate_value
 	gda_row_new
+	gda_row_value_is_valid
 	gda_select_alter_select_for_empty
 	gda_server_operation_add_item_to_sequence
 	gda_server_operation_del_item_from_sequence

Modified: trunk/libgda/sqlite/gda-sqlite-provider.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-provider.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-provider.c	Thu Feb 26 21:46:17 2009
@@ -1771,7 +1771,7 @@
 		return g_object_ref (stmt);
 	}
 
-	add_index = g_slist_length (sst->expr_list);
+	add_index = 0;
 	GSList *list;
 	for (list = sst->from->targets; list; list = list->next) {
 		GdaSqlSelectTarget *target = (GdaSqlSelectTarget*) list->data;
@@ -1782,7 +1782,7 @@
 
 		/* add a field */
 		field = gda_sql_select_field_new (GDA_SQL_ANY_PART (sst));
-		sst->expr_list = g_slist_append (sst->expr_list, field);
+		sst->expr_list = g_slist_insert (sst->expr_list, field, add_index);
 		
 		field->expr = gda_sql_expr_new (GDA_SQL_ANY_PART (field));
 		
@@ -1804,14 +1804,16 @@
 		g_value_take_string ((field->expr->value = gda_value_new (G_TYPE_STRING)), str);
 		
 		/* add to hash table */
+		add_index++;
 		g_hash_table_insert (hash, gda_sql_identifier_remove_quotes (g_strdup (name)),
-				     GINT_TO_POINTER (add_index));
+				     GINT_TO_POINTER (add_index)); /* ADDED 1 to column number, don't forget to remove 1 when using */
 		nb_cols_added ++;
 	}
 	
 	/* prepare return */
 	nstmt = (GdaStatement*) g_object_new (GDA_TYPE_STATEMENT, "structure", sqlst, NULL);
 	gda_sql_statement_free (sqlst);
+	/*g_print ("%s(): Added %d columns: %s\n", __FUNCTION__, nb_cols_added, gda_statement_to_sql (nstmt, NULL, NULL));*/
 	
 	*out_hash = hash;
 	*out_nb_cols_added = nb_cols_added;

Modified: trunk/libgda/sqlite/gda-sqlite-recordset.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-recordset.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-recordset.c	Thu Feb 26 21:46:17 2009
@@ -238,11 +238,12 @@
 		     i < GDA_PSTMT (ps)->ncols; 
 		     i++, list = list->next) {
 			GdaColumn *column;
+			gint real_col = i + ps->nb_rowid_columns;
 			
 			column = GDA_COLUMN (list->data);
-			gda_column_set_description (column, sqlite3_column_name (ps->sqlite_stmt, i));
-			gda_column_set_name (column, sqlite3_column_name (ps->sqlite_stmt, i));
-			gda_column_set_dbms_type (column, sqlite3_column_decltype (ps->sqlite_stmt, i));
+			gda_column_set_description (column, sqlite3_column_name (ps->sqlite_stmt, real_col));
+			gda_column_set_name (column, sqlite3_column_name (ps->sqlite_stmt, real_col));
+			gda_column_set_dbms_type (column, sqlite3_column_decltype (ps->sqlite_stmt, real_col));
 			if (_GDA_PSTMT (ps)->types [i] != GDA_TYPE_NULL)
 				gda_column_set_g_type (column, _GDA_PSTMT (ps)->types [i]);
 		}
@@ -274,20 +275,21 @@
 {
 	const gchar *ctype;
 	GType gtype = GDA_TYPE_NULL;
+	gint real_col = colnum + ps->nb_rowid_columns;
 
 	if (_GDA_PSTMT (ps)->types [colnum] != GDA_TYPE_NULL)
 		return _GDA_PSTMT (ps)->types [colnum];
 	
-	ctype = sqlite3_column_origin_name (ps->sqlite_stmt, colnum);
+	ctype = sqlite3_column_origin_name (ps->sqlite_stmt, real_col);
 	if (ctype && !strcmp (ctype, "rowid"))
 		gtype = G_TYPE_INT64;
 	else {
-		ctype = sqlite3_column_decltype (ps->sqlite_stmt, colnum);
+		ctype = sqlite3_column_decltype (ps->sqlite_stmt, real_col);
 		
 		if (ctype)
 			gtype = GPOINTER_TO_INT (g_hash_table_lookup (cdata->types, ctype));
 		if (gtype == GDA_TYPE_NULL) 
-			gtype = _gda_sqlite_compute_g_type (sqlite3_column_type (ps->sqlite_stmt, colnum));
+			gtype = _gda_sqlite_compute_g_type (sqlite3_column_type (ps->sqlite_stmt, real_col));
 	}
 
 	return gtype;
@@ -313,14 +315,15 @@
 		rc = sqlite3_step (ps->sqlite_stmt);
 	switch (rc) {
 	case  SQLITE_ROW: {
-		gint col;
-		gboolean has_error = FALSE;
+		gint col, real_col;
 		
 		prow = gda_row_new (_GDA_PSTMT (ps)->ncols);
 		for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) {
 			GValue *value;
 			GType type = _GDA_PSTMT (ps)->types [col];
 			
+			real_col = col + ps->nb_rowid_columns;
+
 			if (type == GDA_TYPE_NULL) {
 				type = fuzzy_get_gtype (cdata, ps, col);
 				if (type != GDA_TYPE_NULL) {
@@ -336,7 +339,7 @@
 			
 			/* fill GValue */
 			value = gda_row_get_value (prow, col);
-			if (sqlite3_column_text (ps->sqlite_stmt, col) == NULL) {
+			if (sqlite3_column_text (ps->sqlite_stmt, real_col) == NULL) {
 				/* we have a NULL value */
 				gda_value_set_null (value);
 			}
@@ -348,30 +351,48 @@
 					;
 				else if (type == G_TYPE_INT) {
 					gint64 i;
-					i = sqlite3_column_int (ps->sqlite_stmt, col);
+					i = sqlite3_column_int64 (ps->sqlite_stmt, real_col);
 					if ((i > G_MAXINT) || (i < G_MININT)) {
 						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 							     GDA_SERVER_PROVIDER_DATA_ERROR,
 							     "%s", _("Integer value is too big"));
-						has_error = TRUE;
-						break;
+						gda_row_invalidate_value (prow, value);
+					}
+					else
+						g_value_set_int (value, (gint) i);
+				}
+				else if (type == G_TYPE_UINT) {
+					guint64 i;
+					i = (gint64) sqlite3_column_int64 (ps->sqlite_stmt, real_col);
+					if (i > G_MAXUINT) {
+						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							     GDA_SERVER_PROVIDER_DATA_ERROR,
+							     "%s", _("Integer value is too big"));
+						gda_row_invalidate_value (prow, value);
 					}
-					g_value_set_int (value, (gint) i);
+					else
+						g_value_set_uint (value, (gint) i);
 				}
 				else if (type == G_TYPE_INT64)
-					g_value_set_int64 (value, sqlite3_column_int64 (ps->sqlite_stmt, col));
+					g_value_set_int64 (value, sqlite3_column_int64 (ps->sqlite_stmt, real_col));
+				else if (type == G_TYPE_UINT64)
+					g_value_set_uint64 (value, (guint64) sqlite3_column_int64 (ps->sqlite_stmt,
+												   real_col));
 				else if (type == G_TYPE_DOUBLE)
-					g_value_set_double (value, sqlite3_column_double (ps->sqlite_stmt, col));
+					g_value_set_double (value, sqlite3_column_double (ps->sqlite_stmt,
+											  real_col));
 				else if (type == G_TYPE_STRING)
-					g_value_set_string (value, (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
+					g_value_set_string (value, (gchar *) sqlite3_column_text (ps->sqlite_stmt,
+												  real_col));
 				else if (type == GDA_TYPE_BINARY) {
 					GdaBinary *bin;
 					
 					bin = g_new0 (GdaBinary, 1);
-					bin->binary_length = sqlite3_column_bytes (ps->sqlite_stmt, col);
+					bin->binary_length = sqlite3_column_bytes (ps->sqlite_stmt, real_col);
 					if (bin->binary_length > 0) {
 						bin->data = g_new (guchar, bin->binary_length);
-						memcpy (bin->data, sqlite3_column_blob (ps->sqlite_stmt, col),
+						memcpy (bin->data, sqlite3_column_blob (ps->sqlite_stmt,
+											real_col),
 							bin->binary_length);
 					}
 					else
@@ -384,12 +405,12 @@
 
 					if (ps->rowid_hash) {
 						const char *ctable;
-						ctable = sqlite3_column_name (ps->sqlite_stmt, col);
+						ctable = sqlite3_column_name (ps->sqlite_stmt, real_col);
 						if (ctable)
 							oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash,
 												       ctable));
 						if (oidcol == 0) {
-							ctable = sqlite3_column_table_name (ps->sqlite_stmt, col);
+							ctable = sqlite3_column_table_name (ps->sqlite_stmt, real_col);
 							if (ctable)
 								oidcol = GPOINTER_TO_INT (g_hash_table_lookup (ps->rowid_hash, 
 													       ctable));
@@ -397,19 +418,22 @@
 					}
 					if (oidcol != 0) {
 						gint64 rowid;
-						rowid = sqlite3_column_int64 (ps->sqlite_stmt, oidcol);
+						rowid = sqlite3_column_int64 (ps->sqlite_stmt, oidcol - 1); /* remove 1
+													       because it was added in the first place */
 						bop = gda_sqlite_blob_op_new (cdata,
-									      sqlite3_column_database_name (ps->sqlite_stmt, col),
-									      sqlite3_column_table_name (ps->sqlite_stmt, col),
-									      sqlite3_column_origin_name (ps->sqlite_stmt, col),
+									      sqlite3_column_database_name (ps->sqlite_stmt, 
+													    real_col),
+									      sqlite3_column_table_name (ps->sqlite_stmt,
+													 real_col),
+									      sqlite3_column_origin_name (ps->sqlite_stmt,
+													  real_col),
 									      rowid);
 					}
 					if (!bop) {
 						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 							     GDA_SERVER_PROVIDER_DATA_ERROR,
 							     "%s", _("Unable to open BLOB"));
-						has_error = TRUE;
-						break;
+						gda_row_invalidate_value (prow, value);
 					}
 					else {
 						GdaBlob *blob;
@@ -419,17 +443,17 @@
 					}
 				}
 				else if (type == G_TYPE_BOOLEAN)
-					g_value_set_boolean (value, sqlite3_column_int (ps->sqlite_stmt, col) == 0 ? FALSE : TRUE);
+					g_value_set_boolean (value, sqlite3_column_int (ps->sqlite_stmt, real_col) == 0 ? FALSE : TRUE);
 				else if (type == G_TYPE_DATE) {
 					GDate date;
 					if (!gda_parse_iso8601_date (&date, 
-								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, 
+												    real_col))) {
 						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 							     GDA_SERVER_PROVIDER_DATA_ERROR,
 							     _("Invalid date '%s' (date format should be YYYY-MM-DD)"), 
-							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
-						has_error = TRUE;
-						break;
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, real_col));
+						gda_row_invalidate_value (prow, value);
 					}
 					else
 						g_value_set_boxed (value, &date);
@@ -437,13 +461,13 @@
 				else if (type == GDA_TYPE_TIME) {
 					GdaTime timegda;
 					if (!gda_parse_iso8601_time (&timegda, 
-								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, 
+												    real_col))) {
 						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 							     GDA_SERVER_PROVIDER_DATA_ERROR,
 							     _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), 
-							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
-						has_error = TRUE;
-						break;
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, real_col));
+						gda_row_invalidate_value (prow, value);
 					}
 					else
 						gda_value_set_time (value, &timegda);
@@ -451,13 +475,13 @@
 				else if (type == GDA_TYPE_TIMESTAMP) {
 					GdaTimestamp timestamp;
 					if (!gda_parse_iso8601_timestamp (&timestamp, 
-									  (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+									  (gchar *) sqlite3_column_text (ps->sqlite_stmt,
+													 real_col))) {
 						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 							     GDA_SERVER_PROVIDER_DATA_ERROR,
 							     _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
-							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
-						has_error = TRUE;
-						break;
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, real_col));
+						gda_row_invalidate_value (prow, value);
 					}
 					else
 						gda_value_set_timestamp (value, &timestamp);
@@ -468,17 +492,11 @@
 			}
 		}
 		
-		if (has_error) {
-			g_object_unref (prow);
-			prow = NULL;
-		}
-		else {
-			if (do_store) {
-				/* insert row */
-				gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num);
-			}
-			model->priv->next_row_num ++;
+		if (do_store) {
+			/* insert row */
+			gda_data_select_take_row (GDA_DATA_SELECT (model), prow, model->priv->next_row_num);
 		}
+		model->priv->next_row_num ++;
 		break;
 	}
 	case SQLITE_BUSY:

Modified: trunk/libgda/sqlite/utils.c
==============================================================================
--- trunk/libgda/sqlite/utils.c	(original)
+++ trunk/libgda/sqlite/utils.c	Thu Feb 26 21:46:17 2009
@@ -58,6 +58,9 @@
 	
 	g_hash_table_insert (types, g_strdup ("integer"), GINT_TO_POINTER (G_TYPE_INT));
 	g_hash_table_insert (types, g_strdup ("int"), GINT_TO_POINTER (G_TYPE_INT));
+	g_hash_table_insert (types, g_strdup ("unsigned integer"), GINT_TO_POINTER (G_TYPE_UINT));
+	g_hash_table_insert (types, g_strdup ("unsigned int"), GINT_TO_POINTER (G_TYPE_UINT));
+	g_hash_table_insert (types, g_strdup ("uint"), GINT_TO_POINTER (G_TYPE_UINT));
 	g_hash_table_insert (types, g_strdup ("boolean"), GINT_TO_POINTER (G_TYPE_BOOLEAN));
 	g_hash_table_insert (types, g_strdup ("date"), GINT_TO_POINTER (G_TYPE_DATE));
 	g_hash_table_insert (types, g_strdup ("time"), GINT_TO_POINTER (GDA_TYPE_TIME));
@@ -67,6 +70,8 @@
 	g_hash_table_insert (types, g_strdup ("string"), GINT_TO_POINTER (G_TYPE_STRING));
 	g_hash_table_insert (types, g_strdup ("binary"), GINT_TO_POINTER (GDA_TYPE_BINARY));
 	g_hash_table_insert (types, g_strdup ("blob"), GINT_TO_POINTER (GDA_TYPE_BLOB));
+	g_hash_table_insert (types, g_strdup ("int64"), GINT_TO_POINTER (G_TYPE_INT64));
+	g_hash_table_insert (types, g_strdup ("uint64"), GINT_TO_POINTER (G_TYPE_UINT64));
 }
 
 GType

Modified: trunk/providers/mysql/gda-mysql-recordset.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-recordset.c	(original)
+++ trunk/providers/mysql/gda-mysql-recordset.c	Thu Feb 26 21:46:17 2009
@@ -617,9 +617,13 @@
 				g_value_set_long (value, (long) intvalue);
 			else if (type == G_TYPE_BOOLEAN)
 				g_value_set_boolean (value, intvalue ? TRUE : FALSE);
-			else
-				g_warning (_("Type %s not mapped for value %d"),
-					   g_type_name (type), intvalue);
+			else {
+				gda_row_invalidate_value (row, value);
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Type %s not mapped for value %d"),
+					     g_type_name (type), intvalue);
+			}
 			break;
 		case MYSQL_TYPE_LONGLONG:
 			g_memmove (&longlongvalue, mysql_bind_result[i].buffer, sizeof(long long));
@@ -630,9 +634,13 @@
 				g_value_set_int (value, longlongvalue);
 			else if (type == G_TYPE_LONG)
 				g_value_set_long (value, longlongvalue);
-			else
-				g_warning (_("Type %s not mapped for value %lld"),
-					   g_type_name (type), longlongvalue);
+			else {
+				gda_row_invalidate_value (row, value);
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Type %s not mapped for value %lld"),
+					     g_type_name (type), longlongvalue);
+			}
 			break;
 		case MYSQL_TYPE_NULL:
 			if (G_IS_VALUE(value))
@@ -652,13 +660,15 @@
 					.fraction = timevalue.second_part,
 				};
 				gda_value_set_time (value, &time);
-			} else if (type == G_TYPE_DATE) {
+			}
+			else if (type == G_TYPE_DATE) {
 				GDate *date = g_date_new_dmy
 					((timevalue.day != 0) ? timevalue.day : 1,
 					 (timevalue.month != 0) ? timevalue.month : 1,
 					 (timevalue.year != 0) ? timevalue.year : 1970);
 				g_value_take_boxed (value, date);
-			} else if (type == GDA_TYPE_TIMESTAMP) {
+			}
+			else if (type == GDA_TYPE_TIMESTAMP) {
 				GdaTimestamp timestamp = {
 					.year = timevalue.year,
 					.month = timevalue.month,
@@ -669,11 +679,15 @@
 					.fraction = timevalue.second_part,
 				};
 				gda_value_set_timestamp (value, &timestamp);
-			} else {
-				g_warning (_("Type %s not mapped for value %d/%d/%d %d:%d:%d.%lu"),
-					   g_type_name (type), timevalue.year, timevalue.month, 
-					   timevalue.day, timevalue.hour, timevalue.minute, 
-					   timevalue.second, timevalue.second_part);
+			}
+			else {
+				gda_row_invalidate_value (row, value);
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Type %s not mapped for value %d/%d/%d %d:%d:%d.%lu"),
+					     g_type_name (type), timevalue.year, timevalue.month, 
+					     timevalue.day, timevalue.hour, timevalue.minute, 
+					     timevalue.second, timevalue.second_part);
 			}
 
 			break;
@@ -687,8 +701,11 @@
 			else if (type == G_TYPE_DOUBLE)
 				g_value_set_double (value, doublevalue);
 			else {
-				g_warning (_("Type %s not mapped for value %f"),
-					   g_type_name (type), doublevalue);
+				gda_row_invalidate_value (row, value);
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Type %s not mapped for value %f"),
+					     g_type_name (type), doublevalue);
 			}
 			setlocale (LC_NUMERIC, gda_numeric_locale);
 			
@@ -717,28 +734,38 @@
 					.binary_length = length
 				};
 				gda_value_set_binary (value, &binary);
-			} else if (type == GDA_TYPE_BLOB) {
+			}
+			else if (type == GDA_TYPE_BLOB) {
 				GdaBinary binary = {
 					.data = (guchar*) strvalue,
 					.binary_length = length
 				};
 				gda_value_set_binary (value, &binary);
-			} else if (type == G_TYPE_DOUBLE) {
+			}
+			else if (type == G_TYPE_DOUBLE) {
 				setlocale (LC_NUMERIC, "C");
 				g_value_set_double (value, atof (strvalue));
 				setlocale (LC_NUMERIC, gda_numeric_locale);
-			} else if (type == G_TYPE_BOOLEAN) {
+			}
+			else if (type == G_TYPE_BOOLEAN) {
 				g_value_set_boolean (value, atoi (strvalue));
-			} else {
-				g_warning (_("Type %s not mapped for value %s"),
-					   g_type_name (type), strvalue);
+			}
+			else {
+				gda_row_invalidate_value (row, value);
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+					     GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Type %s not mapped for value %s"),
+					     g_type_name (type), strvalue);
 			}
 			g_free (strvalue);
 			break;
 		}
 		default:
-			g_warning (_("Invalid column bind data type. %d\n"),
-				   mysql_bind_result[i].buffer_type);
+			gda_row_invalidate_value (row, value);
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_DATA_ERROR,
+				     _("Invalid column bind data type. %d\n"),
+				     mysql_bind_result[i].buffer_type);
 		}
 
 	}

Modified: trunk/providers/postgres/gda-postgres-recordset.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-recordset.c	(original)
+++ trunk/providers/postgres/gda-postgres-recordset.c	Thu Feb 26 21:46:17 2009
@@ -62,10 +62,10 @@
 
 /* static helper functions */
 static void make_point (GdaGeometricPoint *point, const gchar *value);
-static void set_value (GdaConnection *cnc, GValue *value, GType type, const gchar *thevalue, gint length);
+static void set_value (GdaConnection *cnc, GdaRow *row, GValue *value, GType type, const gchar *thevalue, gint length, GError **error);
 
-static void     set_prow_with_pg_res (GdaPostgresRecordset *imodel, GdaRow *prow, gint pg_res_rownum);
-static GdaRow *new_row_from_pg_res (GdaPostgresRecordset *imodel, gint pg_res_rownum);
+static void     set_prow_with_pg_res (GdaPostgresRecordset *imodel, GdaRow *prow, gint pg_res_rownum, GError **error);
+static GdaRow *new_row_from_pg_res (GdaPostgresRecordset *imodel, gint pg_res_rownum, GError **error);
 static gboolean row_is_in_current_pg_res (GdaPostgresRecordset *model, gint row);
 static gboolean fetch_next_chunk (GdaPostgresRecordset *model, gboolean *fetch_error, GError **error);
 static gboolean fetch_prev_chunk (GdaPostgresRecordset *model, gboolean *fetch_error, GError **error);
@@ -432,7 +432,7 @@
 		return FALSE;
 	}
 
-	*prow = new_row_from_pg_res (imodel, rownum);
+	*prow = new_row_from_pg_res (imodel, rownum, error);
 	gda_data_select_take_row (model, *prow, rownum);
 
 	if (model->nb_stored_rows == model->advertized_nrows) {
@@ -484,9 +484,9 @@
 
 	if (row_is_in_current_pg_res (imodel, rownum)) {
 		if (imodel->priv->tmp_row)
-			set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf);
+			set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf, error);
 		else
-			imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+			imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 		*prow = imodel->priv->tmp_row;
 		return TRUE;
 	}
@@ -494,9 +494,9 @@
 		gboolean fetch_error = FALSE;
 		if (fetch_next_chunk (imodel, &fetch_error, error)) {
 			if (imodel->priv->tmp_row)
-				set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf);
+				set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf, error);
 			else
-				imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+				imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 			*prow = imodel->priv->tmp_row;
 			return TRUE;
 		}
@@ -521,9 +521,9 @@
 
 	if (row_is_in_current_pg_res (imodel, rownum)) {
 		if (imodel->priv->tmp_row)
-			set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf);
+			set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf, error);
 		else
-			imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+			imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 		*prow = imodel->priv->tmp_row;
 		return TRUE;
 	}
@@ -531,9 +531,9 @@
 		gboolean fetch_error = FALSE;
 		if (fetch_prev_chunk (imodel, &fetch_error, error)) {
 			if (imodel->priv->tmp_row)
-				set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf);
+				set_prow_with_pg_res (imodel, imodel->priv->tmp_row, rownum - imodel->priv->pg_res_inf, error);
 			else
-				imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+				imodel->priv->tmp_row = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 			*prow = imodel->priv->tmp_row;
 			return TRUE;
 		}
@@ -562,14 +562,14 @@
 	}
 
 	if (row_is_in_current_pg_res (imodel, rownum)) {
-		*prow = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+		*prow = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 		imodel->priv->tmp_row = *prow;
 		return TRUE;
 	}
 	else {
 		gboolean fetch_error = FALSE;
 		if (fetch_row_number_chunk (imodel, rownum, &fetch_error, error)) {
-			*prow = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf);
+			*prow = new_row_from_pg_res (imodel, rownum - imodel->priv->pg_res_inf, error);
 			imodel->priv->tmp_row = *prow;
 			return TRUE;
 		}
@@ -599,8 +599,7 @@
 }
 
 static void
-set_value (GdaConnection *cnc, GValue *value, GType type,
-	   const gchar *thevalue, gint length)
+set_value (GdaConnection *cnc, GdaRow *row, GValue *value, GType type, const gchar *thevalue, gint length, GError **error)
 {
 	gda_value_reset_with_type (value, type);
 
@@ -612,15 +611,23 @@
 		g_value_set_int (value, atol (thevalue));
 	else if (type == G_TYPE_DATE) {
 		GDate date;
-		if (!gda_parse_iso8601_date (&date, thevalue)) 
-			g_warning (_("Invalid date '%s' (date format should be YYYY-MM-DD)"), thevalue);
+		if (!gda_parse_iso8601_date (&date, thevalue)) {
+			gda_row_invalidate_value (row, value);
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_DATA_ERROR,
+				     _("Invalid date '%s' (date format should be YYYY-MM-DD)"), thevalue);
+		}
 		else
 			g_value_set_boxed (value, &date);
 	}
 	else if (type == GDA_TYPE_TIME) {
 		GdaTime timegda;
-		if (!gda_parse_iso8601_time (&timegda, thevalue)) 
-			g_warning (_("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), thevalue);
+		if (!gda_parse_iso8601_time (&timegda, thevalue)) {
+			gda_row_invalidate_value (row, value); 
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_DATA_ERROR,
+				     _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), thevalue);
+		}
 		else
 			gda_value_set_time (value, &timegda);
 	}
@@ -657,9 +664,13 @@
 	}
 	else if (type == GDA_TYPE_TIMESTAMP) {
 		GdaTimestamp timestamp;
-		if (! gda_parse_iso8601_timestamp (&timestamp, thevalue))
-			g_warning (_("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
-				   thevalue);
+		if (! gda_parse_iso8601_timestamp (&timestamp, thevalue)) {
+			gda_row_invalidate_value (row, value);
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_DATA_ERROR,
+				     _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
+				     thevalue);
+		}
 		else
 			gda_value_set_timestamp (value, &timestamp);
 	}
@@ -692,7 +703,7 @@
 	else if (type == G_TYPE_GTYPE)
 		g_value_set_gtype (value, gda_g_type_from_string (thevalue));
 	else {
-		g_warning ("Type %s not translated for value '%s' => set as string", g_type_name (type), thevalue);
+		/*g_warning ("Type %s not translated for value '%s' => set as string", g_type_name (type), thevalue);*/
 		gda_value_reset_with_type (value, G_TYPE_STRING);
 		g_value_set_string (value, thevalue);
 	}
@@ -709,7 +720,7 @@
 }
 
 static void
-set_prow_with_pg_res (GdaPostgresRecordset *imodel, GdaRow *prow, gint pg_res_rownum)
+set_prow_with_pg_res (GdaPostgresRecordset *imodel, GdaRow *prow, gint pg_res_rownum, GError **error)
 {
 	gchar *thevalue;
 	gint col;
@@ -720,20 +731,20 @@
 			gda_value_set_null (gda_row_get_value (prow, col));
 		else
 			set_value (gda_data_select_get_connection ((GdaDataSelect*) imodel),
-				   gda_row_get_value (prow, col), 
+				   prow, gda_row_get_value (prow, col), 
 				   ((GdaDataSelect*) imodel)->prep_stmt->types [col], 
 				   thevalue, 
-				   PQgetlength (imodel->priv->pg_res, pg_res_rownum, col));
+				   PQgetlength (imodel->priv->pg_res, pg_res_rownum, col), error);
 	}
 }
 
 static GdaRow *
-new_row_from_pg_res (GdaPostgresRecordset *imodel, gint pg_res_rownum)
+new_row_from_pg_res (GdaPostgresRecordset *imodel, gint pg_res_rownum, GError **error)
 {
 	GdaRow *prow;
 
 	prow = gda_row_new (((GdaDataSelect*) imodel)->prep_stmt->ncols);
-	set_prow_with_pg_res (imodel, prow, pg_res_rownum);
+	set_prow_with_pg_res (imodel, prow, pg_res_rownum, error);
 	return prow;
 }
 



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