Return to interbase.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / interbase |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Authors: Jouni Ahto <jouni.ahto@exdec.fi> | ! 16: | Andrew Avdeev <andy@rsc.mv.ru> | ! 17: | Ard Biesheuvel <a.k.biesheuvel@ewi.tudelft.nl> | ! 18: +----------------------------------------------------------------------+ ! 19: */ ! 20: ! 21: /* $Id: interbase.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 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: { ! 1128: unsigned short i, argn, link_cnt = 0, tpb_len = 0; ! 1129: char last_tpb[TPB_MAX_SIZE]; ! 1130: ibase_db_link **ib_link = NULL; ! 1131: ibase_trans *ib_trans; ! 1132: isc_tr_handle tr_handle = NULL; ! 1133: ISC_STATUS result; ! 1134: ! 1135: RESET_ERRMSG; ! 1136: ! 1137: argn = ZEND_NUM_ARGS(); ! 1138: ! 1139: /* (1+argn) is an upper bound for the number of links this trans connects to */ ! 1140: ib_link = (ibase_db_link **) safe_emalloc(sizeof(ibase_db_link *),1+argn,0); ! 1141: ! 1142: if (argn > 0) { ! 1143: long trans_argl = 0; ! 1144: char *tpb; ! 1145: ISC_TEB *teb; ! 1146: zval ***args = NULL; ! 1147: ! 1148: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) { ! 1149: efree(args); ! 1150: efree(ib_link); ! 1151: RETURN_FALSE; ! 1152: } ! 1153: ! 1154: teb = (ISC_TEB *) safe_emalloc(sizeof(ISC_TEB),argn,0); ! 1155: tpb = (char *) safe_emalloc(TPB_MAX_SIZE,argn,0); ! 1156: ! 1157: /* enumerate all the arguments: assume every non-resource argument ! 1158: specifies modifiers for the link ids that follow it */ ! 1159: for (i = 0; i < argn; ++i) { ! 1160: ! 1161: if (Z_TYPE_PP(args[i]) == IS_RESOURCE) { ! 1162: ! 1163: if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) { ! 1164: efree(teb); ! 1165: efree(tpb); ! 1166: efree(ib_link); ! 1167: efree(args); ! 1168: RETURN_FALSE; ! 1169: } ! 1170: ! 1171: /* copy the most recent modifier string into tbp[] */ ! 1172: memcpy(&tpb[TPB_MAX_SIZE * link_cnt], last_tpb, TPB_MAX_SIZE); ! 1173: ! 1174: /* add a database handle to the TEB with the most recently specified set of modifiers */ ! 1175: teb[link_cnt].db_ptr = &ib_link[link_cnt]->handle; ! 1176: teb[link_cnt].tpb_len = tpb_len; ! 1177: teb[link_cnt].tpb_ptr = &tpb[TPB_MAX_SIZE * link_cnt]; ! 1178: ! 1179: ++link_cnt; ! 1180: ! 1181: } else { ! 1182: ! 1183: tpb_len = 0; ! 1184: ! 1185: convert_to_long_ex(args[i]); ! 1186: trans_argl = Z_LVAL_PP(args[i]); ! 1187: ! 1188: if (trans_argl != PHP_IBASE_DEFAULT) { ! 1189: last_tpb[tpb_len++] = isc_tpb_version3; ! 1190: ! 1191: /* access mode */ ! 1192: if (PHP_IBASE_READ == (trans_argl & PHP_IBASE_READ)) { ! 1193: last_tpb[tpb_len++] = isc_tpb_read; ! 1194: } else if (PHP_IBASE_WRITE == (trans_argl & PHP_IBASE_WRITE)) { ! 1195: last_tpb[tpb_len++] = isc_tpb_write; ! 1196: } ! 1197: ! 1198: /* isolation level */ ! 1199: if (PHP_IBASE_COMMITTED == (trans_argl & PHP_IBASE_COMMITTED)) { ! 1200: last_tpb[tpb_len++] = isc_tpb_read_committed; ! 1201: if (PHP_IBASE_REC_VERSION == (trans_argl & PHP_IBASE_REC_VERSION)) { ! 1202: last_tpb[tpb_len++] = isc_tpb_rec_version; ! 1203: } else if (PHP_IBASE_REC_NO_VERSION == (trans_argl & PHP_IBASE_REC_NO_VERSION)) { ! 1204: last_tpb[tpb_len++] = isc_tpb_no_rec_version; ! 1205: } ! 1206: } else if (PHP_IBASE_CONSISTENCY == (trans_argl & PHP_IBASE_CONSISTENCY)) { ! 1207: last_tpb[tpb_len++] = isc_tpb_consistency; ! 1208: } else if (PHP_IBASE_CONCURRENCY == (trans_argl & PHP_IBASE_CONCURRENCY)) { ! 1209: last_tpb[tpb_len++] = isc_tpb_concurrency; ! 1210: } ! 1211: ! 1212: /* lock resolution */ ! 1213: if (PHP_IBASE_NOWAIT == (trans_argl & PHP_IBASE_NOWAIT)) { ! 1214: last_tpb[tpb_len++] = isc_tpb_nowait; ! 1215: } else if (PHP_IBASE_WAIT == (trans_argl & PHP_IBASE_WAIT)) { ! 1216: last_tpb[tpb_len++] = isc_tpb_wait; ! 1217: } ! 1218: } ! 1219: } ! 1220: } ! 1221: ! 1222: if (link_cnt > 0) { ! 1223: result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb); ! 1224: } ! 1225: ! 1226: efree(args); ! 1227: efree(tpb); ! 1228: efree(teb); ! 1229: } ! 1230: ! 1231: if (link_cnt == 0) { ! 1232: link_cnt = 1; ! 1233: if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[0], ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink)) { ! 1234: efree(ib_link); ! 1235: RETURN_FALSE; ! 1236: } ! 1237: result = isc_start_transaction(IB_STATUS, &tr_handle, 1, &ib_link[0]->handle, tpb_len, last_tpb); ! 1238: } ! 1239: ! 1240: /* start the transaction */ ! 1241: if (result) { ! 1242: _php_ibase_error(TSRMLS_C); ! 1243: efree(ib_link); ! 1244: RETURN_FALSE; ! 1245: } ! 1246: ! 1247: /* register the transaction in our own data structures */ ! 1248: ib_trans = (ibase_trans *) safe_emalloc(link_cnt-1, sizeof(ibase_db_link *), sizeof(ibase_trans)); ! 1249: ib_trans->handle = tr_handle; ! 1250: ib_trans->link_cnt = link_cnt; ! 1251: ib_trans->affected_rows = 0; ! 1252: for (i = 0; i < link_cnt; ++i) { ! 1253: ibase_tr_list **l; ! 1254: ib_trans->db_link[i] = ib_link[i]; ! 1255: ! 1256: /* the first item in the connection-transaction list is reserved for the default transaction */ ! 1257: if (ib_link[i]->tr_list == NULL) { ! 1258: ib_link[i]->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list)); ! 1259: ib_link[i]->tr_list->trans = NULL; ! 1260: ib_link[i]->tr_list->next = NULL; ! 1261: } ! 1262: ! 1263: /* link the transaction into the connection-transaction list */ ! 1264: for (l = &ib_link[i]->tr_list; *l != NULL; l = &(*l)->next); ! 1265: *l = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list)); ! 1266: (*l)->trans = ib_trans; ! 1267: (*l)->next = NULL; ! 1268: } ! 1269: efree(ib_link); ! 1270: ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans); ! 1271: } ! 1272: /* }}} */ ! 1273: ! 1274: int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC) /* {{{ */ ! 1275: { ! 1276: if (ib_link == NULL) { ! 1277: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid database link"); ! 1278: return FAILURE; ! 1279: } ! 1280: ! 1281: /* the first item in the connection-transaction list is reserved for the default transaction */ ! 1282: if (ib_link->tr_list == NULL) { ! 1283: ib_link->tr_list = (ibase_tr_list *) emalloc(sizeof(ibase_tr_list)); ! 1284: ib_link->tr_list->trans = NULL; ! 1285: ib_link->tr_list->next = NULL; ! 1286: } ! 1287: ! 1288: if (*trans == NULL) { ! 1289: ibase_trans *tr = ib_link->tr_list->trans; ! 1290: ! 1291: if (tr == NULL) { ! 1292: tr = (ibase_trans *) emalloc(sizeof(ibase_trans)); ! 1293: tr->handle = NULL; ! 1294: tr->link_cnt = 1; ! 1295: tr->affected_rows = 0; ! 1296: tr->db_link[0] = ib_link; ! 1297: ib_link->tr_list->trans = tr; ! 1298: } ! 1299: if (tr->handle == NULL) { ! 1300: if (isc_start_transaction(IB_STATUS, &tr->handle, 1, &ib_link->handle, 0, NULL)) { ! 1301: _php_ibase_error(TSRMLS_C); ! 1302: return FAILURE; ! 1303: } ! 1304: } ! 1305: *trans = tr; ! 1306: } ! 1307: return SUCCESS; ! 1308: } ! 1309: /* }}} */ ! 1310: ! 1311: static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{{ */ ! 1312: { ! 1313: ibase_trans *trans = NULL; ! 1314: int res_id = 0; ! 1315: ISC_STATUS result; ! 1316: ibase_db_link *ib_link; ! 1317: zval *arg = NULL; ! 1318: int type; ! 1319: ! 1320: RESET_ERRMSG; ! 1321: ! 1322: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &arg) == FAILURE) { ! 1323: return; ! 1324: } ! 1325: ! 1326: if (ZEND_NUM_ARGS() == 0) { ! 1327: ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, NULL, IBG(default_link), LE_LINK, le_link, le_plink); ! 1328: if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) { ! 1329: /* this link doesn't have a default transaction */ ! 1330: _php_ibase_module_error("Default link has no default transaction" TSRMLS_CC); ! 1331: RETURN_FALSE; ! 1332: } ! 1333: trans = ib_link->tr_list->trans; ! 1334: } else { ! 1335: /* one id was passed, could be db or trans id */ ! 1336: if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) { ! 1337: ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans); ! 1338: res_id = Z_RESVAL_P(arg); ! 1339: } else { ! 1340: ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink); ! 1341: ! 1342: if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) { ! 1343: /* this link doesn't have a default transaction */ ! 1344: _php_ibase_module_error("Link has no default transaction" TSRMLS_CC); ! 1345: RETURN_FALSE; ! 1346: } ! 1347: trans = ib_link->tr_list->trans; ! 1348: } ! 1349: } ! 1350: ! 1351: switch (commit) { ! 1352: default: /* == case ROLLBACK: */ ! 1353: result = isc_rollback_transaction(IB_STATUS, &trans->handle); ! 1354: break; ! 1355: case COMMIT: ! 1356: result = isc_commit_transaction(IB_STATUS, &trans->handle); ! 1357: break; ! 1358: case (ROLLBACK | RETAIN): ! 1359: result = isc_rollback_retaining(IB_STATUS, &trans->handle); ! 1360: break; ! 1361: case (COMMIT | RETAIN): ! 1362: result = isc_commit_retaining(IB_STATUS, &trans->handle); ! 1363: break; ! 1364: } ! 1365: ! 1366: if (result) { ! 1367: _php_ibase_error(TSRMLS_C); ! 1368: RETURN_FALSE; ! 1369: } ! 1370: ! 1371: /* Don't try to destroy implicitly opened transaction from list... */ ! 1372: if ((commit & RETAIN) == 0 && res_id != 0) { ! 1373: zend_list_delete(res_id); ! 1374: } ! 1375: RETURN_TRUE; ! 1376: } ! 1377: /* }}} */ ! 1378: ! 1379: /* {{{ proto bool ibase_commit( resource link_identifier ) ! 1380: Commit transaction */ ! 1381: PHP_FUNCTION(ibase_commit) ! 1382: { ! 1383: _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT); ! 1384: } ! 1385: /* }}} */ ! 1386: ! 1387: /* {{{ proto bool ibase_rollback( resource link_identifier ) ! 1388: Rollback transaction */ ! 1389: PHP_FUNCTION(ibase_rollback) ! 1390: { ! 1391: _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK); ! 1392: } ! 1393: /* }}} */ ! 1394: ! 1395: /* {{{ proto bool ibase_commit_ret( resource link_identifier ) ! 1396: Commit transaction and retain the transaction context */ ! 1397: PHP_FUNCTION(ibase_commit_ret) ! 1398: { ! 1399: _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, COMMIT | RETAIN); ! 1400: } ! 1401: /* }}} */ ! 1402: ! 1403: /* {{{ proto bool ibase_rollback_ret( resource link_identifier ) ! 1404: Rollback transaction and retain the transaction context */ ! 1405: PHP_FUNCTION(ibase_rollback_ret) ! 1406: { ! 1407: _php_ibase_trans_end(INTERNAL_FUNCTION_PARAM_PASSTHRU, ROLLBACK | RETAIN); ! 1408: } ! 1409: /* }}} */ ! 1410: ! 1411: /* {{{ proto int ibase_gen_id(string generator [, int increment [, resource link_identifier ]]) ! 1412: Increments the named generator and returns its new value */ ! 1413: PHP_FUNCTION(ibase_gen_id) ! 1414: { ! 1415: zval *link = NULL; ! 1416: char query[128], *generator; ! 1417: int gen_len; ! 1418: long inc = 1; ! 1419: ibase_db_link *ib_link; ! 1420: ibase_trans *trans = NULL; ! 1421: XSQLDA out_sqlda; ! 1422: ISC_INT64 result; ! 1423: ! 1424: RESET_ERRMSG; ! 1425: ! 1426: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &generator, &gen_len, ! 1427: &inc, &link)) { ! 1428: RETURN_FALSE; ! 1429: } ! 1430: ! 1431: if (gen_len > 31) { ! 1432: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid generator name"); ! 1433: RETURN_FALSE; ! 1434: } ! 1435: ! 1436: PHP_IBASE_LINK_TRANS(link, ib_link, trans); ! 1437: ! 1438: snprintf(query, sizeof(query), "SELECT GEN_ID(%s,%ld) FROM rdb$database", generator, inc); ! 1439: ! 1440: /* allocate a minimal descriptor area */ ! 1441: out_sqlda.sqln = out_sqlda.sqld = 1; ! 1442: out_sqlda.version = SQLDA_CURRENT_VERSION; ! 1443: ! 1444: /* allocate the field for the result */ ! 1445: out_sqlda.sqlvar[0].sqltype = SQL_INT64; ! 1446: out_sqlda.sqlvar[0].sqlscale = 0; ! 1447: out_sqlda.sqlvar[0].sqllen = sizeof(result); ! 1448: out_sqlda.sqlvar[0].sqldata = (void*) &result; ! 1449: ! 1450: /* execute the query */ ! 1451: if (isc_dsql_exec_immed2(IB_STATUS, &ib_link->handle, &trans->handle, 0, query, ! 1452: SQL_DIALECT_CURRENT, NULL, &out_sqlda)) { ! 1453: _php_ibase_error(TSRMLS_C); ! 1454: RETURN_FALSE; ! 1455: } ! 1456: ! 1457: /* don't return the generator value as a string unless it doesn't fit in a long */ ! 1458: #if SIZEOF_LONG < 8 ! 1459: if (result < LONG_MIN || result > LONG_MAX) { ! 1460: char *res; ! 1461: int l; ! 1462: ! 1463: l = spprintf(&res, 0, "%" LL_MASK "d", result); ! 1464: RETURN_STRINGL(res, l, 0); ! 1465: } ! 1466: #endif ! 1467: RETURN_LONG((long)result); ! 1468: } ! 1469: ! 1470: /* }}} */ ! 1471: ! 1472: #endif /* HAVE_IBASE */ ! 1473: ! 1474: /* ! 1475: * Local variables: ! 1476: * tab-width: 4 ! 1477: * c-basic-offset: 4 ! 1478: * End: ! 1479: * vim600: sw=4 ts=4 fdm=marker ! 1480: * vim<600: sw=4 ts=4 ! 1481: */