[libgda] Work on the Firebird provider, thanks to Faghmie Davids



commit 1d8eba10492401e6b94114269742ac623c3292d9
Author: Vivien Malerba <malerba gnome-db org>
Date:   Sun Dec 11 21:40:47 2011 +0100

    Work on the Firebird provider, thanks to Faghmie Davids
    
    2 providers are created: one for the client version and one
    for the embedded server version

 configure.ac                                       |   53 +--
 libgda.spec.in                                     |    2 +-
 m4/firebird.m4                                     |  229 ++++++++++
 providers/Makefile.am                              |    4 +-
 providers/firebird/Makefile.am                     |   37 +-
 providers/firebird/gda-firebird-meta.c             |    4 +-
 providers/firebird/gda-firebird-provider.c         |  466 ++++++++++++++++----
 providers/firebird/gda-firebird-pstmt.c            |   10 +-
 providers/firebird/gda-firebird-pstmt.h            |    9 +-
 providers/firebird/gda-firebird-recordset.c        |  416 +++++++++++++++++-
 providers/firebird/gda-firebird-recordset.h        |   31 ++-
 providers/firebird/gda-firebird-util.c             |   16 +-
 providers/firebird/gda-firebird.h                  |   23 +-
 providers/firebird/{libmain.c => libmain-client.c} |    2 +-
 providers/firebird/{libmain.c => libmain-embed.c}  |    4 +-
 15 files changed, 1103 insertions(+), 203 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index e982a31..307c679 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,7 @@ m4_include(m4/mdbtools.m4)
 m4_include(m4/bdb.m4)
 m4_include(m4/mysql.m4)
 m4_include(m4/postgresql.m4)
+m4_include(m4/firebird.m4)
 m4_include(m4/oracle.m4)
 m4_include(m4/java.m4)
 m4_include(m4/ldap.m4)
@@ -602,52 +603,7 @@ dnl Test for LDAP
 LDAP_CHECK($lib)
 
 dnl test for FireBird
-try_firebird=true
-AC_ARG_WITH(firebird,
-[  --with-firebird=<directory>	use FireBird backend in <directoty>],[
-if test $withval = no
-then
-	try_firebird=false
-elif test $withval = yes
-then
-	dir="/usr/local"
-else
-	dir=$withval
-fi
-])
-if test $try_firebird = true
-then
-	AC_MSG_CHECKING(for FireBird installation)
-	for d in $dir /usr/local/firebird /usr/local /usr /opt/firebird
-	do
-		if test -f $d/include/ibase.h
-		then
-			AC_MSG_RESULT(found FireBird in $d)
-			firebirddir=$d
-			break
-		fi
-	done
-	if test x$firebirddir = x
-	then
-		AC_MSG_WARN(FireBird backend not used)
-	else
-		AC_DEFINE(HAVE_FIREBIRD, 1, [Have FireBird])
-		FIREBIRD_CFLAGS="-I${firebirddir}/include"
-		if test -f $firebirddir/lib/libfbembed.so
-		then
-			FIREBIRD_LIBS="-L${firebirddir}/lib -lfbembed"
-		else
-			if test -f $firebirddir/lib/libfbclient.so
-			then
-				FIREBIRD_LIBS="-L${firebirddir}/lib -lfbclient"
-			else
-				FIREBIRD_LIBS="-L${firebirddir}/lib -lgds -ldl -lcrypt"
-			fi
-		fi
-	fi
-fi
-
-AM_CONDITIONAL(FIREBIRD, test x$firebirddir != x)
+FIREBIRD_CHECK($lib)
 
 dnl Test for MDB Tools (for MS Access files)
 MDBTOOLS_CHECK([$lib])
@@ -898,6 +854,8 @@ providers/oracle/Makefile
 providers/oracle/libgda-oracle-5.0.pc
 providers/postgres/Makefile
 providers/postgres/libgda-postgres-5.0.pc
+providers/firebird/Makefile
+providers/firebird/libgda-firebird-5.0.pc
 providers/sqlite/Makefile
 providers/sqlite/libgda-sqlite-5.0.pc
 providers/jdbc/Makefile
@@ -996,7 +954,8 @@ echo "   Building Vala Bindings: `if test x$enable_vala != xno; then echo yes; e
 echo "   Compiled providers:"
 echo "      Berkeley DB = $bdb_found"
 echo "      Berkeley DB SQL = $bdbsql_found"
-dnl echo "      FireBird = `if test x$firebirddir != x; then echo yes; else echo no; fi`"
+echo "      FireBird (client)= $firebird_client_found"
+echo "      FireBird (embed)= $firebird_embed_found"
 echo "      MDB (MS Access) = $mdbtools_found"
 echo "      MySQL = $mysql_found"
 echo "      Oracle = $oracle_found"
diff --git a/libgda.spec.in b/libgda.spec.in
index 6fc4eff..be4479f 100644
--- a/libgda.spec.in
+++ b/libgda.spec.in
@@ -24,7 +24,7 @@
 %define           SYBASE   0
 %define 	  MDB	   0
 %define		  LDAP	   0
-%define		  FIREBIRD 0
+%define		  FIREBIRD 1
 
 %{?_with_tds:%define FREETDS 	1}
 %{?_with_db2:%define IBMDB2 	1}
diff --git a/m4/firebird.m4 b/m4/firebird.m4
new file mode 100644
index 0000000..ab65404
--- /dev/null
+++ b/m4/firebird.m4
@@ -0,0 +1,229 @@
+dnl -*- mode: autoconf -*-
+dnl Copyright 2010 Vivien Malerba
+dnl
+dnl SYNOPSIS
+dnl
+dnl   FIREBIRD_CHECK([libdirname])
+dnl
+dnl   [libdirname]: defaults to "lib". Can be overridden by the --with-firebird-libdir-name option
+dnl
+dnl DESCRIPTION
+dnl
+dnl   This macro tries to find the Firebird libraries and header files.
+dnl
+dnl   It defines two options:
+dnl   --with-firebird=yes/no/<directory>
+dnl   --with-firebird-libdir-name=<dir. name>
+dnl
+dnl   If the 1st option is "yes" then the macro in several well known directories
+dnl
+dnl   If the 1st option is "no" then the macro does not attempt at locating the
+dnl   firebird package
+dnl
+dnl   If the 1st option is a drectory name, then the macro tries to locate the firebird package
+dnl   in the specified directory.
+dnl
+dnl   If the macro has to try to locate the firebird package in one or more directories, it will
+dnl   try to locate the header files in $dir/include and the library files in $dir/lib, unless
+dnl   the second option is used to specify a directory name to be used instead of "lib" (for
+dnl   example lib64).
+dnl
+dnl USED VARIABLES
+dnl
+dnl   $linklibext: contains the library suffix (like ".so"). If not specified ".so" is used.
+dnl   $platform_win32: contains "yes" on Windows platforms. If not specified, assumes "no"
+dnl
+dnl
+dnl DEFINED VARIABLES
+dnl
+dnl   This macro always calls:
+dnl
+dnl    AC_SUBST(FIREBIRD_CLIENT_LIBS)
+dnl    AC_SUBST(FIREBIRD_CLIENT_CFLAGS)
+dnl    firebird_client_found=yes/no
+dnl    AC_SUBST(FIREBIRD_EMBED_LIBS)
+dnl    AC_SUBST(FIREBIRD_EMBED_CFLAGS)
+dnl    firebird_embed_found=yes/no
+dnl
+dnl   and if the firebird package is found:
+dnl
+dnl    AM_CONDITIONAL(FIREBIRD, true)
+dnl    AM_CONDITIONAL(FIREBIRD_CLIENT, true)
+dnl    AM_CONDITIONAL(FIREBIRD_EMBED, true)
+dnl
+dnl
+dnl LICENSE
+dnl
+dnl This file is free software; the author(s) gives unlimited
+dnl permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+
+m4_define([_FIREBIRD_CHECK_INTERNAL],
+[
+    AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+    AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+    AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
+
+    firebird_loclibdir=$1
+    if test "x$firebird_loclibdir" = x
+    then
+        if test "x$platform_win32" = xyes
+	then
+	    firebird_loclibdir=bin
+	else
+	    firebird_loclibdir=lib
+	fi
+    fi
+
+    # determine if Firebird should be searched for
+    firebird_found=no
+    try_firebird=true
+    FIREBIRD_LIBS=""
+    firebird_test_dir="$FIREBIRD_HOME /usr /opt/firebird /local"
+    AC_ARG_WITH(firebird,
+              AS_HELP_STRING([--with-firebird[=@<:@yes/no/<directory>@:>@]],
+                             [Locate Firebird's client libraries]),[
+			     if test $withval = no
+			     then
+			         try_firebird=false
+			     elif test $withval != yes
+			     then
+			         firebird_test_dir=$withval
+			     fi])
+    AC_ARG_WITH(firebird-libdir-name,
+              AS_HELP_STRING([--with-firebird-libdir-name[=@<:@<dir. name>@:>@]],
+                             [Locate FIREBIRD library file, related to the prefix specified from --with-firebird]),
+			     [firebird_loclibdir=$withval])
+
+    # try to locate files
+    if test $try_firebird = true
+    then
+	if test "x$linklibext" = x
+	then
+	    if test $platform_win32 = yes
+	    then
+	        firebird_libext=".dll"
+	    else
+	        firebird_libext=".so"
+            fi
+	else
+	    firebird_libext="$linklibext"
+	fi
+
+	dnl checking for client libraries
+	firebirddir=""
+	for d in $firebird_test_dir
+	do
+	    firebirddir=""
+	    AC_MSG_CHECKING([for Firebird client files in $d])
+	    if test $platform_win32 = yes
+	    then
+	        clntlibname="fbclient$firebird_libext"
+	    else
+	        clntlibname="libfbclient$firebird_libext"
+	    fi
+
+	    if test -f $d/$firebird_loclibdir/$clntlibname
+	    then
+  	        save_CFLAGS="$CFLAGS"
+  	        save_LIBS="$LIBS"
+		CFLAGS="$CFLAGS -I$d/include"
+	        LIBS="$LIBS -L$d/$firebird_loclibdir -lfbclient"
+   	        AC_LINK_IFELSE([AC_LANG_SOURCE([
+#include <ibase.h>
+int main() {
+    printf("%p", isc_open);
+    return 0;
+}
+])],
+	                     firebirddir=$d)
+	        CFLAGS="$save_CFLAGS"
+  	        LIBS="$save_LIBS"
+ 	    fi
+
+	    if test x$firebirddir != x
+	    then
+		AC_MSG_RESULT([found])
+		FIREBIRD_CLIENT_CFLAGS="-I${firebirddir}/include"
+	    	FIREBIRD_CLIENT_LIBS="-L${firebirddir}/$firebird_loclibdir -lfbclient"
+		break
+  	    else
+	        AC_MSG_RESULT([not found])
+	    fi
+	done
+
+	dnl checking for embedded libraries
+	firebirddir=""
+	for d in $firebird_test_dir
+	do
+	    firebirddir=""
+	    AC_MSG_CHECKING([for Firebird embedded library files in $d])
+	    if test $platform_win32 = yes
+	    then
+	        clntlibname="fbembed$firebird_libext"
+	    else
+	        clntlibname="libfbembed$firebird_libext"
+	    fi
+
+	    if test -f $d/$firebird_loclibdir/$clntlibname
+	    then
+  	        save_CFLAGS="$CFLAGS"
+  	        save_LIBS="$LIBS"
+		CFLAGS="$CFLAGS -I$d/include"
+	        LIBS="$LIBS -L$d/$firebird_loclibdir -lfbembed"
+   	        AC_LINK_IFELSE([AC_LANG_SOURCE([
+#include <ibase.h>
+int main() {
+    printf("%p", isc_open);
+    return 0;
+}
+])],
+	                     firebirddir=$d)
+	        CFLAGS="$save_CFLAGS"
+  	        LIBS="$save_LIBS"
+ 	    fi
+
+	    if test x$firebirddir != x
+	    then
+		AC_MSG_RESULT([found])
+		FIREBIRD_EMBED_CFLAGS="-I${firebirddir}/include"
+	    	FIREBIRD_EMBED_LIBS="-L${firebirddir}/$firebird_loclibdir -lfbembed"
+		break
+  	    else
+	        AC_MSG_RESULT([not found])
+	    fi
+	done
+
+
+	if test "x$FIREBIRD_CLIENT_LIBS" = x -a "x$FIREBIRD_EMBED_LIBS"
+	then
+	    AC_MSG_NOTICE([FIREBIRD backend not used])
+	else
+	    if test "x$FIREBIRD_CLIENT_LIBS" != x
+    	    then
+	        firebird_client_found=yes
+	    fi
+	    if test "x$FIREBIRD_EMBED_LIBS" != x
+    	    then
+	        firebird_embed_found=yes
+	    fi
+	fi
+    fi
+
+    AM_CONDITIONAL(FIREBIRD,[test "$firebird_client_found" = "yes" -o "$firebird_embed_found" = "yes"])
+    AM_CONDITIONAL(FIREBIRD_CLIENT,[test "$firebird_client_found" = "yes"])
+    AM_CONDITIONAL(FIREBIRD_EMBED,[test "$firebird_embed_found" = "yes"])
+    AC_SUBST(FIREBIRD_CLIENT_LIBS)
+    AC_SUBST(FIREBIRD_CLIENT_CFLAGS)
+    AC_SUBST(FIREBIRD_EMBED_LIBS)
+    AC_SUBST(FIREBIRD_EMBED_CFLAGS)
+])
+
+dnl Usage:
+dnl   FIREBIRD_CHECK([libdirname])
+
+AC_DEFUN([FIREBIRD_CHECK],
+[
+    _FIREBIRD_CHECK_INTERNAL([$1])
+])
diff --git a/providers/Makefile.am b/providers/Makefile.am
index b8fa6fe..8035971 100644
--- a/providers/Makefile.am
+++ b/providers/Makefile.am
@@ -55,6 +55,6 @@ SUBDIRS = \
 	$(GDA_ORACLE_SERVER) \
 	$(GDA_WEB_SERVER) \
 	$(GDA_SQLCIPHER_SERVER) \
-	$(GDA_LDAP_SERVER)
-#	$(GDA_FIREBIRD_SERVER) 
+	$(GDA_LDAP_SERVER) \
+	$(GDA_FIREBIRD_SERVER) 
 
diff --git a/providers/firebird/Makefile.am b/providers/firebird/Makefile.am
index c9fcd82..2c59649 100644
--- a/providers/firebird/Makefile.am
+++ b/providers/firebird/Makefile.am
@@ -1,14 +1,19 @@
 providerdir=$(libdir)/libgda-$(GDA_ABI_MAJOR_VERSION).$(GDA_ABI_MINOR_VERSION)/providers
-provider_LTLIBRARIES = libgda-firebird.la
+provider_LTLIBRARIES =
 
-#Rem: FIREBIRD_CFLAGS and FIREBIRD_LIBS are the compile and link flags necessary to use the
-# C API. It is specific to the API and should be computed in the configure.in script.
+if FIREBIRD_CLIENT
+provider_LTLIBRARIES+=libgda-firebird-client.la
+endif
+
+if FIREBIRD_EMBED
+provider_LTLIBRARIES+=libgda-firebird-embed.la
+endif
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir) \
 	-I$(top_srcdir)/libgda \
 	-I$(top_builddir) \
-	$(COREDEPS_CFLAGS) $(COREDEPS_WFLAGS) #$(FIREBIRD_CFLAGS) 
+	$(COREDEPS_CFLAGS) $(COREDEPS_WFLAGS) $(FIREBIRD_CFLAGS)
 
 # parser generation
 parser.c parser.h: parser.y $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD)
@@ -22,15 +27,15 @@ firebird_token_types.h: gen_def$(EXEEXT_FOR_BUILD) parser.h
 
 $(OBJECTS) $(libgda_firebird_la_OBJECTS): firebird_token_types.h
 
-libgda_firebird_la_SOURCES = \
+firebird_sources = \
+	gda-firebird-provider.c \
+	gda-firebird-provider.h \
 	gda-firebird-blob-op.c \
 	gda-firebird-blob-op.h \
 	gda-firebird-ddl.c \
 	gda-firebird-ddl.h \
 	gda-firebird-parser.c \
 	gda-firebird-parser.h \
-	gda-firebird-provider.c \
-	gda-firebird-provider.h \
 	gda-firebird-pstmt.h \
 	gda-firebird-pstmt.c \
 	gda-firebird-meta.c \
@@ -40,15 +45,21 @@ libgda_firebird_la_SOURCES = \
 	gda-firebird-util.c \
 	gda-firebird-util.h \
 	gda-firebird.h \
-	libmain.c \
 	parser.h \
-        parser.c \
-        firebird_token_types.h
+	parser.c \
+	firebird_token_types.h
+
+libgda_firebird_client_la_SOURCES = $(firebird_sources) libmain-client.c
+libgda_firebird_client_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED) $(LIBTOOL_PROV_EXPORT_OPTIONS)
+libgda_firebird_client_la_LIBADD = \
+	$(top_builddir)/libgda/libgda-5.0.la \
+	$(COREDEPS_LIBS) $(FIREBIRD_CLIENT_LIBS)
 
-libgda_firebird_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED) $(LIBTOOL_PROV_EXPORT_OPTIONS)
-libgda_firebird_la_LIBADD = \
+libgda_firebird_embed_la_SOURCES = $(firebird_sources) libmain-embed.c
+libgda_firebird_embed_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED) $(LIBTOOL_PROV_EXPORT_OPTIONS)
+libgda_firebird_embed_la_LIBADD = \
 	$(top_builddir)/libgda/libgda-5.0.la \
-	$(COREDEPS_LIBS) #$(FIREBIRD_LIBS)
+	$(COREDEPS_LIBS) $(FIREBIRD_EMBED_LIBS)
 
 xmldir   = $(datadir)/libgda-5.0
 xml_in_files = \
diff --git a/providers/firebird/gda-firebird-meta.c b/providers/firebird/gda-firebird-meta.c
index 3f15214..052b491 100644
--- a/providers/firebird/gda-firebird-meta.c
+++ b/providers/firebird/gda-firebird-meta.c
@@ -130,8 +130,8 @@ _gda_firebird_meta_udt (GdaServerProvider *prov, GdaConnection *cnc,
 	gboolean retval = TRUE;
 
 	/* set internal holder's values from the arguments */
-	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), udt_catalog);
-	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), udt_schema);
+	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), udt_catalog, error);
+	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), udt_schema, error);
 
 	TO_IMPLEMENT;
 	/* fill in @model, with something like:
diff --git a/providers/firebird/gda-firebird-provider.c b/providers/firebird/gda-firebird-provider.c
index 1d14f28..890f79e 100644
--- a/providers/firebird/gda-firebird-provider.c
+++ b/providers/firebird/gda-firebird-provider.c
@@ -40,6 +40,8 @@
 #include "gda-firebird-recordset.h"
 #include "gda-firebird-ddl.h"
 #include "gda-firebird-meta.h"
+#include "gda-firebird-parser.h"
+#include "gda-firebird-util.h"
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
 /*
@@ -54,9 +56,13 @@ static GObjectClass *parent_class = NULL;
  * GdaServerProvider's virtual methods
  */
 /* connection management */
-static gboolean            gda_firebird_provider_open_connection (GdaServerProvider *provider, GdaConnection *cnc,
-								  GdaQuarkList *params, GdaQuarkList *auth,
-								  guint *task_id, GdaServerProviderAsyncCallback async_cb, gpointer cb_data);
+static gboolean            gda_firebird_provider_open_connection (GdaServerProvider *provider,
+								  GdaConnection *cnc,
+								  GdaQuarkList *params,
+								  GdaQuarkList *auth,
+								  guint *task_id,
+								  GdaServerProviderAsyncCallback async_cb,
+								  gpointer cb_data);
 static gboolean            gda_firebird_provider_close_connection (GdaServerProvider *provider, GdaConnection *cnc);
 static const gchar        *gda_firebird_provider_get_server_version (GdaServerProvider *provider, GdaConnection *cnc);
 static const gchar        *gda_firebird_provider_get_database (GdaServerProvider *provider, GdaConnection *cnc);
@@ -101,35 +107,51 @@ static GdaDataHandler     *gda_firebird_provider_get_data_handler (GdaServerProv
 static const gchar*        gda_firebird_provider_get_default_dbms_type (GdaServerProvider *provider, GdaConnection *cnc,
 									GType type);
 /* statements */
-static GdaSqlParser        *gda_firebird_provider_create_parser (GdaServerProvider *provider, GdaConnection *cnc);
-static gchar               *gda_firebird_provider_statement_to_sql  (GdaServerProvider *provider, GdaConnection *cnc,
-								     GdaStatement *stmt, GdaSet *params, 
+static GdaSqlParser        *gda_firebird_provider_create_parser (GdaServerProvider *provider,
+								 GdaConnection *cnc);
+static gchar               *gda_firebird_provider_statement_to_sql  (GdaServerProvider *provider,
+								     GdaConnection *cnc,
+								     GdaStatement *stmt,
+								     GdaSet *params,
 								     GdaStatementSqlFlag flags,
-								     GSList **params_used, GError **error);
-static gboolean             gda_firebird_provider_statement_prepare (GdaServerProvider *provider, GdaConnection *cnc,
+								     GSList **params_used,
+								     GError **error);
+static gboolean             gda_firebird_provider_statement_prepare (GdaServerProvider *provider,
+								     GdaConnection *cnc,
 								     GdaStatement *stmt, GError **error);
-static GObject             *gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnection *cnc,
-								     GdaStatement *stmt, GdaSet *params,
-								     GdaStatementModelUsage model_usage, 
-								     GType *col_types, GdaSet **last_inserted_row, 
-								     guint *task_id, GdaServerProviderAsyncCallback async_cb, 
+static GObject             *gda_firebird_provider_statement_execute (GdaServerProvider *provider,
+								     GdaConnection *cnc,
+								     GdaStatement *stmt,
+								     GdaSet *params,
+								     GdaStatementModelUsage model_usage,
+								     GType *col_types,
+								     GdaSet **last_inserted_row,
+								     guint *task_id,
+								     GdaServerProviderAsyncCallback async_cb,
 								     gpointer cb_data, GError **error);
 
 /* distributed transactions */
-static gboolean gda_firebird_provider_xa_start    (GdaServerProvider *provider, GdaConnection *cnc, 
-						   const GdaXaTransactionId *xid, GError **error);
+static gboolean gda_firebird_provider_xa_start    (GdaServerProvider *provider,
+						   GdaConnection *cnc,
+						   const GdaXaTransactionId *xid,
+						   GError **error);
 
-static gboolean gda_firebird_provider_xa_end      (GdaServerProvider *provider, GdaConnection *cnc, 
-						   const GdaXaTransactionId *xid, GError **error);
-static gboolean gda_firebird_provider_xa_prepare  (GdaServerProvider *provider, GdaConnection *cnc, 
-						   const GdaXaTransactionId *xid, GError **error);
+static gboolean gda_firebird_provider_xa_end      (GdaServerProvider *provider,
+						   GdaConnection *cnc,
+						   const GdaXaTransactionId *xid,
+						   GError **error);
 
-static gboolean gda_firebird_provider_xa_commit   (GdaServerProvider *provider, GdaConnection *cnc, 
+static gboolean gda_firebird_provider_xa_prepare  (GdaServerProvider *provider,
+						   GdaConnection *cnc,
+						   const GdaXaTransactionId *xid,
+						   GError **error);
+
+static gboolean gda_firebird_provider_xa_commit   (GdaServerProvider *provider, GdaConnection *cnc,
 						   const GdaXaTransactionId *xid, GError **error);
-static gboolean gda_firebird_provider_xa_rollback (GdaServerProvider *provider, GdaConnection *cnc, 
+static gboolean gda_firebird_provider_xa_rollback (GdaServerProvider *provider, GdaConnection *cnc,
 						   const GdaXaTransactionId *xid, GError **error);
 
-static GList   *gda_firebird_provider_xa_recover  (GdaServerProvider *provider, GdaConnection *cnc, 
+static GList   *gda_firebird_provider_xa_recover  (GdaServerProvider *provider, GdaConnection *cnc,
 						   GError **error);
 
 /* 
@@ -138,6 +160,8 @@ static GList   *gda_firebird_provider_xa_recover  (GdaServerProvider *provider,
 static void gda_firebird_free_cnc_data (FirebirdConnectionData *cdata);
 
 
+static gchar	*fb_server_get_version (FirebirdConnectionData *fcnc);
+
 /*
  * Prepared internal statements
  * TO_ADD: any prepared statement to be used internally by the provider should be
@@ -187,10 +211,10 @@ gda_firebird_provider_class_init (GdaFirebirdProviderClass *klass)
         provider_class->rollback_savepoint = NULL /*gda_firebird_provider_rollback_savepoint*/;
         provider_class->delete_savepoint = NULL /*gda_firebird_provider_delete_savepoint*/;
 
-	provider_class->create_parser = NULL /*gda_firebird_provider_create_parser*/;
-	provider_class->statement_to_sql = NULL /*gda_firebird_provider_statement_to_sql*/;
-	provider_class->statement_prepare = NULL /*gda_firebird_provider_statement_prepare*/;
-	provider_class->statement_execute = NULL /*gda_firebird_provider_statement_execute*/;
+	provider_class->create_parser = gda_firebird_provider_create_parser;
+	provider_class->statement_to_sql = gda_firebird_provider_statement_to_sql;
+	provider_class->statement_prepare = gda_firebird_provider_statement_prepare;
+	provider_class->statement_execute = gda_firebird_provider_statement_execute;
 
 	provider_class->is_busy = NULL;
 	provider_class->cancel = NULL;
@@ -277,7 +301,7 @@ gda_firebird_provider_get_type (void)
 	static GType type = 0;
 
 	if (G_UNLIKELY (type == 0)) {
-		static GStaticMutex registering = G_STATIC_MUTEX_INIT;
+		//static GStaticMutex registering = G_STATIC_MUTEX_INIT;
 		static GTypeInfo info = {
 			sizeof (GdaFirebirdProviderClass),
 			(GBaseInitFunc) NULL,
@@ -330,6 +354,7 @@ gda_firebird_provider_open_connection (GdaServerProvider *provider, GdaConnectio
 				       GdaQuarkList *params, GdaQuarkList *auth,
 				       guint *task_id, GdaServerProviderAsyncCallback async_cb, gpointer cb_data)
 {
+	g_print("Attempting to open Firebird DB connection\n");
 	g_return_val_if_fail (GDA_IS_FIREBIRD_PROVIDER (provider), FALSE);
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 
@@ -343,7 +368,7 @@ gda_firebird_provider_open_connection (GdaServerProvider *provider, GdaConnectio
 	const gchar *fb_db, *fb_user, *fb_password, *fb_charset;
 	fb_db = (gchar *) gda_quark_list_find (params, "DB_NAME");
         if (!fb_db) {
-                gda_connection_add_event_string (cnc, 
+                gda_connection_add_event_string (cnc,
 						 _("The connection string must contain the DB_NAME values"));
                 return FALSE;
         }
@@ -360,7 +385,7 @@ gda_firebird_provider_open_connection (GdaServerProvider *provider, GdaConnectio
 	cdata = g_new0 (FirebirdConnectionData, 1);
 
 	/* Initialize dpb_buffer */
-        dpb = fcnc->dpb_buffer;
+        dpb = cdata->dpb_buffer;
         *dpb++ = isc_dpb_version1;
 
         /* Set user name */
@@ -388,20 +413,22 @@ gda_firebird_provider_open_connection (GdaServerProvider *provider, GdaConnectio
         }
 
         /* Save dpb length */
-        fcnc->dpb_length = dpb - fcnc->dpb_buffer;
-
-	if (isc_attach_database (fcnc->status, strlen (fb_db), fb_db, &(fcnc->handle), fcnc->dpb_length,
-                                 fcnc->dpb_buffer)) {
-		gda_firebird_free_cnc_data (fcnc);
-		
+        cdata->dpb_length = dpb - cdata->dpb_buffer;
+
+	if (isc_attach_database (cdata->status, strlen (fb_db), fb_db, &(cdata->handle), cdata->dpb_length,
+                                 cdata->dpb_buffer)) {
+		gda_firebird_free_cnc_data (cdata);
+		gda_connection_add_event_string (cnc, 
+						 _("Failed to connect to the database"));
+		//g_print("Failed to connect to the database\n");
 		return FALSE;
 	}
 
 	/* connection is now opened */
 	gda_connection_internal_set_provider_data (cnc, cdata, (GDestroyNotify) gda_firebird_free_cnc_data);
 	 
-        fcnc->dbname = g_strdup (fb_db);
-        fcnc->server_version = fb_server_get_version (fcnc);
+	cdata->dbname = g_strdup (fb_db);
+	cdata->server_version = fb_server_get_version (cdata);
 
 	return TRUE;
 }
@@ -424,12 +451,12 @@ gda_firebird_provider_close_connection (GdaServerProvider *provider, GdaConnecti
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 
 	/* Close the connection using the C API */
-	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
+	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata) 
 		return FALSE;
 
 	/* detach from database */
-        isc_detach_database (fcnc->status, &(fcnc->handle));
+	isc_detach_database (cdata->status, &(cdata->handle));
 
 	/* Free the FirebirdConnectionData structure and its contents*/
 	gda_firebird_free_cnc_data (cdata);
@@ -451,7 +478,7 @@ gda_firebird_provider_get_server_version (GdaServerProvider *provider, GdaConnec
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 
-	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
+	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata) 
 		return FALSE;
 
@@ -471,7 +498,7 @@ gda_firebird_provider_get_database (GdaServerProvider *provider, GdaConnection *
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
 
-	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
+	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata) 
 		return NULL;
 
@@ -659,8 +686,10 @@ gda_firebird_provider_perform_operation (GdaServerProvider *provider, GdaConnect
  * Begin transaction request
  */
 static gboolean
-gda_firebird_provider_begin_transaction (GdaServerProvider *provider, GdaConnection *cnc,
-					 const gchar *name, GdaTransactionIsolation level,
+gda_firebird_provider_begin_transaction (GdaServerProvider *provider,
+					 GdaConnection *cnc,
+					 const gchar *name,
+					 GdaTransactionIsolation level,
 					 GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -688,20 +717,20 @@ gda_firebird_provider_begin_transaction (GdaServerProvider *provider, GdaConnect
 		return FALSE;
 	}
 
-        /* start the transaction */
-        cdata->ftr = g_new0 (isc_tr_handle, 1);
-        if (isc_start_transaction (cdata->status, cdata->ftr, 1, &(cdata->handle),
-                                   (unsigned short) sizeof (tpb), &tpb)) {
-                _gda_firebird_connection_make_error (cnc, 0);
-                g_free (cdata->ftr);
+	/* start the transaction */
+	cdata->ftr = g_new0 (isc_tr_handle, 1);
+	if (isc_start_transaction (cdata->status, (cdata->ftr), 1, &(cdata->handle),
+				(unsigned short) sizeof (tpb), &tpb)) {
+		_gda_firebird_make_error (cnc, 0);
+		g_free (cdata->ftr);
 		cdata->ftr = NULL;
 
-                return FALSE;
-        }
+		return FALSE;
+	}
 
-        gda_connection_internal_transaction_started (cnc, NULL, name, level);
+	gda_connection_internal_transaction_started (cnc, NULL, name, level);
 
-        return TRUE;
+	return TRUE;
 }
 
 /*
@@ -712,7 +741,7 @@ gda_firebird_provider_commit_transaction (GdaServerProvider *provider, GdaConnec
 					  const gchar *name, GError **error)
 {
 	FirebirdConnectionData *cdata;
-        gboolean result;
+	gboolean result;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
@@ -726,8 +755,8 @@ gda_firebird_provider_commit_transaction (GdaServerProvider *provider, GdaConnec
                 return FALSE;
         }
 
-        if (isc_commit_transaction (fcnc->status, cdata->ftr)) {
-		_gda_firebird_connection_make_error (cnc, 0);
+        if (isc_commit_transaction (cdata->status, cdata->ftr)) {
+		_gda_firebird_make_error (cnc, 0);
                 result = FALSE;
         }
         else {
@@ -749,6 +778,7 @@ gda_firebird_provider_rollback_transaction (GdaServerProvider *provider, GdaConn
 					    const gchar *name, GError **error)
 {
 	FirebirdConnectionData *cdata;
+	gboolean result = FALSE;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
@@ -757,9 +787,24 @@ gda_firebird_provider_rollback_transaction (GdaServerProvider *provider, GdaConn
 	if (!cdata) 
 		return FALSE;
 
-	TO_IMPLEMENT;
+	if (!cdata->ftr) {
+		gda_connection_add_event_string (cnc, _("Invalid transaction handle"));
+		return FALSE;
+	}
 
-	return FALSE;
+	if (isc_rollback_transaction (cdata->status, cdata->ftr)) {
+		_gda_firebird_make_error (cnc, 0);
+		result = FALSE;
+	}
+	else {
+		gda_connection_internal_transaction_committed (cnc, name);
+		result = TRUE;
+	}
+
+	g_free (cdata->ftr);
+	cdata->ftr = NULL;
+
+	return result;
 }
 
 /*
@@ -959,8 +1004,8 @@ gda_firebird_provider_get_default_dbms_type (GdaServerProvider *provider, GdaCon
 static GdaSqlParser *
 gda_firebird_provider_create_parser (GdaServerProvider *provider, GdaConnection *cnc)
 {
-	TO_IMPLEMENT;
-	return NULL;
+	return (GdaSqlParser*) g_object_new (GDA_TYPE_FIREBIRD_PARSER, "tokenizer-flavour",
+                                             GDA_SQL_PARSER_FLAVOUR_STANDARD, NULL);
 }
 
 /*
@@ -997,26 +1042,212 @@ static gboolean
 gda_firebird_provider_statement_prepare (GdaServerProvider *provider, GdaConnection *cnc,
 					 GdaStatement *stmt, GError **error)
 {
-	GdaFirebirdPStmt *ps;
+	GdaFirebirdPStmt 		*ps;
+	FirebirdConnectionData	*cdata;
+	gboolean				result = FALSE;
+
+	int            buffer[2048];
+
+	XSQLVAR         *var;
+	short           num_cols, i;
+	short           length, alignment, type, offset;
+	int             fetch_stat;
+	static char     stmt_info[] = { isc_info_sql_stmt_type };
+	char            info_buffer[20];
+	short           l;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, FALSE);
 	g_return_val_if_fail (GDA_IS_STATEMENT (stmt), FALSE);
 
 	/* fetch prepares stmt if already done */
-	ps = gda_connection_get_prepared_statement (cnc, stmt);
+	ps = (GdaFirebirdPStmt *)gda_connection_get_prepared_statement (cnc, stmt);
 	if (ps)
 		return TRUE;
 
+	/* render as SQL understood by Firebird */
+	GdaSet *params		= NULL;
+	gchar *sql			= NULL;
+	GSList *used_params	= NULL;
+	g_print("gda_statement_get_parameters\n\n");
+	if (!gda_statement_get_parameters (stmt, &params, error))
+		goto out_err;
+
+	g_print("gda_firebird_provider_statement_to_sql\n");
+	sql = gda_firebird_provider_statement_to_sql (provider, NULL, stmt, params, GDA_STATEMENT_SQL_PARAMS_AS_COLON,
+						&used_params, error);
+	if (!sql)
+		goto out_err;
+
+	g_print("Now get the internal FB-connection\n");
+	/* get private connection data */
+	cdata = (FirebirdConnectionData *) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		goto out_err;
+
+	/* create the stmt object */
+	ps = (GdaFirebirdPStmt *) g_object_new (GDA_TYPE_FIREBIRD_PSTMT, NULL);
+	ps->stmt_h = 0;
+
+	g_print("isc_dsql_allocate_statement\n\n");
+	/* actually prepare statement */
+	if (isc_dsql_allocate_statement(cdata->status, &(cdata->handle), &(ps->stmt_h)))
+		goto out_err;
+
+
+	g_print("Check if we have a transaction.\n\n");
+	if (NULL == cdata->ftr) {
+		g_print("Begin a transaction.\n");
+
+		if (!gda_firebird_provider_begin_transaction (provider
+					, cnc
+					, "prepare_tr"
+					, GDA_TRANSACTION_ISOLATION_UNKNOWN
+					, error)){
+			g_print("Could not start a transaction.\n");
+			isc_print_status(cdata->status);
+			g_print("\n");
+			goto out_err;
+		}
+	}
+	if (NULL == ps->sqlda){
+		/* 
+		 * Allocate enough space for 20 fields.  
+		 * If more fields get selected, re-allocate SQLDA later.
+		 */
+		ps->sqlda			= g_new0(XSQLDA, 1);
+		ps->sqlda->sqln		= 1;
+		ps->sqlda->version	= 1;
+	}
+	g_print("isc_dsql_prepare\n");
+
+	/* now prepare the fb statement */
+	if (isc_dsql_prepare(cdata->status, (cdata->ftr), &(ps->stmt_h), 0, sql, SQL_DIALECT_V6, ps->sqlda)){
+		//gda_connection_add_event_string (cnc, _("Could not prepare the FB statement"));
+		g_print("Failed to prepare the statement.\n");
+		goto out_err;
+	}
+
+	/* What is the statement type of this statement?
+	 *
+	 * stmt_info is a 1 byte info request.  info_buffer is a buffer
+	 * large enough to hold the returned info packet
+	 * The info_buffer returned contains a isc_info_sql_stmt_type in the first byte, 
+	 * two bytes of length, and a statement_type token.
+	 */
+
+	if (!isc_dsql_sql_info(cdata->status, &(ps->stmt_h), sizeof (stmt_info), stmt_info,
+			       sizeof (info_buffer), info_buffer)) {
+		l = (short) isc_vax_integer((char *) info_buffer + 1, 2);
+		ps->statement_type = isc_vax_integer((char *) info_buffer + 3, l);
+	}
+
+	ps->is_non_select = !ps->sqlda->sqld;
+
+	if (!ps->is_non_select){
+		/*
+		 * Process select statements.
+		 */
+
+		num_cols = ps->sqlda->sqld;
+
+		/* Need more room. */
+		if (ps->sqlda->sqln < num_cols)
+		{
+			g_free(ps->sqlda);
+			ps->sqlda			= g_new0(XSQLDA, num_cols);
+			ps->sqlda->sqln		= num_cols;
+			ps->sqlda->version	= 1;
+
+			if (isc_dsql_describe(cdata->status, &(ps->stmt_h), SQL_DIALECT_V6, ps->sqlda))
+			{
+				goto out_err;
+			}
+
+			num_cols = ps->sqlda->sqld;
+		}
+
+		/*
+		 * Set up SQLDA.
+		 */
+		for (var = ps->sqlda->sqlvar, offset = 0, i = 0; i < num_cols; var++, i++)
+		{
+			length = alignment = var->sqllen;
+			type = var->sqltype & ~1;
+			var->sqlname[var->sqlname_length + 1] = '\0';
+			var->relname[var->relname_length + 1] = '\0';
+			var->ownname[var->ownname_length + 1] = '\0';
+			var->aliasname[var->aliasname_length + 1] = '\0';
+
+			if (type == SQL_TEXT)
+				alignment = 1;
+			else if (type == SQL_VARYING)
+			{
+				length += sizeof (short) + 1;
+				alignment = sizeof (short);
+			}
+			/*  RISC machines are finicky about word alignment
+			 *  So the output buffer values must be placed on
+			 *  word boundaries where appropriate
+			 */
+			offset			= FB_ALIGN(offset, alignment);
+			var->sqldata	= (char *) buffer + offset;
+			offset			+= length;
+			offset			= FB_ALIGN(offset, sizeof (short));
+			var->sqlind		= (short*) ((char *) buffer + offset);
+			offset			+= sizeof  (short);
+		}
+	}
+
 	/* prepare @stmt using the C API, creates @ps */
-	TO_IMPLEMENT;
-	if (!ps)
-		return FALSE;
-	else {
-		gda_connection_add_prepared_statement (cnc, stmt, ps);
-		g_object_unref (ps);
-		return TRUE;
+	/* make a list of the parameter names used in the statement */
+	GSList *param_ids = NULL;
+	if (used_params) {
+		GSList *list;
+		for (list = used_params; list; list = list->next) {
+				const gchar *cid;
+				cid = gda_holder_get_id (GDA_HOLDER (list->data));
+				if (cid) {
+					param_ids = g_slist_append (param_ids, g_strdup (cid));
+					//g_print ("PostgreSQL's PREPARATION: param ID: %s\n", cid);
+				}
+				else {
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_PREPARE_STMT_ERROR,
+						"%s", _("Unnamed parameter is not allowed in prepared statements"));
+					g_slist_foreach (param_ids, (GFunc) g_free, NULL);
+					g_slist_free (param_ids);
+					goto out_err;
+				}
+		}
+	}
+
+	g_print("Adding the prepared statement to GDA.\n");
+	//ps = (GdaFirebirdPStmt *) g_object_new (GDA_TYPE_FIREBIRD_PSTMT, NULL);
+	gda_pstmt_set_gda_statement (_GDA_PSTMT (ps), stmt);
+	_GDA_PSTMT (ps)->param_ids = param_ids;
+	_GDA_PSTMT (ps)->sql = sql;
+
+	gda_connection_add_prepared_statement (cnc, stmt, (GdaPStmt *) ps);
+	g_object_unref (ps);
+
+	/* create a prepared statement */
+
+	result  = TRUE;
+
+ out_err:
+ 	if (FALSE == result){
+		g_print("ERROR OCCURED!!!\n");
+		isc_print_status(cdata->status);
+		g_print("\n");
+
+		if (used_params)
+			g_slist_free (used_params);
+		if (params)
+			g_object_unref (params);
+
+		g_free (sql);
 	}
+	return result;
 }
 
 /*
@@ -1033,15 +1264,20 @@ gda_firebird_provider_statement_prepare (GdaServerProvider *provider, GdaConnect
  * actual inserted row
  */
 static GObject *
-gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnection *cnc,
+gda_firebird_provider_statement_execute (GdaServerProvider *provider,
+					 GdaConnection *cnc,
 					 GdaStatement *stmt, GdaSet *params,
-					 GdaStatementModelUsage model_usage, 
-					 GType *col_types, GdaSet **last_inserted_row, 
-					 guint *task_id, 
-					 GdaServerProviderAsyncCallback async_cb, gpointer cb_data, GError **error)
+					 GdaStatementModelUsage model_usage,
+					 GType *col_types,
+					 GdaSet **last_inserted_row,
+					 guint *task_id,
+					 GdaServerProviderAsyncCallback async_cb,
+					 gpointer cb_data,
+					 GError **error)
 {
 	GdaFirebirdPStmt *ps;
 	FirebirdConnectionData *cdata;
+	gchar *sql;
 
 	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 	g_return_val_if_fail (gda_connection_get_provider (cnc) == provider, NULL);
@@ -1060,7 +1296,7 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 
 
 	/* get/create new prepared statement */
-	ps = gda_connection_get_prepared_statement (cnc, stmt);
+	ps = (GdaFirebirdPStmt *)gda_connection_get_prepared_statement (cnc, stmt);
 	if (!ps) {
 		if (!gda_firebird_provider_statement_prepare (provider, cnc, stmt, NULL)) {
 			/* this case can appear for example if some variables are used in places
@@ -1068,16 +1304,17 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 			 * in a SELECT statement). The action here is to get the actual SQL code for @stmt,
 			 * and use that SQL instead of @stmt to create another GdaFirebirdPStmt object.
 			 */
-			TO_IMPLEMENT;
+			g_print("Could not prepare the statement :-(.\n");
+			//TO_IMPLEMENT;
 			return NULL;
 		}
 		else
-			ps = gda_connection_get_prepared_statement (cnc, stmt);
+			ps = (GdaFirebirdPStmt *)gda_connection_get_prepared_statement (cnc, stmt);
 	}
 	g_assert (ps);
 
 	/* optionnally reset the prepared statement if required by the API */
-	TO_IMPLEMENT;
+	//TO_IMPLEMENT;
 	
 	/* bind statement's parameters */
 	GSList *list;
@@ -1089,7 +1326,7 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 		
 		/* find requested parameter */
 		if (!params) {
-			event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
+			event = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR);
 			gda_connection_event_set_description (event, _("Missing parameter(s) to execute query"));
 			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
 				     GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR,
@@ -1108,17 +1345,18 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 		if (!h) {
 			gchar *str;
 			str = g_strdup_printf (_("Missing parameter '%s' to execute query"), pname);
-			event = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
+			event = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR);
 			gda_connection_event_set_description (event, str);
 			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
-				     "%s", GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, str);
+				     GDA_SERVER_PROVIDER_MISSING_PARAM_ERROR, "%s", str);
 			g_free (str);
 			break;
 		}
 
 		/* actual binding using the C API, for parameter at position @i */
-		const GValue *value = gda_holder_get_value (h);
-		TO_IMPLEMENT;
+		//TODO: Not sure how this should be done right now.
+		//const GValue *value = gda_holder_get_value (h);
+		//TO_IMPLEMENT;
 	}
 		
 	if (event) {
@@ -1127,9 +1365,9 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 	}
 	
 	/* add a connection event for the execution */
-	event = gda_connection_event_new (GDA_CONNECTION_EVENT_COMMAND);
-        gda_connection_event_set_description (event, _GDA_PSTMT (ps)->sql);
-        gda_connection_add_event (cnc, event);
+	event = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_COMMAND);
+	gda_connection_event_set_description (event, _GDA_PSTMT (ps)->sql);
+	gda_connection_add_event (cnc, event);
 	
 	/* execute prepared statement using C API depending on its kind */
 	if (! g_ascii_strncasecmp (_GDA_PSTMT (ps)->sql, "SELECT", 6) ||
@@ -1142,15 +1380,21 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
 		else
 			flags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;
 
-                data_model = (GObject *) gda_firebird_recordset_new (cnc, ps, flags, col_types);
+		data_model = (GObject *) gda_firebird_recordset_new (cnc, ps, flags, col_types);
 		gda_connection_internal_statement_executed (cnc, stmt, params, NULL); /* required: help @cnc keep some stats */
 		return data_model;
         }
 	else {
 		GdaSet *set = NULL;
+		//TODO: What the hell must I do here?
+		//TO_IMPLEMENT;
+		//g_print("SQL: %s\n\n", _GDA_PSTMT (ps)->sql);
+		if (isc_dsql_execute(cdata->status, cdata->ftr, &(ps->stmt_h), SQL_DIALECT_V6, NULL)) {
+			isc_print_status(cdata->status);
+			g_print("\n");
+		}
 
-		TO_IMPLEMENT;
-                /* Create a #GdaSet containing "IMPACTED_ROWS" */
+		/* Create a #GdaSet containing "IMPACTED_ROWS" */
 		/* Create GdaConnectionEvent notice with the type of command and impacted rows */
 
 		gda_connection_internal_statement_executed (cnc, stmt, params, event); /* required: help @cnc keep some stats */
@@ -1162,7 +1406,7 @@ gda_firebird_provider_statement_execute (GdaServerProvider *provider, GdaConnect
  * starts a distributed transaction: put the XA transaction in the ACTIVE state
  */
 static gboolean
-gda_firebird_provider_xa_start (GdaServerProvider *provider, GdaConnection *cnc, 
+gda_firebird_provider_xa_start (GdaServerProvider *provider, GdaConnection *cnc,
 				const GdaXaTransactionId *xid, GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -1184,7 +1428,7 @@ gda_firebird_provider_xa_start (GdaServerProvider *provider, GdaConnection *cnc,
  * This state is required by some database providers before actually going to the PREPARED state
  */
 static gboolean
-gda_firebird_provider_xa_end (GdaServerProvider *provider, GdaConnection *cnc, 
+gda_firebird_provider_xa_end (GdaServerProvider *provider, GdaConnection *cnc,
 			      const GdaXaTransactionId *xid, GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -1205,7 +1449,7 @@ gda_firebird_provider_xa_end (GdaServerProvider *provider, GdaConnection *cnc,
  * prepares the distributed transaction: put the XA transaction in the PREPARED state
  */
 static gboolean
-gda_firebird_provider_xa_prepare (GdaServerProvider *provider, GdaConnection *cnc, 
+gda_firebird_provider_xa_prepare (GdaServerProvider *provider, GdaConnection *cnc,
 				  const GdaXaTransactionId *xid, GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -1227,7 +1471,7 @@ gda_firebird_provider_xa_prepare (GdaServerProvider *provider, GdaConnection *cn
  * terminates the XA transaction
  */
 static gboolean
-gda_firebird_provider_xa_commit (GdaServerProvider *provider, GdaConnection *cnc, 
+gda_firebird_provider_xa_commit (GdaServerProvider *provider, GdaConnection *cnc,
 				 const GdaXaTransactionId *xid, GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -1248,7 +1492,7 @@ gda_firebird_provider_xa_commit (GdaServerProvider *provider, GdaConnection *cnc
  * Rolls back an XA transaction, possible only if in the ACTIVE, IDLE or PREPARED state
  */
 static gboolean
-gda_firebird_provider_xa_rollback (GdaServerProvider *provider, GdaConnection *cnc, 
+gda_firebird_provider_xa_rollback (GdaServerProvider *provider, GdaConnection *cnc,
 				   const GdaXaTransactionId *xid, GError **error)
 {
 	FirebirdConnectionData *cdata;
@@ -1299,3 +1543,37 @@ gda_firebird_free_cnc_data (FirebirdConnectionData *cdata)
 	TO_IMPLEMENT;
 	g_free (cdata);
 }
+
+/*
+ *  fb_server_get_version
+ *
+ *  Gets Firebird connection's server version number
+ *
+ *  Returns: A string containing server version, or NULL if error
+ *           String must be released after use
+ */
+static gchar *
+fb_server_get_version (FirebirdConnectionData *fcnc)
+{
+	gchar buffer[254], item, *p_buffer;
+	gint length;
+	gchar fdb_info[] = {
+		isc_info_isc_version,
+		isc_info_end
+	};
+
+	/* Try to get datbase version */
+	if (! isc_database_info (fcnc->status, &(fcnc->handle), sizeof (fdb_info), fdb_info,
+				 sizeof (buffer), buffer)) {
+		p_buffer = buffer;
+		if (*p_buffer != isc_info_end) {
+			item = *p_buffer++;
+			length = isc_vax_integer (p_buffer, 2);
+			p_buffer += 2;
+			if (item == isc_info_isc_version)
+				return g_strndup ((const gchar *) &p_buffer[2], length-2);
+		}
+	}
+
+	return NULL;
+}
diff --git a/providers/firebird/gda-firebird-pstmt.c b/providers/firebird/gda-firebird-pstmt.c
index f40a655..1e6f4f8 100644
--- a/providers/firebird/gda-firebird-pstmt.c
+++ b/providers/firebird/gda-firebird-pstmt.c
@@ -75,7 +75,8 @@ gda_firebird_pstmt_init (GdaFirebirdPStmt *pstmt, GdaFirebirdPStmtClass *klass)
 	g_return_if_fail (GDA_IS_PSTMT (pstmt));
 	
 	/* initialize specific parts of @pstmt */
-	TO_IMPLEMENT;
+	pstmt->stmt_h = 0;
+	pstmt->sqlda = NULL;
 }
 
 static void
@@ -86,7 +87,12 @@ gda_firebird_pstmt_finalize (GObject *object)
 	g_return_if_fail (GDA_IS_PSTMT (pstmt));
 
 	/* free memory */
-	TO_IMPLEMENT; /* free some specific parts of @pstmt */
+	//TO_IMPLEMENT; /* free some specific parts of @pstmt */
+	isc_dsql_free_statement(pstmt->status, &(pstmt->stmt_h), DSQL_close);
+
+	g_free(pstmt->sqlda);
+	pstmt->sqlda = NULL;
+	pstmt->stmt_h = 0;
 
 	/* chain to parent class */
 	parent_class->finalize (object);
diff --git a/providers/firebird/gda-firebird-pstmt.h b/providers/firebird/gda-firebird-pstmt.h
index 7b97c18..af50341 100644
--- a/providers/firebird/gda-firebird-pstmt.h
+++ b/providers/firebird/gda-firebird-pstmt.h
@@ -37,9 +37,12 @@ typedef struct _GdaFirebirdPStmtClass   GdaFirebirdPStmtClass;
 struct _GdaFirebirdPStmt {
 	GdaPStmt        object;
 
-	/* TO_ADD: this structure holds any information necessary to reference a prepared statement, usually a connection
-         * handle from the C or C++ API
-         */
+	isc_stmt_handle	stmt_h;
+	ISC_STATUS	status[20];
+	XSQLDA 	       *sqlda;
+
+	gint		statement_type;
+	gboolean	is_non_select;
 };
 
 struct _GdaFirebirdPStmtClass {
diff --git a/providers/firebird/gda-firebird-recordset.c b/providers/firebird/gda-firebird-recordset.c
index d387308..4b94e69 100644
--- a/providers/firebird/gda-firebird-recordset.c
+++ b/providers/firebird/gda-firebird-recordset.c
@@ -32,6 +32,7 @@
 #include "gda-firebird.h"
 #include "gda-firebird-recordset.h"
 #include "gda-firebird-provider.h"
+#include <libgda/libgda-global-variables.h>
 
 #define _GDA_PSTMT(x) ((GdaPStmt*)(x))
 
@@ -51,9 +52,27 @@ static gboolean gda_firebird_recordset_fetch_at (GdaDataSelect *model, GdaRow **
 struct _GdaFirebirdRecordsetPrivate {
 	GdaConnection *cnc;
 	/* TO_ADD: specific information */
+	XSQLDA *xsqlda;
+	gint n_columns;
 };
 static GObjectClass *parent_class = NULL;
 
+typedef PARAMVARY VARY2;
+
+
+#ifndef ISC_INT64_FORMAT
+
+/* Define a format string for printf.  Printing of 64-bit integers
+   is not standard between platforms */
+
+#if (defined(_MSC_VER) && defined(WIN32))
+#define	ISC_INT64_FORMAT	"I64"
+#else
+#define	ISC_INT64_FORMAT	"ll"
+#endif
+#endif
+
+
 /*
  * Object init and finalize
  */
@@ -66,7 +85,8 @@ gda_firebird_recordset_init (GdaFirebirdRecordset *recset,
 	recset->priv->cnc = NULL;
 
 	/* initialize specific information */
-	TO_IMPLEMENT;
+	//TO_IMPLEMENT;
+	recset->priv->xsqlda	= NULL;
 }
 
 static void
@@ -98,7 +118,10 @@ gda_firebird_recordset_dispose (GObject *object)
 			g_object_unref (recset->priv->cnc);
 
 		/* free specific information */
-		TO_IMPLEMENT;
+		//TO_IMPLEMENT;
+		if (NULL != recset->priv->xsqlda)
+			g_free(recset->priv->xsqlda);
+
 		g_free (recset->priv);
 		recset->priv = NULL;
 	}
@@ -137,6 +160,316 @@ gda_firebird_recordset_get_type (void)
 	return type;
 }
 
+static GType
+_gda_firebird_type_to_gda (XSQLVAR *var){
+	short       dtype;
+	GType gtype;
+	dtype = var->sqltype & ~1;
+	/*
+	if ((var->sqltype & 1) && (*var->sqlind < 0)){
+		return GDA_TYPE_NULL;
+	}
+	*/
+	switch (dtype){
+		case SQL_TEXT:
+		case SQL_VARYING:
+			gtype = G_TYPE_STRING;
+			//g_print("SQL_TEXT\n");
+			break;
+		case SQL_LONG:
+			gtype = G_TYPE_ULONG;
+			//g_print("SQL_TYPE_LONG\n");
+			break;
+		case SQL_SHORT:
+		case SQL_INT64:
+			gtype = G_TYPE_INT;
+			//g_print("SQL_TYPE_INT\n");
+			break;
+		case SQL_FLOAT:
+			gtype = G_TYPE_FLOAT;
+			//g_print("SQL_TYPE_FLOAT\n");
+			break;
+		case SQL_DOUBLE:
+			gtype = G_TYPE_DOUBLE;
+			//g_print("SQL_TYPE_DOUBLE\n");
+			break;
+		case SQL_TIMESTAMP:
+			//gtype = G_TYPE_DATE_TIME;
+			gtype = GDA_TYPE_TIMESTAMP;
+			//g_print("SQL_TIMESTAMP\n");
+			break;
+		case SQL_TYPE_DATE:
+			gtype = G_TYPE_DATE;
+			//g_print("SQL_TYPE_DATE\n");
+			break;
+		case SQL_TYPE_TIME:
+			gtype = GDA_TYPE_TIME;
+			//g_print("SQL_TYPE_TIME\n");
+			break;
+		case SQL_BLOB:
+		case SQL_ARRAY:
+		default:
+			gtype = GDA_TYPE_BLOB;
+			//g_print("SQL_BLOB\n");
+			break;
+	}
+
+	return gtype;
+}
+
+/*
+ *    Print column's data.
+ */
+void _fb_set_row_data (XSQLVAR *var, GValue *value, GdaRow *row){
+	short       dtype;
+	char        data[2048], *p;
+	char        blob_s[20], date_s[25];
+	VARY2        *vary2;
+	short       len;
+	struct tm   times;
+	ISC_QUAD    bid;
+
+	dtype = var->sqltype & ~1;
+	p = data;
+
+	/* Null handling.  If the column is nullable and null */
+	if ((var->sqltype & 1) && (*var->sqlind < 0))
+	{
+		switch (dtype)
+		{
+			case SQL_TEXT:
+			case SQL_VARYING:
+				len = var->sqllen;
+				break;
+			case SQL_SHORT:
+				len = 6;
+				if (var->sqlscale > 0) len += var->sqlscale;
+				break;
+			case SQL_LONG:
+				len = 11;
+				if (var->sqlscale > 0) len += var->sqlscale;
+				break;
+			case SQL_INT64:
+				len = 21;
+				if (var->sqlscale > 0) len += var->sqlscale;
+				break;
+			case SQL_FLOAT:
+				len = 15;
+				break;
+			case SQL_DOUBLE:
+				len = 24;
+				break;
+			case SQL_TIMESTAMP:
+				len = 24;
+				break;
+			case SQL_TYPE_DATE:
+				len = 10;
+				break;
+			case SQL_TYPE_TIME:
+				len = 13;
+				break;
+				case SQL_BLOB:
+				case SQL_ARRAY:
+				default:
+					len = 17;
+					break;
+		}
+		g_value_set_string (value, "NULL");
+	}
+	else
+	{
+		switch (dtype)
+		{
+			case SQL_TEXT:
+				sprintf (p, "%.*s ", var->sqllen, var->sqldata);
+				g_value_set_string (value, p);
+				break;
+			case SQL_VARYING:
+				vary2 = (VARY2*) var->sqldata;
+				vary2->vary_string[vary2->vary_length] = '\0';	
+				sprintf(p, "%-*s ", var->sqllen, vary2->vary_string);
+				g_value_set_string (value, p);
+				break;
+
+			case SQL_SHORT:
+			case SQL_LONG:
+			case SQL_INT64: {
+				ISC_INT64	fb_value;
+				short		field_width;
+				short		dscale;
+				switch (dtype) {
+					case SQL_SHORT:
+						fb_value = (ISC_INT64)*(short *) var->sqldata;
+						field_width = 6;
+						break;
+					case SQL_LONG:
+						fb_value = (ISC_INT64)*(int *) var->sqldata;
+						field_width = 11;
+						break;
+					case SQL_INT64:
+						fb_value = (ISC_INT64)*(ISC_INT64 *) var->sqldata;
+						field_width = 21;
+						break;
+					default:
+						field_width = 11;
+						fb_value = 0;
+						break;
+				}
+
+				dscale = var->sqlscale;
+				if (dscale < 0) {
+					ISC_INT64	tens;
+					short	i;
+
+					tens = 1;
+					for (i = 0; i > dscale; i--)
+						tens *= 10;
+
+					if (fb_value >= 0)
+						sprintf (p, "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
+							 field_width - 1 + dscale, 
+							 (ISC_INT64) fb_value / tens,
+							 -dscale, 
+							 (ISC_INT64) fb_value % tens);
+					else if ((fb_value / tens) != 0)
+						sprintf (p, "%*" ISC_INT64_FORMAT "d.%0*" ISC_INT64_FORMAT "d",
+							 field_width - 1 + dscale, 
+							 (ISC_INT64) (fb_value / tens),
+							 -dscale, 
+							 (ISC_INT64) -(fb_value % tens));
+					else
+						sprintf (p, "%*s.%0*" ISC_INT64_FORMAT "d",
+							 field_width - 1 + dscale, 
+							 "-0",
+							 -dscale, 
+							 (ISC_INT64) -(fb_value % tens));
+				}
+				else if (dscale){
+					sprintf (p, "%*" ISC_INT64_FORMAT "d%0*d", 
+						 field_width, 
+						 (ISC_INT64) fb_value,
+						 dscale, 0);
+				}
+				else{
+					sprintf (p, "%*" ISC_INT64_FORMAT "d",
+						 field_width, 
+						 (ISC_INT64) fb_value);
+				}
+
+				switch (dtype) {
+					case SQL_SHORT:
+						gda_value_set_short (value, atoi (p));
+						break;
+					case SQL_LONG:
+						g_value_set_ulong (value, atoll (p));
+						break;
+					case SQL_INT64:
+					default:
+						g_value_set_int64 (value, atoll (p));
+						break;
+				}
+				}
+				break;
+
+			case SQL_FLOAT:
+				sprintf(p, "%15g ", *(float *) (var->sqldata));
+				//setlocale (LC_NUMERIC, "C");
+				g_value_set_float (value, atof (p));
+				//setlocale (LC_NUMERIC, gda_numeric_locale);
+				break;
+
+			case SQL_DOUBLE:
+				sprintf(p, "%24f ", *(double *) (var->sqldata));
+				//setlocale (LC_NUMERIC, "C");
+				g_value_set_double (value, atof (p));
+				//setlocale (LC_NUMERIC, gda_numeric_locale);
+				break;
+
+			case SQL_TIMESTAMP:
+				isc_decode_timestamp((ISC_TIMESTAMP *)var->sqldata, &times);
+				sprintf(date_s, "%04d-%02d-%02d %02d:%02d:%02d",
+						times.tm_year + 1900,
+						times.tm_mon+1,
+						times.tm_mday,
+						times.tm_hour,
+						times.tm_min,
+						times.tm_sec);
+				sprintf(p, "%*s ", 22, date_s);
+				//g_value_set_string (value, p);
+
+				GdaTimestamp timestamp;
+				if (! gda_parse_iso8601_timestamp (&timestamp, date_s)) {
+					g_print("****ERROR CONVERTING TO TIMESTAMP: %s\n", date_s);
+
+					//gda_row_invalidate_value (row, value);
+					/*
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							GDA_SERVER_PROVIDER_DATA_ERROR,
+							_("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
+							p);
+					*/
+				}
+				else
+					gda_value_set_timestamp (value, &timestamp);
+				break;
+
+			case SQL_TYPE_DATE:
+				isc_decode_sql_date((ISC_DATE *)var->sqldata, &times);
+				sprintf(date_s, "%04d-%02d-%02d",
+						times.tm_year + 1900,
+						times.tm_mon+1,
+						times.tm_mday);
+				sprintf(p, "%*s ", 10, date_s);
+				GDate date;
+				if (!gda_parse_iso8601_date (&date, p)) {
+					//gda_row_invalidate_value (row, value);
+					/*
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							 GDA_SERVER_PROVIDER_DATA_ERROR,
+							 _("Invalid date '%s' (date format should be YYYY-MM-DD)"), p);
+					*/
+				}
+				else
+					g_value_set_boxed (value, &date);
+				break;
+
+			case SQL_TYPE_TIME:
+				isc_decode_sql_time((ISC_TIME *)var->sqldata, &times);
+				sprintf(date_s, "%02d:%02d:%02d",
+						times.tm_hour,
+						times.tm_min,
+						times.tm_sec);
+				sprintf(p, "%*s ", 11, date_s);
+				GdaTime timegda;
+				if (!gda_parse_iso8601_time (&timegda, p)) {
+					//gda_row_invalidate_value (row, value); 
+					/*
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							 GDA_SERVER_PROVIDER_DATA_ERROR,
+							 _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), p);
+					*/
+				}
+				else
+					gda_value_set_time (value, &timegda);
+				break;
+
+			case SQL_BLOB:
+			case SQL_ARRAY:
+				/* Print the blob id on blobs or arrays */
+				bid = *(ISC_QUAD *) var->sqldata;
+				sprintf(blob_s, "%08x:%08x", bid.gds_quad_high, bid.gds_quad_low);
+				sprintf(p, "%17s ", blob_s);
+				g_value_set_string (value, p);
+				break;
+
+			default:
+				g_value_set_string(value, "TYPE NOT FOUND");
+				break;
+		}
+	}
+}
+
+
 /*
  * the @ps struct is modified and transferred to the new data model created in
  * this function
@@ -145,14 +478,15 @@ GdaDataModel *
 gda_firebird_recordset_new (GdaConnection *cnc, GdaFirebirdPStmt *ps, GdaDataModelAccessFlags flags, GType *col_types)
 {
 	GdaFirebirdRecordset *model;
-        FirebirdConnectionData *cdata;
-        gint i;
+	FirebirdConnectionData *cdata;
+	gint i;
+	gint fetch_stat;
 	GdaDataModelAccessFlags rflags;
 
         g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
-        g_return_val_if_fail (ps != NULL, NULL);
+        g_return_val_if_fail (ps, NULL);
 
-	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
+	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata)
 		return NULL;
 
@@ -162,7 +496,12 @@ gda_firebird_recordset_new (GdaConnection *cnc, GdaFirebirdPStmt *ps, GdaDataMod
 		TO_IMPLEMENT;
 
         /* completing @ps if not yet done */
-        if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
+	if (_GDA_PSTMT (ps)->ncols < 0)
+		/*_GDA_PSTMT (ps)->ncols = ...;*/
+		_GDA_PSTMT (ps)->ncols = ps->sqlda->sqld;
+
+	/* completing @ps if not yet done */
+	if (!_GDA_PSTMT (ps)->types && (_GDA_PSTMT (ps)->ncols > 0)) {
 		/* create prepared statement's columns */
 		GSList *list;
 		for (i = 0; i < _GDA_PSTMT (ps)->ncols; i++)
@@ -188,19 +527,33 @@ gda_firebird_recordset_new (GdaConnection *cnc, GdaFirebirdPStmt *ps, GdaDataMod
 				}
 			}
 		}
-		
+
 		/* fill GdaColumn's data */
 		for (i=0, list = _GDA_PSTMT (ps)->tmpl_columns; 
 		     i < GDA_PSTMT (ps)->ncols; 
 		     i++, list = list->next) {
-			GdaColumn *column;
-			
-			column = GDA_COLUMN (list->data);
+			GdaColumn       *column;
+			GType           gtype;
+			XSQLVAR         *var;
 
+			var = (XSQLVAR *) &(ps->sqlda->sqlvar[i]);
+			column = GDA_COLUMN (list->data);
 			/* use C API to set columns' information using gda_column_set_*() */
-			TO_IMPLEMENT;
+			gtype = _gda_firebird_type_to_gda(var);
+
+			_GDA_PSTMT (ps)->types [i] = gtype;
+			gda_column_set_g_type (column, gtype);
+			gda_column_set_name (column, var->aliasname);
+			gda_column_set_description (column, var->aliasname);
+
+			//g_print("\t\tSQL-NAME:%s\n\t\tREL-NAME: %s\n\t\tOWN-NAME: %s\n\t\tALIAS: %s\n**************************\n\n"
+			//      , var->sqlname
+			//      , var->relname
+			//      , var->ownname
+			//      , var->aliasname);
 		}
-        }
+	}
+
 
 	/* determine access mode: RANDOM or CURSOR FORWARD are the only supported */
 	if (flags & GDA_DATA_MODEL_ACCESS_RANDOM)
@@ -209,14 +562,43 @@ gda_firebird_recordset_new (GdaConnection *cnc, GdaFirebirdPStmt *ps, GdaDataMod
 		rflags = GDA_DATA_MODEL_ACCESS_CURSOR_FORWARD;
 
 	/* create data model */
-        model = g_object_new (GDA_TYPE_FIREBIRD_RECORDSET, "prepared-stmt", ps, "model-usage", rflags, NULL);
-        model->priv->cnc = cnc;
+	model = g_object_new (GDA_TYPE_FIREBIRD_RECORDSET, "prepared-stmt", ps, "model-usage", rflags, NULL);
+	model->priv->cnc = cnc;
+	model->priv->n_columns	= ps->sqlda->sqld;
 	g_object_ref (cnc);
 
+	gda_data_select_set_columns (GDA_DATA_SELECT (model), _GDA_PSTMT (ps)->tmpl_columns);
+
 	/* post init specific code */
-	TO_IMPLEMENT;
+	if (isc_dsql_execute (cdata->status, cdata->ftr, &(ps->stmt_h), SQL_DIALECT_V6, NULL)) {
+		isc_print_status(cdata->status);
+		g_print("\n");
+	}
+
+	gint rownum = 0;
+	while ((fetch_stat = isc_dsql_fetch(cdata->status, &(ps->stmt_h), SQL_DIALECT_V6, ps->sqlda)) == 0) {
+		GdaRow *row = gda_row_new (ps->sqlda->sqld);
+		for (i = 0; i < ps->sqlda->sqld; i++) {
+			GValue *value = gda_row_get_value (row, i);
+			GType type =_gda_firebird_type_to_gda((XSQLVAR *) &(ps->sqlda->sqlvar[i]));
+			//char *data = mysql_row[i];
+
+			//if (!data || (type == GDA_TYPE_NULL))
+			//	continue;
+
+			gda_value_reset_with_type (value, type);
+			//g_value_set_string (value, "faghmie");
+			_fb_set_row_data ((XSQLVAR *) &(ps->sqlda->sqlvar[i]), value, row);
+			//print_column((XSQLVAR *) &sqlda->sqlvar[i]);
+		}
+
+		gda_data_select_take_row ((GdaDataSelect*) model, row, rownum);
+		rownum++;
+	}
+
+	((GdaDataSelect *) model)->advertized_nrows = rownum;
 
-        return GDA_DATA_MODEL (model);
+	return GDA_DATA_MODEL (model);
 }
 
 
diff --git a/providers/firebird/gda-firebird-recordset.h b/providers/firebird/gda-firebird-recordset.h
index 5503747..f3e46d4 100644
--- a/providers/firebird/gda-firebird-recordset.h
+++ b/providers/firebird/gda-firebird-recordset.h
@@ -23,7 +23,7 @@
 #define __GDA_FIREBIRD_RECORDSET_H__
 
 #include <libgda/libgda.h>
-#include <providers-support/gda-data-select.h>
+#include <providers-support/gda-data-select-priv.h>
 #include "gda-firebird-pstmt.h"
 
 G_BEGIN_DECLS
@@ -34,6 +34,34 @@ G_BEGIN_DECLS
 #define GDA_IS_FIREBIRD_RECORDSET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE (obj, GDA_TYPE_FIREBIRD_RECORDSET))
 #define GDA_IS_FIREBIRD_RECORDSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDA_TYPE_FIREBIRD_RECORDSET))
 
+
+#ifdef VMS
+#define FB_ALIGN(n,b)              (n)
+#endif
+
+#ifdef sun
+#ifdef sparc
+#define FB_ALIGN(n,b)          ((n + b - 1) & ~(b - 1))
+#endif
+#endif
+
+#ifdef hpux
+#define FB_ALIGN(n,b)          ((n + b - 1) & ~(b - 1))
+#endif
+
+#ifdef _AIX
+#define FB_ALIGN(n,b)          ((n + b - 1) & ~(b - 1))
+#endif
+ 
+#if (defined(_MSC_VER) && defined(WIN32)) 
+#define FB_ALIGN(n,b)          ((n + b - 1) & ~(b - 1))
+#endif
+
+#ifndef FB_ALIGN
+#define FB_ALIGN(n,b)          ((n+1) & ~1)
+#endif
+
+
 typedef struct _GdaFirebirdRecordset        GdaFirebirdRecordset;
 typedef struct _GdaFirebirdRecordsetClass   GdaFirebirdRecordsetClass;
 typedef struct _GdaFirebirdRecordsetPrivate GdaFirebirdRecordsetPrivate;
@@ -41,6 +69,7 @@ typedef struct _GdaFirebirdRecordsetPrivate GdaFirebirdRecordsetPrivate;
 struct _GdaFirebirdRecordset {
 	GdaDataSelect                model;
 	GdaFirebirdRecordsetPrivate *priv;
+
 };
 
 struct _GdaFirebirdRecordsetClass {
diff --git a/providers/firebird/gda-firebird-util.c b/providers/firebird/gda-firebird-util.c
index bf4eea7..33b7d8c 100644
--- a/providers/firebird/gda-firebird-util.c
+++ b/providers/firebird/gda-firebird-util.c
@@ -24,22 +24,22 @@ GdaConnectionEvent *
 _gda_firebird_make_error (GdaConnection *cnc, const gint statement_type)
 {
 	FirebirdConnectionData *cdata;
-	GdaConnectionEvent *error;
+	GdaConnectionEvent *error_ev;
         gchar *description;
 
         g_return_val_if_fail (GDA_IS_CONNECTION (cnc), NULL);
 
-	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data_error (cnc, error);
+	cdata = (FirebirdConnectionData*) gda_connection_internal_get_provider_data (cnc);
 	if (!cdata) 
 		return FALSE;
 
-        error = gda_connection_event_new (GDA_CONNECTION_EVENT_ERROR);
-        gda_connection_event_set_code (error, isc_sqlcode (cdata->status));
+        error_ev = gda_connection_point_available_event (cnc, GDA_CONNECTION_EVENT_ERROR);
+        gda_connection_event_set_code (error_ev, isc_sqlcode (cdata->status));
         description = fb_sqlerror_get_description (cdata, statement_type);
-        gda_connection_event_set_source (error, "[GDA Firebird]");
-        gda_connection_event_set_description (error, description);
-        gda_connection_add_event (cnc, error);
+        gda_connection_event_set_source (error_ev, "[GDA Firebird]");
+        gda_connection_event_set_description (error_ev, description);
+        gda_connection_add_event (cnc, error_ev);
         g_free (description);
 
-        return error;
+        return error_ev;
 }
diff --git a/providers/firebird/gda-firebird.h b/providers/firebird/gda-firebird.h
index c15af7a..da58f81 100644
--- a/providers/firebird/gda-firebird.h
+++ b/providers/firebird/gda-firebird.h
@@ -20,7 +20,7 @@
  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  * Boston, MA  02110-1301, USA.
  */
-c/* GDA firebird provider
+/* GDA firebird provider
  * Copyright (C) 2008 The GNOME Foundation.
  *
  * AUTHORS:
@@ -50,21 +50,24 @@ c/* GDA firebird provider
  */
 #define FIREBIRD_PROVIDER_NAME "Firebird"
 
+#include <libgda/libgda.h>
 #include <ibase.h>
 
 /*
  * Provider's specific connection data
  */
-typedef struct {
-	gchar         *dbname;
-	gchar         *server_version;
-        isc_db_handle  handle;
-        ISC_STATUS     status[20];
-        gchar          dpb_buffer[128];
-        gshort         dpb_length;
 
-	/* transaction */
-	isc_tr_handle *ftr;
+typedef struct
+{
+	//GdaConnection	*cnc;
+	gchar	       *dbname;
+	gchar	       *server_version;
+	isc_db_handle	handle;
+	ISC_STATUS	status[20];
+	gchar		dpb_buffer[128];
+	gshort		dpb_length;
+
+	isc_tr_handle	*ftr;
 } FirebirdConnectionData;
 
 #endif
diff --git a/providers/firebird/libmain.c b/providers/firebird/libmain-client.c
similarity index 97%
copy from providers/firebird/libmain.c
copy to providers/firebird/libmain-client.c
index e427541..974cd34 100644
--- a/providers/firebird/libmain.c
+++ b/providers/firebird/libmain-client.c
@@ -48,7 +48,7 @@ plugin_get_name (void)
 const gchar *
 plugin_get_description (void)
 {
-	return _("Example provider for C API databases");
+	return _("Provider for Firebird databases");
 }
 
 gchar *
diff --git a/providers/firebird/libmain.c b/providers/firebird/libmain-embed.c
similarity index 95%
rename from providers/firebird/libmain.c
rename to providers/firebird/libmain-embed.c
index e427541..b13cd1d 100644
--- a/providers/firebird/libmain.c
+++ b/providers/firebird/libmain-embed.c
@@ -42,13 +42,13 @@ plugin_init (const gchar *real_path)
 const gchar *
 plugin_get_name (void)
 {
-	return FIREBIRD_PROVIDER_NAME;
+	return FIREBIRD_PROVIDER_NAME "Embed";
 }
 
 const gchar *
 plugin_get_description (void)
 {
-	return _("Example provider for C API databases");
+	return _("Provider for embedded Firebird databases");
 }
 
 gchar *



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