]> granicus.if.org Git - php/commitdiff
Initial check-in of FrontBase extension
authorFrank M. Kromann <fmk@php.net>
Tue, 13 Mar 2001 20:58:47 +0000 (20:58 +0000)
committerFrank M. Kromann <fmk@php.net>
Tue, 13 Mar 2001 20:58:47 +0000 (20:58 +0000)
ext/fbsql/Makefile.in [new file with mode: 0644]
ext/fbsql/config.m4 [new file with mode: 0644]
ext/fbsql/fbsql.dsp [new file with mode: 0644]
ext/fbsql/php_fbsql.c [new file with mode: 0644]
ext/fbsql/php_fbsql.h [new file with mode: 0644]

diff --git a/ext/fbsql/Makefile.in b/ext/fbsql/Makefile.in
new file mode 100644 (file)
index 0000000..66bec05
--- /dev/null
@@ -0,0 +1,10 @@
+
+LTLIBRARY_NAME    = libfbsql.la
+LTLIBRARY_SOURCES = php_fbsql.c
+LTLIBRARY_LIBADD  = $(FBSQL_LIBADD)
+LTLIBRARY_SHARED_NAME    = fbsql.la
+LTLIBRARY_SHARED_LIBADD  = $(FBSQL_SHARED_LIBADD)
+
+SUBDIRS = $(FBSQL_SUBDIRS)
+
+include $(top_srcdir)/build/dynlib.mk
diff --git a/ext/fbsql/config.m4 b/ext/fbsql/config.m4
new file mode 100644 (file)
index 0000000..b166ba3
--- /dev/null
@@ -0,0 +1,41 @@
+dnl $Id$
+
+PHP_ARG_WITH(fbsql, for FrontBase SQL92 (fbsql) support,
+[  --with-fbsql[=DIR]      Include FrontBase support. DIR is the FrontBase base
+                          directory. .], yes)
+
+if test "$PHP_FBSQL" != "no"; then
+  AC_DEFINE(HAVE_FBSQL, 1, [Whether you have FrontBase])
+  PHP_EXTENSION(fbsql,$ext_shared)
+fi
+
+FBSQL_INSTALLATION_DIR=""
+if test "$PHP_FBSQL" = "yes"; then
+  for i in /Local/Library /usr /usr/local /opt /Library
+  do
+     if test -f $i/FrontBase/include/FBCAccess/FBCAccess.h
+     then
+         FBSQL_INSTALLATION_DIR=$i/FrontBase
+         break
+     fi
+  done
+  if test -z "$FBSQL_INSTALLATION_DIR"
+  then
+     AC_MSG_ERROR(Cannot find FrontBase in well know installation directories)
+  fi
+elif  test "$PHP_FBSQL" != "no"; then
+  if test -f $PHP_FBSQL/include/FBCAccess/FBCAccess.h
+  then
+     FBSQL_INSTALLATION_DIR=$PHP_FBSQL
+  else
+     AC_MSG_ERROR(Directory $PHP_FBSQL is not a FrontBase installation directory)
+  fi
+fi 
+
+if test ! -f "$FBSQL_INSTALLATION_DIR/lib/libFBCAccess.a"
+then
+   AC_MSG_ERROR(Could not find $FBSQL_INSTALLATION_DIR/lib/libFBCAccess.a)
+fi
+AC_ADD_LIBRARY_WITH_PATH(FBCAccess, $FBSQL_INSTALLATION_DIR/lib, $FBSQL_INSTALLATION_DIR/lib)
+AC_ADD_INCLUDE($FBSQL_INSTALLATION_DIR/include)
+
diff --git a/ext/fbsql/fbsql.dsp b/ext/fbsql/fbsql.dsp
new file mode 100644 (file)
index 0000000..791f572
--- /dev/null
@@ -0,0 +1,171 @@
+# Microsoft Developer Studio Project File - Name="fbsql" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r
+\r
+CFG=fbsql - Win32 Debug_TS\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "fbsql.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "fbsql.mak" CFG="fbsql - Win32 Debug_TS"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "fbsql - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "fbsql - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "fbsql - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE "fbsql - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+CPP=cl.exe\r
+MTL=midl.exe\r
+RSC=rc.exe\r
+\r
+!IF  "$(CFG)" == "fbsql - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBSQL_EXPORTS" /YX /FD /c\r
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "NDEBUG" /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL_FBSQL" /D HAVE_FBSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x40d /d "NDEBUG"\r
+# ADD RSC /l 0x40d /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4nts.lib /nologo /dll /machine:I386 /out:"Release/php_fbsql.dll" /libpath:"..\..\Release"\r
+\r
+!ELSEIF  "$(CFG)" == "fbsql - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBSQL_EXPORTS" /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /D "_DEBUG" /D ZEND_DEBUG=1 /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL_FBSQL" /D HAVE_FBSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /FR /YX /FD /GZ /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x40d /d "_DEBUG"\r
+# ADD RSC /l 0x40d /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4nts_debug.lib /nologo /dll /debug /machine:I386 /out:"Debug/php_fbsql.dll" /pdbtype:sept /libpath:"..\..\Debug"\r
+\r
+!ELSEIF  "$(CFG)" == "fbsql - Win32 Debug_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug_TS"\r
+# PROP BASE Intermediate_Dir "Debug_TS"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug_TS"\r
+# PROP Intermediate_Dir "Debug_TS"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL" /D HAVE_FBSQL=1 /FR /YX /FD /GZ /c\r
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "\usr\FrontBase\Include" /D "_DEBUG" /D ZEND_DEBUG=1 /D "ZTS" /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL" /D HAVE_FBSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /FR /YX /FD /GZ /c\r
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x40d /d "_DEBUG"\r
+# ADD RSC /l 0x40d /d "_DEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib php4ts_debug.lib FBCAccess.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\Debug_TS/php_fbsql.dll" /pdbtype:sept /libpath:"..\..\Debug_TS" /libpath:"\usr\FrontBase\lib"\r
+\r
+!ELSEIF  "$(CFG)" == "fbsql - Win32 Release_TS"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release_TS"\r
+# PROP BASE Intermediate_Dir "Release_TS"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release_TS"\r
+# PROP Intermediate_Dir "Release_TS"\r
+# PROP Ignore_Export_Lib 0\r
+# PROP Target_Dir ""\r
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\bindlib_w32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL" /D HAVE_FBSQL=1 /YX /FD /c\r
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\main" /I "..\..\Zend" /I "..\..\..\bindlib_w32" /I "..\..\TSRM" /I "\usr\FrontBase\Include" /D "NDEBUG" /D "ZTS" /D ZEND_DEBUG=0 /D "FBSQL_EXPORTS" /D "COMPILE_DL_FBSQL" /D HAVE_FBSQL=1 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ZEND_WIN32" /D "PHP_WIN32" /YX /FD /c\r
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r
+# ADD BASE RSC /l 0x40d /d "NDEBUG"\r
+# ADD RSC /l 0x40d /d "NDEBUG"\r
+BSC32=bscmake.exe\r
+# ADD BASE BSC32 /nologo\r
+# ADD BSC32 /nologo\r
+LINK32=link.exe\r
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib FBCAccess.lib wsock32.lib /nologo /dll /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\Release_TS/php_fbsql.dll" /libpath:"..\..\Release_TS" /libpath:"\usr\FrontBase\lib"\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "fbsql - Win32 Release"\r
+# Name "fbsql - Win32 Debug"\r
+# Name "fbsql - Win32 Debug_TS"\r
+# Name "fbsql - Win32 Release_TS"\r
+# Begin Group "Source Files"\r
+\r
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
+# Begin Source File\r
+\r
+SOURCE=.\php_fbsql.c\r
+# End Source File\r
+# End Group\r
+# Begin Group "Header Files"\r
+\r
+# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
+# Begin Source File\r
+\r
+SOURCE=.\php_fbsql.h\r
+# End Source File\r
+# End Group\r
+# Begin Group "Resource Files"\r
+\r
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"\r
+# End Group\r
+# Begin Source File\r
+\r
+SOURCE=.\Readme_w32.txt\r
+# End Source File\r
+# End Target\r
+# End Project\r
diff --git a/ext/fbsql/php_fbsql.c b/ext/fbsql/php_fbsql.c
new file mode 100644 (file)
index 0000000..cbd78d1
--- /dev/null
@@ -0,0 +1,3039 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2001 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Frank M. Kromann frank@frontbase.com>                       |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* TODO:
+ *
+ * ? Safe mode implementation
+ */
+
+// SB's list:
+//   - BLOBs
+//   - API for a more natural FB connect semantic
+//   - Connect & set session 
+//   - Autoreconnect when disconnected
+//   - Comments and cleanup
+//   - Documentation
+//
+//   - Format database error messages as HTML.
+//
+// BUGS
+//   - Select db with no arguments
+//   - Query with everything defaulted
+//
+#include "php.h"
+#include "php_globals.h"
+#include "php_globals.h"
+#include "ext/standard/info.h"
+#include "ext/standard/php_string.h"
+
+#if WIN32|WINNT
+#include <winsock.h>
+#else
+#include <php_config.h>
+#include <build-defs.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <netdb.h>
+#include <netinet/in.h>
+#endif
+
+#include "php_ini.h"
+
+#define HAVE_FBSQL 1
+
+#if HAVE_FBSQL
+#include "php_fbsql.h"
+#include <signal.h>
+
+static int le_result, le_link, le_plink, le_dba;
+
+struct PHPFBDatabase;
+typedef struct PHPFBDatabase PHPFBDatabase;
+
+struct PHPFBResult;
+typedef struct PHPFBResult PHPFBResult;
+
+struct PHPFBLink;
+typedef struct PHPFBLink PHPFBLink;
+
+// The PHPFBLink structure represents a fbsql link. The lion is used for
+// a connection to a machine, it may be persistant and is reference counted.
+// The reason for refcounting is mostly to avoid to think, it work independent of 
+// any wierd and unforseen allocation deallocation order.
+//
+// The PHPFBDatabse structure implements to actual connection to a FrontBase server
+// ot may be persistant is the link it is connected to is persistant, and refcounted
+// for the same reasons as above.
+//
+// The PHPFBResult structure implements a result from the FrontBase server, and does all
+// required buffereing from of results.
+//
+// In the PHP code the 3 above a data structures are referenced by means of integers in the
+// range from 1 to som configurable maximum.  You can put a limit to the number of links, databases
+// and results.  The integer identifications is implemented by insertion in the list, which is passed
+// as an argument to all the functions, please note the list is polymorph.
+//
+// Database objects and link objects are all reused, base on the host name user name, host name database name 
+// user name.  So connecting twice to the same database as the same user will return the same database id.
+// We use the same coding for that as fbsql does, explioiting the underlying implementation of the lists.
+//
+// Persistant objects are put in the persistent list as well, but only by name, if you connect to a persistant object
+// and it is not in the list it is simply added and get a new index, and refcounted.  Tricky, tricky ...
+//
+
+// Some functions which should be exported from FBCAccess
+
+void*        fbaObjectAtIndex();
+void         fbcInitialize();
+void         fbaRelease();
+unsigned int fbaCount();
+
+
+
+struct PHPFBDatabase
+{
+       unsigned int                    retainCount;            // The refcount 
+       unsigned int                    index;                          // The index in the list
+       PHPFBLink*                              link;                           // A pointer to the corresponding link object, may be NULL if no link were used
+       char*                                   databaseName;           // The name of the database
+       char*                                   databasePassword;       // The database password
+       FBCDatabaseConnection*  connection;                     // The connection to the database
+       unsigned int                    errorNo;                        // The latest error on the connection, 0 is ok.
+       char*                                   errorText;                      // The error text
+       unsigned int                    resultCount;            // Number of active result for this database
+       unsigned int                    rowIndex;                       // The row index of the latest row inserted into the database
+       PHPFBResult**                   results;                        // Pointer to the active results
+};
+
+struct PHPFBResult
+{
+       unsigned int                    retainCount;            // The refcount
+       unsigned int                    index;                          // The index into the list
+       PHPFBLink*                              link;                           // The link for the result, may be NULL if no link 
+       PHPFBDatabase*                  database;                       // The database for the result, may be NULL of no database is related to the result
+       FBCDatabaseConnection*  connection;                     // The database connection, just a convinience
+       char*                                   fetchHandle;                    // The fetch handle, the id used by the server.  
+       FBCMetaData*                    metaData;                       // The metadata describing the result
+       FBCMetaData*                    ResultmetaData;         // The metadata describing the result
+       FBCRowHandler*                  rowHandler;                     // The row handler, the Frontbase structure used for accessing rows in the result
+       unsigned int                    batchSize;                      // The number of row to fetch when expanding the number of rows in the row handler
+       int                                             rowCount;                       // The number of rows in the results set.  The number of row is not in
+                                               // general known when the select is done, one typically needs to fetch all the row
+                                               // to figure out how many row you got. When the rowCount is unknown the value is
+                                               // 0x7ffffffff
+       int                                             columnCount;            // Number of columns in the row set.
+       int                                             rowIndex;                       // The current row index.
+       int                                             columnIndex;            // The current column index
+       void**                                  row;                            // The last row accessed
+       FBArray*                                array;                          // The link may return a result set, the database list, we implement that by the 
+                                               // FBArray, just a list of strings.
+       FBCPList*                               list;                           // The same special kind result just for property list from extract, schema info.
+       unsigned int                    selectResults;          // number of results in select
+       unsigned int                    currentResult;          // current result number
+};
+
+struct PHPFBLink
+{
+       unsigned int                    retainCount;            // The refcount
+       unsigned int                    index;                          // The index in the list
+       int                                             persistant;                     // persistant ?
+       char*                                   hostName;                       // Host name 
+       char*                                   userName;                       // User name
+       char*                                   userPassword;           // User password
+       FBCExecHandler*                 execHandler;            // The exechandler, can be used for database operations
+       unsigned int                    affectedRows;
+       long                                    autoCommit;                     // Enable or disable autoCommit
+
+       PHPFBDatabase*                  currentDatabase;        // The latest referenced database on this link
+
+       unsigned int                    databaseCount;                  // The number of database connect to the link
+       PHPFBDatabase**                 databases;                      // and the pointers 
+
+       unsigned int                    resultCount;            // The number of link results
+       PHPFBResult**                   results;                        // and the pointers.  Only used for list_dbs
+};
+
+#define FBSQL_ASSOC            1<<0
+#define FBSQL_NUM              1<<1
+#define FBSQL_BOTH             (FBSQL_ASSOC|FBSQL_NUM)
+
+
+function_entry fbsql_functions[] = {
+       PHP_FE(fbsql_connect,           NULL)
+       PHP_FE(fbsql_pconnect,          NULL)
+       PHP_FE(fbsql_close,                     NULL)
+       PHP_FE(fbsql_select_db,         NULL)
+       PHP_FE(fbsql_create_db,         NULL)
+       PHP_FE(fbsql_drop_db,           NULL)
+       PHP_FE(fbsql_start_db,          NULL)
+       PHP_FE(fbsql_stop_db,           NULL)
+       PHP_FE(fbsql_query,                     NULL)
+       PHP_FE(fbsql_db_query,          NULL)
+       PHP_FE(fbsql_list_dbs,          NULL)
+       PHP_FE(fbsql_list_tables,       NULL)
+       PHP_FE(fbsql_list_fields,       NULL)
+       PHP_FE(fbsql_error,                     NULL)
+       PHP_FE(fbsql_errno,                     NULL)
+       PHP_FE(fbsql_affected_rows,     NULL)
+       PHP_FE(fbsql_insert_id,         NULL)
+       PHP_FE(fbsql_result,            NULL)
+       PHP_FE(fbsql_next_result,       NULL)
+       PHP_FE(fbsql_num_rows,          NULL)
+       PHP_FE(fbsql_num_fields,        NULL)
+       PHP_FE(fbsql_fetch_row,         NULL)
+       PHP_FE(fbsql_fetch_array,       NULL)
+       PHP_FE(fbsql_fetch_object,      NULL)
+       PHP_FE(fbsql_data_seek,         NULL)
+       PHP_FE(fbsql_fetch_lengths,     NULL)
+       PHP_FE(fbsql_fetch_field,       NULL)
+       PHP_FE(fbsql_field_seek,        NULL)
+       PHP_FE(fbsql_free_result,       NULL)
+       PHP_FE(fbsql_field_name,        NULL)
+       PHP_FE(fbsql_field_table,       NULL)
+       PHP_FE(fbsql_field_len,         NULL)
+       PHP_FE(fbsql_field_type,        NULL)
+       PHP_FE(fbsql_field_flags,       NULL) 
+
+//     Fontbase additions:
+       PHP_FE(fbsql_autocommit,        NULL)
+       PHP_FE(fbsql_commit,            NULL)
+       PHP_FE(fbsql_rollback,          NULL)
+
+       PHP_FE(fbsql_hostname,          NULL)
+       PHP_FE(fbsql_database,          NULL)
+       PHP_FE(fbsql_database_password, NULL)
+       PHP_FE(fbsql_username,          NULL)
+       PHP_FE(fbsql_password,          NULL)
+       PHP_FE(fbsql_warnings,          NULL)
+
+//     Aliases:
+       PHP_FALIAS(fbsql, fbsql_db_query, NULL)
+
+       {NULL, NULL, NULL}
+};
+
+zend_module_entry fbsql_module_entry = {
+   "fbsql",
+   fbsql_functions,
+   PHP_MINIT(fbsql),
+   PHP_MSHUTDOWN(fbsql),
+   PHP_RINIT(fbsql),
+   NULL,
+   PHP_MINFO(fbsql),
+   STANDARD_MODULE_PROPERTIES
+};
+
+ZEND_DECLARE_MODULE_GLOBALS(fbsql)
+
+#ifdef COMPILE_DL_FBSQL
+ZEND_GET_MODULE(fbsql)
+#endif
+
+
+void phpfbReleaseResult   ( PHPFBResult*   result );
+void phpfbReleaseDatabase ( PHPFBDatabase* database );
+void phpfbReleaseLink     ( PHPFBLink*     link );
+
+PHPFBResult* phpfbRetainResult ( PHPFBResult* result )
+{
+       if (result) result->retainCount++;
+       return result;
+}
+
+void phpfbReleaseResult ( PHPFBResult* result )
+{
+       unsigned int i;
+       FBSQLLS_FETCH();
+       if (result)
+    {
+      result->retainCount--;
+//printf("Release result   %x %d %d\n",result,result->index,result->retainCount);
+
+      if (result->retainCount == 0)
+       {
+         if (result->fetchHandle) fbcdcCancelFetch(result->connection,result->fetchHandle);
+         if (result->rowHandler)  fbcrhRelease(result->rowHandler);
+         if (result->ResultmetaData)    fbcmdRelease(result->ResultmetaData);
+//         if (result->metaData)    fbcmdRelease(result->metaData);
+         if (result->list)        fbcplRelease(result->list);
+         if (result->array)       fbaRelease(result->array);
+         if ( result->database)
+          {
+            for (i=0; i < result->database->resultCount; i++)
+             {
+               if (result->database->results[i] == result)
+                {
+                  result->database->results[i] = NULL;
+                  break;
+                }
+             }
+            phpfbReleaseDatabase(result->database);
+          }
+         if (result->link)
+          {
+            for (i=0; i < result->link->resultCount; i++)
+             {
+               if (result->link->results[i] == result)
+                {
+                  result->link->results[i] = NULL;
+                  break;
+                }
+             }
+            phpfbReleaseLink(result->link);
+          }
+         result->link        = 0;
+         result->database    = 0;
+         result->connection  = NULL;
+         result->fetchHandle = NULL;
+         result->metaData    = NULL;
+         result->rowHandler  = NULL;
+         result->batchSize   = 0;
+         result->rowCount    = -1;
+         result->rowIndex    = 0;
+         result->columnIndex = 0;
+         result->row         = NULL;
+         result->array       = NULL;
+         result->list        = NULL;
+         free(result);
+       }
+    }
+}
+
+PHPFBDatabase* phpfbRetainDatabase ( PHPFBDatabase* database )
+{
+   if (database) database->retainCount++;
+   return database;
+}
+
+void phpfbReleaseDatabase ( PHPFBDatabase* database )
+{
+   if (database)
+    {
+      database->retainCount--;
+//printf("Release database %x %d %d\n", database, database->index, database->retainCount);
+      if (database->retainCount == 0)
+       {
+         unsigned int i;
+//         if (FB_SQL_G(databaseIndex == database->index) FB_SQL_G(databaseIndex = 0;
+         if (database->link)
+          {
+            for (i=0; i < database->link->databaseCount; i++)
+             {
+               if (database->link->databases[i] == database)
+                {
+                  database->link->databases[i] = NULL;
+                  break;
+                }
+             }
+            phpfbReleaseLink(database->link);
+          }
+         fbcdcClose(database->connection);
+         fbcdcRelease(database->connection);
+         free(database->databaseName);
+         free(database->databasePassword);
+         free(database->results);
+         free(database);
+       }
+    }
+}
+
+PHPFBLink* phpfbRetainLink ( PHPFBLink* link)
+{
+  if (link) link->retainCount++;
+  return link;
+}
+
+void phpfbReleaseLink ( PHPFBLink* link)
+{
+//  printf("Release %x %d %d\n",link,link->index,link->retainCount);
+  if (link)
+   {
+     link->retainCount--;
+//printf("Release link     %x %d %d\n", link, link->index, link->retainCount);
+     if (link->retainCount == 0)
+      {
+//        if (link->index == FB_SQL_G(linkIndex) FB_SQL_G(linkIndex = 0;
+        free(link->hostName);
+        free(link->userName);
+        free(link->userPassword);
+        if (link->results) free(link->results);
+        if (link->databases) free(link->databases);
+        free(link);
+      }
+   }
+}
+
+PHPFBResult* phpfbQuery (INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBDatabase* database);
+
+PHP_INI_BEGIN()
+  STD_PHP_INI_BOOLEAN  ("fbsql.allow_persistant",  "1" , PHP_INI_SYSTEM, OnUpdateInt,    allowPersistent,  zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_BOOLEAN  ("fbsql.generate_warnings", "0",  PHP_INI_SYSTEM, OnUpdateInt,    generateWarnings, zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_BOOLEAN  ("fbsql.autocommit",               "1",  PHP_INI_SYSTEM, OnUpdateInt,    autoCommit,       zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_ENTRY_EX ("fbsql.max_persistent",   "-1",  PHP_INI_SYSTEM, OnUpdateInt,    maxPersistant,    zend_fbsql_globals, fbsql_globals, display_link_numbers)
+  STD_PHP_INI_ENTRY_EX ("fbsql.max_links",        "128", PHP_INI_SYSTEM, OnUpdateInt,    maxLinks,         zend_fbsql_globals, fbsql_globals, display_link_numbers)
+  STD_PHP_INI_ENTRY_EX ("fbsql.max_connections",  "128", PHP_INI_SYSTEM, OnUpdateInt,    maxConnections,   zend_fbsql_globals, fbsql_globals, display_link_numbers)
+  STD_PHP_INI_ENTRY_EX ("fbsql.max_results",      "128", PHP_INI_SYSTEM, OnUpdateInt,    maxResults,       zend_fbsql_globals, fbsql_globals, display_link_numbers)
+  STD_PHP_INI_ENTRY_EX ("fbsql.mbatchSize",      "1000", PHP_INI_SYSTEM, OnUpdateInt,    batchSize,               zend_fbsql_globals, fbsql_globals, display_link_numbers)
+  STD_PHP_INI_ENTRY    ("fbsql.default_host",     NULL,  PHP_INI_SYSTEM, OnUpdateString, hostName,         zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_ENTRY    ("fbsql.default_user",     "_SYSTEM",  PHP_INI_SYSTEM, OnUpdateString, userName,         zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_ENTRY    ("fbsql.default_password", "",         PHP_INI_SYSTEM, OnUpdateString, userPassword,     zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_ENTRY    ("fbsql.default_database", "",         PHP_INI_SYSTEM, OnUpdateString, databaseName,     zend_fbsql_globals, fbsql_globals)
+  STD_PHP_INI_ENTRY    ("fbsql.default_database_password",
+                                                  "",         PHP_INI_SYSTEM, OnUpdateString, databasePassword, zend_fbsql_globals, fbsql_globals)
+PHP_INI_END()
+      
+
+static void php_fbsql_init_globals(zend_fbsql_globals *fbsql_globals)
+{
+       fbsql_globals->persistantCount = 0;
+
+       if (fbsql_globals->hostName==NULL)
+       {
+               char name[256];
+               gethostname(name,sizeof(name));
+               name[sizeof(name)-1] = 0;
+               fbsql_globals->hostName = strdup(name);
+       }
+//     fbsql_globals->userName                 = strdup(fbsql_globals->userName);
+//     fbsql_globals->userPassword             = strdup(fbsql_globals->userPassword);
+//     fbsql_globals->databaseName             = strdup(fbsql_globals->databaseName);
+//     fbsql_globals->databasePassword = strdup(fbsql_globals->databasePassword);
+
+       fbsql_globals->persistantCount  = 0;
+       fbsql_globals->linkCount                = 0;
+       fbsql_globals->resultCount              = 0;
+  
+       fbsql_globals->linkIndex                = 0;
+       fbsql_globals->databaseIndex    = 0;
+       fbsql_globals->resultIndex              = 0;
+}
+                                        
+PHP_MINIT_FUNCTION(fbsql)
+{
+       ZEND_INIT_MODULE_GLOBALS(fbsql, php_fbsql_init_globals, NULL);
+
+       REGISTER_INI_ENTRIES();
+
+       fbcInitialize();
+
+       le_result   = register_list_destructors(phpfbReleaseResult,NULL);
+       le_link     = register_list_destructors(phpfbReleaseLink,NULL);
+       le_dba      = register_list_destructors(phpfbReleaseDatabase,NULL);
+
+       REGISTER_LONG_CONSTANT("FBSQL_ASSOC", FBSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("FBSQL_NUM",   FBSQL_NUM,   CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("FBSQL_BOTH",  FBSQL_BOTH,  CONST_CS | CONST_PERSISTENT);
+       return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(fbsql)
+{
+  UNREGISTER_INI_ENTRIES();
+  return SUCCESS;
+}
+
+PHP_RINIT_FUNCTION(fbsql)
+{
+   return SUCCESS;
+}
+
+PHP_MINFO_FUNCTION(fbsql)
+{
+       char buf[32];
+       FBSQLLS_FETCH();
+       php_info_print_table_start();
+       php_info_print_table_header(2, "FrontBase support", "enabled");
+
+       php_info_print_table_row(2, "Client API version", "2.20" );
+
+       if (FB_SQL_G(allowPersistent))
+       {
+               sprintf(buf, "%ld", FB_SQL_G(persistantCount));
+               php_info_print_table_row(2, "Active Persistant Links", buf);
+       }
+
+       sprintf(buf, "%ld", FB_SQL_G(linkCount));
+       php_info_print_table_row(2, "Active Links", buf);
+
+       sprintf(buf, "%ld", FB_SQL_G(resultCount));
+       php_info_print_table_row(2, "Active Result Sets", buf);
+       php_info_print_table_end();
+
+       DISPLAY_INI_ENTRIES();
+}
+
+PHPFBLink* phpfbConnect
+(
+       INTERNAL_FUNCTION_PARAMETERS,
+       char*        hostName,
+       char*        userName,
+       char*        userPassword,
+       int          persistant 
+ )
+{
+// Ref count databases and links!!
+// Search for the database/link in the hash plist and in the hashed list
+// If a link was non persistant then an is opened peristant just insert it 
+// in the persistant list
+//
+// Insert the persistant in the list and in the hash p list
+// Insert the non persistant in the 
+       PHPFBLink* result;
+       list_entry *lep;
+       int        type;
+       char       name[1024];
+       FBSQLLS_FETCH();
+
+       if (hostName     == NULL) hostName     = FB_SQL_G(hostName);
+       if (userName     == NULL) userName     = FB_SQL_G(userName);
+       if (userPassword == NULL) userPassword = FB_SQL_G(userPassword);
+
+//printf("Connection %s %s\n",hostName,userName);
+       sprintf(name,"fbsql_%s_%s",hostName,userName);
+//printf("Hash find '%s'",name);
+       if(zend_hash_find(&EG(persistent_list), name, strlen(name), (void **) &lep) == SUCCESS)
+       {
+               PHPFBLink* lnk;
+               result = lep->ptr;
+               lnk = zend_list_find(result->index,&type);
+               if (lnk != result) result->index = zend_list_insert(result, le_link);
+//printf(" Persistant %x %d \n",result,result->index);
+       }
+       else if(zend_hash_find (&EG(regular_list),name,strlen(name),(void **)&lep) == SUCCESS)
+       {
+               result = lep->ptr;
+//printf(" Non persistant %x %d \n",result,result->index);
+       }
+       else if ( FB_SQL_G(linkCount) == FB_SQL_G(maxLinks))
+       {
+               php_error(E_WARNING,"FrontBase link limit %d exceeded ", FB_SQL_G(maxLinks));
+               return NULL;
+       }
+       else
+       {
+               FBCExecHandler* execHandler = fbcehHandlerForHost(hostName,128);
+               list_entry le;
+               if (execHandler == NULL)
+               {
+                       php_error(E_WARNING,"Cannot connect to host '%s'",hostName);
+                       php_error(E_WARNING,fbcehClassErrorMessage());
+                       return NULL;
+               }
+               result = malloc(sizeof(PHPFBLink));
+               result->retainCount     = 1;
+               result->persistant      = persistant;
+               result->hostName        = strdup(hostName);
+               result->userName        = strdup(userName);
+               result->userPassword    = strdup(userPassword);
+               result->execHandler     = execHandler;
+               result->affectedRows    = 0;
+               result->autoCommit              = FB_SQL_G(autoCommit);
+               result->currentDatabase = NULL;
+               result->databaseCount   = 0;
+               result->databases       = NULL;
+               result->resultCount     = 0;
+               result->results         = NULL;
+
+               le.ptr  = result;
+               le.type = le_link; 
+               if (zend_hash_update(persistant?&EG(persistent_list):&EG(regular_list), name, strlen(name), &le, sizeof(le), NULL)==FAILURE)
+               {
+                       phpfbReleaseLink(result);
+                       return NULL;
+        }
+               result->index = zend_list_insert (phpfbRetainLink(result), le_link);
+               FB_SQL_G(linkCount)++;
+//printf(" new %x %d \n",result,result->index);
+//printf("Ny connection %x %x\n",result,result->execHandler);
+       }
+       return result;
+}
+
+
+int phpfbFetchRow ( PHPFBResult* result, int row)
+{
+       if (result->rowHandler == NULL)
+       {
+                void *rawData = fbcdcFetch(result->connection,result->batchSize,result->fetchHandle);
+                if (rawData == NULL)
+                       result->rowCount = 0;
+               else
+                       result->rowHandler = fbcrhInitWith(rawData, result->metaData);
+       }
+       for (;;)
+       {
+               void *rawData; 
+               if ( row >=  result->rowCount) return 0;
+               if (fbcrhRowCount(result->rowHandler) > (unsigned int)row) return 1;
+               rawData = fbcdcFetch(result->connection,result->batchSize,result->fetchHandle);
+               if (!fbcrhAddBatch(result->rowHandler,rawData)) result->rowCount = fbcrhRowCount(result->rowHandler);
+       }
+       return 0;
+}
+
+// int fbsql_connect(string [hostname] , string [username] , string [password] );
+void phpfbDoConnect(INTERNAL_FUNCTION_PARAMETERS,int persistant)
+{
+       PHPFBLink* result; 
+       char*  hostName     = NULL;
+       char*  userName     = NULL;
+       char*  userPassword = NULL;
+       int    argc         = ARG_COUNT(ht);
+       pval* argv[3];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 3)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               hostName = argv[0]->value.str.val;
+       }
+       if (argc >= 2 )
+       {
+               convert_to_string(argv[1]);
+               userName =  argv[1]->value.str.val;
+       }   
+       if (argc == 3 )
+       {
+               convert_to_string(argv[2]);
+               userPassword =  argv[2]->value.str.val;
+       }
+       result = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,hostName,userName,userPassword,persistant);
+       if (result == NULL) RETURN_FALSE;
+       FB_SQL_G(linkIndex)      = result->index;
+       return_value->value.lval = result->index;
+       return_value->type       = IS_LONG;
+}
+
+// int fbsql_connect(string [hostname] , string [username] , string [password] );
+PHP_FUNCTION(fbsql_connect)
+{
+       phpfbDoConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+
+// int fbsql_pconnect(string [hostname] , string [username] , string [password] );
+PHP_FUNCTION(fbsql_pconnect)
+{
+       phpfbDoConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+
+
+PHPFBLink* phpfbGetLink(int id)
+{
+       int         type;
+       PHPFBLink* phpLink = NULL;
+       FBSQLLS_FETCH();
+
+       if (id  == 0 )
+       {
+               php_error(E_WARNING,"FrontBase has no default connection");
+       }
+       else if ((!(phpLink = (PHPFBLink*) zend_list_find (id,&type))) || (( type != le_link)))
+       {
+               php_error(E_WARNING,"%d is not a FBSQL link index",id);
+               phpLink = NULL;
+       }
+       return phpLink;
+}
+
+PHPFBResult* phpfbGetResult(int id)
+{
+       int           type;
+       PHPFBResult* result = NULL;
+       FBSQLLS_FETCH();
+
+       if (id  == 0 ) {
+               php_error(E_WARNING,"FBSQL no default result");
+       }
+       else if ((!(result = (PHPFBResult*) zend_list_find (id,&type))) || (( type != le_result))) {
+               php_error(E_WARNING,"%d is not a FBSQL result index",id);
+               result = NULL;
+       }
+       return result;
+}
+
+
+// int fbsql_close([int link_identifier])
+PHP_FUNCTION(fbsql_close)
+{
+       int   argc = ARG_COUNT(ht);
+       unsigned   i,j;
+       char  name[1024];
+       PHPFBLink* phpLink = NULL;
+       pval*       argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+       if (argc == 1)
+       {
+               convert_to_long(argv[0]);
+               phpLink = phpfbGetLink(argv[0]->value.lval);
+       }
+       else if (FB_SQL_G(linkIndex) != 0)
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+       for (i=0; i < phpLink->databaseCount; i++)
+       {
+               PHPFBDatabase* database = phpLink->databases[i];
+               if (database)
+               {
+                       for (j=0; j < database->resultCount; j++) if (database->results[j])
+                       {
+                               zend_list_delete (database->results[j]->index);
+                               FB_SQL_G(resultCount)--;
+                       }
+                       zend_list_delete (database->index);
+                       FB_SQL_G(databaseCount)--;
+               }
+       }
+       sprintf(name,"fbsql_%s_%s",phpLink->hostName,phpLink->userName);
+       FB_SQL_G(linkCount)--;
+       if (phpLink->persistant)FB_SQL_G(persistantCount)--;
+       zend_hash_del (&EG(regular_list),name,strlen(name));
+       zend_list_delete(phpLink->index);
+         
+       RETURN_TRUE;
+}
+
+
+// int fbsql_select_db(string database_name [, int link_identifier]
+PHPFBDatabase* phpfbSelectDB 
+(      INTERNAL_FUNCTION_PARAMETERS,
+       char*        databaseName,
+       char*        databasePassword,
+       PHPFBLink*   link
+ )
+{
+       PHPFBDatabase* result = NULL;
+       list_entry *lep;
+       unsigned i;
+       char name[1024];
+       FBSQLLS_FETCH();
+
+       sprintf(name,"fbsql_%s@%s:%s",databaseName,link->hostName,link->userName);
+       if(zend_hash_find(&EG(persistent_list),name,strlen(name),(void **)&lep) == SUCCESS)
+       {
+               PHPFBDatabase* dba;
+               int type;
+               result = lep->ptr;
+               dba = zend_list_find(result->index,&type);
+               if (dba != result) result->index = zend_list_insert(result, le_dba);
+       }
+       else if(zend_hash_find(&EG(regular_list),name,strlen(name),(void **)&lep) == SUCCESS)
+       {
+               result = lep->ptr;
+       }
+       else if (FB_SQL_G(databaseCount) == FB_SQL_G(maxConnections))
+       {
+               php_error(E_WARNING,"FrontBase connection limit %d exceeded", FB_SQL_G(maxConnections));
+               return NULL;
+       }
+       else
+       {
+               list_entry             le;
+               FBCDatabaseConnection* c = fbcdcConnectToDatabase(databaseName,link->hostName,databasePassword);
+               FBCMetaData*           md;
+               if (c == NULL)
+               {
+                       php_error(E_WARNING, fbcdcClassErrorMessage());
+                       return NULL;
+               }
+               md = fbcdcCreateSession(c,"PHP",link->userName,link->userPassword,link->userName);
+               if (fbcmdErrorsFound(md))
+               {
+                       FBCErrorMetaData* emd = fbcdcErrorMetaData(c,md);
+                       char*             emg = fbcemdAllErrorMessages(emd);
+                       if (emg)
+                               php_error(E_WARNING, emg);
+                       else
+                               php_error(E_WARNING,"No message");
+                       free(emg);
+                       fbcemdRelease(emd);
+                       fbcmdRelease(md);
+                       fbcdcClose(c);
+                       fbcdcRelease(c);
+                       return NULL;
+               }
+               fbcmdRelease(md);
+
+               if (c)
+               {
+                       if (link->autoCommit)
+                               md = fbcdcExecuteDirectSQL(c,"SET COMMIT TRUE;");
+                       else
+                               md = fbcdcExecuteDirectSQL(c,"SET COMMIT FALSE;");
+                       fbcmdRelease(md);
+               }
+               fbcdcSetOutputCharacterSet(c,FBC_ISO8859_1);
+               fbcdcSetInputCharacterSet(c,FBC_ISO8859_1);
+
+               le.type = le_dba;
+               le.ptr  = result = malloc(sizeof(PHPFBDatabase));
+
+               if (zend_hash_update(link->persistant?&EG(persistent_list):&EG(regular_list), name, strlen(name), &le, sizeof(le), NULL)==FAILURE)
+               {
+                       fbcdcClose(c);
+                       fbcdcRelease(c);
+                       free(result);
+//printf("Returning Null\n");
+                       return NULL;
+               }
+               result->retainCount      = 2;
+               result->index            = zend_list_insert((PHPFBDatabase*)(le.ptr), le_dba);
+               result->link             = phpfbRetainLink(link);
+               result->databaseName     = strdup(databaseName);
+               result->databasePassword = strdup(databasePassword);
+               result->connection       = c;
+               result->errorNo          = 0;
+               result->errorText        = NULL;
+               result->resultCount      = 0;
+               result->rowIndex         = 0;
+               result->results          = NULL;
+               for (i=0; i < link->databaseCount; i++) if ((link->databases[i]) == NULL) break;
+               if (i==link->databaseCount)
+               {
+                       unsigned j;
+                       link->databaseCount += 5;
+                       link->databases      = realloc(link->databases,sizeof(PHPFBDatabase*)*link->databaseCount);
+                       for (j=i; j < link->databaseCount; j++) link->databases[j] = NULL;
+               }
+               link->databases[i] = result;
+
+               FB_SQL_G(databaseCount)++;
+//   printf("Return database %x %x\n",result,c);
+       }
+       link->currentDatabase     = result;
+       return_value->value.lval  = result->index;
+       return_value->type        = IS_LONG;
+       FB_SQL_G(databaseIndex)   = result->index;
+
+       return result;
+}
+
+void phpfbestrdup (const char * s, int* length, char** value )
+{
+       int   l = s?strlen(s):0;
+       if (value)
+       {
+               char* r = emalloc(l+1);
+               if (s)
+                       strcpy(r,s);
+               else
+                       r[0] = 0;
+               *value  = r;
+       }
+       *length = l;
+}
+
+// bool fbsql_list_autocommit(int link_identifier [, bool OnOff])
+PHP_FUNCTION(fbsql_autocommit)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       PHPFBLink*     phpLink = NULL;
+       FBCMetaData* md;
+       zend_bool OnOff;
+       FBSQLLS_FETCH();
+
+       if ((argc < 1 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       convert_to_long(argv[0]);
+       phpLink = phpfbGetLink(argv[0]->value.lval);    
+
+       if (argc == 2 )
+       {
+               convert_to_boolean(argv[1]);
+               OnOff = Z_BVAL_P(argv[1]);
+               if (OnOff)
+                       md = fbcdcExecuteDirectSQL(phpLink->currentDatabase->connection , "SET COMMIT TRUE;");
+               else
+                       md = fbcdcExecuteDirectSQL(phpLink->currentDatabase->connection, "SET COMMIT FALSE;");
+               fbcmdRelease(md);
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_BOOL(phpLink->autoCommit);
+       }
+}
+
+// int fbsql_list_commit([int link_identifier])
+PHP_FUNCTION(fbsql_commit)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       PHPFBLink*     phpLink = NULL;
+       FBCMetaData* md;
+       int link;
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc == 1 )
+       {
+               convert_to_long(argv[0]);
+               link = argv[0]->value.lval;
+       }
+
+       phpLink = phpfbGetLink(link);
+       if (phpLink == NULL) RETURN_FALSE;
+
+       md = fbcdcCommit(phpLink->currentDatabase->connection);
+
+       if (md) {
+               fbcmdRelease(md);
+               RETURN_TRUE;
+       }
+       else
+               RETURN_FALSE;
+}
+
+// int fbsql_list_rollback([int link_identifier])
+PHP_FUNCTION(fbsql_rollback)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       PHPFBLink*     phpLink = NULL;
+       FBCMetaData* md;
+       int link;
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc == 1 )
+       {
+               convert_to_long(argv[0]);
+               link = argv[0]->value.lval;
+       }
+
+       phpLink = phpfbGetLink(link);
+       if (phpLink == NULL) RETURN_FALSE;
+
+       md = fbcdcRollback(phpLink->currentDatabase->connection);
+
+       if (md) {
+               fbcmdRelease(md);
+               RETURN_TRUE;
+       }
+       else
+               RETURN_FALSE;
+}
+
+
+// string fbsql_hostname([string host_name])
+PHP_FUNCTION(fbsql_hostname)
+{
+       int  argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+
+       phpfbestrdup(FB_SQL_G(hostName), &return_value->value.str.len, &return_value->value.str.val);
+       return_value->type = IS_STRING;
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               free(FB_SQL_G(hostName));
+               FB_SQL_G(hostName) = strdup(argv[0]->value.str.val);
+       }
+}
+
+// string fbsql_database([string database])
+PHP_FUNCTION(fbsql_database)
+{
+       int  argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+
+       phpfbestrdup(FB_SQL_G(databaseName), &return_value->value.str.len, &return_value->value.str.val);
+       return_value->type = IS_STRING;
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               free(FB_SQL_G(databaseName));
+               FB_SQL_G(databaseName) = strdup(argv[0]->value.str.val);
+       }
+}
+
+// string fbsql_database_password([string database_password])
+PHP_FUNCTION(fbsql_database_password)
+{
+       int  argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               free(FB_SQL_G(hostName));
+               FB_SQL_G(databasePassword) = strdup(argv[0]->value.str.val); 
+       }
+}
+
+// string fbsql_username([string username])
+PHP_FUNCTION(fbsql_username)
+{
+       int  argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+
+       phpfbestrdup(FB_SQL_G(userName), &return_value->value.str.len, &return_value->value.str.val);
+       return_value->type = IS_STRING;
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               free(FB_SQL_G(userName));
+               FB_SQL_G(userName) = strdup(argv[0]->value.str.val); 
+       }
+}
+
+// string fbsql_username([string password])
+PHP_FUNCTION(fbsql_password)
+{   
+       int  argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               free(FB_SQL_G(userPassword));
+               FB_SQL_G(userPassword) = strdup(argv[0]->value.str.val); 
+       }
+}
+
+// int fbsql_select_db([string database_name [, int link_identifier]])   
+PHP_FUNCTION(fbsql_select_db)
+{
+       int  argc = ARG_COUNT(ht);
+       pval* argv[2];
+       char* name;
+       PHPFBLink*     phpLink = NULL;
+       PHPFBDatabase* database = NULL;
+       FBSQLLS_FETCH();
+
+       name = FB_SQL_G(databaseName);
+
+       if ((argc < 1) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_string(argv[0]);
+               name = argv[0]->value.str.val;
+       }
+
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               phpLink = phpfbGetLink(argv[1]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Select db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+
+       database = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU,name,"",phpLink);
+       if (database == NULL) RETURN_FALSE;
+
+       phpLink->currentDatabase  = database;
+       FB_SQL_G(linkIndex)          = phpLink->index;
+
+       return_value->value.lval   = database->index;
+       return_value->type         = IS_LONG;
+}
+
+// int fbsql_change_user(string user, string password, string [database] , int [link_identifier] );
+PHP_FUNCTION(fbsql_change_user)
+{
+       int             argc     = ARG_COUNT(ht);
+       pval*           argv[4];
+       int             link;
+       PHPFBLink*      phpLink;
+       PHPFBDatabase * phpDatabase;
+       char*           userName;
+       char*           userPassword;
+       char*           databaseName;
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+       databaseName = FB_SQL_G(databaseName);
+
+       if ((argc < 2) || (argc > 4)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2],&argv[3])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       userName = argv[0]->value.str.val;
+
+       convert_to_string(argv[1]);
+       userPassword = argv[1]->value.str.val;
+
+       if (argc >= 3)
+       {
+               convert_to_string(argv[2]);
+               databaseName = argv[2]->value.str.val;
+       }
+       if (argc >= 4)
+       {
+               convert_to_long(argv[3]);
+               link = argv[3]->value.lval;
+       }
+       if ((phpLink = phpfbGetLink(link))==NULL) RETURN_FALSE;
+       if ((phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU,databaseName,"",phpLink)) == NULL) RETURN_FALSE;
+       {
+               char buffer[1024];
+               sprintf(buffer,"SET AUTHORIZATION %s;",userName);
+
+               phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,buffer, phpDatabase);
+               if (return_value->value.lval)
+               {
+                       free(phpLink->userName);
+                       phpLink->userName = strdup(userName);
+               }
+       }
+}
+
+// int fbsql_create_db([string database_name [, int link_identifier]])
+PHP_FUNCTION(fbsql_create_db)
+{
+       PHPFBLink* phpLink = NULL;
+       int   i;
+       int   argc = ARG_COUNT(ht);
+       pval* argv[2];
+       int   link;
+       char* databaseName;
+       char* hostName;
+       FBDatabaseStatus status;
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+       hostName = FB_SQL_G(hostName);
+
+       if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       databaseName = argv[0]->value.str.val;
+
+       if (argc == 2 )
+       {
+               convert_to_long(argv[1]);
+               link = argv[1]->value.lval;
+               phpLink = phpfbGetLink(link);
+               if (phpLink == NULL) RETURN_FALSE;
+       }
+
+       if (phpLink == NULL)
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+               if (phpLink == NULL) RETURN_FALSE;
+       }
+       status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+       if (status != FBUnknownStatus)
+       {
+               char* txt = "Unknown status";
+               if      ( status == FBStopped  ) txt = "stopped";
+               else if ( status == FBStarting ) txt = "starting";
+               else if ( status == FBRunning  ) txt = "running";
+               else if ( status == FBStopping ) txt = "stopping";
+               else if ( status == FBNoExec   ) txt = "no exec";
+               php_error(E_WARNING, "Could not create %s@%s, database is %s",databaseName,hostName,txt);
+               RETURN_FALSE;
+       }
+       if (!fbcehCreateDatabaseNamedWithOptions(phpLink->execHandler, databaseName, ""))
+       {
+               char* error = fbechErrorMessage(phpLink->execHandler);
+               php_error(E_WARNING, "Could not create %s@%s. %s.",databaseName,hostName,error);
+               RETURN_FALSE;
+       }
+       for (i=0; i < 20; i++)
+       {
+#ifdef PHP_WIN32
+               Sleep(1000);
+#else
+               sleep(1);
+#endif
+               status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+               if (status == FBRunning) break;
+       }
+       FB_SQL_G(linkIndex) = phpLink->index;
+       if (status != FBRunning)
+       {
+               php_error(E_WARNING, "Database %s@%s created -- status unknown",databaseName,hostName);
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+
+// int fbsql_drop_db(string database_name [, int link_identifier])
+PHP_FUNCTION(fbsql_drop_db)
+{
+       char* databaseName;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[2];
+       PHPFBLink* phpLink;
+       FBDatabaseStatus status;
+       int   i;
+       FBSQLLS_FETCH();
+
+       if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       databaseName = argv[0]->value.str.val;
+
+       if (argc == 2)
+       {
+               convert_to_long(argv[1]);
+               phpLink = phpfbGetLink(argv[1]->value.lval);
+               if (phpLink == NULL) RETURN_FALSE;
+       }
+       else
+       {
+      phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+    }
+
+       if (phpLink == NULL)
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+               if (phpLink) RETURN_FALSE;
+       }
+       status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+       if (status != FBStopped)
+       {
+               char* txt = "Unknown status";
+               if      ( status == FBStopped       ) txt = "stopped";
+               else if ( status == FBUnknownStatus ) txt = "nonexisting";
+               else if ( status == FBStarting      ) txt = "starting";
+               else if ( status == FBRunning       ) txt = "running";
+               else if ( status == FBStopping      ) txt = "stopping";
+               else if ( status == FBNoExec        ) txt = "no exec";
+               php_error(E_WARNING, "Could not drop %s@%s, database is %s.",databaseName,phpLink->hostName,txt);
+               RETURN_FALSE;
+       }
+
+       if (! fbcehDeleteDatabaseNamed (phpLink->execHandler, databaseName))
+       {
+               char* error = fbechErrorMessage(phpLink->execHandler);
+               php_error(E_WARNING, "Could not drop %s@%s. %s.",databaseName,phpLink->hostName,error);
+               RETURN_FALSE;
+       }
+       for (i=0; i < 20; i++)
+       {
+#ifdef PHP_WIN32
+               Sleep(1000);
+#else
+               sleep(1);
+#endif
+               status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+               if (status == FBUnknownStatus) break;
+       }
+       if (status != FBUnknownStatus)
+       {
+               php_error(E_WARNING, "Database %s@%s dropped -- status unknown",databaseName,phpLink->hostName);
+               RETURN_FALSE;
+       }
+}
+
+// int fbsql_stop_db(string database_name [, int link_identifier])
+PHP_FUNCTION(fbsql_stop_db)
+{
+       PHPFBDatabase*  phpDatabase;
+       PHPFBLink*      phpLink      = NULL;
+       FBDatabaseStatus status;
+       char*            databaseName;
+
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[2];
+       int   link;
+       unsigned   i;
+       char  name[1024];
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+
+       if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       databaseName = argv[0]->value.str.val;
+
+       if (argc == 2)
+       {
+               convert_to_long(argv[1]);
+               link = argv[1]->value.lval;
+               phpLink = phpfbGetLink(link);
+               if (phpLink == NULL) RETURN_FALSE;
+       }
+       if (phpLink == NULL)
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+               if (phpLink == NULL) RETURN_FALSE;
+       }
+
+       phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,"",phpLink);
+       if (phpDatabase == NULL) RETURN_FALSE;
+
+//printf("Stop db %x\n",phpDatabase->connection);
+       if (!fbcdcStopDatabase(phpDatabase->connection))
+       {
+               php_error(E_WARNING, "Cannot stop database %s@%s",databaseName,phpLink->hostName);
+               RETURN_FALSE;
+       }
+
+       for (i=0; i < 20; i++)
+       {
+               status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+               if (status == FBStopped) break;
+#ifdef PHP_WIN32
+               Sleep(1000);
+#else
+               sleep(1);
+#endif
+       }
+
+       for (i=0; i < phpLink->databaseCount; i++) if (phpLink->databases[i] == phpDatabase) phpLink->databases[i] = NULL;
+
+       for (i=0; i < phpDatabase->resultCount; i++) if (phpDatabase->results[i])
+       {
+               FB_SQL_G(resultCount)--;
+               zend_list_delete(phpDatabase->results[i]->index);
+       }
+//   printf("Database %X %d %d\n",phpDatabase,phpDatabase->index,phpDatabase->retainCount);
+       sprintf(name,"fbsql_%s@%s:%s",databaseName,phpLink->hostName, phpLink->userName);
+       zend_list_delete(phpDatabase->index);
+       FB_SQL_G(databaseCount)--;
+
+       zend_hash_del(&EG(regular_list),name,strlen(name));
+
+//   printf("After list delete\n");
+       RETURN_TRUE;
+}
+
+// int fbsql_start_db(string database_name [, int link_identifier])
+PHP_FUNCTION(fbsql_start_db)
+{
+       PHPFBLink* phpLink = NULL;
+       int   i;
+       int   argc = ARG_COUNT(ht);
+       pval* argv[2];
+       char* databaseName;
+       char* hostName;
+       FBDatabaseStatus status;
+       FBSQLLS_FETCH();
+
+       hostName = FB_SQL_G(hostName);
+
+       if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       databaseName = argv[0]->value.str.val;
+
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               phpLink = phpfbGetLink(argv[1]->value.lval);    
+       }
+       else if ( FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+    }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Start db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+       status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+       if ((status != FBStopped) && (status != FBRunning) && ( status != FBStarting))
+       {
+               char* txt = "Unknown status";
+               if      ( status == FBStopped  ) txt = "stopped";
+               else if ( status == FBStarting ) txt = "starting";
+               else if ( status == FBRunning  ) txt = "running";
+               else if ( status == FBStopping ) txt = "stopping";
+               else if ( status == FBNoExec   ) txt = "no exec";
+               php_error(E_WARNING, "Could not start %s@%s, as database is %s.",databaseName,hostName,txt);
+               RETURN_FALSE;
+       }
+
+       if (status == FBStopped)
+       {
+               if (!fbcehStartDatabaseNamed (phpLink->execHandler, databaseName))
+               {
+                       char* error = fbechErrorMessage(phpLink->execHandler);
+                       php_error(E_WARNING, "Could not start %s@%s. %s.",databaseName,hostName,error);
+                       RETURN_FALSE;
+               }
+       }
+
+       for (i=0; i < 20; i++)
+       {
+#ifdef PHP_WIN32
+               Sleep(1000);
+#else
+               sleep(1);
+#endif
+               status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
+               if (status == FBRunning) break;
+       }
+       if (status != FBRunning)
+       {
+               php_error(E_WARNING, "Database %s@%s started -- status unknown",databaseName,hostName);
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+
+int mdOk(PHPFBDatabase* database, FBCMetaData* md )
+{
+       FBCDatabaseConnection* c = database->connection;
+       int result = 1;
+       FBSQLLS_FETCH();
+
+       database->errorNo        = 0;
+       if (database->errorText)
+       {
+               free(database->errorText);
+               database->errorText = NULL;
+       }
+       if (md == NULL)
+       {
+               database->errorNo  = 1;
+               database->errorText  = strdup("Connection was database server was lost");
+               if (FB_SQL_G(generateWarnings)) php_error(E_WARNING, database->errorText);
+               result = 0;
+       }
+       else if (fbcmdErrorsFound(md))
+       {
+               FBCErrorMetaData* emd = fbcdcErrorMetaData(c,md);
+               char*             emg = fbcemdAllErrorMessages(emd);
+               if (FB_SQL_G(generateWarnings))
+               {
+                       if (emg)
+                               php_error(E_WARNING, emg);
+                       else
+                               php_error(E_WARNING,"No message");
+               }
+               database->errorText = emg;
+               database->errorNo  = 1;
+               fbcemdRelease(emd);
+               result = 0;
+       }
+       return result;
+}
+
+PHPFBResult* phpfbQuery(INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBDatabase* database )
+{
+       PHPFBLink*    link   = database->link;
+       PHPFBResult*  result = NULL;
+       FBCMetaData*   md, *meta;
+       int            ok;
+       char*          tp;
+       char*          fh; 
+       unsigned int   sR = 1, cR = 0;
+       FBSQLLS_FETCH();
+
+       meta     = fbcdcExecuteDirectSQL(database->connection,sql);
+
+       if (fbcmdHasMetaDataArray(meta)) {
+               sR = fbcmdMetaDataArrayCount(meta);
+               md = (FBCMetaData*)fbcmdMetaDataAtIndex(meta, cR);
+       }
+       else
+               md = meta;
+
+       ok     = mdOk(database,md);
+       tp     = fbcmdStatementType(md);
+
+       return_value->value.lval = ok?-1:0;
+       return_value->type       = IS_LONG;
+
+//   printf("Result kind %s\n",tp);
+       if (!ok || (tp[0] == 'C') || (tp[0] == 'R'))
+       {
+               unsigned i;
+               for (i=0; i < database->resultCount; i++)
+               {
+                       PHPFBResult* result = database->results[i];
+                       if (result)
+                       {
+//                             printf("Delete from list %d %x",i,database->results[i],database->results[i]->index);
+                               zend_list_delete(database->results[i]->index);
+                               FB_SQL_G(databaseCount)--;
+                               database->results[i] = NULL;
+                       }
+               }
+       }
+       else if (tp[0] == 'I')
+       {
+               database->rowIndex = fbcmdRowIndex(md);
+       }
+       else if ((fh = fbcmdFetchHandle(md)) && (FB_SQL_G(resultCount) == FB_SQL_G(maxResults)))
+       {
+               fbcdcCancelFetch(database->connection,fh);
+               php_error(E_WARNING,"FrontBase result set limit %d exceeded",FB_SQL_G(maxResults));
+       }
+       else if (fh || (tp[0] == 'E'))
+       {
+               unsigned i;
+               result = malloc(sizeof(PHPFBResult));
+               result->retainCount = 1;
+               result->index       = zend_list_insert(result,le_result);
+               result->link        = NULL;
+               result->database    = phpfbRetainDatabase(database);
+               result->connection  = database->connection;
+               result->fetchHandle = fh;
+               result->ResultmetaData    = meta;
+               result->metaData    = md;
+               result->rowHandler  = NULL;
+               result->batchSize   = FB_SQL_G(batchSize);
+               result->rowCount    = 0x7fffffff;
+               result->columnCount = 0;
+               result->rowIndex    = 0;
+               result->columnIndex = 0;
+               result->row         = NULL;
+               result->array       = NULL;
+               result->list        = NULL;
+               result->selectResults = sR;
+               result->currentResult = cR;
+               FB_SQL_G(resultCount)++;
+               for (i=0; i < database->resultCount; i++) if (database->results[i] == NULL) break;
+               if (i == database->resultCount )
+               {
+                       unsigned j;
+                       database->resultCount += 5;
+                       database->results     = realloc(database->results,sizeof(PHPFBResult*)*database->resultCount);
+                       for (j=i; j < database->resultCount; j++) database->results[j] = NULL;
+               }
+               database->results[i] = result;
+               return_value->value.lval = result->index;
+
+               if (tp[0] != 'E')
+               {
+                       result->rowCount    = 0x7fffffff;
+                       result->columnCount = fbcmdColumnCount(md);
+                       result->fetchHandle = fh;
+                       result->batchSize   = FB_SQL_G(batchSize);
+               }
+               else 
+               {
+                       char* r = fbcmdMessage(result->metaData);
+                       if (( result->list = fbcplParse(r)))
+                       {
+                               result->rowCount    = fbcplCount(result->list);
+                               result->columnCount = 7;
+                       }
+               }
+       }
+       if (link) link->affectedRows = fbcmdRowCount(md);
+       if (result == NULL) fbcmdRelease(md);
+       return result;
+}
+
+// int fbsql_query(string query [, int link_identifier])
+PHP_FUNCTION(fbsql_query)
+{
+       PHPFBDatabase*  phpDatabase;
+       PHPFBLink*      phpLink = NULL;
+       PHPFBResult*    phpResult; 
+       char* sql;
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       FBSQLLS_FETCH();
+
+       if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       sql = argv[0]->value.str.val;
+
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               phpLink = phpfbGetLink(argv[1]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+
+       phpDatabase = phpLink->currentDatabase;
+       if (phpDatabase == NULL) RETURN_FALSE;
+
+       phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
+       if (return_value->value.lval)
+       {
+               FB_SQL_G(linkIndex)                    = phpLink->index;
+               if (phpResult) FB_SQL_G(resultIndex)  = phpResult->index;
+       }
+}
+
+// int fbsql_db_query(string database_name, string query [, int link_identifier])
+PHP_FUNCTION(fbsql_db_query)
+{
+       PHPFBDatabase*  phpDatabase;
+       PHPFBLink*      phpLink;
+       PHPFBResult*    phpResult;
+       char* sql;
+       char* databaseName;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[3];
+       FBSQLLS_FETCH();
+
+       if ((argc < 2) || (argc > 3)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
+
+       convert_to_string(argv[0]);
+       databaseName = argv[0]->value.str.val;
+
+       convert_to_string(argv[1]);
+       sql = argv[1]->value.str.val;
+
+       if (argc >= 3 )
+       {
+               convert_to_long(argv[2]);
+               phpLink = phpfbGetLink(argv[2]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+       phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,"",phpLink);
+       if ( phpDatabase == NULL) RETURN_FALSE;
+       phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
+       if (return_value->value.lval)
+       {
+               FB_SQL_G(linkIndex)                   = phpLink->index;
+               if (phpResult) FB_SQL_G(resultIndex)  = phpResult->index;
+       }
+}
+
+// int fbsql_list_dbs([int link_identifier])
+PHP_FUNCTION(fbsql_list_dbs)
+{
+       PHPFBLink*      phpLink = NULL;
+       PHPFBResult*    phpResult;
+       unsigned   i;
+       int   argc = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+       if (argc == 1 )
+       {
+               convert_to_long(argv[0]);
+               phpLink = phpfbGetLink(argv[0]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+       if (FB_SQL_G(resultCount) == FB_SQL_G(maxResults))
+       {
+               php_error(E_WARNING,"FrontBase result set limit %d exceeded",FB_SQL_G(maxResults));
+               RETURN_FALSE
+       }
+       phpResult = malloc(sizeof(PHPFBResult));
+       phpResult->retainCount = 1;
+       phpResult->index       = zend_list_insert(phpResult, le_result);
+       phpResult->link        = phpfbRetainLink(phpLink);
+       phpResult->database    = NULL;
+       phpResult->connection  = NULL;
+       phpResult->fetchHandle = NULL;
+       phpResult->rowHandler  = NULL;
+       phpResult->metaData    = NULL;
+       phpResult->batchSize   = FB_SQL_G(batchSize);
+       phpResult->columnCount = 1;
+       phpResult->rowIndex    = 0;
+       phpResult->columnIndex = 0;
+       phpResult->row         = NULL;
+       phpResult->array       = fbcehAvailableDatabases(phpLink->execHandler);
+       phpResult->rowCount    = fbaCount(phpResult->array);
+       phpResult->list        = NULL;
+       FB_SQL_G(resultCount)++;
+       for (i=0; i < phpLink->resultCount; i++) if (phpLink->results[i] == NULL) break;
+       if (i == phpLink->resultCount )
+       {
+               unsigned j;
+               phpLink->resultCount += 5;
+               phpLink->results     = realloc( phpLink->results,sizeof(PHPFBResult*)* phpLink->resultCount);
+               for (j=i; j < phpLink->resultCount ; j++)phpLink->results[j] = NULL;
+       }
+       phpLink->results[i]     = phpResult;
+       return_value->value.lval = phpResult->index;
+       return_value->type       = IS_LONG;
+       FB_SQL_G(resultIndex)      = phpResult->index;
+       FB_SQL_G(linkIndex)        = phpLink->index;
+}
+
+// int fbsql_list_tables(string database, int [link_identifier] );
+PHP_FUNCTION(fbsql_list_tables)
+{
+       PHPFBDatabase*  phpDatabase;
+       PHPFBLink*      phpLink;
+       PHPFBResult*    phpResult;
+       char* sql = "select t0.\"table_name\"from information_schema.tables t0, information_schema.SCHEMATA t1 where t0.schema_pk = t1.schema_pk and t1.\"schema_name\" = current_schema;";
+       char* databaseName  = NULL;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[2];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if ( argc >= 1 )
+       {
+               convert_to_string(argv[0]);
+               databaseName = argv[0]->value.str.val;
+       } 
+
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               phpLink = phpfbGetLink(argv[1]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+  
+       if ( databaseName == NULL )
+       {
+               phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, FB_SQL_G(databaseName),"",phpLink);
+       }
+       else 
+       {
+               phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,"",phpLink);
+       }
+       phpDatabase = phpLink->currentDatabase;
+       if (phpDatabase == NULL) RETURN_FALSE;
+
+       phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
+
+       if (return_value->value.lval)
+       {
+               FB_SQL_G(linkIndex)                   = phpLink->index;
+               if (phpResult) FB_SQL_G(resultIndex)  = phpResult->index;
+       }
+}
+
+//int fbsql_list_fields(string database_name, string table_name [, int link_identifier])
+PHP_FUNCTION(fbsql_list_fields)
+{
+       PHPFBDatabase*  phpDatabase;
+       PHPFBLink*      phpLink;
+       PHPFBResult*    phpResult;
+       char             sql[1024];
+       char* databaseName = NULL;
+       char* tableName    = NULL;
+       int   argc         = ARG_COUNT(ht);
+       pval* argv[2];
+       FBSQLLS_FETCH();
+
+       if ((argc < 2) || (argc > 3)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if ( argc >= 1 )
+       {
+               convert_to_string(argv[0]);
+               databaseName = argv[0]->value.str.val;
+       } 
+
+       if ( argc >= 2 )
+       {
+               convert_to_string(argv[1]);
+               tableName = argv[1]->value.str.val;
+       } 
+
+       if (argc >= 3 )
+       {
+               convert_to_long(argv[2]);
+               phpLink = phpfbGetLink(argv[2]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+
+       phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,"",phpLink);
+       phpLink->currentDatabase = phpDatabase;
+       if (phpDatabase == NULL) RETURN_FALSE;
+
+       sprintf(sql,"EXTRACT TABLE %s;",tableName);
+
+       phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
+       if (return_value->value.lval)
+       {
+               FB_SQL_G(linkIndex)                   = phpLink->index;
+               if (phpResult) FB_SQL_G(resultIndex)  = phpResult->index;
+       }
+}
+
+// string fbsql_error([int link_identifier])
+PHP_FUNCTION(fbsql_error)
+{
+       PHPFBLink*     phpLink = NULL;
+       PHPFBDatabase* phpDatabase;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 1)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               phpLink = phpfbGetLink(argv[0]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) != 0 )
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+       phpDatabase = phpLink->currentDatabase;
+       if ((phpDatabase == NULL) || (phpDatabase->errorText == NULL))  RETURN_FALSE;
+       phpfbestrdup(phpDatabase->errorText,&return_value->value.str.len,&return_value->value.str.val);
+       return_value->type          = IS_STRING;
+}
+
+// int fbsql_errno([int link_identifier])
+PHP_FUNCTION(fbsql_errno)
+{
+       PHPFBLink*     phpLink = NULL;
+       PHPFBDatabase* phpDatabase;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 1)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               phpLink = phpfbGetLink(argv[0]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) != 0 )
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+//printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName);
+       phpDatabase = phpLink->currentDatabase;
+       if (phpDatabase == NULL) RETURN_FALSE;
+       return_value->value.lval = phpDatabase->errorNo;
+       return_value->type       = IS_LONG;
+}
+
+// int fbsql_generate_warnings( [int flag]);
+PHP_FUNCTION(fbsql_warnings)
+{
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 1)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+       return_value->value.lval = FB_SQL_G(generateWarnings);
+       return_value->type       = IS_LONG;
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               FB_SQL_G(generateWarnings) = argv[0]->value.lval != 0;
+       }
+}
+
+//int fbsql_affected_rows([int link_identifier])
+PHP_FUNCTION(fbsql_affected_rows)
+{
+       PHPFBLink*      phpLink;
+       int   argc       = ARG_COUNT(ht);
+       pval* argv[1];
+       int   link;
+       FBSQLLS_FETCH();
+
+       link = FB_SQL_G(linkIndex);
+
+       if (argc > 1) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc == 1 )
+       {
+               convert_to_string(argv[0]);
+               link = argv[0]->value.lval;
+       }
+       phpLink = phpfbGetLink(link);
+       if (phpLink == NULL) RETURN_FALSE;
+       return_value->value.lval = phpLink->affectedRows;
+       return_value->type       = IS_LONG;
+}
+
+// int fbsql_insert_id([int link_identifier])
+PHP_FUNCTION(fbsql_insert_id)
+{
+       PHPFBLink* phpLink;
+       PHPFBDatabase* phpDatabase;
+       int   argc     = ARG_COUNT(ht);
+       pval* argv[1];
+       FBSQLLS_FETCH();
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc, &argv[0])==FAILURE) RETURN_FALSE;
+       if (argc == 1 )
+       {
+               convert_to_long(argv[0]);
+               phpLink = phpfbGetLink(argv[0]->value.lval);    
+       }
+       else if (FB_SQL_G(linkIndex) == 0 )
+       {
+               phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
+       }
+       else
+       {
+               phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
+       }
+       if (phpLink == NULL) RETURN_FALSE;
+
+       if ( phpLink->currentDatabase == NULL)
+       {
+               phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, FB_SQL_G(databaseName),"",phpLink);
+       }
+       phpDatabase = phpLink->currentDatabase;
+       if (phpDatabase == NULL) RETURN_FALSE;
+
+       return_value->value.lval = phpDatabase->rowIndex;
+       return_value->type       = IS_LONG;
+       FB_SQL_G(linkIndex) = phpLink->index;
+}
+
+int phpSizeOfInt ( int i )
+{
+       int s = 1;
+       if ( i < 0 )
+       {
+               s++;
+               i = -i;
+       }
+       while ((i = i / 10)) s++;
+       return s;
+}
+
+void phpfbColumnAsString ( PHPFBResult* result, int column, void* data ,int* length, char** value)
+{
+       FBCMetaData*               md          = result->metaData;
+       const FBCDatatypeMetaData* dtmd        = fbcmdDatatypeMetaDataAtIndex(md, column);
+       unsigned                   dtc         = fbcdmdDatatypeCode(dtmd);
+       switch (dtc)
+       {
+               case FB_Boolean:
+               {
+                       unsigned char v = *((unsigned char*)(data));
+                       if (v == 255)
+                               phpfbestrdup("Unknown",length,value);
+                       else if (v == 0 )
+                               phpfbestrdup("False",length,value);
+                       else
+                               phpfbestrdup("True",length,value);
+               }
+               break;
+        
+               case FB_PrimaryKey:
+               case FB_Integer:
+               { 
+                       int   v = *((int*)data);
+                       char  b[128];
+                       sprintf(b,"%d",v);
+                       phpfbestrdup(b,length,value);
+               }
+               break;
+
+               case FB_SmallInteger:
+               {
+                       short v = *((short*)data);
+                       char  b[128];
+                       sprintf(b,"%d",v);
+                       phpfbestrdup(b,length,value);
+               }
+               break; 
+
+               case FB_Float:
+               case FB_Real:
+               case FB_Double:
+               case FB_Numeric:
+               case FB_Decimal:
+               {
+                       double v = *((double*)data);
+                       char  b[128];
+                       sprintf(b,"%f",v);
+                       phpfbestrdup(b,length,value);
+               }
+               break;
+
+               case FB_Character:
+               case FB_VCharacter:
+               {
+                       char* v = (char*)data;
+                       phpfbestrdup(v,length,value);
+               }
+               break;
+
+               case FB_Bit:
+               case FB_VBit:
+               {
+                       const FBCColumnMetaData* clmd  =  fbcmdColumnMetaDataAtIndex(md,column);
+                       struct bitValue
+                       {
+                               unsigned int   nBytes;
+                               unsigned char* bytes;
+                       };
+                       struct bitValue*  ptr = data;
+                       unsigned nBits = ptr->nBytes * 8;
+
+                       if (dtc == FB_Bit) nBits = fbcdmdLength(fbccmdDatatype(clmd));
+                       if (nBits %8 == 0 )
+                       {
+                               unsigned i;
+                               unsigned int l = nBits / 8;
+                               *length = l + 5;
+                               if (value)
+                               {
+                                       char*        r = emalloc(l*2+3+1);
+                                       r[0] = 'X';
+                                       r[1] = '\'';
+                                       for ( i = 0; i < nBits / 8; i++)
+                                       {
+                                               char c[4];
+                                               sprintf(c,"%02x",ptr->bytes[i]);
+                                               r[i*2+2] = c[0];
+                                               r[i*2+3] = c[1];
+                                       }
+                                       r[i*2+2] = '\'';
+                                       r[i*2+3] = 0;
+                                       *value  = r;
+                               }
+                       }
+                       else
+                       {
+                               unsigned i;
+                               unsigned int l = nBits;
+                               *length = l + 5;
+                               if (value)
+                               {
+                                       char*        r = emalloc(l*2+3+1);
+                                       r[0] = 'B';
+                                       r[1] = '\'';
+                                       for ( i = 0; i < nBits; i++)
+                                       {
+                                               int bit = 0;
+                                               if (i/8 < ptr->nBytes) bit = ptr->bytes[i/8] & (1<<(7-(i%8)));
+                                               r[i*2+2] = bit?'1':'0';
+                                       }
+                                       r[i*2+2] = '\'';
+                                       r[i*2+3] = 0;
+                                       *value  = r;
+                               }
+                       }
+               }
+               break;
+
+               case FB_Date:
+               case FB_Time:
+               case FB_TimeTZ:
+               case FB_Timestamp:
+               case FB_TimestampTZ:
+               {
+                       char* v = (char*)data;
+                       phpfbestrdup(v,length,value);
+               }
+               break;
+
+               case FB_YearMonth:
+               {
+                       char b[128];
+                       int  v = *((unsigned int*)data);
+                       sprintf(b,"%d",v);
+                       phpfbestrdup(b,length,value);
+               }
+               break;
+
+               case FB_DayTime:
+               {
+                       char b[128];
+                       double seconds = *((double*)data);
+                       sprintf(b,"%f",seconds);
+                       phpfbestrdup(b,length,value);
+               }
+               break;
+
+               case FB_CLOB:
+               case FB_BLOB:
+//      {
+//         unsigned char* bytes = (unsigned char*)data;
+//         if (*bytes == '\1')
+//          {  // Direct
+//            unsigned int   l   = *((unsigned int*)(bytes+1));
+//            unsigned char* ptr = *((unsigned char**)(bytes+5));
+//            unsigned int   i;
+//           mf(file,"%4d:",l);
+//            for (i=0; i < l; i++)
+//             {
+//               if (i)
+//                {
+//                  if ((i % 32) == 0) mf(file,"\n     %*d:",lw+4,i);
+//                  else if ((i % 4) == 0) mf(file,"  ");
+//                }
+//               mf(file,"%02x",*ptr++);
+//             }
+//          }
+//         else
+//{
+//            mf(file,"%s",bytes+1);
+//          }
+//      }
+//     break;
+
+               default:
+                       php_error(E_WARNING,"Unimplemented type");
+               break;
+       }
+}
+
+void phpfbSqlResult ( INTERNAL_FUNCTION_PARAMETERS, PHPFBResult* result, int rowIndex, int  columnIndex )
+{
+       void** row;
+       if (result->list)
+       {
+               FBCPList* columns = (FBCPList*)fbcplValueForKey(result->list,"COLUMNS");
+               FBCPList* column  = (FBCPList*)fbcplValueAtIndex(columns,result->rowIndex);
+               if ( columnIndex == 0 )  
+               { // Name
+                       FBCPList* name = (FBCPList*)fbcplValueForKey(column,"NAME");
+                       return_value->type = IS_STRING;
+                       phpfbestrdup(fbcplString(( FBCPList*)name), &return_value->value.str.len, &return_value->value.str.val);
+               }
+               else if ( columnIndex == 2 )
+               { // Length
+                       FBCPList* name = (FBCPList*)fbcplValueForKey(column,"WIDTH");
+                       return_value->type = IS_STRING;
+                       phpfbestrdup((const char*)fbcplString(name), &return_value->value.str.len, &return_value->value.str.val);
+               }
+               else if ( columnIndex == 1 )
+               { // Type
+                       FBCPList* name = (FBCPList*)fbcplValueForKey(column,"DATATYPE");
+                       return_value->type = IS_STRING;
+                       phpfbestrdup((const char*)fbcplString(name), &return_value->value.str.len, &return_value->value.str.val);
+               }
+               else if ( columnIndex == 3 )
+               { // Flags
+                       return_value->type = IS_STRING;
+                       phpfbestrdup("", &return_value->value.str.len, &return_value->value.str.val);
+               }
+               else
+               {
+                       return_value->type = IS_STRING;
+                       phpfbestrdup("", &return_value->value.str.len, &return_value->value.str.val);
+               }
+       }
+       else if (result->array)
+       { // Special case for get dbs
+               phpfbestrdup((char*)fbaObjectAtIndex(result->array,rowIndex), &return_value->value.str.len, &return_value->value.str.val);
+               return_value->type          = IS_STRING;
+       }
+       else if (!phpfbFetchRow(result,rowIndex))
+       {
+//     php_error(E_WARNING,"No such row %d in result set %d",resultIndex+1,rowIndex);
+               RETURN_FALSE;
+       }
+       else if (columnIndex >= result->columnCount)
+       {
+               php_error(E_WARNING,"No such column %d in result set %d",columnIndex,rowIndex);
+               RETURN_FALSE;
+       }
+       else
+       {
+               row = fbcrhRowAtIndex(result->rowHandler,rowIndex);
+               if (row == NULL)
+               {
+                       RETURN_FALSE;
+               }
+               else if (row[columnIndex])
+               {
+                       phpfbColumnAsString(result,columnIndex,row[columnIndex],&return_value->value.str.len,&return_value->value.str.val);
+                       return_value->type = IS_STRING;
+               }
+               else
+               {
+                       return_value->type = IS_NULL;
+               }
+       }
+}
+                       
+// int fbsql_result(int result, int row [, mixed field])
+PHP_FUNCTION(fbsql_result)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[3];
+       PHPFBResult*       result;
+       int                 resultIndex;
+       int                 rowIndex;
+       int                 columnIndex;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || (argc > 3 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       rowIndex = result->rowIndex;
+       if (argc >= 2)
+       {
+               convert_to_long(argv[1]);
+               rowIndex = argv[1]->value.lval;
+       }
+
+       columnIndex  = result->columnIndex;
+       if (argc == 3)
+       {
+               if ((argv[2]->type == IS_STRING) && (result->metaData))
+               {
+                       for (columnIndex =0; columnIndex < result->columnCount; columnIndex ++)
+                       {
+                               const FBCColumnMetaData* cmd = fbcmdColumnMetaDataAtIndex(result->metaData, columnIndex);
+                               const char*              lbl = fbccmdLabelName(cmd);
+                               if (strcmp((char*)lbl, argv[2]->value.str.val) == 0 ) break;
+                       }
+                       if (columnIndex == result->columnCount) RETURN_FALSE;
+               }
+               else
+               {
+                       convert_to_long(argv[2]);
+                       columnIndex = argv[2]->value.lval;
+                       if ( columnIndex < 0 )
+                       {
+                               php_error(E_WARNING,"Illegal column index - %d",columnIndex);
+                               RETURN_FALSE;
+                       }
+               }
+    }
+   
+       phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,rowIndex,columnIndex);
+
+       FB_SQL_G(resultIndex) = resultIndex;
+       result->columnIndex++;
+       if (result->columnIndex == result->columnCount)
+       {
+               result->rowIndex++;
+               result->columnIndex = 0;
+       }
+}
+
+// int fbsql_next_result(int result)
+PHP_FUNCTION(fbsql_next_result)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       PHPFBResult*       result;
+       int                 resultIndex;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+    convert_to_long(argv[0]);
+       result = phpfbGetResult(argv[0]->value.lval);
+       if (result == NULL) RETURN_FALSE;
+
+    result->currentResult++;
+       if (result->currentResult < result->selectResults) {
+        if (result->fetchHandle) fbcdcCancelFetch(result->connection, result->fetchHandle);
+               if (result->rowHandler) fbcrhRelease(result->rowHandler);
+               result->metaData    = (FBCMetaData*)fbcmdMetaDataAtIndex(result->ResultmetaData, result->currentResult);
+               result->fetchHandle = fbcmdFetchHandle(result->metaData);
+               result->rowHandler  = NULL;
+               result->batchSize   = FB_SQL_G(batchSize);
+               result->rowCount    = 0x7fffffff;
+               result->columnCount = fbcmdColumnCount(result->metaData);;
+               result->rowIndex    = 0;
+               result->columnIndex = 0;
+               result->row         = NULL;
+               result->array       = NULL;
+               result->list        = NULL;
+               if (result->database->link) 
+                       result->database->link->affectedRows = fbcmdRowCount(result->metaData);
+
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_FALSE;
+       }
+}
+
+// int fbsql_num_rows(int result)
+PHP_FUNCTION(fbsql_num_rows)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 rowCount;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       rowCount = fbcmdRowCount (result->metaData);
+       if (rowCount == -1 )
+       {
+               phpfbFetchRow(result,0x7fffffff);
+               rowCount = result->rowCount;
+       }
+       return_value->value.lval = rowCount;
+       return_value->type       = IS_LONG;
+}
+
+// int fbsql_num_fields(int result)
+PHP_FUNCTION(fbsql_num_fields)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       int   resultIndex;
+       PHPFBResult* result;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       return_value->value.lval = result->columnCount;
+       return_value->type       = IS_LONG;
+
+       FB_SQL_G(resultIndex) = resultIndex;
+}
+
+// object fbsql_fetch_object(int result [, int result_typ])
+PHP_FUNCTION(fbsql_fetch_object)
+{
+       PHP_FN(fbsql_fetch_array)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       if (return_value->type==IS_ARRAY)
+       {
+               return_value->type=IS_OBJECT;
+               return_value->value.obj.properties = return_value->value.ht;
+               return_value->value.obj.ce = &zend_standard_class_def;
+       }
+}
+
+// array fbsql_fetch_row(int result)
+PHP_FUNCTION(fbsql_fetch_row)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 i;
+       int                 resultIndex;
+       PHPFBResult*       result;
+       int                 rowIndex ;
+       void**              row;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || (argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 ) {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+   
+       rowIndex = result->rowIndex;
+
+       if (result->fetchHandle == NULL) {
+               RETURN_FALSE;
+       }
+       if (result->rowCount == 0x7fffffff) {
+               if (!phpfbFetchRow(result,rowIndex)) {
+                       RETURN_FALSE;
+               }
+       }
+       if (!(row = fbcrhRowAtIndex(result->rowHandler,rowIndex))) {
+               RETURN_FALSE;
+       }
+       if (array_init(return_value)==FAILURE) {
+               RETURN_FALSE;
+       }
+       result->row = row;
+       for (i=0; i < result->columnCount; i++) {
+               char*        value;
+               unsigned int length;
+               if (row[i]) {
+                       phpfbColumnAsString(result,i,row[i],&length,&value);
+                       add_index_stringl(return_value,i,value,length,0);
+               }
+               else {
+                       add_index_unset(return_value,i);
+               }
+       }
+       result->rowIndex    = rowIndex+1;
+       result->columnIndex = 0;
+       FB_SQL_G(resultIndex) = resultIndex;
+}
+
+// array fbsql_fetch_array(int result [, int result_typ])
+PHP_FUNCTION(fbsql_fetch_array)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 i;
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 rowIndex;
+       int                 result_type = FBSQL_BOTH;
+       void**              row;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1)
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       rowIndex = result->rowIndex;
+       if (argc == 2 )
+       {
+               convert_to_long(argv[1]);
+               result_type = argv[1]->value.lval;
+               if (((result_type & FBSQL_NUM) != FBSQL_NUM) && ((result_type & FBSQL_ASSOC) != FBSQL_ASSOC))
+               {
+                       php_error(E_WARNING,"Illegal result type use FBSQL_NUM, FBSQL_ASSOC, or FBSQL_BOTH.");
+                       RETURN_FALSE;
+               }
+       }
+       if (result->fetchHandle == NULL)
+       {
+               RETURN_FALSE;
+       }
+       if (result->rowCount == 0x7fffffff)
+       {
+               phpfbFetchRow(result,result->rowIndex);
+       }
+       row = fbcrhRowAtIndex(result->rowHandler,rowIndex);
+       if (row == NULL)
+       {
+               RETURN_FALSE;
+       }
+       if (array_init(return_value)==FAILURE)
+       {
+               RETURN_FALSE;
+       }
+       for (i=0; i < result->columnCount; i++)
+       {
+               if (row[i])
+               {
+                       char*        value;
+                       unsigned int length;
+                       unsigned int c = 0;
+                       phpfbColumnAsString(result,i,row[i],&length,&value);
+                       if (result_type & FBSQL_NUM)
+                       {
+                               add_index_stringl(return_value,i,value,length,c);
+                               c = 1;
+                       }
+                       if (result_type & FBSQL_ASSOC)
+                       {
+                               char* key = (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, i));
+                               add_assoc_stringl(return_value,key, value, length, c);
+                       }
+               }
+               else
+               {
+                       if (result_type & FBSQL_NUM)
+                       {
+                               add_index_unset(return_value,i);
+                       }
+                       if (result_type & FBSQL_ASSOC)
+                       {
+                               char* key = (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, i));
+                               add_assoc_unset(return_value,key);
+                       }
+               }
+       }
+       result->rowIndex    = result->rowIndex+1;
+       result->columnIndex = 0;
+}
+
+// int fbsql_data_seek(int result, int row_number)
+PHP_FUNCTION(fbsql_data_seek)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult*       result;
+       int                 rowIndex;
+       FBSQLLS_FETCH();
+
+       if (argc != 2 ) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       convert_to_long(argv[0]);
+       resultIndex = argv[0]->value.lval;
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       convert_to_long(argv[1]);
+       rowIndex = argv[1]->value.lval;
+       if (rowIndex < 0 )
+       {
+               php_error(E_WARNING,"Illegal index",resultIndex+1);
+               RETURN_FALSE;
+       }
+
+       if (result->rowCount == 0x7fffffff) phpfbFetchRow(result,rowIndex);
+       if (rowIndex > result->rowCount) RETURN_FALSE;
+       result->rowIndex = rowIndex;
+
+       RETURN_TRUE;
+}
+
+// array fbsql_fetch_lengths(int result)
+PHP_FUNCTION(fbsql_fetch_lengths)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 i;
+       int                 resultIndex;
+       PHPFBResult* result;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || ( argc > 1 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+   
+       if (result->row == NULL) RETURN_FALSE;
+       if (array_init(return_value)==FAILURE) RETURN_FALSE;
+       for (i=0; i < result->columnCount; i++)
+       {
+               unsigned  length = 0;
+               if (result->row[i]) phpfbColumnAsString(result,i, result->row[i],&length,NULL);
+               add_index_long(return_value, i, length);
+       }
+       FB_SQL_G(resultIndex) = resultIndex;
+}
+
+// object fbsql_fetch_field(int result [, int field_offset])
+PHP_FUNCTION(fbsql_fetch_field)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such column in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       if (object_init(return_value)==FAILURE)
+       {
+               RETURN_FALSE;
+       }
+       add_property_string(return_value, "name",       (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, column)),1);
+       add_property_string(return_value, "table",      (char*)fbccmdTableName(fbcmdColumnMetaDataAtIndex(result->metaData,column)),1);
+       add_property_long(return_value,   "max_length", fbcdmdLength(fbccmdDatatype(fbcmdColumnMetaDataAtIndex(result->metaData,column))));
+       add_property_string(return_value, "type",       (char*)fbcdmdDatatypeString (fbcmdDatatypeMetaDataAtIndex(result->metaData, column)),1);
+//     Remember to add the rest
+//     add_property_long(return_value, "not_null",IS_NOT_NULL(mysql_field->flags)?1:0);
+//     add_property_long(return_value, "primary_key",IS_PRI_KEY(mysql_field->flags)?1:0);
+//     add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
+//     add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
+//     add_property_long(return_value, "numeric",IS_NUM(mysql_field->type)?1:0);
+//     add_property_long(return_value, "blob",IS_BLOB(mysql_field->flags)?1:0);
+//     add_property_string(return_value, "type",php_mysql_get_field_name(mysql_field->type), 1);
+//     add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
+//     add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
+}
+
+// int fbsql_field_seek(int result, int field_offset)
+PHP_FUNCTION(fbsql_field_seek)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || ( argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc>=2)
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+       }
+       if (column < 0 )
+       {
+               php_error(E_WARNING,"Illegal column index %d",column);
+               RETURN_FALSE;
+       }
+       if (column >= result->columnCount)
+       {
+               php_error(E_WARNING,"No such column %d in result %d",column,resultIndex);
+               RETURN_FALSE;
+       }
+
+       FB_SQL_G(resultIndex) = resultIndex;
+       result->columnIndex = column;
+       RETURN_TRUE;
+}
+
+// string mysql_field_name(int result, int field_index)
+PHP_FUNCTION(fbsql_field_name)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such row in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       if (result->list)
+       {
+               phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,0);
+       }
+       else if (result->metaData)
+       {
+       phpfbestrdup(fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, column)),
+                                       &return_value->value.str.len,
+                                       &return_value->value.str.val);
+               return_value->type = IS_STRING;
+               FB_SQL_G(resultIndex) = resultIndex;
+               result->columnIndex = column;
+       }
+}
+
+// string fbsql_field_table(int result, int field_index)
+PHP_FUNCTION(fbsql_field_table)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such row in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       phpfbestrdup(fbccmdTableName(fbcmdColumnMetaDataAtIndex(result->metaData,column)),
+                                       &return_value->value.str.len,
+                                       &return_value->value.str.val);
+       return_value->type = IS_STRING;
+}
+
+// string fbsql_field_lene(int result, int field_index)
+PHP_FUNCTION(fbsql_field_len)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such row in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       if (result->list)
+       {
+               phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,2);
+       }
+       else if (result->metaData)
+       {
+               unsigned int length = fbcdmdLength(fbccmdDatatype(fbcmdColumnMetaDataAtIndex(result->metaData,column)));
+               char         buffer[50];
+               sprintf(buffer,"%d",length);
+               phpfbestrdup(buffer,
+                                       &return_value->value.str.len,
+                                       &return_value->value.str.val);
+               return_value->type = IS_STRING;
+       }
+       else
+       {
+               RETURN_FALSE;
+       }
+}
+
+// string fbsql_field_type(int result, int field_index)
+PHP_FUNCTION(fbsql_field_type)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such column in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       if (result->list)
+       {
+               phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,1);
+       }
+       else if (result->metaData)
+       {
+               phpfbestrdup(fbcdmdDatatypeString (fbcmdDatatypeMetaDataAtIndex(result->metaData, column)),
+                                       &return_value->value.str.len,
+                                       &return_value->value.str.val);
+               return_value->type = IS_STRING;
+       }
+       else
+       {
+               RETURN_FALSE;
+       }
+}
+
+// string fbsql_field_flags(int result, int field_index)
+PHP_FUNCTION(fbsql_field_flags)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[2];
+       int                 resultIndex;
+       PHPFBResult* result;
+       int                 column;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0 ) || (argc > 2 )) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 )
+       {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+
+       column = result->columnIndex;
+       if (argc >= 2 )
+       {
+               convert_to_long(argv[1]);
+               column = argv[1]->value.lval;
+               if (column < 0 )
+               {
+                       php_error(E_WARNING,"Illegal index",resultIndex+1);
+                       RETURN_FALSE;
+               }
+               if (column >= result->columnCount)
+               {
+                       php_error(E_WARNING,"%d no such column in result",column);
+                       RETURN_FALSE;
+               }
+       }
+       if (array_init(return_value)==FAILURE)
+       {
+               RETURN_FALSE;
+       }
+   // We should create the result -- currently empty
+
+}
+
+// int fbsql_free_result(int result)
+PHP_FUNCTION(fbsql_free_result)
+{
+       int   argc    = ARG_COUNT(ht);
+       pval* argv[1];
+       int           resultIndex;
+       PHPFBResult* result;
+       FBSQLLS_FETCH();
+
+       resultIndex = FB_SQL_G(resultIndex);
+
+       if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
+       if (zend_get_parameters(ht,argc,&argv[0])==FAILURE) RETURN_FALSE;
+
+       if (argc >= 1 ) {
+               convert_to_long(argv[0]);
+               resultIndex = argv[0]->value.lval;
+       }
+       result = phpfbGetResult(resultIndex);
+       if (result == NULL) RETURN_FALSE;
+       zend_list_delete(result->index);
+       FB_SQL_G(resultCount)--;
+       FB_SQL_G(resultIndex) = 0;
+       RETURN_TRUE;
+}
+
+#endif
diff --git a/ext/fbsql/php_fbsql.h b/ext/fbsql/php_fbsql.h
new file mode 100644 (file)
index 0000000..135b339
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP version 4.0                                                      |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2001 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Frank M. Kromann frank@frontbase.com>                       |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#define HAVE_FBSQL 1
+
+#ifndef _PHP_FBSQL_H
+#define _PHP_FBSQL_H
+
+#if COMPILE_DL_FBSQL
+#undef HAVE_FBSQL
+#define HAVE_FBSQL 1
+#endif
+#if HAVE_FBSQL
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+extern zend_module_entry fbsql_module_entry;
+#define fbsql_module_ptr &fbsql_module_entry
+
+#include <FBCAccess/FBCAccess.h>
+
+extern PHP_MINIT_FUNCTION(fbsql);
+extern PHP_RINIT_FUNCTION(fbsql);
+extern PHP_MSHUTDOWN_FUNCTION(fbsql);
+PHP_MINFO_FUNCTION(fbsql);
+PHP_FUNCTION(fbsql_connect);
+PHP_FUNCTION(fbsql_pconnect);
+PHP_FUNCTION(fbsql_close);
+PHP_FUNCTION(fbsql_select_db);
+PHP_FUNCTION(fbsql_change_user);
+PHP_FUNCTION(fbsql_create_db);
+PHP_FUNCTION(fbsql_drop_db);
+PHP_FUNCTION(fbsql_start_db);
+PHP_FUNCTION(fbsql_stop_db);
+PHP_FUNCTION(fbsql_query);
+PHP_FUNCTION(fbsql_db_query);
+PHP_FUNCTION(fbsql_list_dbs);
+PHP_FUNCTION(fbsql_list_tables);
+PHP_FUNCTION(fbsql_list_fields);
+PHP_FUNCTION(fbsql_error);
+PHP_FUNCTION(fbsql_errno);
+PHP_FUNCTION(fbsql_affected_rows);
+PHP_FUNCTION(fbsql_insert_id);
+PHP_FUNCTION(fbsql_result);
+PHP_FUNCTION(fbsql_next_result);
+PHP_FUNCTION(fbsql_num_rows);
+PHP_FUNCTION(fbsql_num_fields);
+PHP_FUNCTION(fbsql_fetch_row);
+PHP_FUNCTION(fbsql_fetch_array);
+PHP_FUNCTION(fbsql_fetch_object);
+PHP_FUNCTION(fbsql_data_seek);
+PHP_FUNCTION(fbsql_fetch_lengths);
+PHP_FUNCTION(fbsql_fetch_field);
+PHP_FUNCTION(fbsql_field_seek);
+PHP_FUNCTION(fbsql_free_result);
+PHP_FUNCTION(fbsql_field_name);
+PHP_FUNCTION(fbsql_field_table);
+PHP_FUNCTION(fbsql_field_len);
+PHP_FUNCTION(fbsql_field_type);
+PHP_FUNCTION(fbsql_field_flags);
+PHP_FUNCTION(fbsql_autocommit);
+PHP_FUNCTION(fbsql_commit);
+PHP_FUNCTION(fbsql_rollback);
+PHP_FUNCTION(fbsql_hostname);
+PHP_FUNCTION(fbsql_database);
+PHP_FUNCTION(fbsql_database_password);
+PHP_FUNCTION(fbsql_username);
+PHP_FUNCTION(fbsql_password);
+PHP_FUNCTION(fbsql_warnings);
+
+ZEND_BEGIN_MODULE_GLOBALS(fbsql)
+   long allowPersistent;
+   long generateWarnings;
+   long autoCommit;
+   long maxPersistant;
+   long maxLinks;
+   long maxConnections;
+   long maxResults;
+   long batchSize;
+   char *hostName;
+   char *databaseName;
+   char *databasePassword;
+   char *userName;
+   char *userPassword;
+   long persistantCount;
+   long linkCount;
+   long databaseCount;
+   long resultCount;
+
+   int linkIndex;
+   int databaseIndex;
+   int resultIndex;
+ZEND_END_MODULE_GLOBALS(fbsql)
+
+#ifdef ZTS
+# define FBSQLLS_D             zend_fbsql_globals *fbsql_globals
+# define FBSQLLS_DC            , FBSQLLS_D
+# define FBSQLLS_C             fbsql_globals
+# define FBSQLLS_CC            , FBSQLLS_C
+# define FB_SQL_G(v)   (fbsql_globals->v)
+# define FBSQLLS_FETCH()       zend_fbsql_globals *fbsql_globals = ts_resource(fbsql_globals_id)
+#else
+# define FBSQLLS_D
+# define FBSQLLS_DC
+# define FBSQLLS_C
+# define FBSQLLS_CC
+# define FB_SQL_G(v)   (fbsql_globals.v)
+# define FBSQLLS_FETCH()
+#endif
+
+
+
+//#ifndef ZTS  // No need for external definitions
+//extern fbsql_module* phpfbModule;
+//#endif
+
+#else  //  HAVE_FBSQL
+
+#define fbsql_module_ptr NULL
+#error not ok
+#endif //  HAVE_FBSQL
+
+#define phpext_fbsql_ptr fbsql_module_ptr
+
+#endif /* _PHP_FBSQL_H */