Re: [gnome-db] A few bug fix in mysql provider
- From: Paisa Seeluangsawat <paisa unt edu>
- To: Rodrigo Moya <rodrigo gnome-db org>
- Cc: GDA <gnome-db-list gnome org>
- Subject: Re: [gnome-db] A few bug fix in mysql provider
- Date: Tue, 14 Oct 2003 19:51:36 -0500
> > + /* FIXME: The prototype is: gda_value_free (GdaValue*)
> > + but it is called this way: gda_value_free (GdaValue*, (gpointer) NULL)
> > + Is this safe? Doesn't this write NULL other object's memory?
> > + */
> >
> remove this comment, please.
Removed. I didn't know enough about compiler internal working and was
paranoid of buffer overflow when I saw the type mismatch.
> also, here, just remove the function, no need to add those comments,
> which just make the code more confusing.
> ...
> the same here, please just remove code when it's no longer needed, dont
> comment it out.
> ...
> here, again, what's this comment about? If it's wrong, it shouldn't be
> in the code at all.
Removed. It's a coding style left over from non CVS project. Sorry
for the annoyance, and watch out for more CVS newbies mistakes coming
your way :-).
> > gda_field_attributes_set_defined_size (attrs, mysql_field->length);
> > gda_field_attributes_set_table (attrs, mysql_field->table);
> > /* gda_field_attributes_set_caption(attrs, ); */
> > gda_field_attributes_set_scale (attrs, mysql_field->decimals);
> > gda_field_attributes_set_gdatype (attrs, gda_mysql_type_to_gda (mysql_field->type));
> > gda_field_attributes_set_allow_null (attrs, !IS_NOT_NULL (mysql_field->flags));
> > gda_field_attributes_set_primary_key (attrs, IS_PRI_KEY (mysql_field->flags));
> > gda_field_attributes_set_unique_key (attrs, mysql_field->flags & UNIQUE_KEY_FLAG);
> > /* gda_field_attributes_set_references(attrs, ); */
> > gda_field_attributes_set_auto_increment (attrs, mysql_field->flags & AUTO_INCREMENT_FLAG);
> > /* attrs->auto_increment_start */
> > /* attrs->auto_increment_step */
> > gda_field_attributes_set_position (attrs, col);
> here again, if its wrong, remove it, or just fill in the missing data.
Here we are initializing most members of a big struct. The comments
help there to remind us that other fields are intentially left
untouched--not that they are forgotten or the code is out of sync with
struct's definition. I consider this a good programing style. Please
feel free to remove them if you disagree. You make the call.
> > + /* 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, ...);
> > + */
> >
> so, you dont set the default value? Then, please add the code to handle
> it and send a different patch for it. This patch was about fixing a
> leak, and it contains much more things :-) So, please, send a patch for
> the leak, and then, when done, a different patch for the default value
> implementation.
>
> But adding commented/unfinished code is not an option :-)
It contains more than bug fixes because I started off in CVS HEAD
mindset, and just happened to discover bugs as I go on. Anyway, a
patch with no mention of default_value follows.
Some "FIXME" comments are left in the patch, pointing to bugs that
exist in the original code. Ideally, I should fix these bugs. But
just adding warning comments for now is better than doing nothing with
them ;-).
Paisa
? doc/C/tmpl/gda-enum-types.sgml
? libgda/gda-enum-types.c
? libgda/gda-enum-types.h
? libgda/s-enum-types-c
? libgda/s-enum-types-h
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libgda/ChangeLog,v
retrieving revision 1.575
diff -u -r1.575 ChangeLog
--- ChangeLog 13 Oct 2003 03:19:20 -0000 1.575
+++ ChangeLog 15 Oct 2003 00:37:10 -0000
@@ -1,3 +1,15 @@
+2003-10-13 Paisa Seeluangsawat <paisa users sf net>
+
+ * providers/mysql/gda-mysql-provider.c:
+ - add #include <libgda/gda-util.h>
+ - minor cosmatic fixes to stop some compiler warnings.
+ * providers/mysql/gda-mysql-recordset.c
+ - 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, "".
+
2003-10-12 Paisa Seeluangsawat <paisa users sf net>
* libgda/gda-field.h:
Index: doc/C/tmpl/gda-blob.sgml
===================================================================
RCS file: /cvs/gnome/libgda/doc/C/tmpl/gda-blob.sgml,v
retrieving revision 1.2
diff -u -r1.2 gda-blob.sgml
--- doc/C/tmpl/gda-blob.sgml 11 Oct 2003 15:15:11 -0000 1.2
+++ doc/C/tmpl/gda-blob.sgml 15 Oct 2003 00:37:10 -0000
@@ -9,12 +9,10 @@
</para>
-
<!-- ##### SECTION See_Also ##### -->
<para>
</para>
-
<!-- ##### ENUM GdaBlobMode ##### -->
<para>
Index: providers/mysql/gda-mysql-provider.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/mysql/gda-mysql-provider.c,v
retrieving revision 1.45
diff -u -r1.45 gda-mysql-provider.c
--- providers/mysql/gda-mysql-provider.c 15 Aug 2003 12:53:40 -0000 1.45
+++ providers/mysql/gda-mysql-provider.c 15 Oct 2003 00:37:11 -0000
@@ -23,6 +23,7 @@
*/
#include <libgda/gda-data-model-array.h>
+#include <libgda/gda-util.h>
#include <libgda/gda-intl.h>
#include <stdlib.h>
#include <string.h>
@@ -350,8 +351,8 @@
mysql_res = mysql_store_result (mysql);
recset = gda_mysql_recordset_new (cnc, mysql_res, mysql);
if (GDA_IS_MYSQL_RECORDSET (recset)) {
- gda_data_model_set_command_text (recset, arr[n]);
- gda_data_model_set_command_type (recset, GDA_COMMAND_TYPE_SQL);
+ gda_data_model_set_command_text ( (GdaDataModel*) recset, arr[n]);
+ gda_data_model_set_command_type ( (GdaDataModel*) recset, GDA_COMMAND_TYPE_SQL);
reclist = g_list_append (reclist, recset);
}
@@ -663,7 +664,6 @@
static void
add_aggregate_row (GdaDataModelArray *recset, const gchar *str, const gchar *comments)
{
- GdaValue *value;
GList *list;
g_return_if_fail (GDA_IS_DATA_MODEL_ARRAY (recset));
@@ -870,7 +870,7 @@
{
GList *reclist;
GdaMysqlRecordset *recset;
- GdaDataModelArray *model;
+ GdaDataModel *model;
gint rows, r;
g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
@@ -886,10 +886,10 @@
/* add the extra information */
model = gda_data_model_array_new (4);
- gda_data_model_set_column_title (GDA_DATA_MODEL (model), 0, _("Name"));
- gda_data_model_set_column_title (GDA_DATA_MODEL (model), 1, _("Owner"));
- gda_data_model_set_column_title (GDA_DATA_MODEL (model), 2, _("Comments"));
- gda_data_model_set_column_title (GDA_DATA_MODEL (model), 3, "SQL");
+ gda_data_model_set_column_title (model, 0, _("Name"));
+ gda_data_model_set_column_title (model, 1, _("Owner"));
+ gda_data_model_set_column_title (model, 2, _("Comments"));
+ gda_data_model_set_column_title (model, 3, "SQL");
rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (recset));
for (r = 0; r < rows; r++) {
GList *value_list = NULL;
@@ -924,14 +924,14 @@
else
value_list = g_list_append (value_list, gda_value_new_string (""));
- gda_data_model_append_row (GDA_DATA_MODEL (model), value_list);
+ gda_data_model_append_row (model, value_list);
g_free (name);
g_list_foreach (value_list, (GFunc) gda_value_free, NULL);
g_list_free (value_list);
}
- return GDA_DATA_MODEL (model);
+ return model;
}
static GdaDataModel *
Index: providers/mysql/gda-mysql-recordset.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/mysql/gda-mysql-recordset.c,v
retrieving revision 1.26
diff -u -r1.26 gda-mysql-recordset.c
--- providers/mysql/gda-mysql-recordset.c 24 Aug 2003 12:07:16 -0000 1.26
+++ providers/mysql/gda-mysql-recordset.c 15 Oct 2003 00:37:11 -0000
@@ -41,6 +41,66 @@
* Private functions
*/
+void
+fill_gda_value (GdaValue *gda_value, enum enum_field_types type, gchar *value, unsigned long length)
+{
+ if (!value) {
+ gda_value_set_null (gda_value);
+ return;
+ }
+
+ switch (type) {
+ case FIELD_TYPE_DECIMAL :
+ case FIELD_TYPE_DOUBLE :
+ gda_value_set_double (gda_value, atof (value));
+ break;
+ case FIELD_TYPE_FLOAT :
+ gda_value_set_single (gda_value, atof (value));
+ break;
+ case FIELD_TYPE_LONG :
+ case FIELD_TYPE_YEAR :
+ gda_value_set_integer (gda_value, atol (value));
+ break;
+ case FIELD_TYPE_LONGLONG :
+ case FIELD_TYPE_INT24 :
+ gda_value_set_bigint (gda_value, atoll (value));
+ break;
+ case FIELD_TYPE_SHORT :
+ gda_value_set_smallint (gda_value, atoi (value));
+ break;
+ case FIELD_TYPE_TINY :
+ gda_value_set_tinyint (gda_value, atoi (value));
+ break;
+ case FIELD_TYPE_TINY_BLOB :
+ case FIELD_TYPE_MEDIUM_BLOB :
+ case FIELD_TYPE_LONG_BLOB :
+ case FIELD_TYPE_BLOB :
+ gda_value_set_binary (gda_value, value, length);
+ 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
+ */
+ gda_value_set_string (gda_value, 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 */
+ gda_value_set_string (gda_value, value);
+ break;
+ default :
+ g_printerr ("Unknown MySQL datatype. This is fishy, but continueing anyway.\n");
+ gda_value_set_string (gda_value, value);
+ }
+}
+
+
static GdaRow *
fetch_row (GdaMysqlRecordset *recset, gulong rownum)
{
@@ -48,9 +108,10 @@
gint field_count;
gint row_count;
gint i;
- unsigned long *lengths;
MYSQL_FIELD *mysql_fields;
MYSQL_ROW mysql_row;
+ unsigned long *mysql_lengths;
+
g_return_val_if_fail (GDA_IS_MYSQL_RECORDSET (recset), NULL);
@@ -71,68 +132,19 @@
}
mysql_data_seek (recset->mysql_res, rownum);
- row = gda_row_new (GDA_DATA_MODEL (recset), field_count);
-
- lengths = recset->mysql_res->lengths;
mysql_fields = mysql_fetch_fields (recset->mysql_res);
-
mysql_row = mysql_fetch_row (recset->mysql_res);
- if (!mysql_row)
+ mysql_lengths = mysql_fetch_lengths (recset->mysql_res);
+ if (!mysql_row || !mysql_lengths)
return NULL;
+
+ row = gda_row_new (GDA_DATA_MODEL (recset), field_count);
for (i = 0; i < field_count; i++) {
- 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_gda_value ((GdaValue*) gda_row_get_value (row, i),
+ mysql_fields[i].type,
+ mysql_row[i],
+ mysql_lengths[i]);
}
return row;
@@ -186,24 +198,27 @@
if (col >= field_count)
return NULL;
- attrs = gda_field_attributes_new ();
-
mysql_field = mysql_fetch_field_direct (recset->mysql_res, col);
- if (!mysql_field) {
- gda_field_attributes_free (attrs);
+ if (!mysql_field)
return NULL;
- }
+
+ attrs = gda_field_attributes_new ();
if (mysql_field->name)
gda_field_attributes_set_name (attrs, mysql_field->name);
gda_field_attributes_set_defined_size (attrs, mysql_field->length);
gda_field_attributes_set_table (attrs, mysql_field->table);
+ /* gda_field_attributes_set_caption(attrs, ); */
gda_field_attributes_set_scale (attrs, mysql_field->decimals);
gda_field_attributes_set_gdatype (attrs, gda_mysql_type_to_gda (mysql_field->type));
gda_field_attributes_set_allow_null (attrs, !IS_NOT_NULL (mysql_field->flags));
gda_field_attributes_set_primary_key (attrs, IS_PRI_KEY (mysql_field->flags));
gda_field_attributes_set_unique_key (attrs, mysql_field->flags & UNIQUE_KEY_FLAG);
+ /* gda_field_attributes_set_references(attrs, ); */
gda_field_attributes_set_auto_increment (attrs, mysql_field->flags & AUTO_INCREMENT_FLAG);
+ /* attrs->auto_increment_start */
+ /* attrs->auto_increment_step */
+ gda_field_attributes_set_position (attrs, col);
return attrs;
}
Index: providers/mysql/utils.c
===================================================================
RCS file: /cvs/gnome/libgda/providers/mysql/utils.c,v
retrieving revision 1.6
diff -u -r1.6 utils.c
--- providers/mysql/utils.c 19 May 2002 18:55:52 -0000 1.6
+++ providers/mysql/utils.c 15 Oct 2003 00:37:11 -0000
@@ -78,6 +78,7 @@
return GDA_VALUE_TYPE_BINARY;
case FIELD_TYPE_VAR_STRING :
case FIELD_TYPE_STRING :
+ /* FIXME: Check for BINARY flags and use blob */
return GDA_VALUE_TYPE_STRING;
case FIELD_TYPE_NULL :
case FIELD_TYPE_NEWDATE :
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]