[gnome-db] A few bug fix in mysql provider



Hi,

I've noticed a few bugs in in mysql provider's fetch_row().  Some of
these seem to apply to some other providers too.  I coded up a fix,
but haven't checked it into CVS.  Since I'm new here, I think I should
ask for a permission first.  The diff is below,

  - fixed possible memory leak by moving gda_row_new() a few line down.
  - commented out variable "lengths", which doesn't seem to be used
    anywhere.
  - handle FIELD_TYPE_BLOB length correctly
  - distinguish SQL NULL from 0, 0.0, "".

Note: The code for MySQL data -> GdaValue conversion was factored into
      a seperate function (fill_value) b/c I want to use it somewhere
      else too.

Paisa



Index: providers/mysql/gda-mysql-recordset.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/mysql/gda-mysql-recordset.c,v
retrieving revision 1.26
diff -r1.26 gda-mysql-recordset.c
43a44,108
> void
> fill_value (GdaValue *gda_value, enum enum_field_types type, gchar *value, unsigned long length)
> {
> 	switch (type) {
> 	case FIELD_TYPE_DECIMAL :
> 	case FIELD_TYPE_DOUBLE :
> 		if (value) gda_value_set_double (gda_value, atof (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_FLOAT :
> 		if (value) gda_value_set_single (gda_value, atof (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_LONG :
> 	case FIELD_TYPE_YEAR :
> 		if (value) gda_value_set_integer (gda_value, atol (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_LONGLONG :
> 	case FIELD_TYPE_INT24 :
> 		if (value) gda_value_set_bigint (gda_value, atoll (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_SHORT :
> 		if (value) gda_value_set_smallint (gda_value, atoi (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_TINY :
> 		if (value) gda_value_set_tinyint (gda_value, atoi (value));
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_TINY_BLOB :
> 	case FIELD_TYPE_MEDIUM_BLOB :
> 	case FIELD_TYPE_LONG_BLOB :
> 	case FIELD_TYPE_BLOB :
> 		if (value) gda_value_set_binary (gda_value, value, length);
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_VAR_STRING :
> 	case FIELD_TYPE_STRING :
> 		/* FIXME: we might get "[VAR]CHAR(20) BINARY" type with \0 inside
> 		   We should check for BINARY flag and treat it like a BLOB
> 		 */
> 		if (value) gda_value_set_string (gda_value, value);
> 		else gda_value_set_null (gda_value);
> 		break;
> 	case FIELD_TYPE_DATE :
> 	case FIELD_TYPE_NULL :
> 	case FIELD_TYPE_NEWDATE :
> 	case FIELD_TYPE_ENUM :
> 	case FIELD_TYPE_TIMESTAMP :
> 	case FIELD_TYPE_DATETIME :
> 	case FIELD_TYPE_TIME :
> 	case FIELD_TYPE_SET : /* FIXME */
> 		if (value) gda_value_set_string (gda_value, value);
> 		else gda_value_set_null (gda_value);
> 		break;
> 	default :
> 		g_printerr ("Unknown MySQL datatype.  Fishy, but continueing anyway.\n");
> 		if (value) gda_value_set_string (gda_value, value);
> 		else gda_value_set_null (gda_value);
> 	}
> }
> 
> 
50a116
> 	/* what for?
51a118
> 	*/
53a121,122
> 	unsigned long *mysql_lengths;
> 
74,76c143,145
< 	row = gda_row_new (GDA_DATA_MODEL (recset), field_count);
< 
< 	lengths = recset->mysql_res->lengths;
---
> 	/* what for?
>         lengths = recset->mysql_res->lengths;
> 	*/
78d146
< 
80c148,149
< 	if (!mysql_row)
---
> 	mysql_lengths = mysql_fetch_lengths (recset->mysql_res);
> 	if (!mysql_row || !mysql_lengths)
81a151,152
> 	
> 	row = gda_row_new (GDA_DATA_MODEL (recset), field_count);
84,135c155,159
< 		GdaValue *field;
< 		gchar *thevalue;
< 
< 		field = (GdaValue*) gda_row_get_value (row, i);
< 
< 		thevalue = mysql_row[i];
< 
< 		switch (mysql_fields[i].type) {
< 		case FIELD_TYPE_DECIMAL :
< 		case FIELD_TYPE_DOUBLE :
< 			gda_value_set_double (field, thevalue ? atof (thevalue) : 0.0);
< 			break;
< 		case FIELD_TYPE_FLOAT :
< 			gda_value_set_single (field, thevalue ? atof (thevalue) : 0.0);
< 			break;
< 		case FIELD_TYPE_LONG :
< 		case FIELD_TYPE_YEAR :
< 			gda_value_set_integer (field, thevalue ? atol (thevalue) : 0);
< 			break;
< 		case FIELD_TYPE_LONGLONG :
< 		case FIELD_TYPE_INT24 :
< 			gda_value_set_bigint (field, thevalue ? atoll (thevalue) : 0);
< 			break;
< 		case FIELD_TYPE_SHORT :
< 			gda_value_set_smallint (field, thevalue ? atoi (thevalue) : 0);
< 			break;
< 		case FIELD_TYPE_TINY :
< 			gda_value_set_tinyint (field, thevalue ? atoi (thevalue) : 0);
< 			break;
< 		case FIELD_TYPE_TINY_BLOB :
< 		case FIELD_TYPE_MEDIUM_BLOB :
< 		case FIELD_TYPE_LONG_BLOB :
< 		case FIELD_TYPE_BLOB :
< 			gda_value_set_binary (field, thevalue, mysql_fields[i].max_length);
< 			break;
< 		case FIELD_TYPE_VAR_STRING :
< 		case FIELD_TYPE_STRING :
< 			gda_value_set_string (field, thevalue ? thevalue : "");
< 			break;
< 		case FIELD_TYPE_DATE :
< 		case FIELD_TYPE_NULL :
< 		case FIELD_TYPE_NEWDATE :
< 		case FIELD_TYPE_ENUM :
< 		case FIELD_TYPE_TIMESTAMP :
< 		case FIELD_TYPE_DATETIME :
< 		case FIELD_TYPE_TIME :
< 		case FIELD_TYPE_SET : /* FIXME */
< 			gda_value_set_string (field, thevalue ? thevalue : "");
< 			break;
< 		default :
< 			gda_value_set_string (field, thevalue ? thevalue : "");
< 		}
---
> 		fill_value ((GdaValue*) gda_row_get_value (row, i),
> 			    mysql_fields[i].type,
> 			    mysql_row[i],
> 		/* wrong:   mysql_fields[i].max_length); */ 
> 			    mysql_lengths[i]);
189,190d212
< 	attrs = gda_field_attributes_new ();
< 
192,193c214
< 	if (!mysql_field) {
< 		gda_field_attributes_free (attrs);
---
> 	if (!mysql_field)
195c216,217
< 	}
---
> 
> 	attrs = gda_field_attributes_new ();
200a223
> 	/* gda_field_attributes_set_caption(attrs, ); */
205a229
> 	/* gda_field_attributes_set_references(attrs, ); */
206a231,243
> 	/* attrs->auto_increment_start */
> 	/* attrs->auto_increment_step  */
> 	gda_field_attributes_set_position (attrs, col);
> 	/* FIXME: 
> 	   Can't use mysql_field->def because,
> 	     - don't know length of the mysql_field->def (needed for binary data)
> 	     - manual says we mysql_field->def isn't set unless we use
> 	       mysql_list_fields().  Then it recommend not to use this function,
> 	       but instead use "show columns from table_name;".
> 
> 	       this is same as "describe table_name;" ?
> 	gda_field_attributes_set_default_value (attrs, ...);
> 	*/
Index: providers/mysql/utils.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/mysql/utils.c,v
retrieving revision 1.6
diff -r1.6 utils.c
80a81
> 		/* FIXME: Check for BINARY flags and use blob */



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