root/ext/interbase/interbase.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_GET_MODULE
  2. PHP_FUNCTION
  3. _php_ibase_error
  4. _php_ibase_module_error
  5. _php_ibase_get_link_trans
  6. _php_ibase_commit_link
  7. php_ibase_commit_link_rsrc
  8. _php_ibase_close_link
  9. _php_ibase_close_plink
  10. _php_ibase_free_trans
  11. PHP_INI_DISP
  12. PHP_INI_BEGIN
  13. PHP_MINIT_FUNCTION
  14. PHP_MSHUTDOWN_FUNCTION
  15. PHP_RSHUTDOWN_FUNCTION
  16. PHP_MINFO_FUNCTION
  17. _php_ibase_attach_db
  18. _php_ibase_connect
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. _php_ibase_def_trans
  25. _php_ibase_trans_end
  26. PHP_FUNCTION
  27. PHP_FUNCTION
  28. PHP_FUNCTION
  29. PHP_FUNCTION
  30. PHP_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Authors: Jouni Ahto <jouni.ahto@exdec.fi>                            |
  16    |          Andrew Avdeev <andy@rsc.mv.ru>                              |
  17    |          Ard Biesheuvel <a.k.biesheuvel@ewi.tudelft.nl>              |
  18    +----------------------------------------------------------------------+
  19  */
  20 
  21 #ifdef HAVE_CONFIG_H
  22 #include "config.h"
  23 #endif
  24 
  25 #define _GNU_SOURCE
  26 
  27 #include "php.h"
  28 
  29 #if HAVE_IBASE
  30 
  31 #include "php_ini.h"
  32 #include "ext/standard/php_standard.h"
  33 #include "ext/standard/md5.h"
  34 #include "php_interbase.h"
  35 #include "php_ibase_includes.h"
  36 #include "SAPI.h"
  37 
  38 #include <time.h>
  39 
  40 #define ROLLBACK                0
  41 #define COMMIT                  1
  42 #define RETAIN                  2
  43 
  44 #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
  45 
  46 ZEND_DECLARE_MODULE_GLOBALS(ibase)
  47 static PHP_GINIT_FUNCTION(ibase);
  48 
  49 /* {{{ arginfo */
  50 ZEND_BEGIN_ARG_INFO(arginfo_ibase_errmsg, 0)
  51 ZEND_END_ARG_INFO()
  52 
  53 ZEND_BEGIN_ARG_INFO(arginfo_ibase_errcode, 0)
  54 ZEND_END_ARG_INFO()
  55 
  56 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_connect, 0, 0, 1)
  57         ZEND_ARG_INFO(0, database)
  58         ZEND_ARG_INFO(0, username)
  59         ZEND_ARG_INFO(0, password)
  60         ZEND_ARG_INFO(0, charset)
  61         ZEND_ARG_INFO(0, buffers)
  62         ZEND_ARG_INFO(0, dialect)
  63         ZEND_ARG_INFO(0, role)
  64 ZEND_END_ARG_INFO()
  65 
  66 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_pconnect, 0, 0, 1)
  67         ZEND_ARG_INFO(0, database)
  68         ZEND_ARG_INFO(0, username)
  69         ZEND_ARG_INFO(0, password)
  70         ZEND_ARG_INFO(0, charset)
  71         ZEND_ARG_INFO(0, buffers)
  72         ZEND_ARG_INFO(0, dialect)
  73         ZEND_ARG_INFO(0, role)
  74 ZEND_END_ARG_INFO()
  75 
  76 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_close, 0, 0, 0)
  77         ZEND_ARG_INFO(0, link_identifier)
  78 ZEND_END_ARG_INFO()
  79 
  80 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_drop_db, 0, 0, 0)
  81         ZEND_ARG_INFO(0, link_identifier)
  82 ZEND_END_ARG_INFO()
  83 
  84 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_trans, 0, 0, 0)
  85         ZEND_ARG_INFO(0, trans_args)
  86         ZEND_ARG_INFO(0, link_identifier)
  87         ZEND_ARG_INFO(0, trans_args)
  88         ZEND_ARG_INFO(0, link_identifier)
  89 ZEND_END_ARG_INFO()
  90 
  91 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit, 0, 0, 1)
  92         ZEND_ARG_INFO(0, link_identifier)
  93 ZEND_END_ARG_INFO()
  94 
  95 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback, 0, 0, 1)
  96         ZEND_ARG_INFO(0, link_identifier)
  97 ZEND_END_ARG_INFO()
  98 
  99 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_commit_ret, 0, 0, 1)
 100         ZEND_ARG_INFO(0, link_identifier)
 101 ZEND_END_ARG_INFO()
 102 
 103 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_rollback_ret, 0, 0, 1)
 104         ZEND_ARG_INFO(0, link_identifier)
 105 ZEND_END_ARG_INFO()
 106 
 107 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_gen_id, 0, 0, 1)
 108         ZEND_ARG_INFO(0, generator)
 109         ZEND_ARG_INFO(0, increment)
 110         ZEND_ARG_INFO(0, link_identifier)
 111 ZEND_END_ARG_INFO()
 112 
 113 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_create, 0, 0, 0)
 114         ZEND_ARG_INFO(0, link_identifier)
 115 ZEND_END_ARG_INFO()
 116 
 117 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_open, 0, 0, 0)
 118         ZEND_ARG_INFO(0, link_identifier)
 119         ZEND_ARG_INFO(0, blob_id)
 120 ZEND_END_ARG_INFO()
 121 
 122 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_add, 0, 0, 2)
 123         ZEND_ARG_INFO(0, blob_handle)
 124         ZEND_ARG_INFO(0, data)
 125 ZEND_END_ARG_INFO()
 126 
 127 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_get, 0, 0, 2)
 128         ZEND_ARG_INFO(0, blob_handle)
 129         ZEND_ARG_INFO(0, len)
 130 ZEND_END_ARG_INFO()
 131 
 132 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_close, 0, 0, 1)
 133         ZEND_ARG_INFO(0, blob_handle)
 134 ZEND_END_ARG_INFO()
 135 
 136 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_cancel, 0, 0, 1)
 137         ZEND_ARG_INFO(0, blob_handle)
 138 ZEND_END_ARG_INFO()
 139 
 140 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_info, 0, 0, 0)
 141         ZEND_ARG_INFO(0, link_identifier)
 142         ZEND_ARG_INFO(0, blob_id)
 143 ZEND_END_ARG_INFO()
 144 
 145 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_echo, 0, 0, 0)
 146         ZEND_ARG_INFO(0, link_identifier)
 147         ZEND_ARG_INFO(0, blob_id)
 148 ZEND_END_ARG_INFO()
 149 
 150 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_blob_import, 0, 0, 0)
 151         ZEND_ARG_INFO(0, link_identifier)
 152         ZEND_ARG_INFO(0, file)
 153 ZEND_END_ARG_INFO()
 154 
 155 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_query, 0, 0, 0)
 156         ZEND_ARG_INFO(0, link_identifier)
 157         ZEND_ARG_INFO(0, link_identifier)
 158         ZEND_ARG_INFO(0, query)
 159         ZEND_ARG_INFO(0, bind_arg)
 160         ZEND_ARG_INFO(0, bind_arg)
 161 ZEND_END_ARG_INFO()
 162 
 163 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_affected_rows, 0, 0, 0)
 164         ZEND_ARG_INFO(0, link_identifier)
 165 ZEND_END_ARG_INFO()
 166 
 167 #if abies_0
 168 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_rows, 0, 0, 1)
 169         ZEND_ARG_INFO(0, result_identifier)
 170 ZEND_END_ARG_INFO()
 171 #endif
 172 
 173 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_row, 0, 0, 1)
 174         ZEND_ARG_INFO(0, result)
 175         ZEND_ARG_INFO(0, fetch_flags)
 176 ZEND_END_ARG_INFO()
 177 
 178 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_assoc, 0, 0, 1)
 179         ZEND_ARG_INFO(0, result)
 180         ZEND_ARG_INFO(0, fetch_flags)
 181 ZEND_END_ARG_INFO()
 182 
 183 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_fetch_object, 0, 0, 1)
 184         ZEND_ARG_INFO(0, result)
 185         ZEND_ARG_INFO(0, fetch_flags)
 186 ZEND_END_ARG_INFO()
 187 
 188 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_name_result, 0, 0, 2)
 189         ZEND_ARG_INFO(0, result)
 190         ZEND_ARG_INFO(0, name)
 191 ZEND_END_ARG_INFO()
 192 
 193 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_result, 0, 0, 1)
 194         ZEND_ARG_INFO(0, result)
 195 ZEND_END_ARG_INFO()
 196 
 197 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_prepare, 0, 0, 0)
 198         ZEND_ARG_INFO(0, link_identifier)
 199         ZEND_ARG_INFO(0, query)
 200 ZEND_END_ARG_INFO()
 201 
 202 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_execute, 0, 0, 1)
 203         ZEND_ARG_INFO(0, query)
 204         ZEND_ARG_INFO(0, bind_arg)
 205         ZEND_ARG_INFO(0, bind_arg)
 206 ZEND_END_ARG_INFO()
 207 
 208 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_query, 0, 0, 1)
 209         ZEND_ARG_INFO(0, query)
 210 ZEND_END_ARG_INFO()
 211 
 212 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_fields, 0, 0, 1)
 213         ZEND_ARG_INFO(0, query_result)
 214 ZEND_END_ARG_INFO()
 215 
 216 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_field_info, 0, 0, 2)
 217         ZEND_ARG_INFO(0, query_result)
 218         ZEND_ARG_INFO(0, field_number)
 219 ZEND_END_ARG_INFO()
 220 
 221 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_num_params, 0, 0, 1)
 222         ZEND_ARG_INFO(0, query)
 223 ZEND_END_ARG_INFO()
 224 
 225 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_param_info, 0, 0, 2)
 226         ZEND_ARG_INFO(0, query)
 227         ZEND_ARG_INFO(0, field_number)
 228 ZEND_END_ARG_INFO()
 229 
 230 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_add_user, 0, 0, 3)
 231         ZEND_ARG_INFO(0, service_handle)
 232         ZEND_ARG_INFO(0, user_name)
 233         ZEND_ARG_INFO(0, password)
 234         ZEND_ARG_INFO(0, first_name)
 235         ZEND_ARG_INFO(0, middle_name)
 236         ZEND_ARG_INFO(0, last_name)
 237 ZEND_END_ARG_INFO()
 238 
 239 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_modify_user, 0, 0, 3)
 240         ZEND_ARG_INFO(0, service_handle)
 241         ZEND_ARG_INFO(0, user_name)
 242         ZEND_ARG_INFO(0, password)
 243         ZEND_ARG_INFO(0, first_name)
 244         ZEND_ARG_INFO(0, middle_name)
 245         ZEND_ARG_INFO(0, last_name)
 246 ZEND_END_ARG_INFO()
 247 
 248 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_delete_user, 0, 0, 3)
 249         ZEND_ARG_INFO(0, service_handle)
 250         ZEND_ARG_INFO(0, user_name)
 251         ZEND_ARG_INFO(0, password)
 252         ZEND_ARG_INFO(0, first_name)
 253         ZEND_ARG_INFO(0, middle_name)
 254         ZEND_ARG_INFO(0, last_name)
 255 ZEND_END_ARG_INFO()
 256 
 257 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_attach, 0, 0, 3)
 258         ZEND_ARG_INFO(0, host)
 259         ZEND_ARG_INFO(0, dba_username)
 260         ZEND_ARG_INFO(0, dba_password)
 261 ZEND_END_ARG_INFO()
 262 
 263 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_service_detach, 0, 0, 1)
 264         ZEND_ARG_INFO(0, service_handle)
 265 ZEND_END_ARG_INFO()
 266 
 267 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_backup, 0, 0, 3)
 268         ZEND_ARG_INFO(0, service_handle)
 269         ZEND_ARG_INFO(0, source_db)
 270         ZEND_ARG_INFO(0, dest_file)
 271         ZEND_ARG_INFO(0, options)
 272         ZEND_ARG_INFO(0, verbose)
 273 ZEND_END_ARG_INFO()
 274 
 275 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_restore, 0, 0, 3)
 276         ZEND_ARG_INFO(0, service_handle)
 277         ZEND_ARG_INFO(0, source_file)
 278         ZEND_ARG_INFO(0, dest_db)
 279         ZEND_ARG_INFO(0, options)
 280         ZEND_ARG_INFO(0, verbose)
 281 ZEND_END_ARG_INFO()
 282 
 283 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_maintain_db, 0, 0, 3)
 284         ZEND_ARG_INFO(0, service_handle)
 285         ZEND_ARG_INFO(0, db)
 286         ZEND_ARG_INFO(0, action)
 287         ZEND_ARG_INFO(0, argument)
 288 ZEND_END_ARG_INFO()
 289 
 290 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_db_info, 0, 0, 3)
 291         ZEND_ARG_INFO(0, service_handle)
 292         ZEND_ARG_INFO(0, db)
 293         ZEND_ARG_INFO(0, action)
 294         ZEND_ARG_INFO(0, argument)
 295 ZEND_END_ARG_INFO()
 296 
 297 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_server_info, 0, 0, 2)
 298         ZEND_ARG_INFO(0, service_handle)
 299         ZEND_ARG_INFO(0, action)
 300 ZEND_END_ARG_INFO()
 301 
 302 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_wait_event, 0, 0, 1)
 303         ZEND_ARG_INFO(0, link_identifier)
 304         ZEND_ARG_INFO(0, event)
 305         ZEND_ARG_INFO(0, event2)
 306 ZEND_END_ARG_INFO()
 307 
 308 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_set_event_handler, 0, 0, 2)
 309         ZEND_ARG_INFO(0, link_identifier)
 310         ZEND_ARG_INFO(0, handler)
 311         ZEND_ARG_INFO(0, event)
 312         ZEND_ARG_INFO(0, event2)
 313 ZEND_END_ARG_INFO()
 314 
 315 ZEND_BEGIN_ARG_INFO_EX(arginfo_ibase_free_event_handler, 0, 0, 1)
 316         ZEND_ARG_INFO(0, event)
 317 ZEND_END_ARG_INFO()
 318 /* }}} */
 319 
 320 /* {{{ extension definition structures */
 321 const zend_function_entry ibase_functions[] = {
 322         PHP_FE(ibase_connect,           arginfo_ibase_connect)
 323         PHP_FE(ibase_pconnect,          arginfo_ibase_pconnect)
 324         PHP_FE(ibase_close,             arginfo_ibase_close)
 325         PHP_FE(ibase_drop_db,           arginfo_ibase_drop_db)
 326         PHP_FE(ibase_query,             arginfo_ibase_query)
 327         PHP_FE(ibase_fetch_row,         arginfo_ibase_fetch_row)
 328         PHP_FE(ibase_fetch_assoc,       arginfo_ibase_fetch_assoc)
 329         PHP_FE(ibase_fetch_object,      arginfo_ibase_fetch_object)
 330         PHP_FE(ibase_free_result,       arginfo_ibase_free_result)
 331         PHP_FE(ibase_name_result,       arginfo_ibase_name_result)
 332         PHP_FE(ibase_prepare,           arginfo_ibase_prepare)
 333         PHP_FE(ibase_execute,           arginfo_ibase_execute)
 334         PHP_FE(ibase_free_query,        arginfo_ibase_free_query)
 335         PHP_FE(ibase_gen_id,            arginfo_ibase_gen_id)
 336         PHP_FE(ibase_num_fields,        arginfo_ibase_num_fields)
 337         PHP_FE(ibase_num_params,        arginfo_ibase_num_params)
 338 #if abies_0
 339         PHP_FE(ibase_num_rows,          arginfo_ibase_num_rows)
 340 #endif
 341         PHP_FE(ibase_affected_rows, arginfo_ibase_affected_rows)
 342         PHP_FE(ibase_field_info,        arginfo_ibase_field_info)
 343         PHP_FE(ibase_param_info,        arginfo_ibase_param_info)
 344 
 345         PHP_FE(ibase_trans,             arginfo_ibase_trans)
 346         PHP_FE(ibase_commit,            arginfo_ibase_commit)
 347         PHP_FE(ibase_rollback,          arginfo_ibase_rollback)
 348         PHP_FE(ibase_commit_ret,        arginfo_ibase_commit_ret)
 349         PHP_FE(ibase_rollback_ret,      arginfo_ibase_rollback_ret)
 350 
 351         PHP_FE(ibase_blob_info,         arginfo_ibase_blob_info)
 352         PHP_FE(ibase_blob_create,       arginfo_ibase_blob_create)
 353         PHP_FE(ibase_blob_add,          arginfo_ibase_blob_add)
 354         PHP_FE(ibase_blob_cancel,       arginfo_ibase_blob_cancel)
 355         PHP_FE(ibase_blob_close,        arginfo_ibase_blob_close)
 356         PHP_FE(ibase_blob_open,         arginfo_ibase_blob_open)
 357         PHP_FE(ibase_blob_get,          arginfo_ibase_blob_get)
 358         PHP_FE(ibase_blob_echo,         arginfo_ibase_blob_echo)
 359         PHP_FE(ibase_blob_import,       arginfo_ibase_blob_import)
 360         PHP_FE(ibase_errmsg,            arginfo_ibase_errmsg)
 361         PHP_FE(ibase_errcode,           arginfo_ibase_errcode)
 362 
 363         PHP_FE(ibase_add_user,          arginfo_ibase_add_user)
 364         PHP_FE(ibase_modify_user,       arginfo_ibase_modify_user)
 365         PHP_FE(ibase_delete_user,       arginfo_ibase_delete_user)
 366 
 367         PHP_FE(ibase_service_attach, arginfo_ibase_service_attach)
 368         PHP_FE(ibase_service_detach, arginfo_ibase_service_detach)
 369         PHP_FE(ibase_backup,            arginfo_ibase_backup)
 370         PHP_FE(ibase_restore,           arginfo_ibase_restore)
 371         PHP_FE(ibase_maintain_db,       arginfo_ibase_maintain_db)
 372         PHP_FE(ibase_db_info,           arginfo_ibase_db_info)
 373         PHP_FE(ibase_server_info,       arginfo_ibase_server_info)
 374 
 375         PHP_FE(ibase_wait_event,                        arginfo_ibase_wait_event)
 376         PHP_FE(ibase_set_event_handler,         arginfo_ibase_set_event_handler)
 377         PHP_FE(ibase_free_event_handler,        arginfo_ibase_free_event_handler)
 378 
 379         /**
 380         * These aliases are provided in order to maintain forward compatibility. As Firebird
 381         * and InterBase are developed independently, functionality might be different between
 382         * the two branches in future versions.
 383         * Firebird users should use the aliases, so future InterBase-specific changes will
 384         * not affect their code
 385         */
 386         PHP_FALIAS(fbird_connect,               ibase_connect,          arginfo_ibase_connect)
 387         PHP_FALIAS(fbird_pconnect,              ibase_pconnect,         arginfo_ibase_pconnect)
 388         PHP_FALIAS(fbird_close,                 ibase_close,            arginfo_ibase_close)
 389         PHP_FALIAS(fbird_drop_db,               ibase_drop_db,          arginfo_ibase_drop_db)
 390         PHP_FALIAS(fbird_query,                 ibase_query,            arginfo_ibase_query)
 391         PHP_FALIAS(fbird_fetch_row,             ibase_fetch_row,        arginfo_ibase_fetch_row)
 392         PHP_FALIAS(fbird_fetch_assoc,   ibase_fetch_assoc,      arginfo_ibase_fetch_assoc)
 393         PHP_FALIAS(fbird_fetch_object,  ibase_fetch_object, arginfo_ibase_fetch_object)
 394         PHP_FALIAS(fbird_free_result,   ibase_free_result,      arginfo_ibase_free_result)
 395         PHP_FALIAS(fbird_name_result,   ibase_name_result,      arginfo_ibase_name_result)
 396         PHP_FALIAS(fbird_prepare,               ibase_prepare,          arginfo_ibase_prepare)
 397         PHP_FALIAS(fbird_execute,               ibase_execute,          arginfo_ibase_execute)
 398         PHP_FALIAS(fbird_free_query,    ibase_free_query,       arginfo_ibase_free_query)
 399         PHP_FALIAS(fbird_gen_id,                ibase_gen_id,           arginfo_ibase_gen_id)
 400         PHP_FALIAS(fbird_num_fields,    ibase_num_fields,       arginfo_ibase_num_fields)
 401         PHP_FALIAS(fbird_num_params,    ibase_num_params,       arginfo_ibase_num_params)
 402 #if abies_0
 403         PHP_FALIAS(fbird_num_rows,              ibase_num_rows,         arginfo_ibase_num_rows)
 404 #endif
 405         PHP_FALIAS(fbird_affected_rows, ibase_affected_rows, arginfo_ibase_affected_rows)
 406         PHP_FALIAS(fbird_field_info,    ibase_field_info,       arginfo_ibase_field_info)
 407         PHP_FALIAS(fbird_param_info,    ibase_param_info,       arginfo_ibase_param_info)
 408 
 409         PHP_FALIAS(fbird_trans,                 ibase_trans,            arginfo_ibase_trans)
 410         PHP_FALIAS(fbird_commit,                ibase_commit,           arginfo_ibase_commit)
 411         PHP_FALIAS(fbird_rollback,              ibase_rollback,         arginfo_ibase_rollback)
 412         PHP_FALIAS(fbird_commit_ret,    ibase_commit_ret,       arginfo_ibase_commit_ret)
 413         PHP_FALIAS(fbird_rollback_ret,  ibase_rollback_ret, arginfo_ibase_rollback_ret)
 414 
 415         PHP_FALIAS(fbird_blob_info,             ibase_blob_info,        arginfo_ibase_blob_info)
 416         PHP_FALIAS(fbird_blob_create,   ibase_blob_create,      arginfo_ibase_blob_create)
 417         PHP_FALIAS(fbird_blob_add,              ibase_blob_add,         arginfo_ibase_blob_add)
 418         PHP_FALIAS(fbird_blob_cancel,   ibase_blob_cancel,      arginfo_ibase_blob_cancel)
 419         PHP_FALIAS(fbird_blob_close,    ibase_blob_close,       arginfo_ibase_blob_close)
 420         PHP_FALIAS(fbird_blob_open,             ibase_blob_open,        arginfo_ibase_blob_open)
 421         PHP_FALIAS(fbird_blob_get,              ibase_blob_get,         arginfo_ibase_blob_get)
 422         PHP_FALIAS(fbird_blob_echo,             ibase_blob_echo,        arginfo_ibase_blob_echo)
 423         PHP_FALIAS(fbird_blob_import,   ibase_blob_import,      arginfo_ibase_blob_import)
 424         PHP_FALIAS(fbird_errmsg,                ibase_errmsg,           arginfo_ibase_errmsg)
 425         PHP_FALIAS(fbird_errcode,               ibase_errcode,          arginfo_ibase_errcode)
 426 
 427         PHP_FALIAS(fbird_add_user,              ibase_add_user,         arginfo_ibase_add_user)
 428         PHP_FALIAS(fbird_modify_user,   ibase_modify_user,      arginfo_ibase_modify_user)
 429         PHP_FALIAS(fbird_delete_user,   ibase_delete_user,      arginfo_ibase_delete_user)
 430 
 431         PHP_FALIAS(fbird_service_attach,        ibase_service_attach, arginfo_ibase_service_attach)
 432         PHP_FALIAS(fbird_service_detach,        ibase_service_detach, arginfo_ibase_service_detach)
 433         PHP_FALIAS(fbird_backup,                ibase_backup,           arginfo_ibase_backup)
 434         PHP_FALIAS(fbird_restore,               ibase_restore,          arginfo_ibase_restore)
 435         PHP_FALIAS(fbird_maintain_db,   ibase_maintain_db,      arginfo_ibase_maintain_db)
 436         PHP_FALIAS(fbird_db_info,               ibase_db_info,          arginfo_ibase_db_info)
 437         PHP_FALIAS(fbird_server_info,   ibase_server_info,      arginfo_ibase_server_info)
 438 
 439         PHP_FALIAS(fbird_wait_event,    ibase_wait_event,       arginfo_ibase_wait_event)
 440         PHP_FALIAS(fbird_set_event_handler,     ibase_set_event_handler,        arginfo_ibase_set_event_handler)
 441         PHP_FALIAS(fbird_free_event_handler,    ibase_free_event_handler, arginfo_ibase_free_event_handler)
 442         PHP_FE_END
 443 };
 444 
 445 zend_module_entry ibase_module_entry = {
 446         STANDARD_MODULE_HEADER,
 447         "interbase",
 448         ibase_functions,
 449         PHP_MINIT(ibase),
 450         PHP_MSHUTDOWN(ibase),
 451         NULL,
 452         PHP_RSHUTDOWN(ibase),
 453         PHP_MINFO(ibase),
 454         NO_VERSION_YET,
 455         PHP_MODULE_GLOBALS(ibase),
 456         PHP_GINIT(ibase),
 457         NULL,
 458         NULL,
 459         STANDARD_MODULE_PROPERTIES_EX
 460 };
 461 
 462 #ifdef COMPILE_DL_INTERBASE
 463 ZEND_GET_MODULE(ibase)
 464 #endif
 465 
 466 /* True globals, no need for thread safety */
 467 int le_link, le_plink, le_trans;
 468 
 469 /* }}} */
 470 
 471 /* error handling ---------------------------- */
 472 
 473 /* {{{ proto string ibase_errmsg(void) 
 474    Return error message */
 475 PHP_FUNCTION(ibase_errmsg)
 476 {
 477         if (zend_parse_parameters_none() == FAILURE) {
 478                 return;
 479         }
 480 
 481         if (IBG(sql_code) != 0) {
 482                 RETURN_STRING(IBG(errmsg), 1);
 483         }
 484 
 485         RETURN_FALSE;
 486 }
 487 /* }}} */
 488 
 489 /* {{{ proto int ibase_errcode(void) 
 490    Return error code */
 491 PHP_FUNCTION(ibase_errcode)
 492 {
 493         if (zend_parse_parameters_none() == FAILURE) {
 494                 return;
 495         }
 496 
 497         if (IBG(sql_code) != 0) {
 498                 RETURN_LONG(IBG(sql_code));
 499         }
 500         RETURN_FALSE;
 501 }
 502 /* }}} */
 503 
 504 /* print interbase error and save it for ibase_errmsg() */
 505 void _php_ibase_error(TSRMLS_D) /* {{{ */
 506 {
 507         char *s = IBG(errmsg);
 508         ISC_STATUS *statusp = IB_STATUS;
 509 
 510         IBG(sql_code) = isc_sqlcode(IB_STATUS);
 511         
 512         while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
 513                 strcat(IBG(errmsg), " ");
 514                 s = IBG(errmsg) + strlen(IBG(errmsg));
 515         }
 516 
 517         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
 518 }
 519 /* }}} */
 520 
 521 /* print php interbase module error and save it for ibase_errmsg() */
 522 void _php_ibase_module_error(char *msg TSRMLS_DC, ...) /* {{{ */
 523 {
 524         va_list ap;
 525 
 526 #ifdef ZTS
 527         va_start(ap, TSRMLS_C);
 528 #else
 529         va_start(ap, msg);
 530 #endif
 531 
 532         /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
 533         vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap);
 534         va_end(ap);
 535 
 536         IBG(sql_code) = -999; /* no SQL error */
 537 
 538         php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
 539 }
 540 /* }}} */
 541 
 542 /* {{{ internal macros, functions and structures */
 543 typedef struct {
 544         isc_db_handle *db_ptr;
 545         long tpb_len;
 546         char *tpb_ptr;
 547 } ISC_TEB;
 548 
 549 /* }}} */
 550 
 551 /* Fill ib_link and trans with the correct database link and transaction. */
 552 void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
 553         zval **link_id, ibase_db_link **ib_link, ibase_trans **trans)
 554 {
 555         int type;
 556 
 557         IBDEBUG("Transaction or database link?");
 558         if (zend_list_find(Z_LVAL_PP(link_id), &type)) {
 559                 if (type == le_trans) {
 560                         /* Transaction resource: make sure it refers to one link only, then 
 561                            fetch it; database link is stored in ib_trans->db_link[]. */
 562                         IBDEBUG("Type is le_trans");
 563                         ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
 564                         if ((*trans)->link_cnt > 1) {
 565                                 _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
 566                                         TSRMLS_CC);
 567                                 return;
 568                         }                               
 569                         *ib_link = (*trans)->db_link[0];
 570                         return;
 571                 }
 572         } 
 573         IBDEBUG("Type is le_[p]link or id not found");
 574         /* Database link resource, use default transaction. */
 575         *trans = NULL;
 576         ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
 577 }
 578 /* }}} */       
 579 
 580 /* destructors ---------------------- */
 581 
 582 static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC) /* {{{ */
 583 {
 584         unsigned short i = 0, j;
 585         ibase_tr_list *l;
 586         ibase_event *e;
 587         IBDEBUG("Checking transactions to close...");
 588 
 589         for (l = link->tr_list; l != NULL; ++i) {
 590                 ibase_tr_list *p = l;
 591                 if (p->trans != NULL) {
 592                         if (i == 0) {
 593                                 if (p->trans->handle != NULL) {
 594                                         IBDEBUG("Committing default transaction...");
 595                                         if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) {
 596                                                 _php_ibase_error(TSRMLS_C);
 597                                         }
 598                                 }
 599                                 efree(p->trans); /* default transaction is not a registered resource: clean up */
 600                         } else {
 601                                 if (p->trans->handle != NULL) { 
 602                                         /* non-default trans might have been rolled back by other call of this dtor */
 603                                         IBDEBUG("Rolling back other transactions...");
 604                                         if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) {
 605                                                 _php_ibase_error(TSRMLS_C);
 606                                         }
 607                                 }
 608                                 /* set this link pointer to NULL in the transaction */
 609                                 for (j = 0; j < p->trans->link_cnt; ++j) {
 610                                         if (p->trans->db_link[j] == link) {
 611                                                 p->trans->db_link[j] = NULL;
 612                                                 break;
 613                                         }
 614                                 }
 615                         }
 616                 }
 617                 l = l->next;
 618                 efree(p);
 619         }
 620         link->tr_list = NULL;
 621         
 622         for (e = link->event_head; e; e = e->event_next) {
 623                 _php_ibase_free_event(e TSRMLS_CC);
 624                 e->link = NULL;
 625         }
 626 }
 627 
 628 /* }}} */
 629 
 630 static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
 631 {
 632         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
 633 
 634         _php_ibase_commit_link(link TSRMLS_CC);
 635 }
 636 /* }}} */
 637 
 638 static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
 639 {
 640         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
 641 
 642         _php_ibase_commit_link(link TSRMLS_CC);
 643         if (link->handle != NULL) {
 644                 IBDEBUG("Closing normal link...");
 645                 isc_detach_database(IB_STATUS, &link->handle);
 646         }
 647         IBG(num_links)--;
 648         efree(link);
 649 }
 650 /* }}} */
 651 
 652 static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
 653 {
 654         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
 655 
 656         _php_ibase_commit_link(link TSRMLS_CC);
 657         IBDEBUG("Closing permanent link...");
 658         if (link->handle != NULL) {
 659                 isc_detach_database(IB_STATUS, &link->handle);
 660         }
 661         IBG(num_persistent)--;
 662         IBG(num_links)--;
 663         free(link);
 664 }
 665 /* }}} */
 666 
 667 static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
 668 {
 669         ibase_trans *trans = (ibase_trans *)rsrc->ptr;
 670         unsigned short i;
 671         
 672         IBDEBUG("Cleaning up transaction resource...");
 673         if (trans->handle != NULL) {
 674                 IBDEBUG("Rolling back unhandled transaction...");
 675                 if (isc_rollback_transaction(IB_STATUS, &trans->handle)) {
 676                         _php_ibase_error(TSRMLS_C);
 677                 }
 678         }
 679 
 680         /* now remove this transaction from all the connection-transaction lists */
 681         for (i = 0; i < trans->link_cnt; ++i) {
 682                 if (trans->db_link[i] != NULL) {
 683                         ibase_tr_list **l;
 684                         for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) {
 685                                 if ( (*l)->trans == trans) {
 686                                         ibase_tr_list *p = *l;
 687                                         *l = p->next;
 688                                         efree(p);
 689                                         break;
 690                                 }
 691                         }
 692                 }
 693         }
 694         efree(trans);
 695 }
 696 /* }}} */
 697 
 698 /* TODO this function should be part of either Zend or PHP API */
 699 static PHP_INI_DISP(php_ibase_password_displayer_cb)
 700 {
 701         TSRMLS_FETCH();
 702 
 703         if ((type == PHP_INI_DISPLAY_ORIG && ini_entry->orig_value) 
 704                         || (type == PHP_INI_DISPLAY_ACTIVE && ini_entry->value)) {
 705                 PUTS("********");
 706         } else if (!sapi_module.phpinfo_as_text) {
 707                 PUTS("<i>no value</i>");
 708         } else {
 709                 PUTS("no value");
 710         }
 711 }
 712 
 713 /* {{{ startup, shutdown and info functions */
 714 PHP_INI_BEGIN()
 715         PHP_INI_ENTRY_EX("ibase.allow_persistent", "1", PHP_INI_SYSTEM, NULL, zend_ini_boolean_displayer_cb)
 716         PHP_INI_ENTRY_EX("ibase.max_persistent", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
 717         PHP_INI_ENTRY_EX("ibase.max_links", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
 718         PHP_INI_ENTRY("ibase.default_db", NULL, PHP_INI_SYSTEM, NULL)
 719         PHP_INI_ENTRY("ibase.default_user", NULL, PHP_INI_ALL, NULL)
 720         PHP_INI_ENTRY_EX("ibase.default_password", NULL, PHP_INI_ALL, NULL, php_ibase_password_displayer_cb)
 721         PHP_INI_ENTRY("ibase.default_charset", NULL, PHP_INI_ALL, NULL)
 722         PHP_INI_ENTRY("ibase.timestampformat", IB_DEF_DATE_FMT " " IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
 723         PHP_INI_ENTRY("ibase.dateformat", IB_DEF_DATE_FMT, PHP_INI_ALL, NULL)
 724         PHP_INI_ENTRY("ibase.timeformat", IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
 725 PHP_INI_END()
 726 
 727 static PHP_GINIT_FUNCTION(ibase)
 728 {
 729         ibase_globals->num_persistent = ibase_globals->num_links = 0;
 730         ibase_globals->sql_code = *ibase_globals->errmsg = 0;
 731         ibase_globals->default_link = -1;
 732 }
 733 
 734 PHP_MINIT_FUNCTION(ibase)
 735 {
 736         REGISTER_INI_ENTRIES();
 737 
 738         le_link = zend_register_list_destructors_ex(_php_ibase_close_link, NULL, LE_LINK, module_number);
 739         le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, LE_PLINK, module_number);
 740         le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, LE_TRANS, module_number);
 741 
 742         REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT);
 743         REGISTER_LONG_CONSTANT("IBASE_CREATE", PHP_IBASE_CREATE, CONST_PERSISTENT);
 744         REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */
 745         REGISTER_LONG_CONSTANT("IBASE_FETCH_BLOBS", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT);
 746         REGISTER_LONG_CONSTANT("IBASE_FETCH_ARRAYS", PHP_IBASE_FETCH_ARRAYS, CONST_PERSISTENT);
 747         REGISTER_LONG_CONSTANT("IBASE_UNIXTIME", PHP_IBASE_UNIXTIME, CONST_PERSISTENT);
 748 
 749         /* transactions */
 750         REGISTER_LONG_CONSTANT("IBASE_WRITE", PHP_IBASE_WRITE, CONST_PERSISTENT);
 751         REGISTER_LONG_CONSTANT("IBASE_READ", PHP_IBASE_READ, CONST_PERSISTENT);
 752         REGISTER_LONG_CONSTANT("IBASE_COMMITTED", PHP_IBASE_COMMITTED, CONST_PERSISTENT);
 753         REGISTER_LONG_CONSTANT("IBASE_CONSISTENCY", PHP_IBASE_CONSISTENCY, CONST_PERSISTENT);
 754         REGISTER_LONG_CONSTANT("IBASE_CONCURRENCY", PHP_IBASE_CONCURRENCY, CONST_PERSISTENT);
 755         REGISTER_LONG_CONSTANT("IBASE_REC_VERSION", PHP_IBASE_REC_VERSION, CONST_PERSISTENT);
 756         REGISTER_LONG_CONSTANT("IBASE_REC_NO_VERSION", PHP_IBASE_REC_NO_VERSION, CONST_PERSISTENT);
 757         REGISTER_LONG_CONSTANT("IBASE_NOWAIT", PHP_IBASE_NOWAIT, CONST_PERSISTENT);
 758         REGISTER_LONG_CONSTANT("IBASE_WAIT", PHP_IBASE_WAIT, CONST_PERSISTENT);
 759 
 760         php_ibase_query_minit(INIT_FUNC_ARGS_PASSTHRU);
 761         php_ibase_blobs_minit(INIT_FUNC_ARGS_PASSTHRU);
 762         php_ibase_events_minit(INIT_FUNC_ARGS_PASSTHRU);
 763         php_ibase_service_minit(INIT_FUNC_ARGS_PASSTHRU);
 764         
 765         return SUCCESS;          
 766 }                            
 767                              
 768 PHP_MSHUTDOWN_FUNCTION(ibase)
 769 {
 770 #ifndef PHP_WIN32
 771         /**
 772          * When the Interbase client API library libgds.so is first loaded, it registers a call to 
 773          * gds__cleanup() with atexit(), in order to clean up after itself when the process exits.
 774          * This means that the library is called at process shutdown, and cannot be unloaded beforehand.
 775          * PHP tries to unload modules after every request [dl()'ed modules], and right before the 
 776          * process shuts down [modules loaded from php.ini]. This results in a segfault for this module.
 777          * By NULLing the dlopen() handle in the module entry, Zend omits the call to dlclose(),
 778          * ensuring that the module will remain present until the process exits. However, the functions
 779          * and classes exported by the module will not be available until the module is 'reloaded'. 
 780          * When reloaded, dlopen() will return the handle of the already loaded module. The module will
 781          * be unloaded automatically when the process exits.
 782          */
 783         zend_module_entry *ibase_entry;
 784         if (SUCCESS == zend_hash_find(&module_registry, ibase_module_entry.name,
 785                         strlen(ibase_module_entry.name) +1, (void*) &ibase_entry)) {
 786                 ibase_entry->handle = NULL;
 787         }
 788 #endif
 789         UNREGISTER_INI_ENTRIES();
 790         return SUCCESS;
 791 }
 792 
 793 PHP_RSHUTDOWN_FUNCTION(ibase)
 794 {
 795         IBG(num_links) = IBG(num_persistent);
 796         IBG(default_link)= -1;
 797 
 798         RESET_ERRMSG;
 799 
 800         return SUCCESS;
 801 } 
 802  
 803 PHP_MINFO_FUNCTION(ibase)
 804 {
 805         char tmp[64], *s;
 806 
 807         php_info_print_table_start();
 808         php_info_print_table_row(2, "Firebird/InterBase Support", 
 809 #ifdef COMPILE_DL_INTERBASE
 810                 "dynamic");
 811 #else
 812                 "static");
 813 #endif
 814 
 815 #ifdef FB_API_VER
 816         snprintf( (s = tmp), sizeof(tmp), "Firebird API version %d", FB_API_VER);
 817 #elif (SQLDA_CURRENT_VERSION > 1)
 818         s =  "Interbase 7.0 and up";
 819 #elif !defined(DSC_null)
 820         s = "Interbase 6";
 821 #else
 822         s = "Firebird 1.0";
 823 #endif
 824         php_info_print_table_row(2, "Compile-time Client Library Version", s);
 825 
 826 #if defined(__GNUC__) || defined(PHP_WIN32)
 827         do {
 828                 info_func_t info_func = NULL;
 829 #ifdef __GNUC__
 830                 info_func = (info_func_t)dlsym(RTLD_DEFAULT, "isc_get_client_version");
 831 #else
 832                 HMODULE l = GetModuleHandle("fbclient");
 833 
 834                 if (!l && !(l = GetModuleHandle("gds32"))) {
 835                         break;
 836                 }
 837                 info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version");
 838 #endif
 839                 if (info_func) {
 840                         info_func(s = tmp);
 841                 } else {
 842                         s = "Firebird 1.0/Interbase 6";
 843                 }
 844                 php_info_print_table_row(2, "Run-time Client Library Version", s);
 845         } while (0);
 846 #endif                  
 847         php_info_print_table_end();
 848 
 849         DISPLAY_INI_ENTRIES();
 850 
 851 }
 852 /* }}} */
 853 
 854 enum connect_args { DB = 0, USER = 1, PASS = 2, CSET = 3, ROLE = 4, BUF = 0, DLECT = 1, SYNC = 2 };
 855         
 856 static char const dpb_args[] = { 
 857         0, isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name, 0
 858 };
 859         
 860 int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC)
 861 {
 862         short i, dpb_len, buf_len = 257-2;  /* version byte at the front, and a null at the end */
 863         char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb;
 864 
 865         dpb = dpb_buffer + 1;
 866 
 867         for (i = 0; i < sizeof(dpb_args); ++i) {
 868                 if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
 869                         dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
 870                         dpb += dpb_len;
 871                         buf_len -= dpb_len;
 872                 }
 873         }
 874         if (largs[BUF] && buf_len > 0) {
 875                 dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers, 
 876                         (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
 877                 dpb += dpb_len;
 878                 buf_len -= dpb_len;
 879         }
 880         if (largs[SYNC] && buf_len > 0) {
 881                 dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync ? 1 : 0);
 882                 dpb += dpb_len;
 883                 buf_len -= dpb_len;
 884         }
 885         if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
 886                 _php_ibase_error(TSRMLS_C);
 887                 return FAILURE;
 888         }
 889         return SUCCESS;
 890 }
 891 /* }}} */
 892 
 893 static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */
 894 {
 895         char *c, hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL };
 896         int i, len[] = { 0, 0, 0, 0, 0 };
 897         long largs[] = { 0, 0, 0 };
 898         PHP_MD5_CTX hash_context;
 899         zend_rsrc_list_entry new_index_ptr, *le;
 900         isc_db_handle db_handle = NULL;
 901         ibase_db_link *ib_link;
 902 
 903         RESET_ERRMSG;
 904 
 905         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssllsl",
 906                         &args[DB], &len[DB], &args[USER], &len[USER], &args[PASS], &len[PASS],
 907                         &args[CSET], &len[CSET], &largs[BUF], &largs[DLECT], &args[ROLE], &len[ROLE],
 908                         &largs[SYNC])) {
 909                 RETURN_FALSE;
 910         }
 911         
 912         /* restrict to the server/db in the .ini if in safe mode */
 913         if ((!len[DB] || PG(sql_safe_mode)) && (c = INI_STR("ibase.default_db"))) { 
 914                 args[DB] = c;
 915                 len[DB] = strlen(c);
 916         }
 917         if (!len[USER] && (c = INI_STR("ibase.default_user"))) {
 918                 args[USER] = c;
 919                 len[USER] = strlen(c);
 920         }
 921         if (!len[PASS] && (c = INI_STR("ibase.default_password"))) {
 922                 args[PASS] = c;
 923                 len[PASS] = strlen(c);
 924         }
 925         if (!len[CSET] && (c = INI_STR("ibase.default_charset"))) {
 926                 args[CSET] = c;
 927                 len[CSET] = strlen(c);
 928         }
 929         
 930         /* don't want usernames and passwords floating around */
 931         PHP_MD5Init(&hash_context);
 932         for (i = 0; i < sizeof(args)/sizeof(char*); ++i) {
 933                 PHP_MD5Update(&hash_context,args[i],len[i]);
 934         }
 935         for (i = 0; i < sizeof(largs)/sizeof(long); ++i) {
 936                 PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long));
 937         }
 938         PHP_MD5Final(hash, &hash_context);
 939         
 940         /* try to reuse a connection */
 941         if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) {
 942                 long xlink;
 943                 int type;
 944 
 945                 if (Z_TYPE_P(le) != le_index_ptr) {
 946                         RETURN_FALSE;
 947                 }
 948                         
 949                 xlink = (long) le->ptr;
 950                 if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) {
 951                         zend_list_addref(xlink);
 952                         RETURN_RESOURCE(IBG(default_link) = xlink);
 953                 } else {
 954                         zend_hash_del(&EG(regular_list), hash, sizeof(hash));
 955                 }
 956         }               
 957 
 958         /* ... or a persistent one */
 959         switch (zend_hash_find(&EG(persistent_list), hash, sizeof(hash), (void *) &le)) {
 960                 long l;
 961                 
 962                 static char info[] = { isc_info_base_level, isc_info_end };
 963                 char result[8];
 964                 ISC_STATUS status[20];
 965 
 966         case SUCCESS:
 967 
 968                 if (Z_TYPE_P(le) != le_plink) {
 969                         RETURN_FALSE;
 970                 }
 971                 /* check if connection has timed out */
 972                 ib_link = (ibase_db_link *) le->ptr;
 973                 if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
 974                         ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
 975                         break;
 976                 }
 977                 zend_hash_del(&EG(persistent_list), hash, sizeof(hash));
 978         
 979         default:
 980 
 981                 /* no link found, so we have to open one */
 982         
 983                 if ((l = INI_INT("ibase.max_links")) != -1 && IBG(num_links) >= l) {
 984                         _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links));
 985                         RETURN_FALSE;
 986                 }
 987         
 988                 /* create the ib_link */
 989                 if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle TSRMLS_CC)) {
 990                         RETURN_FALSE;
 991                 }
 992         
 993                 /* use non-persistent if allowed number of persistent links is exceeded */
 994                 if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
 995                         ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
 996                         ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
 997                 } else {
 998                         zend_rsrc_list_entry new_le;
 999 
1000                         ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
1001                         if (!ib_link) {
1002                                 RETURN_FALSE;
1003                         }
1004 
1005                         /* hash it up */
1006                         Z_TYPE(new_le) = le_plink;
1007                         new_le.ptr = ib_link;
1008                         if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash),
1009                                         (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)) {
1010                                 free(ib_link);
1011                                 RETURN_FALSE;
1012                         }
1013                         ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
1014                         ++IBG(num_persistent);
1015                 }
1016                 ib_link->handle = db_handle;
1017                 ib_link->dialect = largs[DLECT] ? (unsigned short)largs[DLECT] : SQL_DIALECT_CURRENT;
1018                 ib_link->tr_list = NULL;
1019                 ib_link->event_head = NULL;
1020         
1021                 ++IBG(num_links);
1022         }
1023 
1024         /* add it to the hash */
1025         new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
1026         Z_TYPE(new_index_ptr) = le_index_ptr;
1027         if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash),
1028                         (void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)) {
1029                 RETURN_FALSE;
1030         }
1031         zend_list_addref(IBG(default_link) = Z_LVAL_P(return_value));
1032 }
1033 /* }}} */
1034 
1035 /* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
1036    Open a connection to an InterBase database */
1037 PHP_FUNCTION(ibase_connect)
1038 {
1039         _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
1040 }
1041 /* }}} */
1042 
1043 /* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
1044    Open a persistent connection to an InterBase database */
1045 PHP_FUNCTION(ibase_pconnect)
1046 {
1047         _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INI_INT("ibase.allow_persistent"));
1048 }
1049 /* }}} */
1050 
1051 /* {{{ proto bool ibase_close([resource link_identifier])
1052    Close an InterBase connection */
1053 PHP_FUNCTION(ibase_close)
1054 {
1055         zval *link_arg = NULL;
1056         ibase_db_link *ib_link;
1057         int link_id;
1058 
1059         RESET_ERRMSG;
1060         
1061         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
1062                 return;
1063         }
1064         
1065         if (ZEND_NUM_ARGS() == 0) {
1066                 link_id = IBG(default_link);
1067                 CHECK_LINK(link_id);
1068                 IBG(default_link) = -1;
1069         } else {
1070                 link_id = Z_RESVAL_P(link_arg);
1071         }
1072 
1073         ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
1074         zend_list_delete(link_id);
1075         RETURN_TRUE;
1076 }
1077 /* }}} */
1078 
1079 /* {{{ proto bool ibase_drop_db([resource link_identifier])
1080    Drop an InterBase database */
1081 PHP_FUNCTION(ibase_drop_db)
1082 {
1083         zval *link_arg = NULL;
1084         ibase_db_link *ib_link;
1085         ibase_tr_list *l;
1086         int link_id;
1087 
1088         RESET_ERRMSG;
1089         
1090         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
1091                 return;
1092         }
1093         
1094         if (ZEND_NUM_ARGS() == 0) {
1095                 link_id = IBG(default_link);
1096                 CHECK_LINK(link_id);
1097                 IBG(default_link) = -1;
1098         } else {
1099                 link_id = Z_RESVAL_P(link_arg);
1100         }
1101         
1102         ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
1103 
1104         if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
1105                 _php_ibase_error(TSRMLS_C);
1106                 RETURN_FALSE;
1107         }
1108 
1109         /* isc_drop_database() doesn't invalidate the transaction handles */
1110         for (l = ib_link->tr_list; l != NULL; l = l->next) {
1111                 if (l->trans != NULL) l->trans->handle = NULL;
1112         }
1113 
1114         zend_list_delete(link_id);
1115         RETURN_TRUE;
1116 }
1117 /* }}} */
1118 
1119 /* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
1120    Start a transaction over one or several databases */
1121 
1122 #define TPB_MAX_SIZE (8*sizeof(char))
1123 
1124 PHP_FUNCTION(ibase_trans)
1125 {
1126         unsigned short i, link_cnt = 0, tpb_len = 0;
1127         int argn;
1128         char last_tpb[TPB_MAX_SIZE];
1129         ibase_db_link **ib_link = NULL;
1130         ibase_trans *ib_trans;
1131         isc_tr_handle tr_handle = NULL;
1132         ISC_STATUS result;
1133         
1134         RESET_ERRMSG;
1135 
1136         argn = ZEND_NUM_ARGS();
1137 
1138         /* (1+argn) is an upper bound for the number of links this trans connects to */
1139         ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0);
1140         
1141         if (argn > 0) {
1142                 long trans_argl = 0;
1143                 char *tpb;
1144                 ISC_TEB *teb;
1145                 zval ***args = NULL;
1146 
1147                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) {
1148                         efree(args);
1149                         efree(ib_link);
1150                         RETURN_FALSE;
1151                 }
1152 
1153                 teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0);
1154                 tpb = (char *) safe_emalloc(TPB_MAX_SIZE,argn,0);
1155 
1156                 /* enumerate all the arguments: assume every non-resource argument 
1157                    specifies modifiers for the link ids that follow it */
1158                 for (i = 0; i < argn; ++i) {
1159                         
1160                         if (Z_TYPE_PP(args[i]) == IS_RESOURCE) {
1161                                 
1162                                 if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) {
1163                                         efree(teb);
1164                                         efree(tpb);
1165                                         efree(ib_link);
1166                                         efree(args);
1167                                         RETURN_FALSE;
1168                                 }
1169         
1170                                 /* copy the most recent modifier string into tbp[] */
1171                                 memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, TPB_MAX_SIZE);
1172 
1173                                 /* add a database handle to the TEB with the most recently specified set of modifiers */
1174                                 teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle;
1175                                 teb[link_cnt].tpb_len = tpb_len;
1176                                 teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
1177                                 
1178                                 ++link_cnt;
1179                                 
1180                         } else {
1181                                 
1182                                 tpb_len = 0;
1183 
1184                                 convert_to_long_ex(args[i]);
1185                                 trans_argl = Z_LVAL_PP(args[i]);
1186 
1187                                 if (trans_argl != PHP_IBASE_DEFAULT) {
1188                                         last_tpb[tpb_len++] = isc_tpb_version3;
1189 
1190                                         /* access mode */
1191                                         if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) {
1192                                                 last_tpb[tpb_len++] = isc_tpb_read;
1193                                         } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) {
1194                                                 last_tpb[tpb_len++] = isc_tpb_write;
1195                                         }
1196 
1197                                         /* isolation level */
1198                                         if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) {
1199                                                 last_tpb[tpb_len++] = isc_tpb_read_committed;
1200                                                 if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) {
1201                                                         last_tpb[tpb_len++] = isc_tpb_rec_version;
1202                                                 } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) {
1203                                                         last_tpb[tpb_len++] = isc_tpb_no_rec_version; 
1204                                                 }       
1205                                         } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) {
1206                                                 last_tpb[tpb_len++] = isc_tpb_consistency;
1207                                         } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) {
1208                                                 last_tpb[tpb_len++] = isc_tpb_concurrency;
1209                                         }
1210                                         
1211                                         /* lock resolution */
1212                                         if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) {
1213                                                 last_tpb[tpb_len++] = isc_tpb_nowait;
1214                                         } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) {
1215                                                 last_tpb[tpb_len++] = isc_tpb_wait;
1216                                         }
1217                                 }
1218                         }
1219                 }       
1220                                         
1221                 if (link_cnt > 0) {
1222                         result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb);
1223                 }
1224 
1225                 efree(args);
1226                 efree(tpb);
1227                 efree(teb);
1228         }
1229 
1230         if (link_cnt == 0) {
1231                 link_cnt = 1;
1232                 if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
1233                         efree(ib_link);
1234                         RETURN_FALSE;
1235                 }
1236                 result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb);
1237         }
1238         
1239         /* start the transaction */
1240         if (result) {
1241                 _php_ibase_error(TSRMLS_C);
1242                 efree(ib_link);
1243                 RETURN_FALSE;
1244         }
1245 
1246         /* register the transaction in our own data structures */
1247         ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans));
1248         ib_trans->handle = tr_handle;
1249         ib_trans->link_cnt = link_cnt;
1250         ib_trans->affected_rows = 0;
1251         for (i = 0; i < link_cnt; ++i) {
1252                 ibase_tr_list **l;
1253                 ib_trans->db_link[i] = ib_link[i];
1254                 
1255                 /* the first item in the connection-transaction list is reserved for the default transaction */
1256                 if (ib_link[i]->tr_list == NULL) {
1257                         ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
1258                         ib_link[i]->tr_list->trans = NULL;
1259                         ib_link[i]->tr_list->next = NULL;
1260                 }
1261 
1262                 /* link the transaction into the connection-transaction list */
1263                 for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next);
1264                 *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
1265                 (*l)->trans = ib_trans;
1266                 (*l)->next = NULL;
1267         }
1268         efree(ib_link);
1269         ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
1270 }
1271 /* }}} */
1272 
1273 int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC) /* {{{ */
1274 {
1275         if (ib_link == NULL) {
1276                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link");
1277                 return FAILURE;
1278         }
1279 
1280         /* the first item in the connection-transaction list is reserved for the default transaction */
1281         if (ib_link->tr_list == NULL) {
1282                 ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
1283                 ib_link->tr_list->trans = NULL;
1284                 ib_link->tr_list->next = NULL;
1285         }
1286 
1287         if (*trans == NULL) {
1288                 ibase_trans *tr = ib_link->tr_list->trans;
1289 
1290                 if (tr == NULL) {
1291                         tr = (ibase_trans *) emalloc(sizeof(ibase_trans));
1292                         tr->handle = NULL;
1293                         tr->link_cnt = 1;
1294                         tr->affected_rows = 0;
1295                         tr->db_link[0] = ib_link;
1296                         ib_link->tr_list->trans = tr;
1297                 }
1298                 if (tr->handle == NULL) {
1299                         if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) {
1300                                 _php_ibase_error(TSRMLS_C);
1301                                 return FAILURE;
1302                         }
1303                 }
1304                 *trans = tr;
1305         }
1306         return SUCCESS;
1307 }
1308 /* }}} */
1309 
1310 static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */
1311 {
1312         ibase_trans *trans = NULL;
1313         int res_id = 0;
1314         ISC_STATUS result;
1315         ibase_db_link *ib_link;
1316         zval *arg = NULL;
1317         int type;
1318 
1319         RESET_ERRMSG;
1320         
1321         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
1322                 return;
1323         }
1324 
1325         if (ZEND_NUM_ARGS() == 0) {
1326                 ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
1327                 if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
1328                         /* this link doesn't have a default transaction */
1329                         _php_ibase_module_error("Default link has no default transaction" TSRMLS_CC);
1330                         RETURN_FALSE;
1331                 }
1332                 trans = ib_link->tr_list->trans;
1333         } else {
1334                 /* one id was passed, could be db or trans id */
1335                 if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) {
1336                         ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans);
1337                         res_id = Z_RESVAL_P(arg);
1338                 } else {
1339                         ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink);
1340 
1341                         if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
1342                                 /* this link doesn't have a default transaction */
1343                                 _php_ibase_module_error("Link has no default transaction" TSRMLS_CC);
1344                                 RETURN_FALSE;
1345                         }
1346                         trans = ib_link->tr_list->trans;
1347                 }
1348         }
1349 
1350         switch (commit) {
1351                 default: /* == case ROLLBACK: */
1352                         result = isc_rollback_transaction(IB_STATUS, &trans->handle);
1353                         break;
1354                 case COMMIT:
1355                         result = isc_commit_transaction(IB_STATUS, &trans->handle);
1356                         break;
1357                 case (ROLLBACK | RETAIN):
1358                         result = isc_rollback_retaining(IB_STATUS, &trans->handle);
1359                         break;
1360                 case (COMMIT | RETAIN):
1361                         result = isc_commit_retaining(IB_STATUS, &trans->handle);
1362                         break;
1363         }
1364         
1365         if (result) {
1366                 _php_ibase_error(TSRMLS_C);
1367                 RETURN_FALSE;
1368         }
1369 
1370         /* Don't try to destroy implicitly opened transaction from list... */
1371         if ((commit & RETAIN) == 0 && res_id != 0) {
1372                 zend_list_delete(res_id);
1373         }
1374         RETURN_TRUE;
1375 }
1376 /* }}} */
1377 
1378 /* {{{ proto bool ibase_commit( resource link_identifier )
1379    Commit transaction */
1380 PHP_FUNCTION(ibase_commit)
1381 {
1382         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
1383 }
1384 /* }}} */
1385 
1386 /* {{{ proto bool ibase_rollback( resource link_identifier )
1387    Rollback transaction */
1388 PHP_FUNCTION(ibase_rollback)
1389 {
1390         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
1391 }
1392 /* }}} */
1393 
1394 /* {{{ proto bool ibase_commit_ret( resource link_identifier )
1395    Commit transaction and retain the transaction context */
1396 PHP_FUNCTION(ibase_commit_ret)
1397 {
1398         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN);
1399 }
1400 /* }}} */
1401 
1402 /* {{{ proto bool ibase_rollback_ret( resource link_identifier )
1403    Rollback transaction and retain the transaction context */
1404 PHP_FUNCTION(ibase_rollback_ret)
1405 {
1406         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN);
1407 }
1408 /* }}} */
1409 
1410 /* {{{ proto int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])
1411    Increments the named generator and returns its new value */
1412 PHP_FUNCTION(ibase_gen_id)
1413 {
1414         zval *link = NULL;
1415         char query[128], *generator;
1416         int gen_len;
1417         long inc = 1;
1418         ibase_db_link *ib_link;
1419         ibase_trans *trans = NULL;
1420         XSQLDA out_sqlda;
1421         ISC_INT64 result;
1422 
1423         RESET_ERRMSG;
1424 
1425         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &generator, &gen_len,
1426                         &inc, &link)) {
1427                 RETURN_FALSE;
1428         }
1429         
1430         if (gen_len > 31) {
1431                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid generator name");
1432                 RETURN_FALSE;
1433         }
1434 
1435         PHP_IBASE_LINK_TRANS(link, ib_link, trans);
1436         
1437         snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc);
1438 
1439         /* allocate a minimal descriptor area */
1440         out_sqlda.sqln = out_sqlda.sqld = 1;
1441         out_sqlda.version = SQLDA_CURRENT_VERSION;
1442         
1443         /* allocate the field for the result */
1444         out_sqlda.sqlvar[0].sqltype = SQL_INT64;
1445         out_sqlda.sqlvar[0].sqlscale = 0;
1446         out_sqlda.sqlvar[0].sqllen = sizeof(result);
1447         out_sqlda.sqlvar[0].sqldata = (void*) &result;
1448 
1449         /* execute the query */
1450         if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query,
1451                         SQL_DIALECT_CURRENT, NULL, &out_sqlda)) {
1452                 _php_ibase_error(TSRMLS_C);
1453                 RETURN_FALSE;
1454         }
1455 
1456         /* don't return the generator value as a string unless it doesn't fit in a long */
1457 #if SIZEOF_LONG < 8
1458         if (result < LONG_MIN || result > LONG_MAX) {
1459                 char *res;
1460                 int l;
1461 
1462                 l = spprintf(&res, 0, "%" LL_MASK "d", result);
1463                 RETURN_STRINGL(res, l, 0);
1464         }
1465 #endif
1466         RETURN_LONG((long)result);
1467 }
1468 
1469 /* }}} */
1470     
1471 #endif /* HAVE_IBASE */
1472 
1473 /*
1474  * Local variables:
1475  * tab-width: 4
1476  * c-basic-offset: 4
1477  * End:
1478  * vim600: sw=4 ts=4 fdm=marker
1479  * vim<600: sw=4 ts=4
1480  */

/* [<][>][^][v][top][bottom][index][help] */