[libgda] Work on the Firebird provider, thanks to Faghmie Davids
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Work on the Firebird provider, thanks to Faghmie Davids
- Date: Sun, 11 Dec 2011 22:08:35 +0000 (UTC)
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, ¶ms, 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, ×);
+ 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 (×tamp, 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, ×tamp);
+ break;
+
+ case SQL_TYPE_DATE:
+ isc_decode_sql_date((ISC_DATE *)var->sqldata, ×);
+ 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, ×);
+ 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]