[PHP-DEV] CVS update: php3/functions From: andrew (php-dev <email protected>)
Date: 03/02/99

Date: Tuesday March 2, 1999 @ 8:08
Author: andrew

Update of /repository/php3/functions
In directory asf:/u/temp/cvs-serv13627/functions

Modified Files:
        interbase.c php3_interbase.h
Log Message:
Many changes.
ibase_prepare() and ibase_execute() now work
ibase_query() support placeholders
blobs read/write support added
transactions redesign
link and transaction handles combine in one variable

some bugs killed and some new added...
Index: php3/functions/interbase.c
diff -c php3/functions/interbase.c:1.11 php3/functions/interbase.c:1.12
*** php3/functions/interbase.c:1.11 Sun Jan 31 12:57:27 1999
--- php3/functions/interbase.c Tue Mar 2 08:08:30 1999
***************
*** 1,36 ****
  /*
     +----------------------------------------------------------------------+
! | PHP HTML Embedded Scripting Language Version 3.0 |
     +----------------------------------------------------------------------+
! | Copyright (c) 1997-1999 PHP Development Team (See Credits file) |
     +----------------------------------------------------------------------+
     | This program is free software; you can redistribute it and/or modify |
! | it under the terms of one of the following licenses: |
! | |
     | A) the GNU General Public License as published by the Free Software |
! | Foundation; either version 2 of the License, or (at your option) |
! | any later version. |
! | |
! | B) the PHP License as published by the PHP Development Team and |
! | included in the distribution in the file: LICENSE |
! | |
! | This program is distributed in the hope that it will be useful, |
! | but WITHOUT ANY WARRANTY; without even the implied warranty of |
! | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
! | GNU General Public License for more details. |
! | |
! | You should have received a copy of both licenses referred to here. |
! | If you did not, or have any questions about PHP licensing, please |
! | contact core <email protected> |
     +----------------------------------------------------------------------+
! | Authors: Jouni Ahto <jah <email protected>> |
! | Andrew Avdeev <andy <email protected>> |
     +----------------------------------------------------------------------+
   */
  
! /* $Id: interbase.c,v 1.11 1999/01/31 17:57:27 andrew Exp $ */
  
! /* TODO: A lot... */
  
  #include "config.h"
  #include "php.h"
--- 1,37 ----
  /*
     +----------------------------------------------------------------------+
! | PHP HTML Embedded Scripting Language Version 3.0 |
     +----------------------------------------------------------------------+
! | Copyright (c) 1997-1999 PHP Development Team (See Credits file) |
     +----------------------------------------------------------------------+
     | This program is free software; you can redistribute it and/or modify |
! | it under the terms of one of the following licenses: |
! | |
     | A) the GNU General Public License as published by the Free Software |
! | Foundation; either version 2 of the License, or (at your option) |
! | any later version. |
! | |
! | B) the PHP License as published by the PHP Development Team and |
! | included in the distribution in the file: LICENSE |
! | |
! | This program is distributed in the hope that it will be useful, |
! | but WITHOUT ANY WARRANTY; without even the implied warranty of |
! | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
! | GNU General Public License for more details. |
! | |
! | You should have received a copy of both licenses referred to here. |
! | If you did not, or have any questions about PHP licensing, please |
! | contact core <email protected> |
     +----------------------------------------------------------------------+
! | Authors: Jouni Ahto <jah <email protected>> |
! | Andrew Avdeev <andy <email protected>> |
     +----------------------------------------------------------------------+
   */
  
! /* $Id: interbase.c,v 1.12 1999/03/02 13:08:30 andrew Exp $ */
  
! /* TODO: Arrays, roles?
! A lot... */
  
  #include "config.h"
  #include "php.h"
***************
*** 42,49 ****
  #include <time.h>
  #include "php3_list.h"
  #include "php3_string.h"
  
! /* {{{ extension definition structures */
  function_entry ibase_functions[] = {
          {"ibase_connect", php3_ibase_connect, NULL},
          {"ibase_pconnect", php3_ibase_pconnect, NULL},
--- 43,52 ----
  #include <time.h>
  #include "php3_list.h"
  #include "php3_string.h"
+ #include "fsock.h"
+ #include "head.h"
  
! /* {{{ extension definition structures */ /*FOLD00*/
  function_entry ibase_functions[] = {
          {"ibase_connect", php3_ibase_connect, NULL},
          {"ibase_pconnect", php3_ibase_pconnect, NULL},
***************
*** 51,82 ****
          {"ibase_query", php3_ibase_query, NULL},
          {"ibase_fetch_row", php3_ibase_fetch_row, NULL},
          {"ibase_fetch_object", php3_ibase_fetch_object,NULL},
! {"ibase_free_result", php3_ibase_free_result, NULL},
          {"ibase_prepare", php3_ibase_prepare, NULL},
- {"ibase_bind", php3_ibase_bind, NULL},
          {"ibase_execute", php3_ibase_execute, NULL},
          {"ibase_free_query", php3_ibase_free_query, NULL},
! {"ibase_timefmt", php3_ibase_timefmt, NULL},
!
          {"ibase_num_fields", php3_ibase_num_fields, NULL},
! {"ibase_field_info", php3_ibase_field_info, NULL},
!
          {"ibase_trans", php3_ibase_trans, NULL},
          {"ibase_commit", php3_ibase_commit, NULL},
! {"ibase_rollback", php3_ibase_rollback, NULL},
!
! {"ibase_blob_info", php3_ibase_blob_info, NULL},
! {"ibase_blob_create", php3_ibase_blob_create, NULL},
! {"ibase_blob_add", php3_ibase_blob_add, NULL},
! {"ibase_blob_cancel", php3_ibase_blob_cancel, NULL},
          {"ibase_blob_close", php3_ibase_blob_close, NULL},
          {"ibase_blob_open", php3_ibase_blob_open, NULL},
! {"ibase_blob_get", php3_ibase_blob_get, NULL},
! {"ibase_blob_echo", php3_ibase_blob_echo, NULL},
! {"ibase_blob_import", php3_ibase_blob_import, NULL},
!
! {"ibase_errmsg", php3_ibase_errmsg, NULL},
! {NULL, NULL, NULL}
  };
  
  php3_module_entry ibase_module_entry =
--- 54,84 ----
          {"ibase_query", php3_ibase_query, NULL},
          {"ibase_fetch_row", php3_ibase_fetch_row, NULL},
          {"ibase_fetch_object", php3_ibase_fetch_object,NULL},
! {"ibase_free_result", php3_ibase_free_result, NULL},
          {"ibase_prepare", php3_ibase_prepare, NULL},
          {"ibase_execute", php3_ibase_execute, NULL},
          {"ibase_free_query", php3_ibase_free_query, NULL},
! {"ibase_timefmt", php3_ibase_timefmt, NULL},
!
          {"ibase_num_fields", php3_ibase_num_fields, NULL},
! {"ibase_field_info", php3_ibase_field_info, NULL},
!
          {"ibase_trans", php3_ibase_trans, NULL},
          {"ibase_commit", php3_ibase_commit, NULL},
! {"ibase_rollback", php3_ibase_rollback, NULL},
!
! {"ibase_blob_info", php3_ibase_blob_info, NULL},
! {"ibase_blob_create", php3_ibase_blob_create, NULL},
! {"ibase_blob_add", php3_ibase_blob_add, NULL},
! {"ibase_blob_cancel", php3_ibase_blob_cancel, NULL},
          {"ibase_blob_close", php3_ibase_blob_close, NULL},
          {"ibase_blob_open", php3_ibase_blob_open, NULL},
! {"ibase_blob_get", php3_ibase_blob_get, NULL},
! {"ibase_blob_echo", php3_ibase_blob_echo, NULL},
! {"ibase_blob_import", php3_ibase_blob_import, NULL},
!
! {"ibase_errmsg", php3_ibase_errmsg, NULL},
! {NULL, NULL, NULL}
  };
  
  php3_module_entry ibase_module_entry =
***************
*** 86,103 ****
          php3_minit_ibase,
          NULL,
          php3_rinit_ibase,
! NULL,
! /*php3_info_ibase*/ NULL,
          STANDARD_MODULE_PROPERTIES
  };
  /* }}} */
  
- /* {{{ prototype for blob destructor */
- static void _php3_ibase_free_blob(ibase_blob_handle *ib_blob);
  /* }}} */
  
  
! /* {{{ thread safety stuff */
  #if defined(THREAD_SAFE)
  typedef ibase_global_struct{
          ibase_module php3_ibase_module;
--- 88,195 ----
          php3_minit_ibase,
          NULL,
          php3_rinit_ibase,
! php3_rfinish_ibase,
! php3_info_ibase,
          STANDARD_MODULE_PROPERTIES
  };
  /* }}} */
+
+
+ /* {{{ internal macros and structs */ /*FOLD00*/
+
+ /* db_handle and transaction handle keep in one variable
+ link = db_handle * IBASE_TRANS_ON_LINK + trans_handle
+ */
+
+ /* get link and transaction from long argument
+ */
+ #define GET_LINK_TRANS(link_id, ib_link, trans_n) { \
+ int type; \
+ trans_n = link_id % IBASE_TRANS_ON_LINK; \
+ link_id /= IBASE_TRANS_ON_LINK; \
+ ib_link = (ibase_db_link *) php3_list_find(link_id, &type); \
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) { \
+ _php3_module_error("%d is not link or transaction index",link_id); \
+ RETURN_FALSE; \
+ }}
+
+
+ /* get query */
+ #define GET_QUERY(query_id, ib_query) { \
+ int type; \
+ ib_query = (ibase_query *) php3_list_find(query_id, &type); \
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) { \
+ _php3_module_error("%d is not query index",query_id); \
+ RETURN_FALSE; \
+ }}
+
+ /* get result */
+ #define GET_RESULT(result_id, ib_result) { \
+ int type; \
+ ib_result = (ibase_result *) php3_list_find(result_id, &type); \
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_result) { \
+ _php3_module_error("%d is not result index",result_id); \
+ RETURN_FALSE; \
+ }}
+
+
+ #define RESET_ERRMSG { IBASE_GLOBAL(php3_ibase_module).errmsg[0] = '\0';}
+
+ #define TEST_ERRMSG ( IBASE_GLOBAL(php3_ibase_module).errmsg[0] != '\0')
+
+ /* sql variables union
+ used for convert and binding input variables
+ */
+ typedef struct{
+ union{
+ short sval;
+ float fval;
+ ISC_QUAD qval;
+ }val;
+ short sqlind;
+ }BIND_BUF;
+
+
+ /* get blob identifier from argument
+ */
+ #define GET_BLOB_ID_ARG(blob_arg, ib_blob) \
+ {\
+ if(blob_arg->type != IS_STRING\
+ || blob_arg->value.str.len != sizeof(ibase_blob_handle)\
+ || ((ibase_blob_handle *)(blob_arg->value.str.val))->bl_handle != 0){\
+ _php3_module_error("invalid blob id");\
+ RETURN_FALSE;\
+ }\
+ ib_blob = (ibase_blob_handle *)blob_arg->value.str.val;\
+ }
+
+
+ /* get blob handle from argument
+ note: blob already open when handle active
+ */
+ #define GET_BLOB_HANDLE_ARG(blob_arg, blob_ptr) \
+ { \
+ int type; \
+ convert_to_long(blob_arg); \
+ blob_ptr = (ibase_blob_handle *) php3_list_find(blob_arg->value.lval, &type); \
+ if (type!=IBASE_GLOBAL(php3_ibase_module).le_blob) { \
+ _php3_module_error("%d is not blob handle",blob_arg->value.lval); \
+ RETURN_FALSE; \
+ } \
+ }
+
+ /* blob information struct */
+ typedef struct {
+ ISC_LONG max_segment; /* Length of longest segment */
+ ISC_LONG num_segments; /* Total number of segments */
+ ISC_LONG total_length; /* Total length of blob */
+ int bl_stream; /* blob is stream ? */
+ }IBASE_BLOBINFO;
  
  /* }}} */
  
  
! /* {{{ thread safety stuff */ /*FOLD00*/
  #if defined(THREAD_SAFE)
  typedef ibase_global_struct{
          ibase_module php3_ibase_module;
***************
*** 115,214 ****
  ibase_module php3_ibase_module;
  #endif
  /* }}} */
-
  
!
! #define RESET_ERRMSG { IBASE_GLOBAL(php3_ibase_module).errmsg[0] = '\0';}
! #define TEST_ERRMSG ( IBASE_GLOBAL(php3_ibase_module).errmsg[0] != '\0')
  
! /* {{{ proto string ibase_errmsg()
! Return error message */
  void php3_ibase_errmsg(INTERNAL_FUNCTION_PARAMETERS)
  {
! char *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
! IBASE_TLS_VARS;
! if(errmsg[0]){
! RETURN_STRING(errmsg,1);
! }
! RETURN_FALSE;
  }
  /* }}} */
  
! /* {{{ _php3_ibase_error(ISC_STATUS *status)
! print interbase error and save it for ibase_errmsg() */
  static void _php3_ibase_error(ISC_STATUS *status)
  {
! char *s, *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
  
          s = errmsg;
          while((s - errmsg) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &status)){
! strcat(errmsg, " ");
                  s = errmsg + strlen(errmsg);
          }
          php3_error(E_WARNING, "InterBase: %s",errmsg);
  }
  /* }}} */
  
! /* {{{ _php3_module_error(char *msg, ...)
! print php interbase module error and save it for ibase_errmsg() */
  static void _php3_module_error(char *msg, ...)
  {
! char *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
! va_list ap;
! int len;
  
          va_start(ap, msg);
          len = vsnprintf(errmsg, MAX_ERRMSG - 1, msg, ap);
! va_end(ap);
! errmsg[len] = '\0';
!
          php3_error(E_WARNING, "InterBase module: %s",errmsg);
  }
  /* }}} */
  
! /* {{{ _php3_ibase_rollback_trans() */
! static void _php3_ibase_rollback_trans(ibase_trans *ib_trans)
  {
          ISC_STATUS status[20];
! IBASE_TLS_VARS;
!
! if(ib_trans->trans != NULL){
! if(isc_rollback_transaction(status, &ib_trans->trans)){
                          _php3_ibase_error(status);
                  }
          }
- efree(ib_trans);
  }
  /* }}} */
  
! /* {{{ _php3_ibase_close_link() */
  static void _php3_ibase_close_link(ibase_db_link *link)
  {
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
  
! if(link->default_trans != NULL){
! if(isc_rollback_transaction(status, &link->default_trans)){
! _php3_ibase_error(status);
! }
! }
          isc_detach_database(status, &link->link);
          IBASE_GLOBAL(php3_ibase_module).num_links--;
          efree(link);
  }
  /* }}} */
  
! /* {{{ _php3_ibase_close_plink() */
  static void _php3_ibase_close_plink(ibase_db_link *link)
  {
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
  
! if(link->default_trans != NULL){
! if(isc_rollback_transaction(status, &link->default_trans)){
! _php3_ibase_error(status);
! }
! }
          isc_detach_database(status, &link->link);
          php3_ibase_module.num_persistent--;
          php3_ibase_module.num_links--;
--- 207,329 ----
  ibase_module php3_ibase_module;
  #endif
  /* }}} */
  
! /* error handling ---------------------------- */
  
! /* {{{ proto string ibase_errmsg() */ /*FOLD00*/
! /* Return error message */
  void php3_ibase_errmsg(INTERNAL_FUNCTION_PARAMETERS)
  {
! char *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
! IBASE_TLS_VARS;
! if(errmsg[0]){
! RETURN_STRING(errmsg,1);
! }
! RETURN_FALSE;
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_error() */ /*FOLD00*/
! /* print interbase error and save it for ibase_errmsg() */
  static void _php3_ibase_error(ISC_STATUS *status)
  {
! char *s, *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
  
          s = errmsg;
          while((s - errmsg) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &status)){
! strcat(errmsg, " ");
                  s = errmsg + strlen(errmsg);
          }
          php3_error(E_WARNING, "InterBase: %s",errmsg);
  }
  /* }}} */
+
  
! /* {{{ _php3_module_error() */ /*FOLD00*/
! /* print php interbase module error and save it for ibase_errmsg() */
  static void _php3_module_error(char *msg, ...)
  {
! char *errmsg = IBASE_GLOBAL(php3_ibase_module).errmsg;
! va_list ap;
! int len;
  
          va_start(ap, msg);
          len = vsnprintf(errmsg, MAX_ERRMSG - 1, msg, ap);
! va_end(ap);
! errmsg[len] = '\0';
!
          php3_error(E_WARNING, "InterBase module: %s",errmsg);
  }
  /* }}} */
+
+
+ /* destructors ---------------------- */
+
+
+ /* {{{ _php3_ibase_free_xsqlda() */ /*FOLD00*/
+ /* not actual destructor ... */
+ static void _php3_ibase_free_xsqlda(XSQLDA *sqlda)
+ {
+ int i;
+ XSQLVAR *var;
+
+ if(sqlda){
+ var = sqlda->sqlvar;
+ for (i = 0; i < sqlda->sqld; i++, var++) {
+ efree(var->sqldata);
+ if(var->sqlind)
+ efree(var->sqlind);
+ }
+ efree(sqlda);
+ }
+ }
+ /* }}} */
+
  
! /* {{{ _php3_ibase_commit_link() */ /*FOLD00*/
! static void _php3_ibase_commit_link(ibase_db_link *link)
  {
          ISC_STATUS status[20];
! int i;
!
! if(link->trans[0] != NULL){ /* commit default */
! if(isc_commit_transaction(status, &link->trans[0])){
                          _php3_ibase_error(status);
                  }
+ }
+ for(i = 1; i < IBASE_TRANS_ON_LINK; i++){
+ if(link->trans[i] != NULL){
+ if(isc_rollback_transaction(status, &link->trans[i])){
+ _php3_ibase_error(status);
+ }
+ }
          }
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_close_link() */ /*FOLD00*/
  static void _php3_ibase_close_link(ibase_db_link *link)
  {
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
  
! _php3_ibase_commit_link(link);
          isc_detach_database(status, &link->link);
          IBASE_GLOBAL(php3_ibase_module).num_links--;
          efree(link);
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_close_plink() */ /*FOLD00*/
  static void _php3_ibase_close_plink(ibase_db_link *link)
  {
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
  
! _php3_ibase_commit_link(link);
          isc_detach_database(status, &link->link);
          php3_ibase_module.num_persistent--;
          php3_ibase_module.num_links--;
***************
*** 216,267 ****
  }
  /* }}} */
  
! /* {{{ _php3_ibase_free_result() */
! static void _php3_ibase_free_result(ibase_result_handle *result)
  {
- int i;
          ISC_STATUS status[20];
! IBASE_TLS_VARS;
!
! if (result->trans_single) { /*FIXME : commit or rollback?*/
! isc_commit_transaction(status, &result->trans_handle);
! }
! if (result->sqlda != NULL) {
! for (i = 0; i < result->sqlda->sqld; i++) {
! efree(result->sqlda->sqlvar[i].sqldata);
! efree(result->sqlda->sqlvar[i].sqlind);
                  }
! efree(result->sqlda);
          }
- isc_dsql_free_statement(status, &result->result, DSQL_drop);
- efree(result);
  }
  /* }}} */
  
! /* {{{ _php3_ibase_free_query() */
! static void _php3_ibase_free_query(ibase_query_handle *query)
  {
- int i;
          ISC_STATUS status[20];
  
! if (query->trans_single) { /*FIXME : commit or rollback?*/
! isc_commit_transaction(status, &query->trans_handle);
! }
! if (query->sqlda != NULL) {
! if (query->alloced) {
! for (i = 0; i < query->sqlda->sqld; i++) {
! efree(query->sqlda->sqlvar[i].sqldata);
! efree(query->sqlda->sqlvar[i].sqlind);
                          }
                  }
- efree(query->sqlda);
          }
! isc_dsql_free_statement(status, &query->query, DSQL_drop);
! efree(query);
  }
  /* }}} */
  
! /* {{{ startup, shutdown and info functions */
  int php3_minit_ibase(INIT_FUNC_ARGS)
  {
          IBASE_TLS_VARS;
--- 331,399 ----
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_free_result() */ /*FOLD00*/
! static void _php3_ibase_free_result(ibase_result *ib_result)
  {
          ISC_STATUS status[20];
!
! if (ib_result){
! _php3_ibase_free_xsqlda(ib_result->out_sqlda);
! if(ib_result->drop_stmt && ib_result->stmt){
! if(isc_dsql_free_statement(status, &ib_result->stmt, DSQL_drop)){
! _php3_ibase_error(status);
! }
! }else{
! if(isc_dsql_free_statement(status, &ib_result->stmt, DSQL_close)){
! _php3_ibase_error(status);
! }
                  }
! efree(ib_result);
          }
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_free_query() */ /*FOLD00*/
! static void _php3_ibase_free_query(ibase_query *ib_query)
  {
          ISC_STATUS status[20];
  
! if(ib_query){
! if (ib_query->in_sqlda) {
! efree(ib_query->in_sqlda);
! }
! if (ib_query->out_sqlda) {
! efree(ib_query->out_sqlda);
! }
! if(ib_query->stmt){
! if(isc_dsql_free_statement(status, &ib_query->stmt, DSQL_drop)){
! _php3_ibase_error(status);
                          }
+ }
+ efree(ib_query);
+ }
+ }
+ /* }}} */
+
+
+ /* {{{ _php3_ibase_free_blob() */ /*FOLD00*/
+ static void _php3_ibase_free_blob(ibase_blob_handle *ib_blob)
+ {
+ ISC_STATUS status[20];
+ IBASE_TLS_VARS;
+
+ if(ib_blob->bl_handle != NULL){ /* blob open*/
+ if(isc_cancel_blob(status, &ib_blob->bl_handle)){
+ _php3_ibase_error(status);
                  }
          }
! efree(ib_blob);
  }
  /* }}} */
  
!
! /* {{{ startup, shutdown and info functions */ /*FOLD00*/
  int php3_minit_ibase(INIT_FUNC_ARGS)
  {
          IBASE_TLS_VARS;
***************
*** 284,295 ****
                  IBASE_GLOBAL(php3_ibase_module).default_password = "";
          }
          if (cfg_get_string("ibase.timeformat", &IBASE_GLOBAL(php3_ibase_module).timeformat) == FAILURE) {
! IBASE_GLOBAL(php3_ibase_module).cfg_timeformat = "%Y-%m-%d %H:%M:%S";
          }
          IBASE_GLOBAL(php3_ibase_module).num_persistent=0;
          IBASE_GLOBAL(php3_ibase_module).le_result = register_list_destructors(_php3_ibase_free_result, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_query = register_list_destructors(_php3_ibase_free_query, NULL);
- IBASE_GLOBAL(php3_ibase_module).le_trans = register_list_destructors(_php3_ibase_rollback_trans, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_blob = register_list_destructors(_php3_ibase_free_blob, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_link = register_list_destructors(_php3_ibase_close_link, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_plink = register_list_destructors(NULL, _php3_ibase_close_plink);
--- 416,426 ----
                  IBASE_GLOBAL(php3_ibase_module).default_password = "";
          }
          if (cfg_get_string("ibase.timeformat", &IBASE_GLOBAL(php3_ibase_module).timeformat) == FAILURE) {
! IBASE_GLOBAL(php3_ibase_module).cfg_timeformat = "%m/%d/%Y %H:%M:%S";
          }
          IBASE_GLOBAL(php3_ibase_module).num_persistent=0;
          IBASE_GLOBAL(php3_ibase_module).le_result = register_list_destructors(_php3_ibase_free_result, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_query = register_list_destructors(_php3_ibase_free_query, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_blob = register_list_destructors(_php3_ibase_free_blob, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_link = register_list_destructors(_php3_ibase_close_link, NULL);
          IBASE_GLOBAL(php3_ibase_module).le_plink = register_list_destructors(NULL, _php3_ibase_close_plink);
***************
*** 322,335 ****
          efree(IBASE_GLOBAL(php3_ibase_module).errmsg);
          return SUCCESS;
  }
  
! void php3_info_ibase(void)
  {
! /* TODO */
  }
  /* }}} */
  
! /* {{{ _php_ibase_attach_db() */
  static int _php_ibase_attach_db(char *server, char *uname, char *passwd, char *charset, int buffers, char *role, isc_db_handle *db)
  {
          char dpb_buffer[256], *dpb, *p;
--- 453,468 ----
          efree(IBASE_GLOBAL(php3_ibase_module).errmsg);
          return SUCCESS;
  }
+
  
! void php3_info_ibase(void) /*FOLD00*/
  {
! php3_printf("");
  }
  /* }}} */
  
!
! /* {{{ _php_ibase_attach_db() */ /*FOLD00*/
  static int _php_ibase_attach_db(char *server, char *uname, char *passwd, char *charset, int buffers, char *role, isc_db_handle *db)
  {
          char dpb_buffer[256], *dpb, *p;
***************
*** 382,410 ****
  
          dpb_length = dpb - dpb_buffer;
  
! if(isc_attach_database(status, strlen(server), server, db, dpb_length, dpb_buffer)){
                          _php3_ibase_error(status);
                          return 1;
          }
          return 0;
  }
  /* }}} */
  
! /* {{{ _php3_ibase_connect() */
  static void _php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
  {
          pval *server, *uname, *passwd;
  
          char *ib_server, *ib_uname, *ib_passwd;
! int ib_server_len, ib_uname_len, ib_passwd_len;
          isc_db_handle db_handle = NULL;
          char *hashed_details;
          int hashed_details_length;
          ibase_db_link *ib_link;
! IBASE_TLS_VARS;
!
! RESET_ERRMSG;
!
          ib_uname = IBASE_GLOBAL(php3_ibase_module).default_user;
          ib_passwd = IBASE_GLOBAL(php3_ibase_module).default_password;
          ib_uname_len = ib_uname ? strlen(ib_uname) : 0;
--- 515,544 ----
  
          dpb_length = dpb - dpb_buffer;
  
! if(isc_attach_database(status, strlen(server), server, db, dpb_length, dpb_buffer)){
                          _php3_ibase_error(status);
                          return 1;
          }
          return 0;
  }
  /* }}} */
+
  
! /* {{{ _php3_ibase_connect() */ /*FOLD00*/
  static void _php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
  {
          pval *server, *uname, *passwd;
  
          char *ib_server, *ib_uname, *ib_passwd;
! int i, ib_server_len, ib_uname_len, ib_passwd_len;
          isc_db_handle db_handle = NULL;
          char *hashed_details;
          int hashed_details_length;
          ibase_db_link *ib_link;
! IBASE_TLS_VARS;
!
! RESET_ERRMSG;
!
          ib_uname = IBASE_GLOBAL(php3_ibase_module).default_user;
          ib_passwd = IBASE_GLOBAL(php3_ibase_module).default_password;
          ib_uname_len = ib_uname ? strlen(ib_uname) : 0;
***************
*** 490,496 ****
  
                          ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
                          ib_link->link = db_handle;
! ib_link->default_trans = NULL;
                          /* hash it up */
                          new_le.type = php3_ibase_module.le_plink;
                          new_le.ptr = ib_link;
--- 624,632 ----
  
                          ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
                          ib_link->link = db_handle;
! for(i = 0; i < IBASE_TRANS_ON_LINK; i++)
! ib_link->trans[i] = NULL;
!
                          /* hash it up */
                          new_le.type = php3_ibase_module.le_plink;
                          new_le.ptr = ib_link;
***************
*** 507,520 ****
                          }
                          /* TODO: ensure that the ib_link did not die */
                          ib_link = (ibase_db_link *) le->ptr;
- ib_link->default_trans = NULL;
                  }
! return_value->value.lval = php3_list_insert(ib_link, IBASE_GLOBAL(php3_ibase_module).le_plink);
                  return_value->type = IS_LONG;
          } else {
                  list_entry *index_ptr, new_index_ptr;
                  
! /* first we check the hash for the hashed_details key. if it exists,
                   * it should point us to the right offset where the actual ib_link sits.
                   * if it doesn't, open a new ib_link, add it to the resource list,
                   * and add a pointer to it with hashed_details as the key.
--- 643,656 ----
                          }
                          /* TODO: ensure that the ib_link did not die */
                          ib_link = (ibase_db_link *) le->ptr;
                  }
! return_value->value.lval = IBASE_TRANS_ON_LINK *
! php3_list_insert(ib_link, IBASE_GLOBAL(php3_ibase_module).le_plink);
                  return_value->type = IS_LONG;
          } else {
                  list_entry *index_ptr, new_index_ptr;
                  
! /* first we check the hash for the hashed_details key. if it exists,
                   * it should point us to the right offset where the actual ib_link sits.
                   * if it doesn't, open a new ib_link, add it to the resource list,
                   * and add a pointer to it with hashed_details as the key.
***************
*** 527,533 ****
                                  RETURN_FALSE;
                          }
                          xlink = (int) index_ptr->ptr;
! ptr = php3_list_find(xlink,&type); /* check if the xlink is still there */
                          if (ptr && (type==IBASE_GLOBAL(php3_ibase_module).le_link || type==IBASE_GLOBAL(php3_ibase_module).le_plink)) {
                                  return_value->value.lval = IBASE_GLOBAL(php3_ibase_module).default_link = xlink;
                                  return_value->type = IS_LONG;
--- 663,669 ----
                                  RETURN_FALSE;
                          }
                          xlink = (int) index_ptr->ptr;
! ptr = php3_list_find(xlink,&type); /* check if the xlink is still there */
                          if (ptr && (type==IBASE_GLOBAL(php3_ibase_module).le_link || type==IBASE_GLOBAL(php3_ibase_module).le_plink)) {
                                  return_value->value.lval = IBASE_GLOBAL(php3_ibase_module).default_link = xlink;
                                  return_value->type = IS_LONG;
***************
*** 551,560 ****
  
                  ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
                  ib_link->link = db_handle;
! ib_link->default_trans = NULL;
  
                  /* add it to the list */
! return_value->value.lval = php3_list_insert(ib_link, IBASE_GLOBAL(php3_ibase_module).le_link);
                  return_value->type = IS_LONG;
  
                  /* add it to the hash */
--- 687,698 ----
  
                  ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
                  ib_link->link = db_handle;
! for(i = 0; i < IBASE_TRANS_ON_LINK; i++)
! ib_link->trans[i] = NULL;
  
                  /* add it to the list */
! return_value->value.lval = IBASE_TRANS_ON_LINK *
! php3_list_insert(ib_link, IBASE_GLOBAL(php3_ibase_module).le_link);
                  return_value->type = IS_LONG;
  
                  /* add it to the hash */
***************
*** 571,603 ****
  }
  /* }}} */
  
! /* {{{ proto int ibase_connect(string database [, string username] [, string password])
! Open a connection to an InterBase database */
  void php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS)
  {
          _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  }
  /* }}} */
  
! /* {{{ proto int ibase_pconnect(string database [, string username] [, string password])
! Open a persistent connection to an InterBase database */
  void php3_ibase_pconnect(INTERNAL_FUNCTION_PARAMETERS)
  {
          _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  }
  /* }}} */
  
! /* {{{ proto int ibase_close([int link_identifier])
! Close an InterBase connection */
  void php3_ibase_close(INTERNAL_FUNCTION_PARAMETERS)
  {
          pval *link_arg;
          ibase_db_link *ib_link;
! int link_id, type;
          IBASE_TLS_VARS;
          
- RESET_ERRMSG;
-
          switch (ARG_COUNT(ht)) {
                  case 0:
                          link_id = IBASE_GLOBAL(php3_ibase_module).default_link;
--- 709,744 ----
  }
  /* }}} */
  
!
! /* {{{ proto int ibase_connect(string database [, string username] [, string password]) */ /*FOLD00*/
! /* Open a connection to an InterBase database */
  void php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS)
  {
          _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  }
  /* }}} */
+
  
! /* {{{ proto int ibase_pconnect(string database [, string username] [, string password]) */ /*FOLD00*/
! /* Open a persistent connection to an InterBase database */
  void php3_ibase_pconnect(INTERNAL_FUNCTION_PARAMETERS)
  {
          _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  }
  /* }}} */
  
!
! /* {{{ proto int ibase_close([int link_identifier]) */ /*FOLD00*/
! /* Close an InterBase connection */
  void php3_ibase_close(INTERNAL_FUNCTION_PARAMETERS)
  {
          pval *link_arg;
          ibase_db_link *ib_link;
! int link_id, trans_n;
          IBASE_TLS_VARS;
+
+ RESET_ERRMSG;
          
          switch (ARG_COUNT(ht)) {
                  case 0:
                          link_id = IBASE_GLOBAL(php3_ibase_module).default_link;
***************
*** 614,823 ****
                          break;
          }
          
! ib_link = (ibase_db_link *) php3_list_find(link_id, &type);
! if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
! _php3_module_error("%d is not link index",link_id);
! RETURN_FALSE;
! }
          
          php3_list_delete(link_id);
          RETURN_TRUE;
  }
  /* }}} */
  
! /* {{{ _php3_ibase_prepare() */
! static XSQLDA *_php3_ibase_prepare(isc_db_handle db, isc_tr_handle tr, isc_stmt_handle *query_handle, char *query)
  {
! ISC_STATUS status[20];
! XSQLDA *isqlda;
  
! isqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
! isqlda->sqln = 0;
! isqlda->version = SQLDA_VERSION1;
  
! if (isc_dsql_allocate_statement(status, &db, query_handle)) {
! efree(isqlda);
                  _php3_ibase_error(status);
! return NULL;
          }
  
! if (isc_dsql_prepare(status, &tr, query_handle, 0, query, 1, isqlda)) {
! efree(isqlda);
                  _php3_ibase_error(status);
! return NULL;
          }
-
- /*
- * Check if query has placeholders and needs binding. If it has, allocate
- * input sqlda big enough and return it.
- */
  
!
! if (isc_dsql_describe_bind(status, query_handle, 1, isqlda)) {
! efree(isqlda);
                  _php3_ibase_error(status);
! return NULL;
          }
!
! if (isqlda->sqld > 1) {
! isqlda = (XSQLDA *) erealloc(isqlda, XSQLDA_LENGTH(isqlda->sqld));
! isqlda->sqln = isqlda->sqld;
! isqlda->version = SQLDA_VERSION1;
! if (isc_dsql_describe(status, query_handle, 1, isqlda)) {
! efree(isqlda);
                          _php3_ibase_error(status);
! return NULL;
                  }
- return isqlda;
- } else if (isqlda->sqld == 1) {
- return isqlda;
- } else {
- efree(isqlda);
- return NULL;
          }
  }
  /* }}} */
  
! /* {{{ _php3_ibase_execute() */
! static XSQLDA *_php3_ibase_execute(isc_tr_handle tr_handle, isc_stmt_handle query_handle, XSQLDA *isqlda, ISC_STATUS *status)
  {
! int i, coltype;
! static char query_info[] = { isc_info_sql_stmt_type };
! char info_buffer[18];
! short l;
! long query_type;
! XSQLDA *osqlda;
  
! /*
! * Find out what kind of query is to be executed.
! */
          
! if (!isc_dsql_sql_info(status, &query_handle, sizeof(query_info), query_info, sizeof(info_buffer), info_buffer)) {
! l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2);
! query_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l);
! }
  
- if (query_type == isc_info_sql_stmt_select || query_type == isc_info_sql_stmt_select_for_upd) {
- /*
- * Select, need to allocate output sqlda and and prepare it for use.
- */
  
! osqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
! osqlda->sqln = 0;
! osqlda->version = SQLDA_VERSION1;
  
! if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
! efree(osqlda);
! _php3_ibase_error(status);
! return NULL;
! }
  
! if (osqlda->sqld) {
! osqlda = (XSQLDA *) erealloc(osqlda, XSQLDA_LENGTH(osqlda->sqld));
! osqlda->sqln = osqlda->sqld;
! osqlda->version = SQLDA_VERSION1;
! if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
! efree(osqlda);
! _php3_ibase_error(status);
! return NULL;
! }
                  }
! for (i = 0; i < osqlda->sqld; i++) {
! osqlda->sqlvar[i].sqlind = (short *) emalloc(sizeof(short));
! coltype = osqlda->sqlvar[i].sqltype & ~1;
! switch(coltype)
! {
! case SQL_TEXT:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen));
! break;
! case SQL_VARYING:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen+2));
! break;
! case SQL_SHORT:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(short));
! break;
! case SQL_LONG:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(long));
! break;
! case SQL_FLOAT:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(float));
! break;
! case SQL_DOUBLE:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(double));
! break;
! case SQL_DATE:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
! break;
! case SQL_BLOB:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
! break;
! case SQL_ARRAY:
! osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
! break;
! }
                  }
! if (isqlda == NULL) {
! if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, NULL)) {
! efree(osqlda);
! _php3_ibase_error(status);
! return NULL;
! } else {
! return osqlda;
! }
          
! } else {
! if (isc_dsql_execute2(status, &tr_handle, &query_handle, 1, isqlda, osqlda)) {
! efree(osqlda);
! _php3_ibase_error(status);
! return NULL;
! } else {
! return osqlda;
! }
          
! }
! } else {
! /* Not select */
! if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, isqlda)) {
! _php3_ibase_error(status);
! return NULL;
                  }
          }
!
! return NULL;
  }
  /* }}} */
  
-
- #define GET_TRANS_ARG(trans_arg,trans_ptr) { \
- int type; \
- convert_to_long(trans_arg); \
- trans_ptr = (ibase_trans *) php3_list_find(trans_arg->value.lval, &type);\
- if (type!=IBASE_GLOBAL(php3_ibase_module).le_trans) {\
- _php3_module_error("%d is not transaction index",trans_arg->value.lval);\
- RETURN_FALSE;\
- } \
- }
-
- #define TRANS_HANDLE(ib_trans,ib_link) \
- (ib_trans ? ib_trans->trans : (ib_link->default_trans ? ib_link->default_trans : 0))
  
!
! /* {{{ proto int ibase_trans([int link_identifier, ][string trans_args])
! Start transaction */
  void php3_ibase_trans(INTERNAL_FUNCTION_PARAMETERS)
  {
          pval *link_arg, *trans_arg;
          char tpb[20], *tpbp = NULL, *trans_args = NULL;
! int tpb_len = 0, link_id, trans_id, type, trans_def = 0;
          ibase_db_link *ib_link;
- ibase_trans *ib_trans;
- isc_tr_handle tr_handle = NULL;
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
          
  
! RESET_ERRMSG;
!
          switch (ARG_COUNT(ht)) {
                  case 0:
                          link_id = IBASE_GLOBAL(php3_ibase_module).default_link;
--- 755,1072 ----
                          break;
          }
          
! GET_LINK_TRANS(link_id, ib_link, trans_n);
          
          php3_list_delete(link_id);
          RETURN_TRUE;
  }
  /* }}} */
  
!
! /* {{{ _php3_ibase_alloc_query() */ /*FOLD00*/
! /* allocate and prepare query */
! static int _php3_ibase_alloc_query(ibase_query **ib_queryp, isc_db_handle link, isc_tr_handle trans, char *query)
  {
! #define IB_QUERY (*ib_queryp)
  
! ISC_STATUS status[20];
  
! IB_QUERY = emalloc(sizeof(ibase_query));
! IB_QUERY->link = link;
! IB_QUERY->trans = trans;
! IB_QUERY->stmt = NULL;
!
! if (isc_dsql_allocate_statement(status, &link, &IB_QUERY->stmt)) {
                  _php3_ibase_error(status);
! efree(IB_QUERY);
! IB_QUERY=NULL;
! return FAILURE;
          }
  
! IB_QUERY->out_sqlda = emalloc(XSQLDA_LENGTH(0));
! IB_QUERY->out_sqlda->sqln = 0;
! IB_QUERY->out_sqlda->version = SQLDA_VERSION1;
!
! if (isc_dsql_prepare(status, &IB_QUERY->trans, &IB_QUERY->stmt, 0, query, SQLDA_VERSION1, IB_QUERY->out_sqlda)) {
                  _php3_ibase_error(status);
! efree(IB_QUERY->out_sqlda);
! efree(IB_QUERY);
! IB_QUERY = NULL;
! return FAILURE;
! }
! /* not enough output variables ? */
! if(IB_QUERY->out_sqlda->sqld > IB_QUERY->out_sqlda->sqln){
! IB_QUERY->out_sqlda = erealloc(IB_QUERY->out_sqlda,XSQLDA_LENGTH(IB_QUERY->out_sqlda->sqld));
! IB_QUERY->out_sqlda->sqln = IB_QUERY->out_sqlda->sqld;
! IB_QUERY->out_sqlda->version = SQLDA_VERSION1;
! if (isc_dsql_describe(status, &IB_QUERY->stmt, SQLDA_VERSION1, IB_QUERY->out_sqlda)) {
! _php3_ibase_error(status);
! efree(IB_QUERY->out_sqlda);
! efree(IB_QUERY);
! IB_QUERY = NULL;
! return FAILURE;
! }
          }
  
! /* maybe have input placeholders? */
! IB_QUERY->in_sqlda = emalloc(XSQLDA_LENGTH(0));
! IB_QUERY->in_sqlda->sqln = 0;
! IB_QUERY->in_sqlda->version = SQLDA_VERSION1;
! if (isc_dsql_describe_bind(status, &IB_QUERY->stmt, SQLDA_VERSION1, IB_QUERY->in_sqlda)) {
! efree(IB_QUERY->out_sqlda);
! efree(IB_QUERY->in_sqlda);
! efree(IB_QUERY);
! IB_QUERY = NULL;
                  _php3_ibase_error(status);
! return FAILURE;
          }
! /* not enough input variables ? */
! if(IB_QUERY->in_sqlda->sqln < IB_QUERY->in_sqlda->sqld){
! IB_QUERY->in_sqlda = erealloc(IB_QUERY->in_sqlda,XSQLDA_LENGTH(IB_QUERY->in_sqlda->sqld));
! IB_QUERY->in_sqlda->sqln = IB_QUERY->in_sqlda->sqld;
! IB_QUERY->in_sqlda->version = SQLDA_VERSION1;
! if (isc_dsql_describe_bind(status, &IB_QUERY->stmt, SQLDA_VERSION1, IB_QUERY->in_sqlda)) {
! efree(IB_QUERY->out_sqlda);
! efree(IB_QUERY->in_sqlda);
! efree(IB_QUERY);
! IB_QUERY = NULL;
                          _php3_ibase_error(status);
! return FAILURE;
                  }
          }
+
+ /* no, haven't placeholders at all */
+ if(IB_QUERY->in_sqlda->sqld == 0){
+ efree(IB_QUERY->in_sqlda);
+ IB_QUERY->in_sqlda = NULL;
+ }
+
+ if(IB_QUERY->out_sqlda->sqld == 0){
+ efree(IB_QUERY->out_sqlda);
+ IB_QUERY->out_sqlda = NULL;
+ }
+
+ return SUCCESS;
+ #undef IB_QUERY
  }
  /* }}} */
+
  
! /* {{{ _php3_ibase_bind() */ /*FOLD00*/
! /* bind php variables to XSQLDA */
! static int _php3_ibase_bind(XSQLDA *sqlda, pval **b_vars, BIND_BUF *buf)
  {
! XSQLVAR *var;
! pval *b_var;
! int i;
!
! var = sqlda->sqlvar;
! for(i = 0; i < sqlda->sqld; var++, i++) { /* binded vars */
! buf[i].sqlind = 0;
! var->sqlind = &buf[i].sqlind;
! b_var = b_vars[i];
! switch(var->sqltype & ~1) {
! case SQL_TEXT: /* direct to variable */
! case SQL_VARYING:
! convert_to_string(b_var);
! var->sqldata = (void ISC_FAR *)b_var->value.str.val;
! var->sqllen = b_var->value.str.len;
! var->sqltype = SQL_TEXT + (var->sqltype & 1);
! break;
! case SQL_SHORT:
! convert_to_long(b_var);
! if(b_var->value.lval > SHRT_MAX || b_var->value.lval < SHRT_MIN){
! _php3_module_error("field %*s overflow", var->aliasname_length, var->aliasname);
! return FAILURE;
! }
! buf[i].val.sval = (short)b_var->value.lval;
! var->sqldata = (void ISC_FAR *)(&buf[i].val.sval);
! break;
! case SQL_LONG: /* direct to variable */
! convert_to_long(b_var);
! var->sqldata = (void ISC_FAR *)(&b_var->value.lval);
! break;
! case SQL_FLOAT:
! convert_to_double(b_var);
! buf[i].val.fval = (float)b_var->value.dval;
! var->sqldata = (void ISC_FAR *)(&buf[i].val.fval);
! break;
! case SQL_DOUBLE: /* direct to variable */
! convert_to_double(b_var);
! var->sqldata = (void ISC_FAR *)(&b_var->value.dval);
! break;
! case SQL_DATE:
! {
! struct tm t;
!
! t.tm_year = t.tm_mon = t.tm_mday = t.tm_hour =
! t.tm_min = t.tm_sec = 0;
!
! convert_to_string(b_var);
! #if HAVE_STRFTIME /*FIXME: HAVE_STRPTIME ?*/
! strptime(b_var->value.str.val, IBASE_GLOBAL(php3_ibase_module).timeformat, &t);
! #else
! {
! int n = sscanf(b_var->value.str.val,"%d%*[/]%d%*[/]%d %d%*[:]%d%*[:]%d",
! &t.tm_mon, &t.tm_mday, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec);
! if(n != 3 && n != 6){
! _php3_module_error("invalid date/time format");
! return FAILURE;
! }
!
! t.tm_year -= 1900;
! t.tm_mon--;
! }
! #endif
! isc_encode_date(&t, &buf[i].val.qval);
! var->sqldata = (void ISC_FAR *)(&buf[i].val.qval);
! }
! break;
! case SQL_BLOB:
! {
! ibase_blob_handle *ib_blob_id;
! if(b_var->type != IS_STRING
! || b_var->value.str.len != sizeof(ibase_blob_handle)
! || ((ibase_blob_handle *)(b_var->value.str.val))->bl_handle != 0){
! _php3_module_error("invalid blob id string");
! return FAILURE;
! }
! ib_blob_id = (ibase_blob_handle *)b_var->value.str.val;
!
! var->sqldata = (void ISC_FAR *)&ib_blob_id->bl_qd;
! }
! break;
! case SQL_ARRAY:
! _php3_module_error("binding arrays not supported yet");
! return FAILURE;
! break;
! }/*switch*/
! }/*for*/
! return SUCCESS;
! }
! /* }}} */
  
!
! /* {{{ _php3_ibase_alloc_xsqlda() */ /*FOLD00*/
! static void _php3_ibase_alloc_xsqlda(XSQLDA *sqlda)
! {
! int i;
! XSQLVAR *var = sqlda->sqlvar;
          
! for (i = 0; i < sqlda->sqld; i++, var++) {
! switch(var->sqltype & ~1){
! case SQL_TEXT:
! var->sqldata = emalloc(sizeof(char)*(var->sqllen));
! break;
! case SQL_VARYING:
! var->sqldata = emalloc(sizeof(char)*(var->sqllen+sizeof(short)));
! break;
! case SQL_SHORT:
! var->sqldata = emalloc(sizeof(short));
! break;
! case SQL_LONG:
! var->sqldata = emalloc(sizeof(long));
! break;
! case SQL_FLOAT:
! var->sqldata = emalloc(sizeof(float));
! break;
! case SQL_DOUBLE:
! var->sqldata = emalloc(sizeof(double));
! break;
! case SQL_DATE:
! case SQL_BLOB:
! case SQL_ARRAY:
! var->sqldata = emalloc(sizeof(ISC_QUAD));
! break;
! }/*switch*/
! if(var->sqltype & 1) /* sql NULL flag */
! var->sqlind = emalloc(sizeof(short));
! else
! var->sqlind = NULL;
! }/* for*/
! }
! /* }}} */
  
  
! /* {{{ _php3_ibase_exec() */ /*FOLD00*/
! static int _php3_ibase_exec(ibase_result **ib_resultp, ibase_query *ib_query, int argc, pval **args)
! {
! #define IB_RESULT (*ib_resultp)
! XSQLDA *in_sqlda = NULL, *out_sqlda = NULL;
! BIND_BUF *bind_buf = NULL;
! int rv = FAILURE;
! ISC_STATUS status[20];
  
! IB_RESULT = NULL;
!
! /* allocate sqlda and output buffers */
! if(ib_query->out_sqlda){ /* output variables in select, select for update */
! IB_RESULT = emalloc(sizeof(ibase_result));
! IB_RESULT->link = ib_query->link;
! IB_RESULT->trans = ib_query->trans;
! IB_RESULT->stmt = ib_query->stmt;
! IB_RESULT->drop_stmt = 0; /* when free result close but not drop!*/
! out_sqlda = IB_RESULT->out_sqlda = emalloc(XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
! memcpy(out_sqlda,ib_query->out_sqlda,XSQLDA_LENGTH(ib_query->out_sqlda->sqld));
! _php3_ibase_alloc_xsqlda(out_sqlda);
! }
  
! if(ib_query->in_sqlda){ /* has placeholders */
! if (ib_query->in_sqlda->sqld != argc){
! _php3_module_error("placeholders (%d) and variables (%d) mismatch",ib_query->in_sqlda->sqld, argc);
! goto _php3_ibase_exec_error; /* yes mommy, goto! */
                  }
! in_sqlda = emalloc(XSQLDA_LENGTH(ib_query->in_sqlda->sqld));
! memcpy(in_sqlda,ib_query->in_sqlda,XSQLDA_LENGTH(ib_query->in_sqlda->sqld));
! bind_buf = emalloc(sizeof(BIND_BUF) * ib_query->in_sqlda->sqld);
! if(_php3_ibase_bind(in_sqlda, args, bind_buf) == FAILURE){
! goto _php3_ibase_exec_error;
                  }
! }
!
! if (isc_dsql_execute(status, &ib_query->trans, &ib_query->stmt, 1, in_sqlda)) {
! _php3_ibase_error(status);
! goto _php3_ibase_exec_error;
! }
!
! rv = SUCCESS;
          
! _php3_ibase_exec_error: /* I'm a bad boy... */
          
! if(in_sqlda)
! efree(in_sqlda);
! if(bind_buf)
! efree(bind_buf);
!
! if(rv == FAILURE){
! if(IB_RESULT){
! efree(IB_RESULT);
! IB_RESULT = NULL;
                  }
+ if(out_sqlda)
+ efree(out_sqlda);
          }
!
! return rv;
! #undef IB_RESULT
  }
  /* }}} */
  
  
! /* {{{ proto int ibase_trans([int link_identifier, ][string trans_args]) */ /*FOLD00*/
! /* Start transaction */
  void php3_ibase_trans(INTERNAL_FUNCTION_PARAMETERS)
  {
          pval *link_arg, *trans_arg;
          char tpb[20], *tpbp = NULL, *trans_args = NULL;
! int tpb_len = 0, link_id, trans_n;
          ibase_db_link *ib_link;
          ISC_STATUS status[20];
          IBASE_TLS_VARS;
          
  
! RESET_ERRMSG;
!
          switch (ARG_COUNT(ht)) {
                  case 0:
                          link_id = IBASE_GLOBAL(php3_ibase_module).default_link;
***************
*** 843,863 ****
                          WRONG_PARAM_COUNT;
                          break;
          }
! ib_link = (ibase_db_link *) php3_list_find(link_id, &type);
! if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
! _php3_module_error("%d is not link index",link_id);
! RETURN_FALSE;
! }
          if(trans_args){
                  tpb[tpb_len++] = isc_tpb_version3;
! tpbp = tpb;
! if(strstr(trans_args,"DEFAULT")||strstr(trans_args,"default")){
! trans_def = 1;
! if(ib_link->default_trans != NULL){
! _php3_module_error("default transaction already started");
! RETURN_FALSE;
! }
! }
                  /* access mode */
                  if(strstr(trans_args,"READ")||strstr(trans_args,"read")) /* READ ONLY TRANSACTION */
                          tpb[tpb_len++] = isc_tpb_read;
--- 1092,1103 ----
                          WRONG_PARAM_COUNT;
                          break;
          }
!
! GET_LINK_TRANS(link_id, ib_link, trans_n);
!
          if(trans_args){
                  tpb[tpb_len++] = isc_tpb_version3;
! tpbp = tpb;
                  /* access mode */
                  if(strstr(trans_args,"READ")||strstr(trans_args,"read")) /* READ ONLY TRANSACTION */
                          tpb[tpb_len++] = isc_tpb_read;
***************
*** 878,1182 ****
  
          }
  
! if (isc_start_transaction(status, &tr_handle, 1, &ib_link->link, tpb_len, tpbp)) {
                  _php3_ibase_error(status);
                  RETURN_FALSE;
          }
  
! if(trans_def){
! ib_link->default_trans = tr_handle;
! RETURN_TRUE;
! }else{
! ib_trans = (ibase_trans *) emalloc(sizeof(ibase_trans));
! ib_trans->trans = tr_handle;
! trans_id = php3_list_insert(ib_trans, IBASE_GLOBAL(php3_ibase_module).le_trans);
! RETURN_LONG(trans_id);
! }
  }
  /* }}} */
  
! /* {{{ _php3_ibase_trans_end() */
! #define COMMIT 1
! #define ROLLBACK 0
! static void _php3_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit)
  {
- pval *trans_arg;
- int trans_id, type;
- ibase_db_link *ib_link;
- ibase_trans *ib_trans = NULL;
- isc_tr_handle tr_handle;
          ISC_STATUS status[20];
! IBASE_TLS_VARS;
!
!
! RESET_ERRMSG;
!
          switch (ARG_COUNT(ht)) {
                  case 0:
! trans_id = IBASE_GLOBAL(php3_ibase_module).default_link;
                          break;
! case 1:
! if (getParameters(ht, 1, &trans_arg) == FAILURE) {
                                  RETURN_FALSE;
                          }
! convert_to_long(trans_arg);
! trans_id = trans_arg->value.lval;
                          break;
                  default:
                          WRONG_PARAM_COUNT;
                          break;
- }
- ib_trans = (ibase_trans *) php3_list_find(trans_id, &type);
- ib_link = (ibase_db_link *)ib_trans;
- if (type==IBASE_GLOBAL(php3_ibase_module).le_link || type==IBASE_GLOBAL(php3_ibase_module).le_plink) {
- ib_link = (ibase_db_link *)ib_trans; /* default transaction */
- ib_trans = NULL;
- tr_handle = ib_link->default_trans;
- }else if (type==IBASE_GLOBAL(php3_ibase_module).le_trans){
- ib_link = NULL; /* manual transaction */
- tr_handle = ib_trans->trans;
- }else{
- _php3_module_error("%d is not link or transaction index",trans_id);
- RETURN_FALSE;
          }
  
          if (commit) {
! if(isc_commit_transaction(status, &tr_handle)){
! _php3_ibase_error(status);
! RETURN_FALSE;
                  }
          }else{
! if(isc_rollback_transaction(status, &tr_handle)){
! _php3_ibase_error(status);
! RETURN_FALSE;
                  }
          }
!
! if(ib_link){ /* default transaction */
! ib_link->default_trans = NULL;
! }else{ /* manual transaction */
! ib_trans->trans = NULL; /* already commited or rolled...*/
! php3_list_delete(trans_id);
! }
          
          RETURN_TRUE;
  }
  /* }}} */
  
! /* {{{ proto int ibase_commit([int link_identifier, ] int trans_number)
! Commit transaction */
  void php3_ibase_commit(INTERNAL_FUNCTION_PARAMETERS)
  {
! _php3_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
  }
  /* }}} */
  
! /* {{{ proto int ibase_rollback([int link_identifier, ] int trans_number)
! Roolback transaction */
  void php3_ibase_rollback(INTERNAL_FUNCTION_PARAMETERS)
  {
          _php3_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
  }
  /* }}} */
  
! /* {{{ proto int ibase_query([int link_identifier, ]string query[, trans])
! Execute a query (without parameter placeholders). */
  void php3_ibase_query(INTERNAL_FUNCTION_PARAMETERS)
  {
! pval *link_arg, *query_arg, *trans_arg;
! int link_id, type, trans_single = 0;
          ibase_db_link *ib_link;
! ibase_trans *ib_trans = NULL;
! isc_tr_handle trans_handle = NULL;
! isc_stmt_handle query_handle = NULL;
! ISC_STATUS status[20];
! XSQLDA *isqlda, *osqlda;
! ibase_result_handle *ibase_result;
! IBASE_TLS_VARS;
  
! RESET_ERRMSG;
  
! switch (ARG_COUNT(ht)) {
! case 1:
! if (getParameters(ht, 1, &query_arg) == FAILURE) {
! RETURN_FALSE;
! }
! link_id = IBASE_GLOBAL(php3_ibase_module).default_link;
! break;
! case 2:
! if (getParameters(ht, 2, &link_arg, &query_arg) == FAILURE) {
! RETURN_FALSE;
! }
! convert_to_long(link_arg);
! link_id = link_arg->value.lval;
! break;
! case 3:
! if (getParameters(ht, 3, &link_arg, &query_arg, &trans_arg) == FAILURE) {
! RETURN_FALSE;
! }
! convert_to_long(link_arg);
! link_id = link_arg->value.lval;
! GET_TRANS_ARG(trans_arg,ib_trans);
! break;
! default:
! WRONG_PARAM_COUNT;
! break;
          }
          
! ib_link = (ibase_db_link *) php3_list_find(link_id, &type);
! if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
! _php3_module_error("%d is not link index",link_id);
! RETURN_FALSE;
! }
!
! trans_handle = TRANS_HANDLE(ib_trans,ib_link);
!
! trans_single = (trans_handle == NULL);
! if(trans_single){
! if (isc_start_transaction(status, &trans_handle, 1, &ib_link->link, 0, NULL)) {
! _php3_ibase_error(status);
! RETURN_FALSE;
! }
! }
!
! convert_to_string(query_arg);
  
! isqlda = _php3_ibase_prepare(ib_link->link, trans_handle, &query_handle, query_arg->value.str.val);
! if(TEST_ERRMSG){
! RETURN_FALSE;
! }
! if (isqlda != NULL) {
! if(trans_single)
! isc_rollback_transaction(status, &trans_handle);
! isc_dsql_free_statement(status, &query_handle, DSQL_drop);
! _php3_module_error("ibase_query doesn't support parameter placeholders in query");
                  RETURN_FALSE;
          }
  
! osqlda = _php3_ibase_execute(trans_handle, query_handle, isqlda, status);
! if (osqlda != NULL) {
! ibase_result = (ibase_result_handle *) emalloc(sizeof(ibase_result_handle));
! ibase_result->result = query_handle;
! ibase_result->sqlda = osqlda;
! ibase_result->trans_handle = trans_handle;
! ibase_result->trans_single = trans_single;
! ibase_result->link = ib_link->link;
! RETURN_LONG(php3_list_insert(ibase_result, php3_ibase_module.le_result));
! } else {
! if (trans_single) {
! if (status[0] && status[1]) {
! isc_rollback_transaction(status, &trans_handle);
! isc_dsql_free_statement(status, &query_handle, DSQL_drop);
! RETURN_FALSE;
! } else {
! isc_commit_transaction(status, &trans_handle);
! isc_dsql_free_statement(status, &query_handle, DSQL_drop);
! RETURN_TRUE;
! }
! }
          }
  }
  /* }}} */
  
  
! /* {{{ _php3_ibase_fetch_hash() */
  static void _php3_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS)
  {
          pval *result_arg, *blflag_arg;
! int type, blobchar = 0, i, collen;
          char string_data[255], *char_data;
! ibase_result_handle *ibase_result;
          ISC_STATUS status[20];
          XSQLVAR *var;
          IBASE_VCHAR *vchar;
&n