Re: [gnome-db] Bind parameters



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



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