libgda r3241 - in trunk: . doc/C doc/C/tmpl libgda providers/mysql



Author: vivien
Date: Wed Oct 15 18:59:50 2008
New Revision: 3241
URL: http://svn.gnome.org/viewvc/libgda?rev=3241&view=rev

Log:
2008-10-15  Vivien Malerba <malerba gnome-db org>

	* providers/mysql/gda-mysql-pstmt.[ch]:
	* providers/mysql/gda-mysql-blob-op.[ch]:
	* providers/mysql/gda-mysql-provider.c:
	* providers/mysql/gda-mysql-recordset.[ch]: corrections for cursor based access SELECT
	statements, thanks to Carlos Savoretti
	* libgda/gda-data-model-iter.[ch]: added the gda_data_model_iter_compute_attributes()
	method to force the iterator to compute and set the correct attributes for
	each of its GdaHolder; a separate method is required because computing them
	all the time consumes too much ressources, see bug #556327


2008-10-15  Johannes Schmid  <jschmid openismus com>

	* libgda/Makefile.am: Install gda-error.h header
	* libgda/gda-error.c (gda_error_get_type):
	Fixed a typo (GDaError <-> GdaError), for bug #556258


Modified:
   trunk/ChangeLog
   trunk/doc/C/libgda-4.0-sections.txt
   trunk/doc/C/tmpl/gda-data-model-iter.sgml
   trunk/libgda/Makefile.am
   trunk/libgda/gda-data-model-iter.c
   trunk/libgda/gda-data-model-iter.h
   trunk/libgda/gda-error.c
   trunk/providers/mysql/gda-mysql-blob-op.c
   trunk/providers/mysql/gda-mysql-blob-op.h
   trunk/providers/mysql/gda-mysql-provider.c
   trunk/providers/mysql/gda-mysql-pstmt.c
   trunk/providers/mysql/gda-mysql-pstmt.h
   trunk/providers/mysql/gda-mysql-recordset.c
   trunk/providers/mysql/gda-mysql-recordset.h

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	Wed Oct 15 18:59:50 2008
@@ -371,6 +371,7 @@
 gda_data_model_iter_get_row
 gda_data_model_iter_get_holder_for_field
 gda_data_model_iter_invalidate_contents
+gda_data_model_iter_compute_attributes
 <SUBSECTION Standard>
 GDA_DATA_MODEL_ITER
 GDA_DATA_MODEL_ITER_CLASS

Modified: trunk/doc/C/tmpl/gda-data-model-iter.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-data-model-iter.sgml	(original)
+++ trunk/doc/C/tmpl/gda-data-model-iter.sgml	Wed Oct 15 18:59:50 2008
@@ -193,3 +193,13 @@
 @iter: 
 
 
+<!-- ##### FUNCTION gda_data_model_iter_compute_attributes ##### -->
+<para>
+
+</para>
+
+ iter: 
+ error: 
+ Returns: 
+
+

Modified: trunk/libgda/Makefile.am
==============================================================================
--- trunk/libgda/Makefile.am	(original)
+++ trunk/libgda/Makefile.am	Wed Oct 15 18:59:50 2008
@@ -51,6 +51,7 @@
 	gda-debug-macros.h \
 	gda-decl.h \
 	gda-easy.h \
+	gda-error.h \
 	gda-enums.h \
 	gda-holder.h \
 	gda-lockable.h \
@@ -107,7 +108,6 @@
 	gda-data-select-extra.h \
 	gda-easy.c \
 	gda-error.c \
-	gda-error.h \
 	gda-holder.c \
 	gda-init.c \
 	gda-lockable.c \

Modified: trunk/libgda/gda-data-model-iter.c
==============================================================================
--- trunk/libgda/gda-data-model-iter.c	(original)
+++ trunk/libgda/gda-data-model-iter.c	Wed Oct 15 18:59:50 2008
@@ -381,86 +381,6 @@
 	parent_class->finalize (object);
 }
 
-static void
-set_holders_properties_from_select_stmt (GdaDataModelIter *iter, GdaConnection *cnc, GdaStatement *sel_stmt)
-{
-	GdaSqlStatement *sqlst = NULL;
-	GdaSqlStatementSelect *select;
-	GdaSqlSelectTarget *target;
-
-	g_object_get (G_OBJECT (sel_stmt), "structure", &sqlst, NULL);
-	g_assert (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT);
-	select = (GdaSqlStatementSelect*) sqlst->contents;
-
-	/* we only want a single target */
-	if (!select->from || !select->from->targets || select->from->targets->next)
-		goto out;
-	
-	target = (GdaSqlSelectTarget *) select->from->targets->data;
-	if (!target || !target->table_name)
-		goto out;
-
-	if (! gda_sql_statement_check_validity (sqlst, cnc, NULL))
-		goto out;
-
-	if (!target->validity_meta_object) {
-		g_warning ("Internal gda_sql_statement_check_validity() error: target->validity_meta_object is not set");
-		goto out;
-	}
-
-	/* FIXME: also set some column attributes using gda_column_set_attribute() */
-
-	GSList *fields, *holders;
-	for (fields = select->expr_list, holders = GDA_SET (iter)->holders; 
-	     fields && holders; 
-	     fields = fields->next) {
-		GdaSqlSelectField *selfield = (GdaSqlSelectField*) fields->data;
-		if (selfield->validity_meta_table_column) {
-			GdaMetaTableColumn *tcol = selfield->validity_meta_table_column;
-
-			/*g_print ("==> %s\n", tcol->column_name);*/
-			gda_holder_set_not_null (GDA_HOLDER (holders->data), ! tcol->nullok);
-			if (tcol->default_value) {
-				GValue *dvalue;
-				g_value_set_string ((dvalue = gda_value_new (G_TYPE_STRING)), tcol->default_value);
-				gda_holder_set_default_value (GDA_HOLDER (holders->data), dvalue);
-				gda_value_free (dvalue);
-			}
-			holders = holders->next;
-		}
-		else if (selfield->validity_meta_object && 
-			 (selfield->validity_meta_object->obj_type == GDA_META_DB_TABLE) &&
-			 selfield->expr && selfield->expr->value && !selfield->expr->param_spec && 
-			 (G_VALUE_TYPE (selfield->expr->value) == G_TYPE_STRING) &&
-			 !strcmp (g_value_get_string (selfield->expr->value), "*")) {
-			/* expand all the fields */
-			GdaMetaTable *mtable = GDA_META_TABLE (selfield->validity_meta_object);
-			GSList *tmplist;
-			for (tmplist = mtable->columns; tmplist; tmplist = tmplist->next) {
-				GdaMetaTableColumn *tcol = (GdaMetaTableColumn*) tmplist->data;
-				/*g_print ("*==> %s\n", tcol->column_name);*/
-				gda_holder_set_not_null (GDA_HOLDER (holders->data), ! tcol->nullok);
-				if (tcol->default_value) {
-					GValue *dvalue;
-					g_value_set_string ((dvalue = gda_value_new (G_TYPE_STRING)), tcol->default_value);
-					gda_holder_set_default_value (GDA_HOLDER (holders->data), dvalue);
-					gda_value_free (dvalue);
-				}
-				if (tmplist)
-					holders = holders->next;
-			}
-		}
-		else
-			holders = holders->next;
-	}
-	if (fields || holders)
-		g_warning ("Internal error: GdaDataModelIter has %d GdaHolders, and SELECT statement has %d expressions",
-			   g_slist_length (GDA_SET (iter)->holders), g_slist_length (select->expr_list));
-
- out:
-	gda_sql_statement_free (sqlst);
-}
-
 static void 
 gda_data_model_iter_set_property (GObject *object,
 				  guint param_id,
@@ -551,19 +471,6 @@
 										  G_CALLBACK (model_row_removed_cb), iter);
 			iter->priv->model_changes_signals [2] = g_signal_connect (G_OBJECT (ptr), "reset",
 										  G_CALLBACK (model_reset_cb), iter);
-
-			if (GDA_IS_DATA_SELECT (iter->priv->data_model)) {
-				GdaStatement *sel_stmt;
-				GdaConnection *cnc;
-				g_object_get (G_OBJECT (iter->priv->data_model), "connection", &cnc, 
-					      "select-stmt", &sel_stmt, NULL);
-				if (sel_stmt && cnc) 
-					set_holders_properties_from_select_stmt (iter, cnc, sel_stmt);
-				if (sel_stmt)
-					g_object_unref (sel_stmt);
-				if (cnc)
-					g_object_unref (cnc);
-			}
 			break;
                 }
 		case PROP_CURRENT_ROW:
@@ -1064,3 +971,113 @@
 	else
 		return NULL;
 }
+
+static void
+set_holders_properties_from_select_stmt (GdaDataModelIter *iter, GdaConnection *cnc, GdaStatement *sel_stmt)
+{
+	GdaSqlStatement *sqlst = NULL;
+	GdaSqlStatementSelect *select;
+	GdaSqlSelectTarget *target;
+	GSList *fields, *holders;
+
+	g_object_get (G_OBJECT (sel_stmt), "structure", &sqlst, NULL);
+	g_assert (sqlst->stmt_type == GDA_SQL_STATEMENT_SELECT);
+	select = (GdaSqlStatementSelect*) sqlst->contents;
+
+	/* we only want a single target */
+	if (!select->from || !select->from->targets || select->from->targets->next)
+		goto out;
+	
+	target = (GdaSqlSelectTarget *) select->from->targets->data;
+	if (!target || !target->table_name)
+		goto out;
+
+	if (! gda_sql_statement_check_validity (sqlst, cnc, NULL))
+		goto out;
+
+	if (!target->validity_meta_object) {
+		g_warning ("Internal gda_sql_statement_check_validity() error: target->validity_meta_object is not set");
+		goto out;
+	}
+
+	/* FIXME: also set some column attributes using gda_column_set_attribute() */
+
+	for (fields = select->expr_list, holders = GDA_SET (iter)->holders; 
+	     fields && holders; 
+	     fields = fields->next) {
+		GdaSqlSelectField *selfield = (GdaSqlSelectField*) fields->data;
+		if (selfield->validity_meta_table_column) {
+			GdaMetaTableColumn *tcol = selfield->validity_meta_table_column;
+
+			/*g_print ("==> %s\n", tcol->column_name);*/
+			gda_holder_set_not_null (GDA_HOLDER (holders->data), ! tcol->nullok);
+			if (tcol->default_value) {
+				GValue *dvalue;
+				g_value_set_string ((dvalue = gda_value_new (G_TYPE_STRING)), tcol->default_value);
+				gda_holder_set_default_value (GDA_HOLDER (holders->data), dvalue);
+				gda_value_free (dvalue);
+			}
+			holders = holders->next;
+		}
+		else if (selfield->validity_meta_object && 
+			 (selfield->validity_meta_object->obj_type == GDA_META_DB_TABLE) &&
+			 selfield->expr && selfield->expr->value && !selfield->expr->param_spec && 
+			 (G_VALUE_TYPE (selfield->expr->value) == G_TYPE_STRING) &&
+			 !strcmp (g_value_get_string (selfield->expr->value), "*")) {
+			/* expand all the fields */
+			GdaMetaTable *mtable = GDA_META_TABLE (selfield->validity_meta_object);
+			GSList *tmplist;
+			for (tmplist = mtable->columns; tmplist; tmplist = tmplist->next) {
+				GdaMetaTableColumn *tcol = (GdaMetaTableColumn*) tmplist->data;
+				/*g_print ("*==> %s\n", tcol->column_name);*/
+				gda_holder_set_not_null (GDA_HOLDER (holders->data), ! tcol->nullok);
+				if (tcol->default_value) {
+					GValue *dvalue;
+					g_value_set_string ((dvalue = gda_value_new (G_TYPE_STRING)), tcol->default_value);
+					gda_holder_set_default_value (GDA_HOLDER (holders->data), dvalue);
+					gda_value_free (dvalue);
+				}
+				if (tmplist)
+					holders = holders->next;
+			}
+		}
+		else
+			holders = holders->next;
+	}
+	if (fields || holders)
+		g_warning ("Internal error: GdaDataModelIter has %d GdaHolders, and SELECT statement has %d expressions",
+			   g_slist_length (GDA_SET (iter)->holders), g_slist_length (select->expr_list));
+
+ out:
+	gda_sql_statement_free (sqlst);
+}
+
+/**
+ * gda_data_model_iter_compute_attributes
+ * @iter: a #GdaDataModelIter object
+ * @error: a place to store errors, or %NULL
+ *
+ * Requests that @iter compute the attributes of each of its #GdaHolder value holders.
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_data_model_iter_compute_attributes (GdaDataModelIter *iter, GError **error)
+{
+	g_return_val_if_fail (GDA_IS_DATA_MODEL_ITER (iter), FALSE);
+	g_return_val_if_fail (iter->priv, FALSE);
+
+	if (GDA_IS_DATA_SELECT (iter->priv->data_model)) {
+		GdaStatement *sel_stmt;
+		GdaConnection *cnc;
+		g_object_get (G_OBJECT (iter->priv->data_model), "connection", &cnc, 
+			      "select-stmt", &sel_stmt, NULL);
+		if (sel_stmt && cnc) 
+			set_holders_properties_from_select_stmt (iter, cnc, sel_stmt);
+		if (sel_stmt)
+			g_object_unref (sel_stmt);
+		if (cnc)
+			g_object_unref (cnc);
+	}
+	return TRUE;
+}

Modified: trunk/libgda/gda-data-model-iter.h
==============================================================================
--- trunk/libgda/gda-data-model-iter.h	(original)
+++ trunk/libgda/gda-data-model-iter.h	Wed Oct 15 18:59:50 2008
@@ -76,6 +76,8 @@
 
 GdaHolder        *gda_data_model_iter_get_holder_for_field (GdaDataModelIter *iter, gint col);
 
+gboolean          gda_data_model_iter_compute_attributes   (GdaDataModelIter *iter, GError **error);
+
 G_END_DECLS
 
 #endif

Modified: trunk/libgda/gda-error.c
==============================================================================
--- trunk/libgda/gda-error.c	(original)
+++ trunk/libgda/gda-error.c	Wed Oct 15 18:59:50 2008
@@ -29,7 +29,7 @@
 		static GStaticMutex registering = G_STATIC_MUTEX_INIT;
 		g_static_mutex_lock (&registering);
                 if (type == 0)
-			type = g_boxed_type_register_static ("GDaError",
+			type = g_boxed_type_register_static ("GdaError",
 							     (GBoxedCopyFunc) g_error_copy,
 							     (GBoxedFreeFunc) g_error_free);
 		g_static_mutex_unlock (&registering);

Modified: trunk/providers/mysql/gda-mysql-blob-op.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-blob-op.c	(original)
+++ trunk/providers/mysql/gda-mysql-blob-op.c	Wed Oct 15 18:59:50 2008
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 The GNOME Foundation
  *
  * AUTHORS:
- *      TO_ADD: your name and email
+ *      Carlos Savoretti <csavoretti gmail com>
  *
  * This Library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public License as
@@ -27,7 +27,7 @@
 #include "gda-mysql-blob-op.h"
 
 struct _GdaMysqlBlobOpPrivate {
-	GdaConnection *cnc;
+	GdaConnection  *cnc;
 	/* TO_ADD: specific information describing a Blob in the C API */
 };
 
@@ -72,8 +72,8 @@
 }
 
 static void
-gda_mysql_blob_op_init (GdaMysqlBlobOp *op,
-			   GdaMysqlBlobOpClass *klass)
+gda_mysql_blob_op_init (GdaMysqlBlobOp       *op,
+			GdaMysqlBlobOpClass  *klass)
 {
 	g_return_if_fail (GDA_IS_MYSQL_BLOB_OP (op));
 
@@ -84,7 +84,7 @@
 }
 
 static void
-gda_mysql_blob_op_class_init (GdaMysqlBlobOpClass *klass)
+gda_mysql_blob_op_class_init (GdaMysqlBlobOpClass  *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	GdaBlobOpClass *blob_class = GDA_BLOB_OP_CLASS (klass);
@@ -98,7 +98,7 @@
 }
 
 static void
-gda_mysql_blob_op_finalize (GObject * object)
+gda_mysql_blob_op_finalize (GObject  *object)
 {
 	GdaMysqlBlobOp *pgop = (GdaMysqlBlobOp *) object;
 
@@ -114,7 +114,7 @@
 }
 
 GdaBlobOp *
-gda_mysql_blob_op_new (GdaConnection *cnc)
+gda_mysql_blob_op_new (GdaConnection  *cnc)
 {
 	GdaMysqlBlobOp *pgop;
 
@@ -130,7 +130,7 @@
  * Get length request
  */
 static glong
-gda_mysql_blob_op_get_length (GdaBlobOp *op)
+gda_mysql_blob_op_get_length (GdaBlobOp  *op)
 {
 	GdaMysqlBlobOp *pgop;
 
@@ -147,7 +147,10 @@
  * Blob read request
  */
 static glong
-gda_mysql_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size)
+gda_mysql_blob_op_read (GdaBlobOp  *op,
+			GdaBlob    *blob,
+			glong       offset,
+			glong       size)
 {
 	GdaMysqlBlobOp *pgop;
 	GdaBinary *bin;
@@ -176,7 +179,9 @@
  * Blob write request
  */
 static glong
-gda_mysql_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset)
+gda_mysql_blob_op_write (GdaBlobOp  *op,
+			 GdaBlob    *blob,
+			 glong       offset)
 {
 	GdaMysqlBlobOp *pgop;
 	GdaBinary *bin;

Modified: trunk/providers/mysql/gda-mysql-blob-op.h
==============================================================================
--- trunk/providers/mysql/gda-mysql-blob-op.h	(original)
+++ trunk/providers/mysql/gda-mysql-blob-op.h	Wed Oct 15 18:59:50 2008
@@ -2,7 +2,7 @@
  * Copyright (C) 2008 The GNOME Foundation
  *
  * AUTHORS:
- *      TO_ADD: your name and email
+ *      Carlos Savoretti <csavoretti gmail com>
  *
  * This Library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public License as
@@ -38,16 +38,16 @@
 typedef struct _GdaMysqlBlobOpPrivate GdaMysqlBlobOpPrivate;
 
 struct _GdaMysqlBlobOp {
-	GdaBlobOp             parent;
-	GdaMysqlBlobOpPrivate *priv;
+	GdaBlobOp               parent;
+	GdaMysqlBlobOpPrivate  *priv;
 };
 
 struct _GdaMysqlBlobOpClass {
-	GdaBlobOpClass        parent_class;
+	GdaBlobOpClass          parent_class;
 };
 
 GType         gda_mysql_blob_op_get_type     (void) G_GNUC_CONST;
-GdaBlobOp    *gda_mysql_blob_op_new          (GdaConnection *cnc);
+GdaBlobOp    *gda_mysql_blob_op_new          (GdaConnection  *cnc);
 
 /* TO_ADD: more convenient API to create a GdaBlobOp with some specific information as argument */
 

Modified: trunk/providers/mysql/gda-mysql-provider.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-provider.c	(original)
+++ trunk/providers/mysql/gda-mysql-provider.c	Wed Oct 15 18:59:50 2008
@@ -420,7 +420,6 @@
 	if (compress)
 		flags |= CLIENT_COMPRESS;
 	
-	
 	MYSQL *mysql = g_new0 (MYSQL, 1);
 	mysql_init (mysql);
 
@@ -529,7 +528,6 @@
 	use_ssl = gda_quark_list_find (params, "USE_SSL");
 	compress = gda_quark_list_find (params, "COMPRESS");
 	
-	
 	/* open the real connection to the database */
 	/* TO_ADD: C API specific function calls;
 	 * if it fails, add a connection event and return FALSE */
@@ -558,7 +556,6 @@
 		_gda_mysql_make_error (cnc, NULL, mysql_stmt, NULL);
 		return FALSE;
 	}
-	
 
 	/* Create a new instance of the provider specific data associated to a connection (MysqlConnectionData),
 	 * and set its contents */
@@ -574,7 +571,6 @@
 	cdata->version_long = mysql_get_server_version (mysql);
 	cdata->version = get_mysql_version (mysql);
 	
-
 	/* Optionnally set some attributes for the newly opened connection (encoding to UTF-8 for example )*/
 	// TO_IMPLEMENT;
 
@@ -1178,7 +1174,6 @@
 
 	/* prepare @stmt using the C API, creates @ps */
 	// TO_IMPLEMENT;
-	
 
 	cdata = (MysqlConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata) 
@@ -1193,7 +1188,6 @@
 		(provider, cnc, stmt, set,
 		 GDA_STATEMENT_SQL_PARAMS_AS_UQMARK, &used_set, error);
 
-	
 	if (!sql)
 		goto cleanup;
 
@@ -1229,7 +1223,6 @@
 	if (!ps)
 		return FALSE;
 	else {
-		
 		gda_pstmt_set_gda_statement (_GDA_PSTMT(ps), stmt);
 		_GDA_PSTMT(ps)->param_ids = param_ids;
 		_GDA_PSTMT(ps)->sql = sql;
@@ -1348,7 +1341,6 @@
 			g_free (sql);
 			if (!ps)
 				return NULL;
-			
 		}
 		else
 			ps = (GdaMysqlPStmt *) gda_connection_get_prepared_statement (cnc, stmt);
@@ -1367,10 +1359,10 @@
 	char **param_values = g_new0 (char *, nb_params + 1);
         int *param_lengths = g_new0 (int, nb_params + 1);
         int *param_formats = g_new0 (int, nb_params + 1);
-	/* g_print ("NB=%d, SQL=%s\n", nb_params, _GDA_PSTMT(ps)->sql); */
+	//g_print ("NB=%d, SQL=%s\n", nb_params, _GDA_PSTMT(ps)->sql);
 
 	MYSQL_BIND *mysql_bind_param = g_new0 (MYSQL_BIND, nb_params);
-	
+
 	for (i = 0, list = _GDA_PSTMT (ps)->param_ids; list; list = list->next, i++) {
 		const gchar *pname = (gchar *) list->data;
 
@@ -1405,12 +1397,13 @@
 				break;
 			} else {
                                 /* bind param to NULL */
-                                TO_IMPLEMENT;
+                                //TO_IMPLEMENT;
+				param_values[i] = NULL;
                                 empty_rs = TRUE;
                                 continue;
 			}
-
 		}
+
 		if (!gda_holder_is_valid (h)) {
 
 			if (!allow_noparam) {
@@ -1424,11 +1417,11 @@
 				break;
 			} else {
                                 /* bind param to NULL */
-				TO_IMPLEMENT;
+				//TO_IMPLEMENT;
+				param_values[i] = NULL;
                                 empty_rs = TRUE;
                                 continue;
                         }
-
 		}
 
 		/* actual binding using the C API, for parameter at position @i */
@@ -1440,14 +1433,12 @@
 		} else if ((G_VALUE_TYPE(value) == G_TYPE_DATE) ||
 			   (G_VALUE_TYPE(value) == GDA_TYPE_TIME) ||
 			   (G_VALUE_TYPE(value) == GDA_TYPE_TIMESTAMP)) {
-			
 			GdaHandlerTime *handler_time = (GdaHandlerTime *) gda_server_provider_get_data_handler_gtype
 				(provider, cnc, G_VALUE_TYPE(value));
 			g_assert (handler_time);
 			param_values[i] = gda_handler_time_get_no_locale_str_from_value (handler_time,
 											 value);
-			
-			/* g_print ("--- TIME=%s\n", param_values[i]); */
+			//g_print ("--- TIME=%s\n", param_values[i]);
 		} else {
 			GdaDataHandler *data_handler = gda_server_provider_get_data_handler_gtype
 				(provider, cnc, G_VALUE_TYPE(value));
@@ -1456,15 +1447,13 @@
 			else
 				param_values[i] = gda_data_handler_get_str_from_value (data_handler,
 										       value);
-			/* g_print ("--- PV=%s\n", param_values[i]); */
+			//g_print ("--- PV=%s\n", param_values[i]);
 
 			mysql_bind_param[i].buffer_type = MYSQL_TYPE_STRING;
 			mysql_bind_param[i].buffer = g_strdup (param_values[i]);
 			mysql_bind_param[i].buffer_length = strlen (param_values[i]);
 			mysql_bind_param[i].length = g_malloc0 (sizeof(unsigned long));
-
 		}
-
 	}
 		
 	if (mysql_stmt_bind_param (cdata->mysql_stmt, mysql_bind_param)) {
@@ -1510,23 +1499,28 @@
 		 * execute another SQL which is the code shown here.
 		 *
 		 * To adapt depending on the C API and its features */
-		GdaStatement *estmt;
-                gchar *esql;
-                estmt = gda_select_alter_select_for_empty (stmt, error);
-                if (!estmt)
+		GdaStatement *stmt_for_empty;
+                gchar *sql_for_empty;
+                stmt_for_empty = gda_select_alter_select_for_empty (stmt, error);
+                if (!stmt_for_empty)
                         return NULL;
-                esql = gda_statement_to_sql (estmt, NULL, error);
-                g_object_unref (estmt);
-                if (!esql)
+                sql_for_empty = gda_statement_to_sql (stmt_for_empty, NULL, error);
+                g_object_unref (stmt_for_empty);
+                if (!sql_for_empty)
                         return NULL;
 
-		/* Execute the 'esql' SQL code */
-                g_free (esql);
+		/* This is a re-prepare of the statement.  The function mysql_stmt_prepare
+		 * will handle this on the server side. */
+		if (mysql_stmt_prepare (cdata->mysql_stmt, sql_for_empty, strlen (sql_for_empty))) {
+			GdaConnectionEvent *event = _gda_mysql_make_error
+				(cdata->cnc, NULL, cdata->mysql_stmt, NULL);
+			return NULL;
+		}
 
-		TO_IMPLEMENT;
-	} else {
-		/* Execute the _GDA_PSTMT (ps)->sql SQL code */
-		TO_IMPLEMENT;
+		/* Execute the 'sql_for_empty' SQL code */
+                g_free (sql_for_empty);
+
+		//TO_IMPLEMENT;
 	}
 
 	
@@ -1561,7 +1555,6 @@
 			// TO_IMPLEMENT;
 			/* Create a #GdaSet containing "IMPACTED_ROWS" */
 			/* Create GdaConnectionEvent notice with the type of command and impacted rows */
-
 			
 			affected_rows = mysql_stmt_affected_rows (cdata->mysql_stmt);
 			if (affected_rows >= 0) {
@@ -1579,12 +1572,9 @@
 			} else {
 				return_value = (GObject *) gda_data_model_array_new (0);
 			}
-			
 		}
-		
 	}
 	return return_value;
-	
 }
 
 /*

Modified: trunk/providers/mysql/gda-mysql-pstmt.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-pstmt.c	(original)
+++ trunk/providers/mysql/gda-mysql-pstmt.c	Wed Oct 15 18:59:50 2008
@@ -84,10 +84,8 @@
 	
 	/* initialize specific parts of @pstmt */
 	// TO_IMPLEMENT;
-	
 	pstmt->mysql_bind_param = NULL;
 	pstmt->mysql_bind_result = NULL;
-	
 }
 
 static void
@@ -99,7 +97,6 @@
 
 	/* free memory */
 	// TO_IMPLEMENT; /* free some specific parts of @pstmt */
-	
 	gint i;
 	for (i = 0; i < g_slist_length (((GdaPStmt *) pstmt)->param_ids); ++i) {
 		g_free (pstmt->mysql_bind_param[i].buffer);
@@ -115,7 +112,6 @@
 	}
 	g_free (pstmt->mysql_bind_result);
 	pstmt->mysql_bind_result = NULL;
-	
 
 	/* chain to parent class */
 	parent_class->finalize (object);

Modified: trunk/providers/mysql/gda-mysql-pstmt.h
==============================================================================
--- trunk/providers/mysql/gda-mysql-pstmt.h	(original)
+++ trunk/providers/mysql/gda-mysql-pstmt.h	Wed Oct 15 18:59:50 2008
@@ -41,6 +41,7 @@
 	GdaPStmt        object;
 
 	GdaConnection  *cnc;
+
 	MYSQL          *mysql;
 	MYSQL_STMT     *mysql_stmt;
 	MYSQL_BIND     *mysql_bind_param;

Modified: trunk/providers/mysql/gda-mysql-recordset.c
==============================================================================
--- trunk/providers/mysql/gda-mysql-recordset.c	(original)
+++ trunk/providers/mysql/gda-mysql-recordset.c	Wed Oct 15 18:59:50 2008
@@ -37,7 +37,6 @@
 
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
-
 enum
 {
 	PROP_0,
@@ -45,7 +44,6 @@
 	PROP_CHUNKS_READ
 };
 
-
 static void
 gda_mysql_recordset_class_init (GdaMysqlRecordsetClass  *klass);
 static void
@@ -59,35 +57,36 @@
 gda_mysql_recordset_fetch_nb_rows (GdaDataSelect  *model);
 static gboolean
 gda_mysql_recordset_fetch_random (GdaDataSelect  *model,
-				  GdaRow    **row,
-				  gint        rownum,
-				  GError    **error);
+				  GdaRow        **row,
+				  gint            rownum,
+				  GError        **error);
 static gboolean
 gda_mysql_recordset_fetch_next (GdaDataSelect  *model,
-				GdaRow    **row,
-				gint        rownum,
-				GError    **error);
+				GdaRow        **row,
+				gint            rownum,
+				GError        **error);
 static gboolean
 gda_mysql_recordset_fetch_prev (GdaDataSelect  *model,
-				GdaRow    **row,
-				gint        rownum,
-				GError    **error);
+				GdaRow        **row,
+				gint            rownum,
+				GError        **error);
 static gboolean
 gda_mysql_recordset_fetch_at (GdaDataSelect  *model,
-			      GdaRow    **row,
-			      gint        rownum,
-			      GError    **error);
-
+			      GdaRow        **row,
+			      gint            rownum,
+			      GError        **error);
 
 struct _GdaMysqlRecordsetPrivate {
-	GdaConnection *cnc;
+	GdaConnection  *cnc;
 	/* TO_ADD: specific information */
 	
-	MYSQL_STMT  *mysql_stmt;
+	MYSQL_STMT     *mysql_stmt;
 
-	gint  chunk_size;    /* Number of rows to fetch at a time when iterating forward/backward. */
-	gint  chunks_read;   /* Number of times that we've iterated forward/backward. */
-	
+	gint            chunk_size;    /* Number of rows to fetch at a time when iterating forward/backward. */
+	gint            chunks_read;   /* Number of times that we've iterated forward/backward. */
+	//
+	GdaRow         *tmp_row;       /* Used in cursor mode to store a reference to the latest #GdaRow. */
+	//
 };
 static GObjectClass *parent_class = NULL;
 
@@ -104,10 +103,8 @@
 
 	/* initialize specific information */
 	// TO_IMPLEMENT;
-	
 	recset->priv->chunk_size = 1;
 	recset->priv->chunks_read = 0;
-	
 }
 
 
@@ -140,7 +137,6 @@
 	g_warning (_("Could not use CURSOR. Mysql version 5.0 at least is required. "
 		     "Chunk size ignored."));
 #endif
-
 }
 
 gint
@@ -157,17 +153,17 @@
 				  const GValue  *value,
 				  GParamSpec    *pspec)
 {
-	GdaMysqlRecordset *record_set;
+	GdaMysqlRecordset *recordset;
 
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (GDA_IS_MYSQL_RECORDSET(object));
 	g_return_if_fail (GDA_MYSQL_RECORDSET(object)->priv != NULL);
 
-	record_set = GDA_MYSQL_RECORDSET(object);
+	recordset = GDA_MYSQL_RECORDSET(object);
 
 	switch (param_id) {
 	case PROP_CHUNK_SIZE:
-		gda_mysql_recordset_set_chunk_size (record_set,
+		gda_mysql_recordset_set_chunk_size (recordset,
 						    g_value_get_int (value));
 		break;
 	case PROP_CHUNKS_READ:
@@ -183,20 +179,20 @@
 				  GValue      *value,
 				  GParamSpec  *pspec)
 {
-	GdaMysqlRecordset *record_set;
+	GdaMysqlRecordset *recordset;
 
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (GDA_IS_MYSQL_RECORDSET(object));
 	g_return_if_fail (GDA_MYSQL_RECORDSET(object)->priv != NULL);
 
-	record_set = GDA_MYSQL_RECORDSET(object);
+	recordset = GDA_MYSQL_RECORDSET(object);
 
 	switch (param_id) {
 	case PROP_CHUNK_SIZE:
-		g_value_set_int (value, record_set->priv->chunk_size);
+		g_value_set_int (value, recordset->priv->chunk_size);
 		break;
 	case PROP_CHUNKS_READ:
-		g_value_set_int (value, record_set->priv->chunks_read);
+		g_value_set_int (value, recordset->priv->chunks_read);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -250,12 +246,17 @@
 	g_return_if_fail (GDA_IS_MYSQL_RECORDSET (recset));
 
 	if (recset->priv) {
-		if (recset->priv->cnc) 
-			g_object_unref (recset->priv->cnc);
+		if (recset->priv->cnc) {
+			g_object_unref (G_OBJECT(recset->priv->cnc));
+			recset->priv->cnc = NULL;
+		}
+		if (recset->priv->tmp_row) {
+			g_object_unref (G_OBJECT(recset->priv->tmp_row));
+			recset->priv->tmp_row = NULL;
+		}
 
 		/* free specific information */
 		// TO_IMPLEMENT;
-		
 		g_free (recset->priv);
 		recset->priv = NULL;
 	}
@@ -323,7 +324,6 @@
 		// TO_IMPLEMENT;
 		
 		_GDA_PSTMT(ps)->ncols = mysql_stmt_field_count (cdata->mysql_stmt);
-		
 	}
 
         /* completing @ps if not yet done */
@@ -356,7 +356,7 @@
 		MYSQL_FIELD *mysql_fields = mysql_fetch_fields (mysql_res);
 		
 		MYSQL_BIND *mysql_bind_result = g_new0 (MYSQL_BIND, GDA_PSTMT (ps)->ncols);
-		//		
+
 		/* fill GdaColumn's data */
 		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
 		     i < GDA_PSTMT (ps)->ncols; 
@@ -423,17 +423,16 @@
 				g_warning (_("Invalid column bind data type. %d\n"),
 					   mysql_bind_result[i].buffer_type);
 			}
-			
 		}
 		
                 if (mysql_stmt_bind_result (cdata->mysql_stmt, mysql_bind_result)) {
-                        g_warning ("mysql_stmt_bind_result failed: %s\n", mysql_stmt_error (cdata->mysql_stmt));
+                        g_warning ("mysql_stmt_bind_result failed: %s\n",
+				   mysql_stmt_error (cdata->mysql_stmt));
                 }
 		
 		mysql_free_result (mysql_res);
 
 		ps->mysql_bind_result = mysql_bind_result;
-
         }
 
 	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported */
@@ -458,7 +457,6 @@
 
 	((GdaDataSelect *) model)->advertized_nrows = mysql_stmt_affected_rows (cdata->mysql_stmt);
 	
-
         return GDA_DATA_MODEL (model);
 }
 
@@ -480,7 +478,6 @@
 	
 	model->advertized_nrows = mysql_stmt_affected_rows (imodel->priv->mysql_stmt);
 	
-
 	return model->advertized_nrows;
 }
 
@@ -489,7 +486,13 @@
 new_row_from_mysql_stmt (GdaMysqlRecordset  *imodel,
 			 gint                rownum)
 {
-	/* g_print ("*** %s -- %d -- %d\n", __func__, ((GdaDataSelect *) imodel)->prep_stmt->ncols, rownum); */
+	/* g_print ("%s(): NCOLS=%d  ROWNUM=%d\n", __func__, */
+	/* 	 ((GdaDataSelect *) imodel)->prep_stmt->ncols, rownum); */
+
+	g_return_val_if_fail (imodel->priv->mysql_stmt != NULL, NULL);
+
+	if (mysql_stmt_fetch (imodel->priv->mysql_stmt))
+		return NULL;
 	
 	MYSQL_BIND *mysql_bind_result = ((GdaMysqlPStmt *) ((GdaDataSelect *) imodel)->prep_stmt)->mysql_bind_result;
 	g_assert (mysql_bind_result);
@@ -497,7 +500,6 @@
 	GdaRow *row = gda_row_new (((GdaDataSelect *) imodel)->prep_stmt->ncols);
 	gint col;
 	for (col = 0; col < ((GdaDataSelect *) imodel)->prep_stmt->ncols; ++col) {
-		
 		gint i = col;
 		
 		GValue *value = gda_row_get_value (row, i);
@@ -635,11 +637,6 @@
 		}
 
 		g_free (strvalue);
-		
-		/* gchar *str = gda_value_stringify (value); */
-		/* g_print ("***V%d=%s\n", i, str); */
-		/* g_free (str); */
-
 	}
 	return row;
 }
@@ -662,28 +659,17 @@
  */
 static gboolean 
 gda_mysql_recordset_fetch_random (GdaDataSelect  *model,
-				  GdaRow    **row,
-				  gint        rownum,
-				  GError    **error)
+				  GdaRow        **row,
+				  gint            rownum,
+				  GError        **error)
 {
 	GdaMysqlRecordset *imodel;
 
 	imodel = GDA_MYSQL_RECORDSET (model);
 
 	// TO_IMPLEMENT;
-	
 	if (*row)
 		return TRUE;
-
-	if (imodel->priv->mysql_stmt == NULL) {
-		g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
-			     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
-			     _("Internal error"));
-		return FALSE;
-	}
-	
-	if (mysql_stmt_fetch (imodel->priv->mysql_stmt))
-		return FALSE;
 	
 	*row = new_row_from_mysql_stmt (imodel, rownum);
 	gda_data_select_take_row (model, *row, rownum);
@@ -702,7 +688,7 @@
  */
 static gboolean
 gda_mysql_recordset_store_all (GdaDataSelect  *model,
-			       GError    **error)
+			       GError        **error)
 {
 	GdaMysqlRecordset *imodel;
 	gint i;
@@ -732,17 +718,26 @@
  */
 static gboolean 
 gda_mysql_recordset_fetch_next (GdaDataSelect  *model,
-				GdaRow    **row,
-				gint        rownum,
-				GError    **error)
+				GdaRow        **row,
+				gint            rownum,
+				GError        **error)
 {
 	GdaMysqlRecordset *imodel = (GdaMysqlRecordset*) model;
 
 	// TO_IMPLEMENT;
-	//
 
-	// gda_data_select_iter_next increments rownum
-	return /* TRUE */ gda_mysql_recordset_fetch_random (model, row, rownum, error);
+	// gda_data_select_iter_next () increments rownum
+
+	if (imodel->priv->tmp_row != NULL) {
+		g_object_unref (G_OBJECT(imodel->priv->tmp_row));
+		imodel->priv->tmp_row = NULL;
+	}
+	
+	*row = new_row_from_mysql_stmt (imodel, rownum);
+
+	imodel->priv->tmp_row = *row;
+
+	return TRUE;
 }
 
 /*
@@ -759,9 +754,9 @@
  */
 static gboolean 
 gda_mysql_recordset_fetch_prev (GdaDataSelect  *model,
-				GdaRow    **row,
-				gint        rownum,
-				GError    **error)
+				GdaRow        **row,
+				gint            rownum,
+				GError        **error)
 {
 	GdaMysqlRecordset *imodel = (GdaMysqlRecordset*) model;
 
@@ -784,9 +779,9 @@
  */
 static gboolean 
 gda_mysql_recordset_fetch_at (GdaDataSelect  *model,
-			      GdaRow    **row,
-			      gint        rownum,
-			      GError    **error)
+			      GdaRow        **row,
+			      gint            rownum,
+			      GError        **error)
 {
 	GdaMysqlRecordset *imodel = (GdaMysqlRecordset*) model;
 	

Modified: trunk/providers/mysql/gda-mysql-recordset.h
==============================================================================
--- trunk/providers/mysql/gda-mysql-recordset.h	(original)
+++ trunk/providers/mysql/gda-mysql-recordset.h	Wed Oct 15 18:59:50 2008
@@ -40,12 +40,12 @@
 typedef struct _GdaMysqlRecordsetPrivate GdaMysqlRecordsetPrivate;
 
 struct _GdaMysqlRecordset {
-	GdaDataSelect                model;
-	GdaMysqlRecordsetPrivate *priv;
+	GdaDataSelect              model;
+	GdaMysqlRecordsetPrivate  *priv;
 };
 
 struct _GdaMysqlRecordsetClass {
-	GdaDataSelectClass             parent_class;
+	GdaDataSelectClass         parent_class;
 };
 
 GType



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