Annotation of embedaddon/php/ext/interbase/interbase.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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: 
1.1.1.2   misho      21: /* $Id$ */
1.1       misho      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: PHP_FUNCTION(ibase_errmsg)
                    478: {
                    479:        if (zend_parse_parameters_none() == FAILURE) {
                    480:                return;
                    481:        }
                    482: 
                    483:        if (IBG(sql_code) != 0) {
                    484:                RETURN_STRING(IBG(errmsg), 1);
                    485:        }
                    486: 
                    487:        RETURN_FALSE;
                    488: }
                    489: /* }}} */
                    490: 
                    491: /* {{{ proto int ibase_errcode(void) 
                    492:    Return error code */
                    493: PHP_FUNCTION(ibase_errcode)
                    494: {
                    495:        if (zend_parse_parameters_none() == FAILURE) {
                    496:                return;
                    497:        }
                    498: 
                    499:        if (IBG(sql_code) != 0) {
                    500:                RETURN_LONG(IBG(sql_code));
                    501:        }
                    502:        RETURN_FALSE;
                    503: }
                    504: /* }}} */
                    505: 
                    506: /* print interbase error and save it for ibase_errmsg() */
                    507: void _php_ibase_error(TSRMLS_D) /* {{{ */
                    508: {
                    509:        char *s = IBG(errmsg);
                    510:        ISC_STATUS *statusp = IB_STATUS;
                    511: 
                    512:        IBG(sql_code) = isc_sqlcode(IB_STATUS);
                    513:        
                    514:        while ((s - IBG(errmsg)) < MAX_ERRMSG - (IBASE_MSGSIZE + 2) && isc_interprete(s, &statusp)) {
                    515:                strcat(IBG(errmsg), " ");
                    516:                s = IBG(errmsg) + strlen(IBG(errmsg));
                    517:        }
                    518: 
                    519:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
                    520: }
                    521: /* }}} */
                    522: 
                    523: /* print php interbase module error and save it for ibase_errmsg() */
                    524: 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:        va_start(ap, msg);
                    532: #endif
                    533: 
                    534:        /* vsnprintf NUL terminates the buf and writes at most n-1 chars+NUL */
                    535:        vsnprintf(IBG(errmsg), MAX_ERRMSG, msg, ap);
                    536:        va_end(ap);
                    537: 
                    538:        IBG(sql_code) = -999; /* no SQL error */
                    539: 
                    540:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", IBG(errmsg));
                    541: }
                    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: 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:        if (zend_list_find(Z_LVAL_PP(link_id), &type)) {
                    561:                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:                        ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans);
                    566:                        if ((*trans)->link_cnt > 1) {
                    567:                                _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections."
                    568:                                        TSRMLS_CC);
                    569:                                return;
                    570:                        }                               
                    571:                        *ib_link = (*trans)->db_link[0];
                    572:                        return;
                    573:                }
                    574:        } 
                    575:        IBDEBUG("Type is le_[p]link or id not found");
                    576:        /* Database link resource, use default transaction. */
                    577:        *trans = NULL;
                    578:        ZEND_FETCH_RESOURCE2(*ib_link, ibase_db_link *, link_id, -1, LE_LINK, le_link, le_plink);
                    579: }
                    580: /* }}} */      
                    581: 
                    582: /* destructors ---------------------- */
                    583: 
                    584: static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC) /* {{{ */
                    585: {
                    586:        unsigned short i = 0, j;
                    587:        ibase_tr_list *l;
                    588:        ibase_event *e;
                    589:        IBDEBUG("Checking transactions to close...");
                    590: 
                    591:        for (l = link->tr_list; l != NULL; ++i) {
                    592:                ibase_tr_list *p = l;
                    593:                if (p->trans != NULL) {
                    594:                        if (i == 0) {
                    595:                                if (p->trans->handle != NULL) {
                    596:                                        IBDEBUG("Committing default transaction...");
                    597:                                        if (isc_commit_transaction(IB_STATUS, &p->trans->handle)) {
                    598:                                                _php_ibase_error(TSRMLS_C);
                    599:                                        }
                    600:                                }
                    601:                                efree(p->trans); /* default transaction is not a registered resource: clean up */
                    602:                        } else {
                    603:                                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:                                        if (isc_rollback_transaction(IB_STATUS, &p->trans->handle)) {
                    607:                                                _php_ibase_error(TSRMLS_C);
                    608:                                        }
                    609:                                }
                    610:                                /* set this link pointer to NULL in the transaction */
                    611:                                for (j = 0; j < p->trans->link_cnt; ++j) {
                    612:                                        if (p->trans->db_link[j] == link) {
                    613:                                                p->trans->db_link[j] = NULL;
                    614:                                                break;
                    615:                                        }
                    616:                                }
                    617:                        }
                    618:                }
                    619:                l = l->next;
                    620:                efree(p);
                    621:        }
                    622:        link->tr_list = NULL;
                    623:        
                    624:        for (e = link->event_head; e; e = e->event_next) {
                    625:                _php_ibase_free_event(e TSRMLS_CC);
                    626:                e->link = NULL;
                    627:        }
                    628: }
                    629: 
                    630: /* }}} */
                    631: 
                    632: static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
                    633: {
                    634:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
                    635: 
                    636:        _php_ibase_commit_link(link TSRMLS_CC);
                    637: }
                    638: /* }}} */
                    639: 
                    640: static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
                    641: {
                    642:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
                    643: 
                    644:        _php_ibase_commit_link(link TSRMLS_CC);
                    645:        if (link->handle != NULL) {
                    646:                IBDEBUG("Closing normal link...");
                    647:                isc_detach_database(IB_STATUS, &link->handle);
                    648:        }
                    649:        IBG(num_links)--;
                    650:        efree(link);
                    651: }
                    652: /* }}} */
                    653: 
                    654: static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
                    655: {
                    656:        ibase_db_link *link = (ibase_db_link *) rsrc->ptr;
                    657: 
                    658:        _php_ibase_commit_link(link TSRMLS_CC);
                    659:        IBDEBUG("Closing permanent link...");
                    660:        if (link->handle != NULL) {
                    661:                isc_detach_database(IB_STATUS, &link->handle);
                    662:        }
                    663:        IBG(num_persistent)--;
                    664:        IBG(num_links)--;
                    665:        free(link);
                    666: }
                    667: /* }}} */
                    668: 
                    669: static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
                    670: {
                    671:        ibase_trans *trans = (ibase_trans *)rsrc->ptr;
                    672:        unsigned short i;
                    673:        
                    674:        IBDEBUG("Cleaning up transaction resource...");
                    675:        if (trans->handle != NULL) {
                    676:                IBDEBUG("Rolling back unhandled transaction...");
                    677:                if (isc_rollback_transaction(IB_STATUS, &trans->handle)) {
                    678:                        _php_ibase_error(TSRMLS_C);
                    679:                }
                    680:        }
                    681: 
                    682:        /* now remove this transaction from all the connection-transaction lists */
                    683:        for (i = 0; i < trans->link_cnt; ++i) {
                    684:                if (trans->db_link[i] != NULL) {
                    685:                        ibase_tr_list **l;
                    686:                        for (l = &trans->db_link[i]->tr_list; *l != NULL; l = &(*l)->next) {
                    687:                                if ( (*l)->trans == trans) {
                    688:                                        ibase_tr_list *p = *l;
                    689:                                        *l = p->next;
                    690:                                        efree(p);
                    691:                                        break;
                    692:                                }
                    693:                        }
                    694:                }
                    695:        }
                    696:        efree(trans);
                    697: }
                    698: /* }}} */
                    699: 
                    700: /* TODO this function should be part of either Zend or PHP API */
                    701: static PHP_INI_DISP(php_ibase_password_displayer_cb)
                    702: {
                    703:        TSRMLS_FETCH();
                    704: 
                    705:        if ((type == PHP_INI_DISPLAY_ORIG && ini_entry->orig_value) 
                    706:                        || (type == PHP_INI_DISPLAY_ACTIVE && ini_entry->value)) {
                    707:                PUTS("********");
                    708:        } else if (!sapi_module.phpinfo_as_text) {
                    709:                PUTS("<i>no value</i>");
                    710:        } else {
                    711:                PUTS("no value");
                    712:        }
                    713: }
                    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: static PHP_GINIT_FUNCTION(ibase)
                    730: {
                    731:        ibase_globals->num_persistent = ibase_globals->num_links = 0;
                    732:        ibase_globals->sql_code = *ibase_globals->errmsg = 0;
                    733:        ibase_globals->default_link = -1;
                    734: }
                    735: 
                    736: PHP_MINIT_FUNCTION(ibase)
                    737: {
                    738:        REGISTER_INI_ENTRIES();
                    739: 
                    740:        le_link = zend_register_list_destructors_ex(_php_ibase_close_link, NULL, LE_LINK, module_number);
                    741:        le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, LE_PLINK, module_number);
                    742:        le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, LE_TRANS, module_number);
                    743: 
                    744:        REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT);
                    745:        REGISTER_LONG_CONSTANT("IBASE_CREATE", PHP_IBASE_CREATE, CONST_PERSISTENT);
                    746:        REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */
                    747:        REGISTER_LONG_CONSTANT("IBASE_FETCH_BLOBS", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT);
                    748:        REGISTER_LONG_CONSTANT("IBASE_FETCH_ARRAYS", PHP_IBASE_FETCH_ARRAYS, CONST_PERSISTENT);
                    749:        REGISTER_LONG_CONSTANT("IBASE_UNIXTIME", PHP_IBASE_UNIXTIME, CONST_PERSISTENT);
                    750: 
                    751:        /* transactions */
                    752:        REGISTER_LONG_CONSTANT("IBASE_WRITE", PHP_IBASE_WRITE, CONST_PERSISTENT);
                    753:        REGISTER_LONG_CONSTANT("IBASE_READ", PHP_IBASE_READ, CONST_PERSISTENT);
                    754:        REGISTER_LONG_CONSTANT("IBASE_COMMITTED", PHP_IBASE_COMMITTED, CONST_PERSISTENT);
                    755:        REGISTER_LONG_CONSTANT("IBASE_CONSISTENCY", PHP_IBASE_CONSISTENCY, CONST_PERSISTENT);
                    756:        REGISTER_LONG_CONSTANT("IBASE_CONCURRENCY", PHP_IBASE_CONCURRENCY, CONST_PERSISTENT);
                    757:        REGISTER_LONG_CONSTANT("IBASE_REC_VERSION", PHP_IBASE_REC_VERSION, CONST_PERSISTENT);
                    758:        REGISTER_LONG_CONSTANT("IBASE_REC_NO_VERSION", PHP_IBASE_REC_NO_VERSION, CONST_PERSISTENT);
                    759:        REGISTER_LONG_CONSTANT("IBASE_NOWAIT", PHP_IBASE_NOWAIT, CONST_PERSISTENT);
                    760:        REGISTER_LONG_CONSTANT("IBASE_WAIT", PHP_IBASE_WAIT, CONST_PERSISTENT);
                    761: 
                    762:        php_ibase_query_minit(INIT_FUNC_ARGS_PASSTHRU);
                    763:        php_ibase_blobs_minit(INIT_FUNC_ARGS_PASSTHRU);
                    764:        php_ibase_events_minit(INIT_FUNC_ARGS_PASSTHRU);
                    765:        php_ibase_service_minit(INIT_FUNC_ARGS_PASSTHRU);
                    766:        
                    767:        return SUCCESS;          
                    768: }                            
                    769:                              
                    770: 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:        if (SUCCESS == zend_hash_find(&module_registry, ibase_module_entry.name,
                    787:                        strlen(ibase_module_entry.name) +1, (void*) &ibase_entry)) {
                    788:                ibase_entry->handle = NULL;
                    789:        }
                    790: #endif
                    791:        UNREGISTER_INI_ENTRIES();
                    792:        return SUCCESS;
                    793: }
                    794: 
                    795: PHP_RSHUTDOWN_FUNCTION(ibase)
                    796: {
                    797:        IBG(num_links) = IBG(num_persistent);
                    798:        IBG(default_link)= -1;
                    799: 
                    800:        RESET_ERRMSG;
                    801: 
                    802:        return SUCCESS;
                    803: } 
                    804:  
                    805: PHP_MINFO_FUNCTION(ibase)
                    806: {
                    807:        char tmp[64], *s;
                    808: 
                    809:        php_info_print_table_start();
                    810:        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:        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:        php_info_print_table_row(2, "Compile-time Client Library Version", s);
                    827: 
                    828: #if defined(__GNUC__) || defined(PHP_WIN32)
                    829:        do {
                    830:                info_func_t info_func = NULL;
                    831: #ifdef __GNUC__
                    832:                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:                if (info_func) {
                    842:                        info_func(s = tmp);
                    843:                } else {
                    844:                        s = "Firebird 1.0/Interbase 6";
                    845:                }
                    846:                php_info_print_table_row(2, "Run-time Client Library Version", s);
                    847:        } while (0);
                    848: #endif                 
                    849:        php_info_print_table_end();
                    850: 
                    851:        DISPLAY_INI_ENTRIES();
                    852: 
                    853: }
                    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: int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC)
                    863: {
                    864:        short i, dpb_len, buf_len = 257-2;  /* version byte at the front, and a null at the end */
                    865:        char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb;
                    866: 
                    867:        dpb = dpb_buffer + 1;
                    868: 
                    869:        for (i = 0; i < sizeof(dpb_args); ++i) {
                    870:                if (dpb_args[i] && args[i] && len[i] && buf_len > 0) {
                    871:                        dpb_len = slprintf(dpb, buf_len, "%c%c%s", dpb_args[i],(unsigned char)len[i],args[i]);
                    872:                        dpb += dpb_len;
                    873:                        buf_len -= dpb_len;
                    874:                }
                    875:        }
                    876:        if (largs[BUF] && buf_len > 0) {
                    877:                dpb_len = slprintf(dpb, buf_len, "%c\2%c%c", isc_dpb_num_buffers, 
                    878:                        (char)(largs[BUF] >> 8), (char)(largs[BUF] & 0xff));
                    879:                dpb += dpb_len;
                    880:                buf_len -= dpb_len;
                    881:        }
                    882:        if (largs[SYNC] && buf_len > 0) {
                    883:                dpb_len = slprintf(dpb, buf_len, "%c\1%c", isc_dpb_force_write, largs[SYNC] == isc_spb_prp_wm_sync ? 1 : 0);
                    884:                dpb += dpb_len;
                    885:                buf_len -= dpb_len;
                    886:        }
                    887:        if (isc_attach_database(IB_STATUS, (short)len[DB], args[DB], db, (short)(dpb-dpb_buffer), dpb_buffer)) {
                    888:                _php_ibase_error(TSRMLS_C);
                    889:                return FAILURE;
                    890:        }
                    891:        return SUCCESS;
                    892: }
                    893: /* }}} */
                    894: 
                    895: static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* {{{ */
                    896: {
                    897:        char *c, hash[16], *args[] = { NULL, NULL, NULL, NULL, NULL };
                    898:        int i, len[] = { 0, 0, 0, 0, 0 };
                    899:        long largs[] = { 0, 0, 0 };
                    900:        PHP_MD5_CTX hash_context;
                    901:        zend_rsrc_list_entry new_index_ptr, *le;
                    902:        isc_db_handle db_handle = NULL;
                    903:        ibase_db_link *ib_link;
                    904: 
                    905:        RESET_ERRMSG;
                    906: 
                    907:        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:                RETURN_FALSE;
                    912:        }
                    913:        
                    914:        /* restrict to the server/db in the .ini if in safe mode */
                    915:        if ((!len[DB] || PG(sql_safe_mode)) && (c = INI_STR("ibase.default_db"))) { 
                    916:                args[DB] = c;
                    917:                len[DB] = strlen(c);
                    918:        }
                    919:        if (!len[USER] && (c = INI_STR("ibase.default_user"))) {
                    920:                args[USER] = c;
                    921:                len[USER] = strlen(c);
                    922:        }
                    923:        if (!len[PASS] && (c = INI_STR("ibase.default_password"))) {
                    924:                args[PASS] = c;
                    925:                len[PASS] = strlen(c);
                    926:        }
                    927:        if (!len[CSET] && (c = INI_STR("ibase.default_charset"))) {
                    928:                args[CSET] = c;
                    929:                len[CSET] = strlen(c);
                    930:        }
                    931:        
                    932:        /* don't want usernames and passwords floating around */
                    933:        PHP_MD5Init(&hash_context);
                    934:        for (i = 0; i < sizeof(args)/sizeof(char*); ++i) {
                    935:                PHP_MD5Update(&hash_context,args[i],len[i]);
                    936:        }
                    937:        for (i = 0; i < sizeof(largs)/sizeof(long); ++i) {
                    938:                PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long));
                    939:        }
                    940:        PHP_MD5Final(hash, &hash_context);
                    941:        
                    942:        /* try to reuse a connection */
                    943:        if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) {
                    944:                long xlink;
                    945:                int type;
                    946: 
                    947:                if (Z_TYPE_P(le) != le_index_ptr) {
                    948:                        RETURN_FALSE;
                    949:                }
                    950:                        
                    951:                xlink = (long) le->ptr;
                    952:                if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) {
                    953:                        zend_list_addref(xlink);
                    954:                        RETURN_RESOURCE(IBG(default_link) = xlink);
                    955:                } else {
                    956:                        zend_hash_del(&EG(regular_list), hash, sizeof(hash));
                    957:                }
                    958:        }               
                    959: 
                    960:        /* ... or a persistent one */
                    961:        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:                if (Z_TYPE_P(le) != le_plink) {
                    971:                        RETURN_FALSE;
                    972:                }
                    973:                /* check if connection has timed out */
                    974:                ib_link = (ibase_db_link *) le->ptr;
                    975:                if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) {
                    976:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
                    977:                        break;
                    978:                }
                    979:                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:                if ((l = INI_INT("ibase.max_links")) != -1 && IBG(num_links) >= l) {
                    986:                        _php_ibase_module_error("Too many open links (%ld)" TSRMLS_CC, IBG(num_links));
                    987:                        RETURN_FALSE;
                    988:                }
                    989:        
                    990:                /* create the ib_link */
                    991:                if (FAILURE == _php_ibase_attach_db(args, len, largs, &db_handle TSRMLS_CC)) {
                    992:                        RETURN_FALSE;
                    993:                }
                    994:        
                    995:                /* use non-persistent if allowed number of persistent links is exceeded */
                    996:                if (!persistent || ((l = INI_INT("ibase.max_persistent") != -1) && IBG(num_persistent) >= l)) {
                    997:                        ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link));
                    998:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link);
                    999:                } else {
                   1000:                        zend_rsrc_list_entry new_le;
                   1001: 
                   1002:                        ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link));
                   1003:                        if (!ib_link) {
                   1004:                                RETURN_FALSE;
                   1005:                        }
                   1006: 
                   1007:                        /* hash it up */
                   1008:                        Z_TYPE(new_le) = le_plink;
                   1009:                        new_le.ptr = ib_link;
                   1010:                        if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash),
                   1011:                                        (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)) {
                   1012:                                free(ib_link);
                   1013:                                RETURN_FALSE;
                   1014:                        }
                   1015:                        ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink);
                   1016:                        ++IBG(num_persistent);
                   1017:                }
                   1018:                ib_link->handle = db_handle;
                   1019:                ib_link->dialect = largs[DLECT] ? (unsigned short)largs[DLECT] : SQL_DIALECT_CURRENT;
                   1020:                ib_link->tr_list = NULL;
                   1021:                ib_link->event_head = NULL;
                   1022:        
                   1023:                ++IBG(num_links);
                   1024:        }
                   1025: 
                   1026:        /* add it to the hash */
                   1027:        new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
                   1028:        Z_TYPE(new_index_ptr) = le_index_ptr;
                   1029:        if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash),
                   1030:                        (void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)) {
                   1031:                RETURN_FALSE;
                   1032:        }
                   1033:        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: PHP_FUNCTION(ibase_connect)
                   1040: {
                   1041:        _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   1042: }
                   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: PHP_FUNCTION(ibase_pconnect)
                   1048: {
                   1049:        _php_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INI_INT("ibase.allow_persistent"));
                   1050: }
                   1051: /* }}} */
                   1052: 
                   1053: /* {{{ proto bool ibase_close([resource link_identifier])
                   1054:    Close an InterBase connection */
                   1055: PHP_FUNCTION(ibase_close)
                   1056: {
                   1057:        zval *link_arg = NULL;
                   1058:        ibase_db_link *ib_link;
                   1059:        int link_id;
                   1060: 
                   1061:        RESET_ERRMSG;
                   1062:        
                   1063:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
                   1064:                return;
                   1065:        }
                   1066:        
                   1067:        if (ZEND_NUM_ARGS() == 0) {
                   1068:                link_id = IBG(default_link);
                   1069:                CHECK_LINK(link_id);
                   1070:                IBG(default_link) = -1;
                   1071:        } else {
                   1072:                link_id = Z_RESVAL_P(link_arg);
                   1073:        }
                   1074: 
                   1075:        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
                   1076:        zend_list_delete(link_id);
                   1077:        RETURN_TRUE;
                   1078: }
                   1079: /* }}} */
                   1080: 
                   1081: /* {{{ proto bool ibase_drop_db([resource link_identifier])
                   1082:    Drop an InterBase database */
                   1083: PHP_FUNCTION(ibase_drop_db)
                   1084: {
                   1085:        zval *link_arg = NULL;
                   1086:        ibase_db_link *ib_link;
                   1087:        ibase_tr_list *l;
                   1088:        int link_id;
                   1089: 
                   1090:        RESET_ERRMSG;
                   1091:        
                   1092:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &link_arg) == FAILURE) {
                   1093:                return;
                   1094:        }
                   1095:        
                   1096:        if (ZEND_NUM_ARGS() == 0) {
                   1097:                link_id = IBG(default_link);
                   1098:                CHECK_LINK(link_id);
                   1099:                IBG(default_link) = -1;
                   1100:        } else {
                   1101:                link_id = Z_RESVAL_P(link_arg);
                   1102:        }
                   1103:        
                   1104:        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink);
                   1105: 
                   1106:        if (isc_drop_database(IB_STATUS, &ib_link->handle)) {
                   1107:                _php_ibase_error(TSRMLS_C);
                   1108:                RETURN_FALSE;
                   1109:        }
                   1110: 
                   1111:        /* isc_drop_database() doesn't invalidate the transaction handles */
                   1112:        for (l = ib_link->tr_list; l != NULL; l = l->next) {
                   1113:                if (l->trans != NULL) l->trans->handle = NULL;
                   1114:        }
                   1115: 
                   1116:        zend_list_delete(link_id);
                   1117:        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: PHP_FUNCTION(ibase_trans)
                   1127: {
1.1.1.2   misho    1128:        unsigned short i, link_cnt = 0, tpb_len = 0;
                   1129:        int argn;
1.1       misho    1130:        char last_tpb[TPB_MAX_SIZE];
                   1131:        ibase_db_link **ib_link = NULL;
                   1132:        ibase_trans *ib_trans;
                   1133:        isc_tr_handle tr_handle = NULL;
                   1134:        ISC_STATUS result;
                   1135:        
                   1136:        RESET_ERRMSG;
                   1137: 
                   1138:        argn = ZEND_NUM_ARGS();
                   1139: 
                   1140:        /* (1+argn) is an upper bound for the number of links this trans connects to */
                   1141:        ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0);
                   1142:        
                   1143:        if (argn > 0) {
                   1144:                long trans_argl = 0;
                   1145:                char *tpb;
                   1146:                ISC_TEB *teb;
                   1147:                zval ***args = NULL;
                   1148: 
                   1149:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) {
                   1150:                        efree(args);
                   1151:                        efree(ib_link);
                   1152:                        RETURN_FALSE;
                   1153:                }
                   1154: 
                   1155:                teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0);
                   1156:                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:                for (i = 0; i < argn; ++i) {
                   1161:                        
                   1162:                        if (Z_TYPE_PP(args[i]) == IS_RESOURCE) {
                   1163:                                
                   1164:                                if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) {
                   1165:                                        efree(teb);
                   1166:                                        efree(tpb);
                   1167:                                        efree(ib_link);
                   1168:                                        efree(args);
                   1169:                                        RETURN_FALSE;
                   1170:                                }
                   1171:        
                   1172:                                /* copy the most recent modifier string into tbp[] */
                   1173:                                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:                                teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle;
                   1177:                                teb[link_cnt].tpb_len = tpb_len;
                   1178:                                teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt];
                   1179:                                
                   1180:                                ++link_cnt;
                   1181:                                
                   1182:                        } else {
                   1183:                                
                   1184:                                tpb_len = 0;
                   1185: 
                   1186:                                convert_to_long_ex(args[i]);
                   1187:                                trans_argl = Z_LVAL_PP(args[i]);
                   1188: 
                   1189:                                if (trans_argl != PHP_IBASE_DEFAULT) {
                   1190:                                        last_tpb[tpb_len++] = isc_tpb_version3;
                   1191: 
                   1192:                                        /* access mode */
                   1193:                                        if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) {
                   1194:                                                last_tpb[tpb_len++] = isc_tpb_read;
                   1195:                                        } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) {
                   1196:                                                last_tpb[tpb_len++] = isc_tpb_write;
                   1197:                                        }
                   1198: 
                   1199:                                        /* isolation level */
                   1200:                                        if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) {
                   1201:                                                last_tpb[tpb_len++] = isc_tpb_read_committed;
                   1202:                                                if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) {
                   1203:                                                        last_tpb[tpb_len++] = isc_tpb_rec_version;
                   1204:                                                } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) {
                   1205:                                                        last_tpb[tpb_len++] = isc_tpb_no_rec_version; 
                   1206:                                                }       
                   1207:                                        } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) {
                   1208:                                                last_tpb[tpb_len++] = isc_tpb_consistency;
                   1209:                                        } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) {
                   1210:                                                last_tpb[tpb_len++] = isc_tpb_concurrency;
                   1211:                                        }
                   1212:                                        
                   1213:                                        /* lock resolution */
                   1214:                                        if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) {
                   1215:                                                last_tpb[tpb_len++] = isc_tpb_nowait;
                   1216:                                        } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) {
                   1217:                                                last_tpb[tpb_len++] = isc_tpb_wait;
                   1218:                                        }
                   1219:                                }
                   1220:                        }
                   1221:                }       
                   1222:                                        
                   1223:                if (link_cnt > 0) {
                   1224:                        result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb);
                   1225:                }
                   1226: 
                   1227:                efree(args);
                   1228:                efree(tpb);
                   1229:                efree(teb);
                   1230:        }
                   1231: 
                   1232:        if (link_cnt == 0) {
                   1233:                link_cnt = 1;
                   1234:                if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) {
                   1235:                        efree(ib_link);
                   1236:                        RETURN_FALSE;
                   1237:                }
                   1238:                result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb);
                   1239:        }
                   1240:        
                   1241:        /* start the transaction */
                   1242:        if (result) {
                   1243:                _php_ibase_error(TSRMLS_C);
                   1244:                efree(ib_link);
                   1245:                RETURN_FALSE;
                   1246:        }
                   1247: 
                   1248:        /* register the transaction in our own data structures */
                   1249:        ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans));
                   1250:        ib_trans->handle = tr_handle;
                   1251:        ib_trans->link_cnt = link_cnt;
                   1252:        ib_trans->affected_rows = 0;
                   1253:        for (i = 0; i < link_cnt; ++i) {
                   1254:                ibase_tr_list **l;
                   1255:                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:                if (ib_link[i]->tr_list == NULL) {
                   1259:                        ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
                   1260:                        ib_link[i]->tr_list->trans = NULL;
                   1261:                        ib_link[i]->tr_list->next = NULL;
                   1262:                }
                   1263: 
                   1264:                /* link the transaction into the connection-transaction list */
                   1265:                for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next);
                   1266:                *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
                   1267:                (*l)->trans = ib_trans;
                   1268:                (*l)->next = NULL;
                   1269:        }
                   1270:        efree(ib_link);
                   1271:        ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans);
                   1272: }
                   1273: /* }}} */
                   1274: 
                   1275: int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC) /* {{{ */
                   1276: {
                   1277:        if (ib_link == NULL) {
                   1278:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link");
                   1279:                return FAILURE;
                   1280:        }
                   1281: 
                   1282:        /* the first item in the connection-transaction list is reserved for the default transaction */
                   1283:        if (ib_link->tr_list == NULL) {
                   1284:                ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list));
                   1285:                ib_link->tr_list->trans = NULL;
                   1286:                ib_link->tr_list->next = NULL;
                   1287:        }
                   1288: 
                   1289:        if (*trans == NULL) {
                   1290:                ibase_trans *tr = ib_link->tr_list->trans;
                   1291: 
                   1292:                if (tr == NULL) {
                   1293:                        tr = (ibase_trans *) emalloc(sizeof(ibase_trans));
                   1294:                        tr->handle = NULL;
                   1295:                        tr->link_cnt = 1;
                   1296:                        tr->affected_rows = 0;
                   1297:                        tr->db_link[0] = ib_link;
                   1298:                        ib_link->tr_list->trans = tr;
                   1299:                }
                   1300:                if (tr->handle == NULL) {
                   1301:                        if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) {
                   1302:                                _php_ibase_error(TSRMLS_C);
                   1303:                                return FAILURE;
                   1304:                        }
                   1305:                }
                   1306:                *trans = tr;
                   1307:        }
                   1308:        return SUCCESS;
                   1309: }
                   1310: /* }}} */
                   1311: 
                   1312: static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */
                   1313: {
                   1314:        ibase_trans *trans = NULL;
                   1315:        int res_id = 0;
                   1316:        ISC_STATUS result;
                   1317:        ibase_db_link *ib_link;
                   1318:        zval *arg = NULL;
                   1319:        int type;
                   1320: 
                   1321:        RESET_ERRMSG;
                   1322:        
                   1323:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) {
                   1324:                return;
                   1325:        }
                   1326: 
                   1327:        if (ZEND_NUM_ARGS() == 0) {
                   1328:                ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink);
                   1329:                if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
                   1330:                        /* this link doesn't have a default transaction */
                   1331:                        _php_ibase_module_error("Default link has no default transaction" TSRMLS_CC);
                   1332:                        RETURN_FALSE;
                   1333:                }
                   1334:                trans = ib_link->tr_list->trans;
                   1335:        } else {
                   1336:                /* one id was passed, could be db or trans id */
                   1337:                if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) {
                   1338:                        ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans);
                   1339:                        res_id = Z_RESVAL_P(arg);
                   1340:                } else {
                   1341:                        ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink);
                   1342: 
                   1343:                        if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) {
                   1344:                                /* this link doesn't have a default transaction */
                   1345:                                _php_ibase_module_error("Link has no default transaction" TSRMLS_CC);
                   1346:                                RETURN_FALSE;
                   1347:                        }
                   1348:                        trans = ib_link->tr_list->trans;
                   1349:                }
                   1350:        }
                   1351: 
                   1352:        switch (commit) {
                   1353:                default: /* == case ROLLBACK: */
                   1354:                        result = isc_rollback_transaction(IB_STATUS, &trans->handle);
                   1355:                        break;
                   1356:                case COMMIT:
                   1357:                        result = isc_commit_transaction(IB_STATUS, &trans->handle);
                   1358:                        break;
                   1359:                case (ROLLBACK | RETAIN):
                   1360:                        result = isc_rollback_retaining(IB_STATUS, &trans->handle);
                   1361:                        break;
                   1362:                case (COMMIT | RETAIN):
                   1363:                        result = isc_commit_retaining(IB_STATUS, &trans->handle);
                   1364:                        break;
                   1365:        }
                   1366:        
                   1367:        if (result) {
                   1368:                _php_ibase_error(TSRMLS_C);
                   1369:                RETURN_FALSE;
                   1370:        }
                   1371: 
                   1372:        /* Don't try to destroy implicitly opened transaction from list... */
                   1373:        if ((commit & RETAIN) == 0 && res_id != 0) {
                   1374:                zend_list_delete(res_id);
                   1375:        }
                   1376:        RETURN_TRUE;
                   1377: }
                   1378: /* }}} */
                   1379: 
                   1380: /* {{{ proto bool ibase_commit( resource link_identifier )
                   1381:    Commit transaction */
                   1382: PHP_FUNCTION(ibase_commit)
                   1383: {
                   1384:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT);
                   1385: }
                   1386: /* }}} */
                   1387: 
                   1388: /* {{{ proto bool ibase_rollback( resource link_identifier )
                   1389:    Rollback transaction */
                   1390: PHP_FUNCTION(ibase_rollback)
                   1391: {
                   1392:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK);
                   1393: }
                   1394: /* }}} */
                   1395: 
                   1396: /* {{{ proto bool ibase_commit_ret( resource link_identifier )
                   1397:    Commit transaction and retain the transaction context */
                   1398: PHP_FUNCTION(ibase_commit_ret)
                   1399: {
                   1400:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN);
                   1401: }
                   1402: /* }}} */
                   1403: 
                   1404: /* {{{ proto bool ibase_rollback_ret( resource link_identifier )
                   1405:    Rollback transaction and retain the transaction context */
                   1406: PHP_FUNCTION(ibase_rollback_ret)
                   1407: {
                   1408:        _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN);
                   1409: }
                   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: PHP_FUNCTION(ibase_gen_id)
                   1415: {
                   1416:        zval *link = NULL;
                   1417:        char query[128], *generator;
                   1418:        int gen_len;
                   1419:        long inc = 1;
                   1420:        ibase_db_link *ib_link;
                   1421:        ibase_trans *trans = NULL;
                   1422:        XSQLDA out_sqlda;
                   1423:        ISC_INT64 result;
                   1424: 
                   1425:        RESET_ERRMSG;
                   1426: 
                   1427:        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &generator, &gen_len,
                   1428:                        &inc, &link)) {
                   1429:                RETURN_FALSE;
                   1430:        }
                   1431:        
                   1432:        if (gen_len > 31) {
                   1433:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid generator name");
                   1434:                RETURN_FALSE;
                   1435:        }
                   1436: 
                   1437:        PHP_IBASE_LINK_TRANS(link, ib_link, trans);
                   1438:        
                   1439:        snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc);
                   1440: 
                   1441:        /* allocate a minimal descriptor area */
                   1442:        out_sqlda.sqln = out_sqlda.sqld = 1;
                   1443:        out_sqlda.version = SQLDA_CURRENT_VERSION;
                   1444:        
                   1445:        /* allocate the field for the result */
                   1446:        out_sqlda.sqlvar[0].sqltype = SQL_INT64;
                   1447:        out_sqlda.sqlvar[0].sqlscale = 0;
                   1448:        out_sqlda.sqlvar[0].sqllen = sizeof(result);
                   1449:        out_sqlda.sqlvar[0].sqldata = (void*) &result;
                   1450: 
                   1451:        /* execute the query */
                   1452:        if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query,
                   1453:                        SQL_DIALECT_CURRENT, NULL, &out_sqlda)) {
                   1454:                _php_ibase_error(TSRMLS_C);
                   1455:                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:        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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>