On Mon, 2005-11-14 at 12:55 +0100, Rodrigo Moya wrote: > On Tue, 2005-11-01 at 19:14 +0000, Bob Ham wrote: > > Hi, > > > > I'm trying to get bind parameters to work with the MySQL provider. > > Unfortunately, there's a problem with the use of glib hashes in > > GdaParameterList. MySQL doesn't support binding by name, only by > > position and the ordering of parameter additions isn't maintained by the > > GdaParameterList. I've hacked a solution that sorts the parameter names > > alphabetically in the provider, and used numerical parameter names in my > > application. This seems too much of a hack, though. The only decent > > solution I can see is to subclass GdaParameterList and use an ordered > > list to store parameter names. I'd welcome additional input, however. > > > can't you use the position as the "name"? As noted above, this is what I've done. However, it's dependant on the provider sorting the parameter names before binding. It introduces provider-specific semantics to the API. A better solution is to ensure that GdaParameterList maintains parameter ordering. I've reimplemented it using GList instead of GHashTable (attached.) This is less efficient, but is a drop in replacement that provides the requisite semantics. The best solution would be an implementation that uses GHashTable and also maintains ordering. This may be forthcoming. Bob -- Bob Ham <rah bash sh>
Index: gda-parameter.c =================================================================== RCS file: /cvs/gnome/libgda/libgda/gda-parameter.c,v retrieving revision 1.28 diff -u -u -p -r1.28 gda-parameter.c --- gda-parameter.c 25 Sep 2004 14:02:12 -0000 1.28 +++ gda-parameter.c 17 Nov 2005 19:09:39 -0000 @@ -1,4 +1,7 @@ -/* GDA library +/* -*- mode: c; c-basic-offset: 8; -*- + * + * GDA library + * * Copyright (C) 1998-2002 The GNOME Foundation. * * AUTHORS: @@ -20,14 +23,14 @@ * Boston, MA 02111-1307, USA. */ -#include <glib/ghash.h> +#include <glib/glist.h> #include <glib/gmem.h> #include <glib/gmessages.h> #include <glib/gstrfuncs.h> #include <libgda/gda-parameter.h> struct _GdaParameterList { - GHashTable *hash; + GList *list; }; GType @@ -58,12 +61,10 @@ gda_parameter_list_get_type (void) * Private functions */ -static gboolean -free_hash_param (gpointer key, gpointer value, gpointer user_data) +static void +free_list_param (gpointer data, gpointer user_data) { - g_free (key); - gda_parameter_free ((GdaParameter *) value); - return TRUE; + gda_parameter_free ((GdaParameter *) data); } /** @@ -86,7 +87,7 @@ gda_parameter_new_from_value (const gcha param = g_new0 (GdaParameter, 1); param->name = g_strdup (name); - param->value = gda_value_copy (value); + param->value = gda_value_copy ((GdaValue *) value); return param; } @@ -292,7 +293,7 @@ gda_parameter_list_new (void) GdaParameterList *plist; plist = g_new0 (GdaParameterList, 1); - plist->hash = g_hash_table_new (g_str_hash, g_str_equal); + plist->list = NULL; return plist; } @@ -308,8 +309,8 @@ gda_parameter_list_free (GdaParameterLis { g_return_if_fail (plist != NULL); - g_hash_table_foreach (plist->hash, (GHFunc) free_hash_param, NULL); - g_hash_table_destroy (plist->hash); + g_list_foreach (plist->list, (GFunc) free_list_param, NULL); + g_list_free (plist->list); g_free (plist); } @@ -325,21 +326,18 @@ gda_parameter_list_free (GdaParameterLis GdaParameterList * gda_parameter_list_copy (GdaParameterList *plist) { - GdaParameterList *new_list; - GList *node, *names; + GdaParameterList *new_list = gda_parameter_list_new(); + GdaParameter *param; + GList *node; - g_return_val_if_fail (plist != NULL, NULL); - - new_list = gda_parameter_list_new (); - names = gda_parameter_list_get_names (plist); - for (node = g_list_first (names); - node != NULL; - node = g_list_next (node)) { - GdaParameter *param = gda_parameter_list_find (plist, (const gchar *)node->data); - if (param != NULL) /* normally should always be non-null... */ - gda_parameter_list_add_parameter (new_list, param); + for (node = plist->list; node != NULL; node = g_list_next(node)) { + param = (GdaParameter *) node->data; + new_list->list = + g_list_append (new_list->list, + gda_parameter_new_from_value (gda_parameter_get_name (param), + gda_parameter_get_value(param))); } - g_list_free (names); + return new_list; } @@ -356,31 +354,36 @@ gda_parameter_list_copy (GdaParameterLis void gda_parameter_list_add_parameter (GdaParameterList *plist, GdaParameter *param) { - gpointer orig_key; - gpointer orig_value; - const gchar *name; g_return_if_fail (plist != NULL); g_return_if_fail (param != NULL); - name = gda_parameter_get_name (param); - - /* first look for the key in our list */ - if (g_hash_table_lookup_extended (plist->hash, name, &orig_key, &orig_value)) { - g_hash_table_remove (plist->hash, name); - g_free (orig_key); - gda_parameter_free ((GdaParameter *) orig_value); + if (plist->list != NULL) { + const gchar *name; + GList *node; + GdaParameter *list_param; + + name = gda_parameter_get_name (param); + + for (node = plist->list; node != NULL; node = g_list_next (node)) { + list_param = (GdaParameter *) node->data; + if (strcmp (gda_parameter_get_name (list_param), name) == 0) { + plist->list = g_list_remove_link (plist->list, node); + g_list_free_1 (node); + gda_parameter_free (list_param); + } + } } /* add the parameter to the list */ - g_hash_table_insert (plist->hash, g_strdup (name), param); + plist->list = g_list_append (plist->list, param); } static void -get_names_cb (gpointer key, gpointer value, gpointer user_data) +get_names_cb (gpointer data, gpointer user_data) { GList **list = (GList **) user_data; - *list = g_list_append (*list, key); + *list = g_list_append (*list, (gpointer) gda_parameter_get_name((GdaParameter *) data)); } /** @@ -399,7 +402,7 @@ gda_parameter_list_get_names (GdaParamet g_return_val_if_fail (plist != NULL, NULL); - g_hash_table_foreach (plist->hash, get_names_cb, &list); + g_list_foreach (plist->list, get_names_cb, &list); return list; } @@ -416,10 +419,20 @@ gda_parameter_list_get_names (GdaParamet GdaParameter * gda_parameter_list_find (GdaParameterList *plist, const gchar *name) { + GList * node; + GdaParameter * param; + g_return_val_if_fail (plist != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); - return g_hash_table_lookup (plist->hash, name); + for (node = plist->list; node; node = g_list_next (node)) { + param = (GdaParameter *) node->data; + if (strcmp (gda_parameter_get_name (param), name) == 0) { + return param; + } + } + + return NULL; } /** @@ -434,7 +447,9 @@ void gda_parameter_list_clear (GdaParameterList *plist) { g_return_if_fail (plist != NULL); - g_hash_table_foreach_remove (plist->hash, free_hash_param, NULL); + g_list_foreach (plist->list, free_list_param, NULL); + g_list_free (plist->list); + plist->list = NULL; } /** @@ -446,5 +461,5 @@ gda_parameter_list_clear (GdaParameterLi guint gda_parameter_list_get_length (GdaParameterList *plist) { - return plist ? g_hash_table_size (plist->hash) : 0; + return plist ? g_list_length (plist->list) : 0; }
Attachment:
signature.asc
Description: This is a digitally signed message part