PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/interbase - interbase.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 384 472 81.4 %
Date: 2017-09-08 Functions: 27 30 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2017 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==NULL) { php_error_docref(NULL, 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             :         PHP_INTERBASE_VERSION,
     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             : #ifdef ZTS
     464             : ZEND_TSRMLS_CACHE_DEFINE()
     465             : #endif
     466             : ZEND_GET_MODULE(ibase)
     467             : #endif
     468             : 
     469             : /* True globals, no need for thread safety */
     470             : int le_link, le_plink, le_trans;
     471             : 
     472             : /* }}} */
     473             : 
     474             : /* error handling ---------------------------- */
     475             : 
     476             : /* {{{ proto string ibase_errmsg(void)
     477             :    Return error message */
     478           3 : PHP_FUNCTION(ibase_errmsg)
     479             : {
     480           3 :         if (zend_parse_parameters_none() == FAILURE) {
     481           0 :                 return;
     482             :         }
     483             : 
     484           3 :         if (IBG(sql_code) != 0) {
     485           4 :                 RETURN_STRING(IBG(errmsg));
     486             :         }
     487             : 
     488           1 :         RETURN_FALSE;
     489             : }
     490             : /* }}} */
     491             : 
     492             : /* {{{ proto int ibase_errcode(void)
     493             :    Return error code */
     494           0 : PHP_FUNCTION(ibase_errcode)
     495             : {
     496           0 :         if (zend_parse_parameters_none() == FAILURE) {
     497           0 :                 return;
     498             :         }
     499             : 
     500           0 :         if (IBG(sql_code) != 0) {
     501           0 :                 RETURN_LONG(IBG(sql_code));
     502             :         }
     503           0 :         RETURN_FALSE;
     504             : }
     505             : /* }}} */
     506             : 
     507             : /* print interbase error and save it for ibase_errmsg() */
     508           9 : void _php_ibase_error(void) /* {{{ */
     509             : {
     510           9 :         char *s = IBG(errmsg);
     511           9 :         const ISC_STATUS *statusp = IB_STATUS;
     512             : 
     513           9 :         IBG(sql_code) = isc_sqlcode(IB_STATUS);
     514             : 
     515          45 :         while ((s - IBG(errmsg)) < MAX_ERRMSG && fb_interpret(s, MAX_ERRMSG - strlen(IBG(errmsg)) - 1, &statusp)) {
     516          27 :                 strcat(IBG(errmsg), " ");
     517          27 :                 s = IBG(errmsg) + strlen(IBG(errmsg));
     518             :         }
     519             : 
     520           9 :         php_error_docref(NULL, E_WARNING, "%s", IBG(errmsg));
     521           9 : }
     522             : /* }}} */
     523             : 
     524             : /* print php interbase module error and save it for ibase_errmsg() */
     525           4 : void _php_ibase_module_error(char *msg, ...) /* {{{ */
     526             : {
     527             :         va_list ap;
     528             : 
     529           4 :         va_start(ap, msg);
     530             : 
     531             :         /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
     532           4 :         vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap);
     533           4 :         va_end(ap);
     534             : 
     535           4 :         IBG(sql_code) = -999; /* no SQL error */
     536             : 
     537           4 :         php_error_docref(NULL, E_WARNING, "%s", IBG(errmsg));
     538           4 : }
     539             : /* }}} */
     540             : 
     541             : /* {{{ internal macros, functions and structures */
     542             : typedef struct {
     543             :         isc_db_handle *db_ptr;
     544             :         zend_long tpb_len;
     545             :         char *tpb_ptr;
     546             : } ISC_TEB;
     547             : 
     548             : /* }}} */
     549             : 
     550             : /* Fill ib_link and trans with the correct database link and transaction. */
     551         147 : void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */
     552             :         zval *link_id, ibase_db_link **ib_link, ibase_trans **trans)
     553             : {
     554             :         IBDEBUG("Transaction or database link?");
     555         147 :         if (Z_RES_P(link_id)->type == le_trans) {
     556             :                 /* Transaction resource: make sure it refers to one link only, then
     557             :                    fetch it; database link is stored in ib_trans->db_link[]. */
     558             :                 IBDEBUG("Type is le_trans");
     559         128 :                 *trans = (ibase_trans *)zend_fetch_resource_ex(link_id, LE_TRANS, le_trans);
     560         128 :                 if ((*trans)->link_cnt > 1) {
     561           0 :                         _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
     562             :                                 );
     563           0 :                         return;
     564             :                 }
     565         128 :                 *ib_link = (*trans)->db_link[0];
     566         128 :                 return;
     567             :         }
     568             :         IBDEBUG("Type is le_[p]link or id not found");
     569             :         /* Database link resource, use default transaction. */
     570          19 :         *trans = NULL;
     571          19 :         *ib_link = (ibase_db_link *)zend_fetch_resource2_ex(link_id, LE_LINK, le_link, le_plink);
     572             : }
     573             : /* }}} */
     574             : 
     575             : /* destructors ---------------------- */
     576             : 
     577         172 : static void _php_ibase_commit_link(ibase_db_link *link) /* {{{ */
     578             : {
     579         172 :         unsigned short i = 0, j;
     580             :         ibase_tr_list *l;
     581             :         ibase_event *e;
     582             :         IBDEBUG("Checking transactions to close...");
     583             : 
     584         267 :         for (l = link->tr_list; l != NULL; ++i) {
     585          95 :                 ibase_tr_list *p = l;
     586          95 :                 if (p->trans != 0) {
     587          34 :                         if (i == 0) {
     588          22 :                                 if (p->trans->handle != 0) {
     589             :                                         IBDEBUG("Committing default transaction...");
     590          17 :                                         if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) {
     591           0 :                                                 _php_ibase_error();
     592             :                                         }
     593             :                                 }
     594          22 :                                 efree(p->trans); /* default transaction is not a registered resource: clean up */
     595             :                         } else {
     596          12 :                                 if (p->trans->handle != 0) {
     597             :                                         /* non-default trans might have been rolled back by other call of this dtor */
     598             :                                         IBDEBUG("Rolling back other transactions...");
     599           8 :                                         if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) {
     600           0 :                                                 _php_ibase_error();
     601             :                                         }
     602             :                                 }
     603             :                                 /* set this link pointer to NULL in the transaction */
     604          13 :                                 for (j = 0; j < p->trans->link_cnt; ++j) {
     605          13 :                                         if (p->trans->db_link[j] == link) {
     606          12 :                                                 p->trans->db_link[j] = NULL;
     607          12 :                                                 break;
     608             :                                         }
     609             :                                 }
     610             :                         }
     611             :                 }
     612          95 :                 l = l->next;
     613          95 :                 efree(p);
     614             :         }
     615         172 :         link->tr_list = NULL;
     616             : 
     617         177 :         for (e = link->event_head; e; e = e->event_next) {
     618           5 :                 _php_ibase_free_event(e);
     619           5 :                 e->link = NULL;
     620             :         }
     621         172 : }
     622             : 
     623             : /* }}} */
     624             : 
     625           6 : static void php_ibase_commit_link_rsrc(zend_resource *rsrc) /* {{{ */
     626             : {
     627           6 :         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
     628             : 
     629           6 :         _php_ibase_commit_link(link);
     630           6 : }
     631             : /* }}} */
     632             : 
     633         164 : static void _php_ibase_close_link(zend_resource *rsrc) /* {{{ */
     634             : {
     635         164 :         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
     636             : 
     637         164 :         _php_ibase_commit_link(link);
     638         164 :         if (link->handle != 0) {
     639             :                 IBDEBUG("Closing normal link...");
     640         109 :                 isc_detach_database(IB_STATUS, &link->handle);
     641             :         }
     642         164 :         IBG(num_links)--;
     643         164 :         efree(link);
     644         164 : }
     645             : /* }}} */
     646             : 
     647           2 : static void _php_ibase_close_plink(zend_resource *rsrc) /* {{{ */
     648             : {
     649           2 :         ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
     650             : 
     651           2 :         _php_ibase_commit_link(link);
     652             :         IBDEBUG("Closing permanent link...");
     653           2 :         if (link->handle != 0) {
     654           0 :                 isc_detach_database(IB_STATUS, &link->handle);
     655             :         }
     656           2 :         IBG(num_persistent)--;
     657           2 :         IBG(num_links)--;
     658           2 :         free(link);
     659           2 : }
     660             : /* }}} */
     661             : 
     662          70 : static void _php_ibase_free_trans(zend_resource *rsrc) /* {{{ */
     663             : {
     664          70 :         ibase_trans *trans = (ibase_trans *)rsrc->ptr;
     665             :         unsigned short i;
     666             : 
     667             :         IBDEBUG("Cleaning up transaction resource...");
     668          70 :         if (trans->handle != 0) {
     669             :                 IBDEBUG("Rolling back unhandled transaction...");
     670           0 :                 if (isc_rollback_transaction(IB_STATUS, &trans->handle)) {
     671           0 :                         _php_ibase_error();
     672             :                 }
     673             :         }
     674             : 
     675             :         /* now remove this transaction from all the connection-transaction lists */
     676         141 :         for (i = 0; i < trans->link_cnt; ++i) {
     677          71 :                 if (trans->db_link[i] != NULL) {
     678             :                         ibase_tr_list **l;
     679         118 :                         for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) {
     680         118 :                                 if ( (*l)->trans == trans) {
     681          59 :                                         ibase_tr_list *p = *l;
     682          59 :                                         *l = p->next;
     683          59 :                                         efree(p);
     684          59 :                                         break;
     685             :                                 }
     686             :                         }
     687             :                 }
     688             :         }
     689          70 :         efree(trans);
     690          70 : }
     691             : /* }}} */
     692             : 
     693             : /* TODO this function should be part of either Zend or PHP API */
     694         292 : static PHP_INI_DISP(php_ibase_password_displayer_cb)
     695             : {
     696             : 
     697         438 :         if ((type == PHP_INI_DISPLAY_ORIG && ini_entry->orig_value)
     698         146 :                         || (type == PHP_INI_DISPLAY_ACTIVE && ini_entry->value)) {
     699           0 :                 PUTS("********");
     700         292 :         } else if (!sapi_module.phpinfo_as_text) {
     701           2 :                 PUTS("<i>no value</i>");
     702             :         } else {
     703         290 :                 PUTS("no value");
     704             :         }
     705         292 : }
     706             : 
     707             : /* {{{ startup, shutdown and info functions */
     708             : PHP_INI_BEGIN()
     709             :         PHP_INI_ENTRY_EX("ibase.allow_persistent", "1", PHP_INI_SYSTEM, NULL, zend_ini_boolean_displayer_cb)
     710             :         PHP_INI_ENTRY_EX("ibase.max_persistent", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
     711             :         PHP_INI_ENTRY_EX("ibase.max_links", "-1", PHP_INI_SYSTEM, NULL, display_link_numbers)
     712             :         PHP_INI_ENTRY("ibase.default_db", NULL, PHP_INI_SYSTEM, NULL)
     713             :         PHP_INI_ENTRY("ibase.default_user", NULL, PHP_INI_ALL, NULL)
     714             :         PHP_INI_ENTRY_EX("ibase.default_password", NULL, PHP_INI_ALL, NULL, php_ibase_password_displayer_cb)
     715             :         PHP_INI_ENTRY("ibase.default_charset", NULL, PHP_INI_ALL, NULL)
     716             :         PHP_INI_ENTRY("ibase.timestampformat", IB_DEF_DATE_FMT " " IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
     717             :         PHP_INI_ENTRY("ibase.dateformat", IB_DEF_DATE_FMT, PHP_INI_ALL, NULL)
     718             :         PHP_INI_ENTRY("ibase.timeformat", IB_DEF_TIME_FMT, PHP_INI_ALL, NULL)
     719             : PHP_INI_END()
     720             : 
     721       24608 : static PHP_GINIT_FUNCTION(ibase)
     722             : {
     723             : #if defined(COMPILE_DL_INTERBASE) && defined(ZTS)
     724             :         ZEND_TSRMLS_CACHE_UPDATE();
     725             : #endif
     726       24608 :         ibase_globals->num_persistent = ibase_globals->num_links = 0;
     727       24608 :         ibase_globals->sql_code = *ibase_globals->errmsg = 0;
     728       24608 :         ibase_globals->default_link = NULL;
     729       24608 : }
     730             : 
     731       24608 : PHP_MINIT_FUNCTION(ibase)
     732             : {
     733       24608 :         REGISTER_INI_ENTRIES();
     734             : 
     735       24608 :         le_link = zend_register_list_destructors_ex(_php_ibase_close_link, NULL, LE_LINK, module_number);
     736       24608 :         le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, LE_PLINK, module_number);
     737       24608 :         le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, LE_TRANS, module_number);
     738             : 
     739       24608 :         REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT);
     740       24608 :         REGISTER_LONG_CONSTANT("IBASE_CREATE", PHP_IBASE_CREATE, CONST_PERSISTENT);
     741       24608 :         REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */
     742       24608 :         REGISTER_LONG_CONSTANT("IBASE_FETCH_BLOBS", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT);
     743       24608 :         REGISTER_LONG_CONSTANT("IBASE_FETCH_ARRAYS", PHP_IBASE_FETCH_ARRAYS, CONST_PERSISTENT);
     744       24608 :         REGISTER_LONG_CONSTANT("IBASE_UNIXTIME", PHP_IBASE_UNIXTIME, CONST_PERSISTENT);
     745             : 
     746             :         /* transactions */
     747       24608 :         REGISTER_LONG_CONSTANT("IBASE_WRITE", PHP_IBASE_WRITE, CONST_PERSISTENT);
     748       24608 :         REGISTER_LONG_CONSTANT("IBASE_READ", PHP_IBASE_READ, CONST_PERSISTENT);
     749       24608 :         REGISTER_LONG_CONSTANT("IBASE_COMMITTED", PHP_IBASE_COMMITTED, CONST_PERSISTENT);
     750       24608 :         REGISTER_LONG_CONSTANT("IBASE_CONSISTENCY", PHP_IBASE_CONSISTENCY, CONST_PERSISTENT);
     751       24608 :         REGISTER_LONG_CONSTANT("IBASE_CONCURRENCY", PHP_IBASE_CONCURRENCY, CONST_PERSISTENT);
     752       24608 :         REGISTER_LONG_CONSTANT("IBASE_REC_VERSION", PHP_IBASE_REC_VERSION, CONST_PERSISTENT);
     753       24608 :         REGISTER_LONG_CONSTANT("IBASE_REC_NO_VERSION", PHP_IBASE_REC_NO_VERSION, CONST_PERSISTENT);
     754       24608 :         REGISTER_LONG_CONSTANT("IBASE_NOWAIT", PHP_IBASE_NOWAIT, CONST_PERSISTENT);
     755       24608 :         REGISTER_LONG_CONSTANT("IBASE_WAIT", PHP_IBASE_WAIT, CONST_PERSISTENT);
     756             : 
     757       24608 :         php_ibase_query_minit(INIT_FUNC_ARGS_PASSTHRU);
     758       24608 :         php_ibase_blobs_minit(INIT_FUNC_ARGS_PASSTHRU);
     759       24608 :         php_ibase_events_minit(INIT_FUNC_ARGS_PASSTHRU);
     760       24608 :         php_ibase_service_minit(INIT_FUNC_ARGS_PASSTHRU);
     761             : 
     762       24608 :         return SUCCESS;
     763             : }
     764             : 
     765       24653 : PHP_MSHUTDOWN_FUNCTION(ibase)
     766             : {
     767             : #ifndef PHP_WIN32
     768             :         /**
     769             :          * When the Interbase client API library libgds.so is first loaded, it registers a call to
     770             :          * gds__cleanup() with atexit(), in order to clean up after itself when the process exits.
     771             :          * This means that the library is called at process shutdown, and cannot be unloaded beforehand.
     772             :          * PHP tries to unload modules after every request [dl()'ed modules], and right before the
     773             :          * process shuts down [modules loaded from php.ini]. This results in a segfault for this module.
     774             :          * By NULLing the dlopen() handle in the module entry, Zend omits the call to dlclose(),
     775             :          * ensuring that the module will remain present until the process exits. However, the functions
     776             :          * and classes exported by the module will not be available until the module is 'reloaded'.
     777             :          * When reloaded, dlopen() will return the handle of the already loaded module. The module will
     778             :          * be unloaded automatically when the process exits.
     779             :          */
     780             :         zend_module_entry *ibase_entry;
     781       49306 :         if ((ibase_entry = zend_hash_str_find_ptr(&module_registry, ibase_module_entry.name,
     782             :                         strlen(ibase_module_entry.name))) != NULL) {
     783           0 :                 ibase_entry->handle = 0;
     784             :         }
     785             : #endif
     786       24653 :         UNREGISTER_INI_ENTRIES();
     787       24653 :         return SUCCESS;
     788             : }
     789             : 
     790       24598 : PHP_RSHUTDOWN_FUNCTION(ibase)
     791             : {
     792       24598 :         IBG(num_links) = IBG(num_persistent);
     793       24598 :         IBG(default_link)= NULL;
     794             : 
     795       24598 :         RESET_ERRMSG;
     796             : 
     797       24598 :         return SUCCESS;
     798             : }
     799             : 
     800         146 : PHP_MINFO_FUNCTION(ibase)
     801             : {
     802             :         char tmp[64], *s;
     803             : 
     804         146 :         php_info_print_table_start();
     805         146 :         php_info_print_table_row(2, "Firebird/InterBase Support",
     806             : #ifdef COMPILE_DL_INTERBASE
     807             :                 "dynamic");
     808             : #else
     809             :                 "static");
     810             : #endif
     811             : 
     812             : #ifdef FB_API_VER
     813         146 :         snprintf( (s = tmp), sizeof(tmp), "Firebird API version %d", FB_API_VER);
     814             : #elif (SQLDA_CURRENT_VERSION > 1)
     815             :         s =  "Interbase 7.0 and up";
     816             : #endif
     817         146 :         php_info_print_table_row(2, "Compile-time Client Library Version", s);
     818             : 
     819             : #if defined(__GNUC__) || defined(PHP_WIN32)
     820             :         do {
     821         146 :                 info_func_t info_func = NULL;
     822             : #ifdef __GNUC__
     823         146 :                 info_func = (info_func_t)dlsym(RTLD_DEFAULT, "isc_get_client_version");
     824             : #else
     825             :                 HMODULE l = GetModuleHandle("fbclient");
     826             : 
     827             :                 if (!l && !(l = GetModuleHandle("gds32"))) {
     828             :                         break;
     829             :                 }
     830             :                 info_func = (info_func_t)GetProcAddress(l, "isc_get_client_version");
     831             : #endif
     832         146 :                 if (info_func) {
     833         146 :                         info_func(s = tmp);
     834             :                 }
     835         146 :                 php_info_print_table_row(2, "Run-time Client Library Version", s);
     836             : #ifdef PHP_WIN32
     837             :                 FreeLibrary(l);
     838             : #endif
     839             :         } while (0);
     840             : #endif
     841         146 :         php_info_print_table_end();
     842             : 
     843         146 :         DISPLAY_INI_ENTRIES();
     844             : 
     845         146 : }
     846             : /* }}} */
     847             : 
     848             : enum connect_args { DB = 0, USER = 1, PASS = 2, CSET = 3, ROLE = 4, BUF = 0, DLECT = 1, SYNC = 2 };
     849             : 
     850             : static char const dpb_args[] = {
     851             :         0, isc_dpb_user_name, isc_dpb_password, isc_dpb_lc_ctype, isc_dpb_sql_role_name, 0
     852             : };
     853             : 
     854         107 : int _php_ibase_attach_db(char **args, size_t *len, zend_long *largs, isc_db_handle *db) /* {{{ */
     855             : {
     856         107 :         short i, dpb_len, buf_len = 257-2;  /* version byte at the front, and a null at the end */
     857         107 :         char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb;
     858             : 
     859         107 :         dpb = dpb_buffer + 1;
     860             : 
     861         749 :         for (i = 0; i < sizeof(dpb_args); ++i) {
     862         642 :                 if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
     863         214 :                         dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
     864         214 :                         dpb += dpb_len;
     865         214 :                         buf_len -= dpb_len;
     866             :                 }
     867             :         }
     868         107 :         if (largs[BUF] && buf_len > 0) {
     869           0 :                 dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers,
     870           0 :                         (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
     871           0 :                 dpb += dpb_len;
     872           0 :                 buf_len -= dpb_len;
     873             :         }
     874         107 :         if (largs[SYNC] && buf_len > 0) {
     875           0 :                 dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync ? 1 : 0);
     876           0 :                 dpb += dpb_len;
     877           0 :                 buf_len -= dpb_len;
     878             :         }
     879         107 :         if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
     880           0 :                 _php_ibase_error();
     881           0 :                 return FAILURE;
     882             :         }
     883         107 :         return SUCCESS;
     884             : }
     885             : /* }}} */
     886             : 
     887         111 : static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */
     888             : {
     889         111 :         char *c, hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL };
     890             :         int i;
     891         111 :         size_t len[] = { 0, 0, 0, 0, 0 };
     892         111 :         zend_long largs[] = { 0, 0, 0 };
     893             :         PHP_MD5_CTX hash_context;
     894             :         zend_resource new_index_ptr, *le;
     895         111 :         isc_db_handle db_handle = 0;
     896             :         ibase_db_link *ib_link;
     897             : 
     898         111 :         RESET_ERRMSG;
     899             : 
     900         111 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "|ssssllsl",
     901             :                         &args[DB], &len[DB], &args[USER], &len[USER], &args[PASS], &len[PASS],
     902             :                         &args[CSET], &len[CSET], &largs[BUF], &largs[DLECT], &args[ROLE], &len[ROLE],
     903             :                         &largs[SYNC])) {
     904           0 :                 RETURN_FALSE;
     905             :         }
     906             : 
     907             :         /* restrict to the server/db in the .ini if in safe mode */
     908         111 :         if (!len[DB] && (c = INI_STR("ibase.default_db"))) {
     909           0 :                 args[DB] = c;
     910           0 :                 len[DB] = strlen(c);
     911             :         }
     912         111 :         if (!len[USER] && (c = INI_STR("ibase.default_user"))) {
     913         111 :                 args[USER] = c;
     914         111 :                 len[USER] = strlen(c);
     915             :         }
     916         111 :         if (!len[PASS] && (c = INI_STR("ibase.default_password"))) {
     917         111 :                 args[PASS] = c;
     918         111 :                 len[PASS] = strlen(c);
     919             :         }
     920         111 :         if (!len[CSET] && (c = INI_STR("ibase.default_charset"))) {
     921           0 :                 args[CSET] = c;
     922           0 :                 len[CSET] = strlen(c);
     923             :         }
     924             : 
     925             :         /* don't want usernames and passwords floating around */
     926         111 :         PHP_MD5Init(&hash_context);
     927         666 :         for (i = 0; i < sizeof(args)/sizeof(char*); ++i) {
     928         555 :                 PHP_MD5Update(&hash_context,args[i],len[i]);
     929             :         }
     930         444 :         for (i = 0; i < sizeof(largs)/sizeof(zend_long); ++i) {
     931         333 :                 PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(zend_long));
     932             :         }
     933         111 :         PHP_MD5Final((unsigned char*)hash, &hash_context);
     934             : 
     935             :         /* try to reuse a connection */
     936         111 :         if ((le = zend_hash_str_find_ptr(&EG(regular_list), hash, sizeof(hash)-1)) != NULL) {
     937             :                 zend_resource *xlink;
     938             : 
     939          53 :                 if (le->type != le_index_ptr) {
     940           0 :                         RETURN_FALSE;
     941             :                 }
     942             : 
     943          53 :                 xlink = (zend_resource*) le->ptr;
     944          92 :                 if ((!persistent && xlink->type == le_link) || xlink->type == le_plink) {
     945          39 :                         if (IBG(default_link)) {
     946          39 :                                 zend_list_close(IBG(default_link));
     947             :                         }
     948          39 :                         xlink->gc.refcount++;
     949          39 :                         xlink->gc.refcount++;
     950          39 :                         IBG(default_link) = xlink;
     951          39 :                         RETVAL_RES(xlink);
     952             :                 } else {
     953          14 :                         zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1);
     954             :                 }
     955             :         }
     956             : 
     957             :         /* ... or a persistent one */
     958             :         do {
     959             :                 zend_long l;
     960             :                 static char info[] = { isc_info_base_level, isc_info_end };
     961             :                 char result[8];
     962             :                 ISC_STATUS status[20];
     963             : 
     964         111 :                 if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hash, sizeof(hash)-1)) != NULL) {
     965           4 :                         if (le->type != le_plink) {
     966           0 :                                 RETURN_FALSE;
     967             :                         }
     968             :                         /* check if connection has timed out */
     969           4 :                         ib_link = (ibase_db_link *) le->ptr;
     970           4 :                         if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
     971           4 :                                 RETVAL_RES(zend_register_resource(ib_link, le_plink));
     972           4 :                                 break;
     973             :                         }
     974           0 :                         zend_hash_str_del(&EG(persistent_list), hash, sizeof(hash)-1);
     975             :                 }
     976             : 
     977             :                 /* no link found, so we have to open one */
     978             : 
     979         107 :                 if ((l = INI_INT("ibase.max_links")) != -1 && IBG(num_links) >= l) {
     980           0 :                         _php_ibase_module_error("Too many open links (%ld)", IBG(num_links));
     981           0 :                         RETURN_FALSE;
     982             :                 }
     983             : 
     984             :                 /* create the ib_link */
     985         107 :                 if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle)) {
     986           0 :                         RETURN_FALSE;
     987             :                 }
     988             : 
     989             :                 /* use non-persistent if allowed number of persistent links is exceeded */
     990         212 :                 if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
     991         105 :                         ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
     992         105 :                         RETVAL_RES(zend_register_resource(ib_link, le_link));
     993             :                 } else {
     994             :                         zend_resource new_le;
     995             : 
     996           2 :                         ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
     997           2 :                         if (!ib_link) {
     998           0 :                                 RETURN_FALSE;
     999             :                         }
    1000             : 
    1001             :                         /* hash it up */
    1002           2 :                         new_le.type = le_plink;
    1003           2 :                         new_le.ptr = ib_link;
    1004           2 :                         if (zend_hash_str_update_mem(&EG(persistent_list), hash, sizeof(hash)-1,
    1005             :                                         (void *) &new_le, sizeof(zend_resource)) == NULL) {
    1006           0 :                                 free(ib_link);
    1007           0 :                                 RETURN_FALSE;
    1008             :                         }
    1009           2 :                         RETVAL_RES(zend_register_resource(ib_link, le_plink));
    1010           2 :                         ++IBG(num_persistent);
    1011             :                 }
    1012         107 :                 ib_link->handle = db_handle;
    1013         107 :                 ib_link->dialect = largs[DLECT] ? (unsigned short)largs[DLECT] : SQL_DIALECT_CURRENT;
    1014         107 :                 ib_link->tr_list = NULL;
    1015         107 :                 ib_link->event_head = NULL;
    1016             : 
    1017         107 :                 ++IBG(num_links);
    1018             :         } while (0);
    1019             : 
    1020             :         /* add it to the hash */
    1021         111 :         new_index_ptr.ptr = (void *) Z_RES_P(return_value);
    1022         111 :         new_index_ptr.type = le_index_ptr;
    1023         111 :         if (zend_hash_str_update_mem(&EG(regular_list), hash, sizeof(hash)-1,
    1024             :                         (void *) &new_index_ptr, sizeof(zend_resource)) == NULL) {
    1025           0 :                 RETURN_FALSE;
    1026             :         }
    1027         111 :         if (IBG(default_link)) {
    1028          97 :                 zend_list_delete(IBG(default_link));
    1029             :         }
    1030         111 :         IBG(default_link) = Z_RES_P(return_value);
    1031         111 :         Z_TRY_ADDREF_P(return_value);
    1032         111 :         Z_TRY_ADDREF_P(return_value);
    1033             : }
    1034             : /* }}} */
    1035             : 
    1036             : /* {{{ proto resource ibase_connect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
    1037             :    Open a connection to an InterBase database */
    1038         107 : PHP_FUNCTION(ibase_connect)
    1039             : {
    1040         107 :         _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    1041         107 : }
    1042             : /* }}} */
    1043             : 
    1044             : /* {{{ proto resource ibase_pconnect(string database [, string username [, string password [, string charset [, int buffers [, int dialect [, string role]]]]]])
    1045             :    Open a persistent connection to an InterBase database */
    1046           4 : PHP_FUNCTION(ibase_pconnect)
    1047             : {
    1048           4 :         _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INI_INT("ibase.allow_persistent"));
    1049           4 : }
    1050             : /* }}} */
    1051             : 
    1052             : /* {{{ proto bool ibase_close([resource link_identifier])
    1053             :    Close an InterBase connection */
    1054          82 : PHP_FUNCTION(ibase_close)
    1055             : {
    1056          82 :         zval *link_arg = NULL;
    1057             :         zend_resource *link_res;
    1058             : 
    1059          82 :         RESET_ERRMSG;
    1060             : 
    1061          82 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &link_arg) == FAILURE) {
    1062           1 :                 return;
    1063             :         }
    1064             : 
    1065          81 :         if (ZEND_NUM_ARGS() == 0) {
    1066          14 :                 link_res = IBG(default_link);
    1067          14 :                 CHECK_LINK(link_res);
    1068          14 :                 IBG(default_link) = NULL;
    1069             :         } else {
    1070          67 :                 link_res = Z_RES_P(link_arg);
    1071             :         }
    1072             : 
    1073             :         /* we have at least 3 additional references to this resource ??? */
    1074          81 :         if (GC_REFCOUNT(link_res) < 4) {
    1075          16 :                 zend_list_close(link_res);
    1076             :         } else {
    1077          65 :                 zend_list_delete(link_res);
    1078             :         }
    1079          81 :         RETURN_TRUE;
    1080             : }
    1081             : /* }}} */
    1082             : 
    1083             : /* {{{ proto bool ibase_drop_db([resource link_identifier])
    1084             :    Drop an InterBase database */
    1085          61 : PHP_FUNCTION(ibase_drop_db)
    1086             : {
    1087          61 :         zval *link_arg = NULL;
    1088             :         ibase_db_link *ib_link;
    1089             :         ibase_tr_list *l;
    1090             :         zend_resource *link_res;
    1091             : 
    1092          61 :         RESET_ERRMSG;
    1093             : 
    1094          61 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &link_arg) == FAILURE) {
    1095           2 :                 return;
    1096             :         }
    1097             : 
    1098          59 :         if (ZEND_NUM_ARGS() == 0) {
    1099           0 :                 link_res = IBG(default_link);
    1100           0 :                 CHECK_LINK(link_res);
    1101           0 :                 IBG(default_link) = NULL;
    1102             :         } else {
    1103          59 :                 link_res = Z_RES_P(link_arg);
    1104             :         }
    1105             : 
    1106          59 :         ib_link = (ibase_db_link *)zend_fetch_resource2(link_res, LE_LINK, le_link, le_plink);
    1107             : 
    1108          59 :         if (!ib_link) {
    1109           0 :                 RETURN_FALSE;
    1110             :         }
    1111             : 
    1112          59 :         if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
    1113           2 :                 _php_ibase_error();
    1114           2 :                 RETURN_FALSE;
    1115             :         }
    1116             : 
    1117             :         /* isc_drop_database() doesn't invalidate the transaction handles */
    1118          57 :         for (l = ib_link->tr_list; l != NULL; l = l->next) {
    1119           0 :                 if (l->trans != NULL) l->trans->handle = 0;
    1120             :         }
    1121             : 
    1122          57 :         zend_list_delete(link_res);
    1123             : 
    1124          57 :         RETURN_TRUE;
    1125             : }
    1126             : /* }}} */
    1127             : 
    1128             : /* {{{ proto resource ibase_trans([int trans_args [, resource link_identifier [, ... ], int trans_args [, resource link_identifier [, ... ]] [, ...]]])
    1129             :    Start a transaction over one or several databases */
    1130             : 
    1131             : #define TPB_MAX_SIZE (8*sizeof(char))
    1132             : 
    1133          72 : PHP_FUNCTION(ibase_trans)
    1134             : {
    1135          72 :         unsigned short i, link_cnt = 0, tpb_len = 0;
    1136             :         int argn;
    1137             :         char last_tpb[TPB_MAX_SIZE];
    1138          72 :         ibase_db_link **ib_link = NULL;
    1139             :         ibase_trans *ib_trans;
    1140          72 :         isc_tr_handle tr_handle = 0;
    1141             :         ISC_STATUS result;
    1142             : 
    1143          72 :         RESET_ERRMSG;
    1144             : 
    1145          72 :         argn = ZEND_NUM_ARGS();
    1146             : 
    1147             :         /* (1+argn) is an upper bound for the number of links this trans connects to */
    1148          72 :         ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0);
    1149             : 
    1150          72 :         if (argn > 0) {
    1151          70 :                 zend_long trans_argl = 0;
    1152             :                 char *tpb;
    1153             :                 ISC_TEB *teb;
    1154          70 :                 zval *args = NULL;
    1155             : 
    1156          70 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argn) == FAILURE) {
    1157           0 :                         efree(ib_link);
    1158           0 :                         RETURN_FALSE;
    1159             :                 }
    1160             : 
    1161          70 :                 teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0);
    1162          70 :                 tpb = (char *) safe_emalloc(TPB_MAX_SIZE,argn,0);
    1163             : 
    1164             :                 /* enumerate all the arguments: assume every non-resource argument
    1165             :                    specifies modifiers for the link ids that follow it */
    1166         146 :                 for (i = 0; i < argn; ++i) {
    1167             : 
    1168         154 :                         if (Z_TYPE(args[i]) == IS_RESOURCE) {
    1169             : 
    1170          65 :                                 if ((ib_link[link_cnt] = (ibase_db_link *)zend_fetch_resource2_ex(&args[i], LE_LINK, le_link, le_plink)) == NULL) {
    1171           1 :                                         efree(teb);
    1172           1 :                                         efree(tpb);
    1173           1 :                                         efree(ib_link);
    1174           1 :                                         RETURN_FALSE;
    1175             :                                 }
    1176             : 
    1177             :                                 /* copy the most recent modifier string into tbp[] */
    1178          64 :                                 memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, TPB_MAX_SIZE);
    1179             : 
    1180             :                                 /* add a database handle to the TEB with the most recently specified set of modifiers */
    1181          64 :                                 teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle;
    1182          64 :                                 teb[link_cnt].tpb_len = tpb_len;
    1183          64 :                                 teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
    1184             : 
    1185          64 :                                 ++link_cnt;
    1186             : 
    1187             :                         } else {
    1188             : 
    1189          12 :                                 tpb_len = 0;
    1190             : 
    1191          24 :                                 convert_to_long_ex(&args[i]);
    1192          12 :                                 trans_argl = Z_LVAL(args[i]);
    1193             : 
    1194          12 :                                 if (trans_argl != PHP_IBASE_DEFAULT) {
    1195           9 :                                         last_tpb[tpb_len++] = isc_tpb_version3;
    1196             : 
    1197             :                                         /* access mode */
    1198           9 :                                         if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) {
    1199           5 :                                                 last_tpb[tpb_len++] = isc_tpb_read;
    1200           4 :                                         } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) {
    1201           3 :                                                 last_tpb[tpb_len++] = isc_tpb_write;
    1202             :                                         }
    1203             : 
    1204             :                                         /* isolation level */
    1205           9 :                                         if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) {
    1206           3 :                                                 last_tpb[tpb_len++] = isc_tpb_read_committed;
    1207           3 :                                                 if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) {
    1208           1 :                                                         last_tpb[tpb_len++] = isc_tpb_rec_version;
    1209           2 :                                                 } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) {
    1210           1 :                                                         last_tpb[tpb_len++] = isc_tpb_no_rec_version;
    1211             :                                                 }
    1212           6 :                                         } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) {
    1213           0 :                                                 last_tpb[tpb_len++] = isc_tpb_consistency;
    1214           6 :                                         } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) {
    1215           0 :                                                 last_tpb[tpb_len++] = isc_tpb_concurrency;
    1216             :                                         }
    1217             : 
    1218             :                                         /* lock resolution */
    1219           9 :                                         if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) {
    1220           1 :                                                 last_tpb[tpb_len++] = isc_tpb_nowait;
    1221           8 :                                         } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) {
    1222           1 :                                                 last_tpb[tpb_len++] = isc_tpb_wait;
    1223             :                                         }
    1224             :                                 }
    1225             :                         }
    1226             :                 }
    1227             : 
    1228          69 :                 if (link_cnt > 0) {
    1229          63 :                         result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb);
    1230             :                 }
    1231             : 
    1232          69 :                 efree(tpb);
    1233          69 :                 efree(teb);
    1234             :         }
    1235             : 
    1236          71 :         if (link_cnt == 0) {
    1237           8 :                 link_cnt = 1;
    1238           8 :                 if ((ib_link[0] = (ibase_db_link *)zend_fetch_resource2(IBG(default_link), LE_LINK, le_link, le_plink)) == NULL) {
    1239           3 :                         efree(ib_link);
    1240           3 :                         RETURN_FALSE;
    1241             :                 }
    1242           5 :                 result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb);
    1243             :         }
    1244             : 
    1245             :         /* start the transaction */
    1246          68 :         if (result) {
    1247           0 :                 _php_ibase_error();
    1248           0 :                 efree(ib_link);
    1249           0 :                 RETURN_FALSE;
    1250             :         }
    1251             : 
    1252             :         /* register the transaction in our own data structures */
    1253          68 :         ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans));
    1254          68 :         ib_trans->handle = tr_handle;
    1255          68 :         ib_trans->link_cnt = link_cnt;
    1256          68 :         ib_trans->affected_rows = 0;
    1257         137 :         for (i = 0; i < link_cnt; ++i) {
    1258             :                 ibase_tr_list **l;
    1259          69 :                 ib_trans->db_link[i] = ib_link[i];
    1260             : 
    1261             :                 /* the first item in the connection-transaction list is reserved for the default transaction */
    1262          69 :                 if (ib_link[i]->tr_list == NULL) {
    1263          63 :                         ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
    1264          63 :                         ib_link[i]->tr_list->trans = NULL;
    1265          63 :                         ib_link[i]->tr_list->next = NULL;
    1266             :                 }
    1267             : 
    1268             :                 /* link the transaction into the connection-transaction list */
    1269          69 :                 for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next);
    1270          69 :                 *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
    1271          69 :                 (*l)->trans = ib_trans;
    1272          69 :                 (*l)->next = NULL;
    1273             :         }
    1274          68 :         efree(ib_link);
    1275          68 :         RETVAL_RES(zend_register_resource(ib_trans, le_trans));
    1276          68 :         Z_TRY_ADDREF_P(return_value);
    1277             : }
    1278             : /* }}} */
    1279             : 
    1280         279 : int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans) /* {{{ */
    1281             : {
    1282         279 :         if (ib_link == NULL) {
    1283           0 :                 php_error_docref(NULL, E_WARNING, "Invalid database link");
    1284           0 :                 return FAILURE;
    1285             :         }
    1286             : 
    1287             :         /* the first item in the connection-transaction list is reserved for the default transaction */
    1288         279 :         if (ib_link->tr_list == NULL) {
    1289          20 :                 ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
    1290          20 :                 ib_link->tr_list->trans = NULL;
    1291          20 :                 ib_link->tr_list->next = NULL;
    1292             :         }
    1293             : 
    1294         279 :         if (*trans == NULL) {
    1295         151 :                 ibase_trans *tr = ib_link->tr_list->trans;
    1296             : 
    1297         151 :                 if (tr == NULL) {
    1298          22 :                         tr = (ibase_trans *) emalloc(sizeof(ibase_trans));
    1299          22 :                         tr->handle = 0;
    1300          22 :                         tr->link_cnt = 1;
    1301          22 :                         tr->affected_rows = 0;
    1302          22 :                         tr->db_link[0] = ib_link;
    1303          22 :                         ib_link->tr_list->trans = tr;
    1304             :                 }
    1305         151 :                 if (tr->handle == 0) {
    1306          37 :                         if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) {
    1307           0 :                                 _php_ibase_error();
    1308           0 :                                 return FAILURE;
    1309             :                         }
    1310             :                 }
    1311         151 :                 *trans = tr;
    1312             :         }
    1313         279 :         return SUCCESS;
    1314             : }
    1315             : /* }}} */
    1316             : 
    1317         141 : static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */
    1318             : {
    1319         141 :         ibase_trans *trans = NULL;
    1320         141 :         int res_id = 0;
    1321             :         ISC_STATUS result;
    1322             :         ibase_db_link *ib_link;
    1323         141 :         zval *arg = NULL;
    1324             : 
    1325         141 :         RESET_ERRMSG;
    1326             : 
    1327         141 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|r", &arg) == FAILURE) {
    1328           0 :                 return;
    1329             :         }
    1330             : 
    1331         141 :         if (ZEND_NUM_ARGS() == 0) {
    1332          18 :                 ib_link = (ibase_db_link *)zend_fetch_resource2(IBG(default_link), LE_LINK, le_link, le_plink);
    1333          18 :                 if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
    1334             :                         /* this link doesn't have a default transaction */
    1335           0 :                         _php_ibase_module_error("Default link has no default transaction");
    1336           0 :                         RETURN_FALSE;
    1337             :                 }
    1338          18 :                 trans = ib_link->tr_list->trans;
    1339             :         } else {
    1340             :                 /* one id was passed, could be db or trans id */
    1341         123 :                 if (Z_RES_P(arg)->type == le_trans) {
    1342         120 :                         trans = (ibase_trans *)zend_fetch_resource_ex(arg, LE_TRANS, le_trans);
    1343         120 :                         res_id = Z_RES_P(arg)->handle;
    1344             :                 } else {
    1345           3 :                         ib_link = (ibase_db_link *)zend_fetch_resource2_ex(arg, LE_LINK, le_link, le_plink);
    1346             : 
    1347           3 :                         if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
    1348             :                                 /* this link doesn't have a default transaction */
    1349           0 :                                 _php_ibase_module_error("Link has no default transaction");
    1350           0 :                                 RETURN_FALSE;
    1351             :                         }
    1352           3 :                         trans = ib_link->tr_list->trans;
    1353             :                 }
    1354             :         }
    1355             : 
    1356         141 :         switch (commit) {
    1357             :                 default: /* == case ROLLBACK: */
    1358           6 :                         result = isc_rollback_transaction(IB_STATUS, &trans->handle);
    1359           6 :                         break;
    1360             :                 case COMMIT:
    1361          77 :                         result = isc_commit_transaction(IB_STATUS, &trans->handle);
    1362          77 :                         break;
    1363             :                 case (ROLLBACK | RETAIN):
    1364           0 :                         result = isc_rollback_retaining(IB_STATUS, &trans->handle);
    1365           0 :                         break;
    1366             :                 case (COMMIT | RETAIN):
    1367          58 :                         result = isc_commit_retaining(IB_STATUS, &trans->handle);
    1368             :                         break;
    1369             :         }
    1370             : 
    1371         141 :         if (result) {
    1372           1 :                 _php_ibase_error();
    1373           1 :                 RETURN_FALSE;
    1374             :         }
    1375             : 
    1376             :         /* Don't try to destroy implicitly opened transaction from list... */
    1377         140 :         if ((commit & RETAIN) == 0 && res_id != 0) {
    1378          62 :                 zend_list_delete(Z_RES_P(arg));
    1379             :         }
    1380         140 :         RETURN_TRUE;
    1381             : }
    1382             : /* }}} */
    1383             : 
    1384             : /* {{{ proto bool ibase_commit( resource link_identifier )
    1385             :    Commit transaction */
    1386          77 : PHP_FUNCTION(ibase_commit)
    1387             : {
    1388          77 :         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
    1389          77 : }
    1390             : /* }}} */
    1391             : 
    1392             : /* {{{ proto bool ibase_rollback( resource link_identifier )
    1393             :    Rollback transaction */
    1394           6 : PHP_FUNCTION(ibase_rollback)
    1395             : {
    1396           6 :         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
    1397           6 : }
    1398             : /* }}} */
    1399             : 
    1400             : /* {{{ proto bool ibase_commit_ret( resource link_identifier )
    1401             :    Commit transaction and retain the transaction context */
    1402          58 : PHP_FUNCTION(ibase_commit_ret)
    1403             : {
    1404          58 :         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN);
    1405          58 : }
    1406             : /* }}} */
    1407             : 
    1408             : /* {{{ proto bool ibase_rollback_ret( resource link_identifier )
    1409             :    Rollback transaction and retain the transaction context */
    1410           0 : PHP_FUNCTION(ibase_rollback_ret)
    1411             : {
    1412           0 :         _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN);
    1413           0 : }
    1414             : /* }}} */
    1415             : 
    1416             : /* {{{ proto int ibase_gen_id(string generator [, int increment [, resource link_identifier ]])
    1417             :    Increments the named generator and returns its new value */
    1418           0 : PHP_FUNCTION(ibase_gen_id)
    1419             : {
    1420           0 :         zval *link = NULL;
    1421             :         char query[128], *generator;
    1422             :         size_t gen_len;
    1423           0 :         zend_long inc = 1;
    1424             :         ibase_db_link *ib_link;
    1425           0 :         ibase_trans *trans = NULL;
    1426             :         XSQLDA out_sqlda;
    1427             :         ISC_INT64 result;
    1428             : 
    1429           0 :         RESET_ERRMSG;
    1430             : 
    1431           0 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr", &generator, &gen_len,
    1432             :                         &inc, &link)) {
    1433           0 :                 RETURN_FALSE;
    1434             :         }
    1435             : 
    1436           0 :         if (gen_len > 31) {
    1437           0 :                 php_error_docref(NULL, E_WARNING, "Invalid generator name");
    1438           0 :                 RETURN_FALSE;
    1439             :         }
    1440             : 
    1441           0 :         PHP_IBASE_LINK_TRANS(link, ib_link, trans);
    1442             : 
    1443           0 :         snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc);
    1444             : 
    1445             :         /* allocate a minimal descriptor area */
    1446           0 :         out_sqlda.sqln = out_sqlda.sqld = 1;
    1447           0 :         out_sqlda.version = SQLDA_CURRENT_VERSION;
    1448             : 
    1449             :         /* allocate the field for the result */
    1450           0 :         out_sqlda.sqlvar[0].sqltype = SQL_INT64;
    1451           0 :         out_sqlda.sqlvar[0].sqlscale = 0;
    1452           0 :         out_sqlda.sqlvar[0].sqllen = sizeof(result);
    1453           0 :         out_sqlda.sqlvar[0].sqldata = (void*) &result;
    1454             : 
    1455             :         /* execute the query */
    1456           0 :         if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query,
    1457             :                         SQL_DIALECT_CURRENT, NULL, &out_sqlda)) {
    1458           0 :                 _php_ibase_error();
    1459           0 :                 RETURN_FALSE;
    1460             :         }
    1461             : 
    1462             :         /* don't return the generator value as a string unless it doesn't fit in a long */
    1463             : #if SIZEOF_ZEND_LONG < 8
    1464             :         if (result < ZEND_LONG_MIN || result > ZEND_LONG_MAX) {
    1465             :                 char *res;
    1466             :                 int l;
    1467             : 
    1468             :                 l = spprintf(&res, 0, "%" LL_MASK "d", result);
    1469             :                 RETURN_STRINGL(res, l);
    1470             :         }
    1471             : #endif
    1472           0 :         RETURN_LONG((zend_long)result);
    1473             : }
    1474             : 
    1475             : /* }}} */
    1476             : 
    1477             : #endif /* HAVE_IBASE */
    1478             : 
    1479             : /*
    1480             :  * Local variables:
    1481             :  * tab-width: 4
    1482             :  * c-basic-offset: 4
    1483             :  * End:
    1484             :  * vim600: sw=4 ts=4 fdm=marker
    1485             :  * vim<600: sw=4 ts=4
    1486             :  */

Generated by: LCOV version 1.10

Generated at Sat, 09 Sep 2017 03:10:36 +0000 (13 days ago)

Copyright © 2005-2017 The PHP Group
All rights reserved.