[libgda] Render TRUE as 1 and FALSE as 0 in the MySQL and SQLite providers



commit 4ce6e35db8edbf1460cbd6b55e0dd272a4c25176
Author: Vivien Malerba <malerba gnome-db org>
Date:   Fri Feb 5 21:02:16 2010 +0100

    Render TRUE as 1 and FALSE as 0 in the MySQL and SQLite providers

 libgda/sqlite/Makefile.am                   |    2 +
 libgda/sqlite/gda-sqlite-handler-boolean.c  |  279 +++++++++++++++++++++++++++
 libgda/sqlite/gda-sqlite-handler-boolean.h  |   57 ++++++
 libgda/sqlite/gda-sqlite-provider.c         |   15 ++-
 po/POTFILES.in                              |    1 +
 providers/mysql/Makefile.am                 |    2 +
 providers/mysql/gda-mysql-handler-boolean.c |  279 +++++++++++++++++++++++++++
 providers/mysql/gda-mysql-handler-boolean.h |   57 ++++++
 providers/mysql/gda-mysql-provider.c        |  151 ++++++++++++++-
 providers/oracle/gda-oracle-provider.c      |    2 +
 10 files changed, 840 insertions(+), 5 deletions(-)
---
diff --git a/libgda/sqlite/Makefile.am b/libgda/sqlite/Makefile.am
index dd2a66f..7288ccc 100644
--- a/libgda/sqlite/Makefile.am
+++ b/libgda/sqlite/Makefile.am
@@ -44,6 +44,8 @@ libgda_sqlite_la_SOURCES = \
 	gda-sqlite-ddl.h \
 	gda-sqlite-handler-bin.c \
 	gda-sqlite-handler-bin.h \
+	gda-sqlite-handler-boolean.c \
+	gda-sqlite-handler-boolean.h \
 	gda-sqlite-meta.c \
 	gda-sqlite-meta.h \
 	gda-sqlite-provider.c \
diff --git a/libgda/sqlite/gda-sqlite-handler-boolean.c b/libgda/sqlite/gda-sqlite-handler-boolean.c
new file mode 100644
index 0000000..23d94c7
--- /dev/null
+++ b/libgda/sqlite/gda-sqlite-handler-boolean.c
@@ -0,0 +1,279 @@
+/* gda-sqlite-handler-boolean.c
+ *
+ * Copyright (C) 2010 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gda-sqlite-handler-boolean.h"
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+static void gda_sqlite_handler_boolean_class_init (GdaSqliteHandlerBooleanClass * class);
+static void gda_sqlite_handler_boolean_init (GdaSqliteHandlerBoolean * wid);
+static void gda_sqlite_handler_boolean_dispose (GObject   * object);
+
+
+/* GdaDataHandler interface */
+static void         gda_sqlite_handler_boolean_data_handler_init      (GdaDataHandlerIface *iface);
+static gchar       *gda_sqlite_handler_boolean_get_sql_from_value     (GdaDataHandler *dh, const GValue *value);
+static gchar       *gda_sqlite_handler_boolean_get_str_from_value     (GdaDataHandler *dh, const GValue *value);
+static GValue      *gda_sqlite_handler_boolean_get_value_from_sql     (GdaDataHandler *dh, const gchar *sql, 
+								      GType type);
+static GValue      *gda_sqlite_handler_boolean_get_value_from_str     (GdaDataHandler *iface, const gchar *str, 
+								      GType type);
+
+static GValue      *gda_sqlite_handler_boolean_get_sane_init_value    (GdaDataHandler * dh, GType type);
+
+static gboolean     gda_sqlite_handler_boolean_accepts_g_type         (GdaDataHandler * dh, GType type);
+
+static const gchar *gda_sqlite_handler_boolean_get_descr              (GdaDataHandler *dh);
+
+struct  _GdaSqliteHandlerBooleanPriv {
+	gchar          *detailed_descr;
+	guint           nb_g_types;
+	GType          *valid_g_types;
+};
+
+/* get a pointer to the parents to be able to call their destructor */
+static GObjectClass *parent_class = NULL;
+
+GType
+_gda_sqlite_handler_boolean_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+		static const GTypeInfo info = {
+			sizeof (GdaSqliteHandlerBooleanClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gda_sqlite_handler_boolean_class_init,
+			NULL,
+			NULL,
+			sizeof (GdaSqliteHandlerBoolean),
+			0,
+			(GInstanceInitFunc) gda_sqlite_handler_boolean_init
+		};		
+
+		static const GInterfaceInfo data_entry_info = {
+			(GInterfaceInitFunc) gda_sqlite_handler_boolean_data_handler_init,
+			NULL,
+			NULL
+		};
+
+		g_static_mutex_lock (&registering);
+		if (type == 0) {
+			type = g_type_register_static (G_TYPE_OBJECT, "GdaSqliteHandlerBoolean", &info, 0);
+			g_type_add_interface_static (type, GDA_TYPE_DATA_HANDLER, &data_entry_info);
+		}
+		g_static_mutex_unlock (&registering);
+	}
+	return type;
+}
+
+static void
+gda_sqlite_handler_boolean_data_handler_init (GdaDataHandlerIface *iface)
+{
+	iface->get_sql_from_value = gda_sqlite_handler_boolean_get_sql_from_value;
+	iface->get_str_from_value = gda_sqlite_handler_boolean_get_str_from_value;
+	iface->get_value_from_sql = gda_sqlite_handler_boolean_get_value_from_sql;
+	iface->get_value_from_str = gda_sqlite_handler_boolean_get_value_from_str;
+	iface->get_sane_init_value = gda_sqlite_handler_boolean_get_sane_init_value;
+	iface->accepts_g_type = gda_sqlite_handler_boolean_accepts_g_type;
+	iface->get_descr = gda_sqlite_handler_boolean_get_descr;
+}
+
+
+static void
+gda_sqlite_handler_boolean_class_init (GdaSqliteHandlerBooleanClass * class)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (class);
+	
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gda_sqlite_handler_boolean_dispose;
+}
+
+static void
+gda_sqlite_handler_boolean_init (GdaSqliteHandlerBoolean *hdl)
+{
+	/* Private structure */
+	hdl->priv = g_new0 (GdaSqliteHandlerBooleanPriv, 1);
+	hdl->priv->detailed_descr = _("Boolean values handler");
+	hdl->priv->nb_g_types = 1;
+	hdl->priv->valid_g_types = g_new0 (GType, 1);
+	hdl->priv->valid_g_types[0] = G_TYPE_BOOLEAN;
+
+	g_object_set_data (G_OBJECT (hdl), "name", "SqliteBoolean");
+	g_object_set_data (G_OBJECT (hdl), "descr", _("Sqlite boolean representation"));
+}
+
+static void
+gda_sqlite_handler_boolean_dispose (GObject *object)
+{
+	GdaSqliteHandlerBoolean *hdl;
+
+	g_return_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (object));
+
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (object);
+
+	if (hdl->priv) {
+		g_free (hdl->priv->valid_g_types);
+		hdl->priv->valid_g_types = NULL;
+
+		g_free (hdl->priv);
+		hdl->priv = NULL;
+	}
+
+	/* for the parent class */
+	parent_class->dispose (object);
+}
+
+/*
+ * _gda_sqlite_handler_boolean_new
+ *
+ * Creates a data handler for booleans
+ *
+ * Returns: the new object
+ */
+GdaDataHandler *
+_gda_sqlite_handler_boolean_new (void)
+{
+	GObject *obj;
+
+	obj = g_object_new (GDA_TYPE_SQLITE_HANDLER_BOOLEAN, NULL);
+
+	return (GdaDataHandler *) obj;
+}
+
+static gchar *
+gda_sqlite_handler_boolean_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
+{
+	gchar *retval;
+	GdaSqliteHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	if (g_value_get_boolean (value)) 
+		retval = g_strdup ("1");
+	else
+		retval = g_strdup ("0");
+
+	return retval;
+}
+
+static gchar *
+gda_sqlite_handler_boolean_get_str_from_value (GdaDataHandler *iface, const GValue *value)
+{
+	GdaSqliteHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	return gda_value_stringify ((GValue *) value);
+}
+
+static GValue *
+gda_sqlite_handler_boolean_get_value_from_sql (GdaDataHandler *iface, const gchar *sql, GType type)
+{
+	GdaSqliteHandlerBoolean *hdl;
+	GValue *value;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	if (*sql == '0')
+		g_value_set_boolean (value, FALSE);
+	else
+		g_value_set_boolean (value, TRUE);
+	return value;
+}
+
+static GValue *
+gda_sqlite_handler_boolean_get_value_from_str (GdaDataHandler *iface, const gchar *str, GType type)
+{
+	GdaSqliteHandlerBoolean *hdl;
+	GValue *value = NULL;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	if (*str == '0')
+		g_value_set_boolean (value, FALSE);
+	else
+		g_value_set_boolean (value, TRUE);
+
+	return value;
+}
+
+
+static GValue *
+gda_sqlite_handler_boolean_get_sane_init_value (GdaDataHandler *iface, GType type)
+{
+	GdaSqliteHandlerBoolean *hdl;
+	GValue *value;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	g_value_set_boolean (value, FALSE);
+
+	return value;
+}
+
+static gboolean
+gda_sqlite_handler_boolean_accepts_g_type (GdaDataHandler *iface, GType type)
+{
+	GdaSqliteHandlerBoolean *hdl;
+	guint i = 0;
+	gboolean found = FALSE;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), FALSE);
+	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, 0);
+
+	while (!found && (i < hdl->priv->nb_g_types)) {
+		if (hdl->priv->valid_g_types [i] == type)
+			found = TRUE;
+		i++;
+	}
+
+	return found;
+}
+
+static const gchar *
+gda_sqlite_handler_boolean_get_descr (GdaDataHandler *iface)
+{
+	GdaSqliteHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_SQLITE_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	return g_object_get_data (G_OBJECT (hdl), "descr");
+}
diff --git a/libgda/sqlite/gda-sqlite-handler-boolean.h b/libgda/sqlite/gda-sqlite-handler-boolean.h
new file mode 100644
index 0000000..026f071
--- /dev/null
+++ b/libgda/sqlite/gda-sqlite-handler-boolean.h
@@ -0,0 +1,57 @@
+/* gda-sqlite-handler-boolean.h
+ *
+ * Copyright (C) 2010 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDA_SQLITE_HANDLER_BOOLEAN__
+#define __GDA_SQLITE_HANDLER_BOOLEAN__
+
+#include <glib-object.h>
+#include <libgda/gda-data-handler.h>
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_SQLITE_HANDLER_BOOLEAN          (_gda_sqlite_handler_boolean_get_type())
+#define GDA_SQLITE_HANDLER_BOOLEAN(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, _gda_sqlite_handler_boolean_get_type(), GdaSqliteHandlerBoolean)
+#define GDA_SQLITE_HANDLER_BOOLEAN_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, _gda_sqlite_handler_boolean_get_type (), GdaSqliteHandlerBooleanClass)
+#define GDA_IS_SQLITE_HANDLER_BOOLEAN(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, _gda_sqlite_handler_boolean_get_type ())
+
+typedef struct _GdaSqliteHandlerBoolean      GdaSqliteHandlerBoolean;
+typedef struct _GdaSqliteHandlerBooleanClass GdaSqliteHandlerBooleanClass;
+typedef struct _GdaSqliteHandlerBooleanPriv  GdaSqliteHandlerBooleanPriv;
+
+/* struct for the object's data */
+struct _GdaSqliteHandlerBoolean
+{
+	GObject                 object;
+	GdaSqliteHandlerBooleanPriv  *priv;
+};
+
+/* struct for the object's class */
+struct _GdaSqliteHandlerBooleanClass
+{
+	GObjectClass           parent_class;
+};
+
+
+GType           _gda_sqlite_handler_boolean_get_type      (void) G_GNUC_CONST;
+GdaDataHandler *_gda_sqlite_handler_boolean_new           (void);
+
+G_END_DECLS
+
+#endif
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 4d8d393..9bc6400 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -40,6 +40,7 @@
 #include "gda-sqlite-util.h"
 #include "gda-sqlite-meta.h"
 #include "gda-sqlite-handler-bin.h"
+#include "gda-sqlite-handler-boolean.h"
 #include "gda-sqlite-blob-op.h"
 #include <libgda/gda-connection-private.h>
 #include <libgda/binreloc/gda-binreloc.h>
@@ -1229,6 +1230,16 @@ gda_sqlite_provider_get_data_handler (GdaServerProvider *provider, GdaConnection
 			g_object_unref (dh);
 		}
 	}
+	else if (type == G_TYPE_BOOLEAN) {
+		dh = gda_server_provider_handler_find (provider, cnc, type, NULL);
+		if (!dh) {
+			dh = _gda_sqlite_handler_boolean_new ();
+			if (dh) {
+				gda_server_provider_handler_declare (provider, dh, cnc, G_TYPE_BOOLEAN, NULL);
+				g_object_unref (dh);
+			}
+		}
+	}
 	else
 		dh = gda_server_provider_get_data_handler_default (provider, cnc, type, dbms_type);
 
@@ -1314,10 +1325,12 @@ gda_sqlite_provider_statement_to_sql (GdaServerProvider *provider, GdaConnection
 	}
 
 	memset (&context, 0, sizeof (context));
+	context.provider = provider;
+	context.cnc = cnc;
 	context.params = params;
 	context.flags = flags;
 	context.render_operation = (GdaSqlRenderingFunc) sqlite_render_operation; /* specific REGEXP rendering */
-	context.render_expr = sqlite_render_expr; /* render "FALSE" as 0 and TRUE as !0 */
+	context.render_expr = sqlite_render_expr; /* render "FALSE" as 0 and TRUE as 1 */
 
 	str = gda_statement_to_sql_real (stmt, &context, error);
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2b497f7..428d4a7 100755
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -139,6 +139,7 @@ providers/mdb/gda-mdb-provider.c
 providers/mdb/libmain.c
 providers/mdb/mdb_specs_dsn.xml.in
 providers/mysql/gda-mysql-ddl.c
+providers/mysql/gda-mysql-handler-boolean.c
 providers/mysql/gda-mysql-provider.c
 providers/mysql/gda-mysql-recordset.c
 providers/mysql/gda-mysql-util.c
diff --git a/providers/mysql/Makefile.am b/providers/mysql/Makefile.am
index ffe0534..06a2569 100644
--- a/providers/mysql/Makefile.am
+++ b/providers/mysql/Makefile.am
@@ -16,6 +16,8 @@ libgda_mysql_la_SOURCES = \
 	gda-mysql-blob-op.h \
 	gda-mysql-ddl.c \
 	gda-mysql-ddl.h \
+	gda-mysql-handler-boolean.c \
+	gda-mysql-handler-boolean.h \
 	gda-mysql-provider.c \
 	gda-mysql-provider.h \
 	gda-mysql-recordset.c \
diff --git a/providers/mysql/gda-mysql-handler-boolean.c b/providers/mysql/gda-mysql-handler-boolean.c
new file mode 100644
index 0000000..05640e1
--- /dev/null
+++ b/providers/mysql/gda-mysql-handler-boolean.c
@@ -0,0 +1,279 @@
+/* gda-mysql-handler-boolean.c
+ *
+ * Copyright (C) 2010 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gda-mysql-handler-boolean.h"
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+static void gda_mysql_handler_boolean_class_init (GdaMysqlHandlerBooleanClass * class);
+static void gda_mysql_handler_boolean_init (GdaMysqlHandlerBoolean * wid);
+static void gda_mysql_handler_boolean_dispose (GObject   * object);
+
+
+/* GdaDataHandler interface */
+static void         gda_mysql_handler_boolean_data_handler_init      (GdaDataHandlerIface *iface);
+static gchar       *gda_mysql_handler_boolean_get_sql_from_value     (GdaDataHandler *dh, const GValue *value);
+static gchar       *gda_mysql_handler_boolean_get_str_from_value     (GdaDataHandler *dh, const GValue *value);
+static GValue      *gda_mysql_handler_boolean_get_value_from_sql     (GdaDataHandler *dh, const gchar *sql, 
+								      GType type);
+static GValue      *gda_mysql_handler_boolean_get_value_from_str     (GdaDataHandler *iface, const gchar *str, 
+								      GType type);
+
+static GValue      *gda_mysql_handler_boolean_get_sane_init_value    (GdaDataHandler * dh, GType type);
+
+static gboolean     gda_mysql_handler_boolean_accepts_g_type         (GdaDataHandler * dh, GType type);
+
+static const gchar *gda_mysql_handler_boolean_get_descr              (GdaDataHandler *dh);
+
+struct  _GdaMysqlHandlerBooleanPriv {
+	gchar          *detailed_descr;
+	guint           nb_g_types;
+	GType          *valid_g_types;
+};
+
+/* get a pointer to the parents to be able to call their destructor */
+static GObjectClass *parent_class = NULL;
+
+GType
+gda_mysql_handler_boolean_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+		static const GTypeInfo info = {
+			sizeof (GdaMysqlHandlerBooleanClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gda_mysql_handler_boolean_class_init,
+			NULL,
+			NULL,
+			sizeof (GdaMysqlHandlerBoolean),
+			0,
+			(GInstanceInitFunc) gda_mysql_handler_boolean_init
+		};		
+
+		static const GInterfaceInfo data_entry_info = {
+			(GInterfaceInitFunc) gda_mysql_handler_boolean_data_handler_init,
+			NULL,
+			NULL
+		};
+
+		g_static_mutex_lock (&registering);
+		if (type == 0) {
+			type = g_type_register_static (G_TYPE_OBJECT, "GdaMysqlHandlerBoolean", &info, 0);
+			g_type_add_interface_static (type, GDA_TYPE_DATA_HANDLER, &data_entry_info);
+		}
+		g_static_mutex_unlock (&registering);
+	}
+	return type;
+}
+
+static void
+gda_mysql_handler_boolean_data_handler_init (GdaDataHandlerIface *iface)
+{
+	iface->get_sql_from_value = gda_mysql_handler_boolean_get_sql_from_value;
+	iface->get_str_from_value = gda_mysql_handler_boolean_get_str_from_value;
+	iface->get_value_from_sql = gda_mysql_handler_boolean_get_value_from_sql;
+	iface->get_value_from_str = gda_mysql_handler_boolean_get_value_from_str;
+	iface->get_sane_init_value = gda_mysql_handler_boolean_get_sane_init_value;
+	iface->accepts_g_type = gda_mysql_handler_boolean_accepts_g_type;
+	iface->get_descr = gda_mysql_handler_boolean_get_descr;
+}
+
+
+static void
+gda_mysql_handler_boolean_class_init (GdaMysqlHandlerBooleanClass * class)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (class);
+	
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gda_mysql_handler_boolean_dispose;
+}
+
+static void
+gda_mysql_handler_boolean_init (GdaMysqlHandlerBoolean *hdl)
+{
+	/* Private structure */
+	hdl->priv = g_new0 (GdaMysqlHandlerBooleanPriv, 1);
+	hdl->priv->detailed_descr = _("Boolean values handler");
+	hdl->priv->nb_g_types = 1;
+	hdl->priv->valid_g_types = g_new0 (GType, 1);
+	hdl->priv->valid_g_types[0] = G_TYPE_BOOLEAN;
+
+	g_object_set_data (G_OBJECT (hdl), "name", "MySQLBoolean");
+	g_object_set_data (G_OBJECT (hdl), "descr", _("MySQL boolean representation"));
+}
+
+static void
+gda_mysql_handler_boolean_dispose (GObject *object)
+{
+	GdaMysqlHandlerBoolean *hdl;
+
+	g_return_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (object));
+
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (object);
+
+	if (hdl->priv) {
+		g_free (hdl->priv->valid_g_types);
+		hdl->priv->valid_g_types = NULL;
+
+		g_free (hdl->priv);
+		hdl->priv = NULL;
+	}
+
+	/* for the parent class */
+	parent_class->dispose (object);
+}
+
+/**
+ * gda_mysql_handler_boolean_new
+ *
+ * Creates a data handler for booleans
+ *
+ * Returns: the new object
+ */
+GdaDataHandler *
+gda_mysql_handler_boolean_new (void)
+{
+	GObject *obj;
+
+	obj = g_object_new (GDA_TYPE_MYSQL_HANDLER_BOOLEAN, NULL);
+
+	return (GdaDataHandler *) obj;
+}
+
+static gchar *
+gda_mysql_handler_boolean_get_sql_from_value (GdaDataHandler *iface, const GValue *value)
+{
+	gchar *retval;
+	GdaMysqlHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	if (g_value_get_boolean (value)) 
+		retval = g_strdup ("1");
+	else
+		retval = g_strdup ("0");
+
+	return retval;
+}
+
+static gchar *
+gda_mysql_handler_boolean_get_str_from_value (GdaDataHandler *iface, const GValue *value)
+{
+	GdaMysqlHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	return gda_value_stringify ((GValue *) value);
+}
+
+static GValue *
+gda_mysql_handler_boolean_get_value_from_sql (GdaDataHandler *iface, const gchar *sql, GType type)
+{
+	GdaMysqlHandlerBoolean *hdl;
+	GValue *value;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	if (*sql == '0')
+		g_value_set_boolean (value, FALSE);
+	else
+		g_value_set_boolean (value, TRUE);
+	return value;
+}
+
+static GValue *
+gda_mysql_handler_boolean_get_value_from_str (GdaDataHandler *iface, const gchar *str, GType type)
+{
+	GdaMysqlHandlerBoolean *hdl;
+	GValue *value = NULL;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	if (*str == '0')
+		g_value_set_boolean (value, FALSE);
+	else
+		g_value_set_boolean (value, TRUE);
+
+	return value;
+}
+
+
+static GValue *
+gda_mysql_handler_boolean_get_sane_init_value (GdaDataHandler *iface, GType type)
+{
+	GdaMysqlHandlerBoolean *hdl;
+	GValue *value;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	value = g_value_init (g_new0 (GValue, 1), G_TYPE_BOOLEAN);
+	g_value_set_boolean (value, FALSE);
+
+	return value;
+}
+
+static gboolean
+gda_mysql_handler_boolean_accepts_g_type (GdaDataHandler *iface, GType type)
+{
+	GdaMysqlHandlerBoolean *hdl;
+	guint i = 0;
+	gboolean found = FALSE;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), FALSE);
+	g_return_val_if_fail (type != G_TYPE_INVALID, FALSE);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, 0);
+
+	while (!found && (i < hdl->priv->nb_g_types)) {
+		if (hdl->priv->valid_g_types [i] == type)
+			found = TRUE;
+		i++;
+	}
+
+	return found;
+}
+
+static const gchar *
+gda_mysql_handler_boolean_get_descr (GdaDataHandler *iface)
+{
+	GdaMysqlHandlerBoolean *hdl;
+
+	g_return_val_if_fail (GDA_IS_MYSQL_HANDLER_BOOLEAN (iface), NULL);
+	hdl = GDA_MYSQL_HANDLER_BOOLEAN (iface);
+	g_return_val_if_fail (hdl->priv, NULL);
+
+	return g_object_get_data (G_OBJECT (hdl), "descr");
+}
diff --git a/providers/mysql/gda-mysql-handler-boolean.h b/providers/mysql/gda-mysql-handler-boolean.h
new file mode 100644
index 0000000..94a76c7
--- /dev/null
+++ b/providers/mysql/gda-mysql-handler-boolean.h
@@ -0,0 +1,57 @@
+/* gda-mysql-handler-boolean.h
+ *
+ * Copyright (C) 2010 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDA_MYSQL_HANDLER_BOOLEAN__
+#define __GDA_MYSQL_HANDLER_BOOLEAN__
+
+#include <glib-object.h>
+#include <libgda/gda-data-handler.h>
+
+G_BEGIN_DECLS
+
+#define GDA_TYPE_MYSQL_HANDLER_BOOLEAN          (gda_mysql_handler_boolean_get_type())
+#define GDA_MYSQL_HANDLER_BOOLEAN(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gda_mysql_handler_boolean_get_type(), GdaMysqlHandlerBoolean)
+#define GDA_MYSQL_HANDLER_BOOLEAN_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gda_mysql_handler_boolean_get_type (), GdaMysqlHandlerBooleanClass)
+#define GDA_IS_MYSQL_HANDLER_BOOLEAN(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gda_mysql_handler_boolean_get_type ())
+
+typedef struct _GdaMysqlHandlerBoolean      GdaMysqlHandlerBoolean;
+typedef struct _GdaMysqlHandlerBooleanClass GdaMysqlHandlerBooleanClass;
+typedef struct _GdaMysqlHandlerBooleanPriv  GdaMysqlHandlerBooleanPriv;
+
+/* struct for the object's data */
+struct _GdaMysqlHandlerBoolean
+{
+	GObject                 object;
+	GdaMysqlHandlerBooleanPriv  *priv;
+};
+
+/* struct for the object's class */
+struct _GdaMysqlHandlerBooleanClass
+{
+	GObjectClass           parent_class;
+};
+
+
+GType           gda_mysql_handler_boolean_get_type      (void) G_GNUC_CONST;
+GdaDataHandler *gda_mysql_handler_boolean_new           (void);
+
+G_END_DECLS
+
+#endif
diff --git a/providers/mysql/gda-mysql-provider.c b/providers/mysql/gda-mysql-provider.c
index 13833ce..a185206 100644
--- a/providers/mysql/gda-mysql-provider.c
+++ b/providers/mysql/gda-mysql-provider.c
@@ -43,6 +43,7 @@
 
 #include "gda-mysql-util.h"
 #include "gda-mysql-parser.h"
+#include "gda-mysql-handler-boolean.h"
 
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
@@ -1280,6 +1281,16 @@ gda_mysql_provider_get_data_handler (GdaServerProvider  *provider,
 		TO_IMPLEMENT; /* define data handlers for these types */
 		dh = NULL;
 	}
+	else if (type == G_TYPE_BOOLEAN){
+		dh = gda_server_provider_handler_find (provider, cnc, type, NULL);
+                if (!dh) {
+                        dh = gda_mysql_handler_boolean_new ();
+                        if (dh) {
+                                gda_server_provider_handler_declare (provider, dh, cnc, G_TYPE_BOOLEAN, NULL);
+                                g_object_unref (dh);
+                        }
+                }
+	}
 	else
 		dh = gda_server_provider_get_data_handler_default (provider, cnc, type, dbms_type);
 
@@ -1372,6 +1383,9 @@ gda_mysql_provider_create_parser (GdaServerProvider  *provider,
  * This method renders a #GdaStatement into its SQL representation.
  */
 static gchar *mysql_render_function (GdaSqlFunction *func, GdaSqlRenderingContext *context, GError **error);
+static gchar *mysql_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context, 
+				 gboolean *is_default, gboolean *is_null,
+				 GError **error);
 static gchar *
 gda_mysql_provider_statement_to_sql (GdaServerProvider    *provider,
 				     GdaConnection        *cnc,
@@ -1391,15 +1405,14 @@ gda_mysql_provider_statement_to_sql (GdaServerProvider    *provider,
         }
 
         memset (&context, 0, sizeof (context));
+	context.provider = provider;
+	context.cnc = cnc;
         context.params = params;
         context.flags = flags;
 	context.render_function = (GdaSqlRenderingFunc) mysql_render_function; /* don't put any space between function name
 										* and the opening parenthesis, see
 										* http://blog.152.org/2009/12/mysql-error-1305-function-xxx-does-not.html */
-	if (cnc) {
-		context.cnc = cnc;
-		context.provider = gda_connection_get_provider (cnc);
-	}
+	context.render_expr = mysql_render_expr; /* render "FALSE" as 0 and TRUE as 1 */
 
         str = gda_statement_to_sql_real (stmt, &context, error);
 
@@ -1451,6 +1464,136 @@ mysql_render_function (GdaSqlFunction *func, GdaSqlRenderingContext *context, GE
 	return NULL;
 }
 
+static gchar *
+mysql_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context, 
+		   gboolean *is_default, gboolean *is_null,
+		   GError **error)
+{
+	GString *string;
+	gchar *str = NULL;
+
+	g_return_val_if_fail (expr, NULL);
+	g_return_val_if_fail (GDA_SQL_ANY_PART (expr)->type == GDA_SQL_ANY_EXPR, NULL);
+
+	if (is_default)
+		*is_default = FALSE;
+	if (is_null)
+		*is_null = FALSE;
+
+	/* can't have: 
+	 *  - expr->cast_as && expr->param_spec 
+	 */
+	if (!gda_sql_any_part_check_structure (GDA_SQL_ANY_PART (expr), error)) return NULL;
+
+	string = g_string_new ("");
+	if (expr->param_spec) {
+		str = context->render_param_spec (expr->param_spec, expr, context, is_default, is_null, error);
+		if (!str) goto err;
+	}
+	else if (expr->value) {
+		if (expr->value_is_ident && (G_VALUE_TYPE (expr->value) == G_TYPE_STRING) &&
+		    g_value_get_string (expr->value)) {
+			gchar **ids_array;
+			gint i;
+			GString *string = NULL;
+			GdaConnectionOptions cncoptions = 0;
+			if (context->cnc)
+				g_object_get (G_OBJECT (context->cnc), "options", &cncoptions, NULL);
+
+			ids_array = gda_sql_identifier_split (g_value_get_string (expr->value));
+			if (!ids_array) 
+				str = g_value_dup_string (expr->value);
+			else if (!(ids_array[0])) goto err;
+			else {
+				for (i = 0; ids_array[i]; i++) {
+					gchar *tmp;
+					if (!string)
+						string = g_string_new ("");
+					else
+						g_string_append_c (string, '.');
+					tmp = gda_sql_identifier_quote (ids_array[i], context->cnc,
+									context->provider, FALSE,
+					   cncoptions & GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE);
+					g_string_append (string, tmp);
+					g_free (tmp);
+				}
+				g_strfreev (ids_array);
+				str = g_string_free (string, FALSE);
+			}
+		}
+		else {
+			str = gda_value_stringify (expr->value);
+			if (!str) goto err;
+			if (is_null && gda_value_is_null (expr->value))
+				*is_null = TRUE;
+			else if (is_default && (G_VALUE_TYPE (expr->value) == G_TYPE_STRING) && 
+				 !g_ascii_strcasecmp (g_value_get_string (expr->value), "default"))
+				*is_default = TRUE;
+			else if (!g_ascii_strcasecmp (str, "FALSE")) {
+				g_free (str);
+				str = g_strdup ("0");
+			}
+			else if (!g_ascii_strcasecmp (str, "TRUE")) {
+				g_free (str);
+				str = g_strdup ("1");
+			}
+		}
+	}
+	else if (expr->func) {
+		str = context->render_function (GDA_SQL_ANY_PART (expr->func), context, error);
+		if (!str) goto err;
+	}
+	else if (expr->cond) {
+		str = context->render_operation (GDA_SQL_ANY_PART (expr->cond), context, error);
+		if (!str) goto err;
+	}
+	else if (expr->select) {
+		gchar *str1;
+		if (GDA_SQL_ANY_PART (expr->select)->type == GDA_SQL_ANY_STMT_SELECT)
+			str1 = context->render_select (GDA_SQL_ANY_PART (expr->select), context, error);
+		else
+			str1 = context->render_compound (GDA_SQL_ANY_PART (expr->select), context, error);
+		if (!str1) goto err;
+
+		if (! GDA_SQL_ANY_PART (expr)->parent ||
+		    (GDA_SQL_ANY_PART (expr)->parent->type != GDA_SQL_ANY_SQL_FUNCTION)) {
+			str = g_strdup_printf ("(%s)", str1);
+			g_free (str1);
+		}
+		else
+			str = str1;
+	}
+	else if (expr->case_s) {
+		str = context->render_case (GDA_SQL_ANY_PART (expr->case_s), context, error);
+		if (!str) goto err;
+	}
+	else {
+		if (is_null)
+			*is_null = TRUE;
+		str = g_strdup ("NULL");
+	}
+
+	if (!str) {
+		/* TO REMOVE */
+		str = g_strdup ("[...]");
+	}
+
+	if (expr->cast_as) 
+		g_string_append_printf (string, "CAST (%s AS %s)", str, expr->cast_as);
+	else
+		g_string_append (string, str);
+	g_free (str);
+
+	str = string->str;
+	g_string_free (string, FALSE);
+	return str;
+
+ err:
+	g_string_free (string, TRUE);
+	return NULL;
+}
+
+
 static GdaMysqlPStmt *
 real_prepare (GdaServerProvider *provider, GdaConnection *cnc, GdaStatement *stmt, GError **error)
 {
diff --git a/providers/oracle/gda-oracle-provider.c b/providers/oracle/gda-oracle-provider.c
index 71881d4..8bf66b4 100644
--- a/providers/oracle/gda-oracle-provider.c
+++ b/providers/oracle/gda-oracle-provider.c
@@ -1261,6 +1261,8 @@ gda_oracle_provider_statement_to_sql (GdaServerProvider *provider, GdaConnection
 	}
 
 	memset (&context, 0, sizeof (context));
+	context.provider = provider;
+	context.cnc = cnc;
 	context.params = params;
 	context.flags = flags;
 	context.render_select = (GdaSqlRenderingFunc) oracle_render_select;



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