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: 376 465 80.9 %
Date: 2014-04-18 Functions: 27 30 90.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:28 +0000 (5 days ago)

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