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