abies Sun Aug 17 20:14:53 2003 EDT Modified files: /php-src/ext/interbase php_interbase.h interbase.c Log: Nuke bogus BLOB ids # User-space BLOB id no longer contains transaction handle, so BLOB ids # now remain valid throughout multiple transactions. # Oh, and they look better too :-)
Index: php-src/ext/interbase/php_interbase.h diff -u php-src/ext/interbase/php_interbase.h:1.52 php-src/ext/interbase/php_interbase.h:1.53 --- php-src/ext/interbase/php_interbase.h:1.52 Sat Aug 16 11:31:06 2003 +++ php-src/ext/interbase/php_interbase.h Sun Aug 17 20:14:53 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_interbase.h,v 1.52 2003/08/16 15:31:06 abies Exp $ */ +/* $Id: php_interbase.h,v 1.53 2003/08/18 00:14:53 abies Exp $ */ #ifndef PHP_INTERBASE_H #define PHP_INTERBASE_H @@ -114,6 +114,7 @@ char *cfg_timeformat; char errmsg[MAX_ERRMSG]; long sql_code; + HashTable blob_table; ZEND_END_MODULE_GLOBALS(ibase) typedef struct { @@ -142,10 +143,10 @@ } ibase_array; typedef struct { - isc_tr_handle trans_handle; - isc_db_handle link; - ISC_QUAD bl_qd; + ibase_db_link *link; isc_blob_handle bl_handle; + ISC_QUAD bl_qd; + unsigned short type; } ibase_blob_handle; typedef struct { @@ -164,8 +165,8 @@ } ibase_query; typedef struct { - isc_db_handle link; /* db link for this result */ - isc_tr_handle trans; + ibase_db_link *link; + ibase_trans *trans; isc_stmt_handle stmt; int drop_stmt; XSQLDA *out_sqlda; Index: php-src/ext/interbase/interbase.c diff -u php-src/ext/interbase/interbase.c:1.152 php-src/ext/interbase/interbase.c:1.153 --- php-src/ext/interbase/interbase.c:1.152 Sun Aug 17 12:30:15 2003 +++ php-src/ext/interbase/interbase.c Sun Aug 17 20:14:53 2003 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: interbase.c,v 1.152 2003/08/17 16:30:15 abies Exp $ */ +/* $Id: interbase.c,v 1.153 2003/08/18 00:14:53 abies Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -51,6 +51,9 @@ #define SAFE_STRING(s) ((s)?(s):"") +#define BLOB_ID_LEN 18 +#define BLOB_ID_MASK "0x%08lx%08lx" + /* {{{ extension definition structures */ function_entry ibase_functions[] = { PHP_FE(ibase_connect, NULL) @@ -264,24 +267,6 @@ short sqlind; } BIND_BUF; -/* get blob identifier from argument - * on empty unset argument ib_blob set to NULL - */ -static int _php_ibase_get_blob_id(zval **blob_arg, ibase_blob_handle **ib_blob) -{ - if (Z_TYPE_PP(blob_arg) == IS_STRING && Z_STRLEN_PP(blob_arg) == 0) { - *ib_blob = NULL; - } else if (Z_TYPE_PP(blob_arg) != IS_STRING - || Z_STRLEN_PP(blob_arg) != sizeof(ibase_blob_handle) - || ((ibase_blob_handle *)(Z_STRVAL_PP(blob_arg)))->bl_handle != 0) { - - _php_ibase_module_error("Invalid blob id"); - return FAILURE; - } else { - *ib_blob = (ibase_blob_handle *)Z_STRVAL_PP(blob_arg); - } - return SUCCESS; -} /* get blob handle from argument * note: blob already open when handle active @@ -582,7 +567,6 @@ } _php_ibase_event_free(event->event_buffer,event->result_buffer); } - /* }}} */ /* {{{ startup, shutdown and info functions */ @@ -664,6 +648,8 @@ RESET_ERRMSG; + zend_hash_init(&IBG(blob_table), 0, NULL, NULL, 0); + return SUCCESS; } @@ -690,6 +676,8 @@ } IBG(timeformat) = NULL; + zend_hash_destroy(&IBG(blob_table)); + return SUCCESS; } @@ -699,7 +687,7 @@ php_info_print_table_start(); php_info_print_table_row(2, "Interbase Support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.152 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.153 $"); #ifdef COMPILE_DL_INTERBASE php_info_print_table_row(2, "Dynamic Module", "Yes"); #endif @@ -864,15 +852,15 @@ int open_new_connection = 1; if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void **) &le) != FAILURE) { - char tmp_1[] = {isc_info_base_level, isc_info_end}; - char tmp_2[8]; /* Enough? Hope so... */ + static char info[] = {isc_info_base_level, isc_info_end}; + char result[8]; /* Enough? Hope so... */ if (Z_TYPE_P(le) != le_plink) { RETURN_FALSE; } /* Check if connection has timed out */ ib_link = (ibase_db_link *) le->ptr; - if (!isc_database_info(IB_STATUS, &ib_link->handle, sizeof(tmp_1), tmp_1, sizeof(tmp_2), tmp_2)) { + if (!isc_database_info(IB_STATUS, &ib_link->handle, sizeof(info), info, sizeof(result), result)) { open_new_connection = 0; } } @@ -1027,6 +1015,7 @@ } ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, "InterBase link", le_link, le_plink); + zend_hash_clean(&IBG(blob_table)); /* TODO only remove entries that belong to closed link */ zend_list_delete(link_id); RETURN_TRUE; } @@ -1072,6 +1061,7 @@ } zend_list_delete(link_id); + zend_hash_clean(&IBG(blob_table)); /* TODO only remove entries that belong to closed link */ RETURN_TRUE; } /* }}} */ @@ -1172,7 +1162,8 @@ static int _php_ibase_alloc_query(ibase_query **ib_queryp, ibase_db_link *link, ibase_trans *trans, char *query, unsigned short dialect, int trans_res_id TSRMLS_DC) { #define IB_QUERY (*ib_queryp) - char info_type[] = {isc_info_sql_stmt_type}, result[8]; + static char info_type[] = {isc_info_sql_stmt_type}; + char result[8]; IB_QUERY = emalloc(sizeof(ibase_query)); IB_QUERY->link = link; @@ -1462,33 +1453,38 @@ #endif break; case SQL_BLOB: - if (Z_TYPE_P(b_var) != IS_STRING || Z_STRLEN_P(b_var) != sizeof(ibase_blob_handle) || - ((ibase_blob_handle *)(Z_STRVAL_P(b_var)))->bl_handle != 0) { - - ibase_blob_handle ib_blob; - - ib_blob.trans_handle = ib_query->trans->handle; - ib_blob.link = ib_query->link->handle; - ib_blob.bl_handle = NULL; - - if (isc_create_blob(IB_STATUS, &ib_blob.link, &ib_blob.trans_handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { - _php_ibase_error(TSRMLS_C); - return FAILURE; - } + { + ibase_blob_handle *blob; + + convert_to_string(b_var); - if (_php_ibase_blob_add(&b_var, &ib_blob TSRMLS_CC) != SUCCESS) { - return FAILURE; - } + if (Z_STRLEN_P(b_var) != BLOB_ID_LEN || + zend_hash_find(&IBG(blob_table),Z_STRVAL_P(b_var),Z_STRLEN_P(b_var),(void **) &blob) != SUCCESS) { + + ibase_blob_handle ib_blob; + + ib_blob.link = ib_query->link; + ib_blob.bl_handle = NULL; + + if (isc_create_blob(IB_STATUS, &ib_blob.link->handle, &ib_query->trans->handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { + _php_ibase_error(TSRMLS_C); + return FAILURE; + } + + if (_php_ibase_blob_add(&b_var, &ib_blob TSRMLS_CC) != SUCCESS) { + return FAILURE; + } + + if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) { + _php_ibase_error(TSRMLS_C); + return FAILURE; + } + buf[i].val.qval = ib_blob.bl_qd; + var->sqldata = (void ISC_FAR *) &buf[i].val.qval; - if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) { - _php_ibase_error(TSRMLS_C); - return FAILURE; + } else { + var->sqldata = (void ISC_FAR *) &blob->bl_qd; } - buf[i].val.qval = ib_blob.bl_qd; - var->sqldata = (void ISC_FAR *) &buf[i].val.qval; - - } else { - var->sqldata = (void ISC_FAR *) &((ibase_blob_handle *) Z_STRVAL_P(b_var))->bl_qd; } break; case SQL_ARRAY: @@ -1568,7 +1564,8 @@ XSQLDA *in_sqlda = NULL, *out_sqlda = NULL; BIND_BUF *bind_buf = NULL; int rv = FAILURE; - char info_count[] = {isc_info_sql_records}, result[64]; + static char info_count[] = {isc_info_sql_records}; + char result[64]; ISC_STATUS isc_result; RESET_ERRMSG; @@ -1639,8 +1636,8 @@ if (ib_query->out_sqlda) { /* output variables in select, select for update */ IBDEBUG("Query wants XSQLDA for output"); IB_RESULT = emalloc(sizeof(ibase_result)); - IB_RESULT->link = ib_query->link->handle; - IB_RESULT->trans = ib_query->trans->handle; + IB_RESULT->link = ib_query->link; + IB_RESULT->trans = ib_query->trans; IB_RESULT->stmt = ib_query->stmt; IB_RESULT->statement_type = ib_query->statement_type; IB_RESULT->drop_stmt = 0; /* when free result close but not drop!*/ @@ -2272,7 +2269,8 @@ zval **result_arg; ibase_result *ib_result; - char info_count[] = {isc_info_sql_records}, result[64]; + static char info_count[] = {isc_info_sql_records}; + char result[64]; RESET_ERRMSG; @@ -2627,12 +2625,13 @@ ibase_blob_handle blob_handle; unsigned long max_len = 0; - char bl_items[] = {isc_info_blob_total_length}, bl_info[20], *p; + static char bl_items[] = {isc_info_blob_total_length}; + char bl_info[20], *p; blob_handle.bl_handle = NULL; blob_handle.bl_qd = *(ISC_QUAD ISC_FAR *) var->sqldata; - if (isc_open_blob(IB_STATUS, &ib_result->link, &ib_result->trans, &blob_handle.bl_handle, &blob_handle.bl_qd)) { + if (isc_open_blob(IB_STATUS, &ib_result->link->handle, &ib_result->trans->handle, &blob_handle.bl_handle, &blob_handle.bl_qd)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } @@ -2671,14 +2670,12 @@ } } else { /* blob id only */ - - ibase_blob_handle *ib_blob_id = (ibase_blob_handle *) ecalloc(1, sizeof(ibase_blob_handle) + 1); - - ib_blob_id->link = ib_result->link; - ib_blob_id->trans_handle = ib_result->trans; - ib_blob_id->bl_qd = *(ISC_QUAD ISC_FAR *) var->sqldata; + char result[BLOB_ID_LEN]; + ibase_blob_handle ib_blob = { ib_result->link, NULL, *(ISC_QUAD ISC_FAR *) var->sqldata }; - ZVAL_STRINGL(&tmp, (char *) ib_blob_id, sizeof(ibase_blob_handle),0); + sprintf(result, BLOB_ID_MASK, ib_blob.bl_qd.gds_quad_high, ib_blob.bl_qd.gds_quad_low); + zend_hash_update(&IBG(blob_table), result, BLOB_ID_LEN, &ib_blob, sizeof(ibase_blob_handle), NULL); + ZVAL_STRINGL(&tmp, result, BLOB_ID_LEN,1); } break; case SQL_ARRAY: { @@ -2691,7 +2688,7 @@ ar_data = emalloc(ib_array->ar_size); - if (isc_array_get_slice(IB_STATUS, &ib_result->link, &ib_result->trans, &ar_qd, &ib_array->ar_desc, ar_data, &ib_array->ar_size)) { + if (isc_array_get_slice(IB_STATUS, &ib_result->link->handle, &ib_result->trans->handle, &ar_qd, &ib_array->ar_desc, ar_data, &ib_array->ar_size)) { _php_ibase_error(TSRMLS_C); efree(ar_data); RETURN_FALSE; @@ -3298,6 +3295,10 @@ /* {{{ proto int ibase_blob_create([resource link_identifier]) Create blob for adding data */ + +#define BLOB_INPUT 1 +#define BLOB_OUTPUT 2 + PHP_FUNCTION(ibase_blob_create) { zval **link_arg; @@ -3328,11 +3329,11 @@ } ib_blob = (ibase_blob_handle *) emalloc(sizeof(ibase_blob_handle)); - ib_blob->trans_handle = trans->handle; - ib_blob->link = ib_link->handle; + ib_blob->link = ib_link; ib_blob->bl_handle = NULL; + ib_blob->type = BLOB_INPUT; - if (isc_create_blob(IB_STATUS, &ib_blob->link, &ib_blob->trans_handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) { + if (isc_create_blob(IB_STATUS, &ib_blob->link->handle, &trans->handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) { efree(ib_blob); _php_ibase_error(TSRMLS_C); RETURN_FALSE; @@ -3348,6 +3349,7 @@ { zval **blob_arg; ibase_blob_handle *ib_blob, *ib_blob_id; + ibase_trans *trans = NULL; RESET_ERRMSG; @@ -3357,20 +3359,23 @@ ib_blob = (ibase_blob_handle *) emalloc(sizeof(ibase_blob_handle)); - if (_php_ibase_get_blob_id(blob_arg, &ib_blob_id) != SUCCESS) { - efree(ib_blob); - RETURN_FALSE; - } - - if (ib_blob_id == NULL) { /* blob IS NULL or argument unset */ + convert_to_string_ex(blob_arg); + + if (zend_hash_find(&IBG(blob_table), Z_STRVAL_PP(blob_arg), Z_STRLEN_PP(blob_arg), (void **) &ib_blob_id) != SUCCESS) { efree(ib_blob); RETURN_FALSE; } *ib_blob = *ib_blob_id; ib_blob->bl_handle = NULL; + ib_blob->type = BLOB_OUTPUT; + + /* open default transaction */ + if (_php_ibase_def_trans(ib_blob->link, &trans TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } - if (isc_open_blob(IB_STATUS, &ib_blob->link, &ib_blob->trans_handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) { + if (isc_open_blob(IB_STATUS, &ib_blob->link->handle, &trans->handle, &ib_blob->bl_handle, &ib_blob->bl_qd)) { efree(ib_blob); _php_ibase_error(TSRMLS_C); RETURN_FALSE; @@ -3396,6 +3401,11 @@ if (_php_ibase_get_blob_handle(blob_arg, &ib_blob TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } + + if (ib_blob->type != BLOB_INPUT) { + _php_ibase_module_error("BLOB is not open for input"); + RETURN_FALSE; + } if (_php_ibase_blob_add(string_arg, ib_blob TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } @@ -3419,7 +3429,13 @@ RETURN_FALSE; } + if (ib_blob->type != BLOB_OUTPUT) { + _php_ibase_module_error("BLOB is not open for output"); + RETURN_FALSE; + } + convert_to_long_ex(len_arg); + if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_PP(len_arg) TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } @@ -3435,6 +3451,7 @@ { zval **blob_arg; ibase_blob_handle *ib_blob; + char *result; RESET_ERRMSG; @@ -3447,6 +3464,7 @@ } if (bl_end == BLOB_CLOSE) { /* return id here */ + if (ib_blob->bl_qd.gds_quad_high || ib_blob->bl_qd.gds_quad_low) { /*not null ?*/ if (isc_close_blob(IB_STATUS, &ib_blob->bl_handle)) { _php_ibase_error(TSRMLS_C); @@ -3454,17 +3472,23 @@ } } ib_blob->bl_handle = NULL; - RETVAL_STRINGL((char *) ib_blob, sizeof(ibase_blob_handle), 1); - zend_list_delete(Z_LVAL_PP(blob_arg)); + + result = (char *) emalloc(BLOB_ID_LEN+1); + sprintf(result, BLOB_ID_MASK, ib_blob->bl_qd.gds_quad_high, ib_blob->bl_qd.gds_quad_low); + result[BLOB_ID_LEN] = '\0'; + if (ib_blob->type == BLOB_INPUT) { + zend_hash_update(&IBG(blob_table), result, BLOB_ID_LEN, ib_blob, sizeof(ibase_blob_handle), NULL); + } + RETVAL_STRINGL(result, BLOB_ID_LEN, 0); } else { /* discard created blob */ if (isc_cancel_blob(IB_STATUS, &ib_blob->bl_handle)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } ib_blob->bl_handle = NULL; - zend_list_delete(Z_LVAL_PP(blob_arg)); - RETURN_TRUE; + RETVAL_BOOL(1); } + zend_list_delete(Z_LVAL_PP(blob_arg)); } /* }}} */ @@ -3490,6 +3514,7 @@ { zval **blob_arg, **result_var; ibase_blob_handle *ib_blob_id; + ibase_trans *trans = NULL; IBASE_BLOBINFO bl_info; RESET_ERRMSG; @@ -3498,14 +3523,19 @@ WRONG_PARAM_COUNT; } - if (_php_ibase_get_blob_id(blob_arg, &ib_blob_id) != SUCCESS) { + if (zend_hash_find(&IBG(blob_table), Z_STRVAL_PP(blob_arg), Z_STRLEN_PP(blob_arg), (void **) &ib_blob_id) != SUCCESS) { RETURN_FALSE; } - + + /* open default transaction */ + if (_php_ibase_def_trans(ib_blob_id->link, &trans TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } + array_init(return_value); if (ib_blob_id->bl_qd.gds_quad_high || ib_blob_id->bl_qd.gds_quad_low) { /* not null ? */ - if (isc_open_blob(IB_STATUS, &ib_blob_id->link, &ib_blob_id->trans_handle, &ib_blob_id->bl_handle, &ib_blob_id->bl_qd)) { + if (isc_open_blob(IB_STATUS, &ib_blob_id->link->handle, &trans->handle, &ib_blob_id->bl_handle, &ib_blob_id->bl_qd)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } @@ -3561,6 +3591,7 @@ char bl_data[IBASE_BLOB_SEG]; unsigned short seg_len; ibase_blob_handle *ib_blob_id; + ibase_trans *trans = NULL; RESET_ERRMSG; @@ -3568,32 +3599,34 @@ WRONG_PARAM_COUNT; } - if (_php_ibase_get_blob_id(blob_arg, &ib_blob_id) != SUCCESS) { + if (zend_hash_find(&IBG(blob_table), Z_STRVAL_PP(blob_arg), Z_STRLEN_PP(blob_arg), (void **) &ib_blob_id) != SUCCESS) { RETURN_FALSE; } - if (ib_blob_id) { /* not null? */ - - if (isc_open_blob(IB_STATUS, &ib_blob_id->link, &ib_blob_id->trans_handle, &ib_blob_id->bl_handle, &ib_blob_id->bl_qd)) { - _php_ibase_error(TSRMLS_C); - RETURN_FALSE; - } + /* open default transaction */ + if (_php_ibase_def_trans(ib_blob_id->link, &trans TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } - while (!isc_get_segment(IB_STATUS, &ib_blob_id->bl_handle, &seg_len, sizeof(bl_data), bl_data) || IB_STATUS[1] == isc_segment) { - PHPWRITE(bl_data, seg_len); - } - - if (IB_STATUS[0] && (IB_STATUS[1] != isc_segstr_eof)) { - _php_ibase_error(TSRMLS_C); - RETURN_FALSE; - } + if (isc_open_blob(IB_STATUS, &ib_blob_id->link->handle, &trans->handle, &ib_blob_id->bl_handle, &ib_blob_id->bl_qd)) { + _php_ibase_error(TSRMLS_C); + RETURN_FALSE; + } - if (isc_close_blob(IB_STATUS, &ib_blob_id->bl_handle)) { - _php_ibase_error(TSRMLS_C); - RETURN_FALSE; - } - ib_blob_id->bl_handle = NULL; - } /* not null ? */ + while (!isc_get_segment(IB_STATUS, &ib_blob_id->bl_handle, &seg_len, sizeof(bl_data), bl_data) || IB_STATUS[1] == isc_segment) { + PHPWRITE(bl_data, seg_len); + } + + if (IB_STATUS[0] && (IB_STATUS[1] != isc_segstr_eof)) { + _php_ibase_error(TSRMLS_C); + RETURN_FALSE; + } + + if (isc_close_blob(IB_STATUS, &ib_blob_id->bl_handle)) { + _php_ibase_error(TSRMLS_C); + RETURN_FALSE; + } + ib_blob_id->bl_handle = NULL; RETURN_TRUE; } @@ -3606,7 +3639,7 @@ zval **link_arg, **file_arg; int link_id = 0, size; unsigned short b; - ibase_blob_handle ib_blob = { NULL, NULL, { 0, 0 }, NULL }; + ibase_blob_handle ib_blob = { NULL, NULL, { 0, 0 }, 0 }; ibase_db_link *ib_link; ibase_trans *trans = NULL; #if (IBASE_BLOB_SEG > USHRT_MAX) @@ -3614,6 +3647,7 @@ #else char bl_data[IBASE_BLOB_SEG]; #endif + char result[BLOB_ID_LEN]; php_stream *stream; RESET_ERRMSG; @@ -3644,10 +3678,9 @@ php_stream_from_zval(stream, file_arg); - ib_blob.link = ib_link->handle; - ib_blob.trans_handle = trans->handle; + ib_blob.link = ib_link; - if (isc_create_blob(IB_STATUS, &ib_blob.link, &ib_blob.trans_handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { + if (isc_create_blob(IB_STATUS, &ib_blob.link->handle, &trans->handle, &ib_blob.bl_handle, &ib_blob.bl_qd)) { _php_ibase_error(TSRMLS_C); RETURN_FALSE; } @@ -3667,8 +3700,9 @@ RETURN_FALSE; } - ib_blob.bl_handle = NULL; - RETVAL_STRINGL((char *) &ib_blob, sizeof(ibase_blob_handle), 1); + sprintf(result, BLOB_ID_MASK, ib_blob.bl_qd.gds_quad_high, ib_blob.bl_qd.gds_quad_low); + zend_hash_update(&IBG(blob_table), result, BLOB_ID_LEN, &ib_blob, sizeof(ibase_blob_handle), NULL); + RETURN_STRINGL(result, BLOB_ID_LEN, 1); } /* }}} */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php