From: Dmitry Stogov Date: Tue, 29 Jul 2014 06:15:01 +0000 (+0400) Subject: ext/interbase support (incomplete) X-Git-Tag: POST_PHPNG_MERGE~45^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21dec5f511f8d3c5973e921d468359ad459545f5;p=php ext/interbase support (incomplete) --- diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index c196134657..d7b419225e 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -628,6 +628,17 @@ static inline void *zend_hash_index_find_ptr(const HashTable *ht, ulong h) return zv ? Z_PTR_P(zv) : NULL; } +static inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, int len) +{ + ulong idx; + + if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) { + return zend_hash_index_find_ptr(ht, idx); + } else { + return zend_hash_str_find_ptr(ht, str, len); + } +} + static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos) { zval *zv; diff --git a/ext/interbase/ibase_blobs.c b/ext/interbase/ibase_blobs.c index 94f32f87ed..8b8d731d7b 100644 --- a/ext/interbase/ibase_blobs.c +++ b/ext/interbase/ibase_blobs.c @@ -32,7 +32,7 @@ static int le_blob; -static void _php_ibase_free_blob(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_free_blob(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_blob *ib_blob = (ibase_blob *)rsrc->ptr; @@ -118,26 +118,28 @@ int _php_ibase_blob_get(zval *return_value, ibase_blob *ib_blob, unsigned long m _php_ibase_error(TSRMLS_C); return FAILURE; } - RETVAL_STRINGL(bl_data, cur_len, 0); + // TODO: avoid double reallocation??? + RETVAL_STRINGL(bl_data, cur_len); + efree(bl_data); } else { /* null blob */ - RETVAL_STRING("", 1); /* empty string */ + RETVAL_EMPTY_STRING(); /* empty string */ } return SUCCESS; } /* }}} */ -int _php_ibase_blob_add(zval **string_arg, ibase_blob *ib_blob TSRMLS_DC) /* {{{ */ +int _php_ibase_blob_add(zval *string_arg, ibase_blob *ib_blob TSRMLS_DC) /* {{{ */ { unsigned long put_cnt = 0, rem_cnt; unsigned short chunk_size; convert_to_string_ex(string_arg); - for (rem_cnt = Z_STRLEN_PP(string_arg); rem_cnt > 0; rem_cnt -= chunk_size) { + for (rem_cnt = Z_STRLEN_P(string_arg); rem_cnt > 0; rem_cnt -= chunk_size) { chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt; - if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &Z_STRVAL_PP(string_arg)[put_cnt] )) { + if (isc_put_segment(IB_STATUS, &ib_blob->bl_handle, chunk_size, &Z_STRVAL_P(string_arg)[put_cnt] )) { _php_ibase_error(TSRMLS_C); return FAILURE; } @@ -228,6 +230,7 @@ PHP_FUNCTION(ibase_blob_create) } ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob); + Z_ADDREF_P(return_value); } /* }}} */ @@ -278,6 +281,7 @@ PHP_FUNCTION(ibase_blob_open) } ZEND_REGISTER_RESOURCE(return_value, ib_blob, le_blob); + Z_ADDREF_P(return_value); return; } while (0); @@ -291,7 +295,7 @@ PHP_FUNCTION(ibase_blob_open) Add data into created blob */ PHP_FUNCTION(ibase_blob_add) { - zval **blob_arg, **string_arg; + zval *blob_arg, *string_arg; ibase_blob *ib_blob; RESET_ERRMSG; @@ -317,7 +321,7 @@ PHP_FUNCTION(ibase_blob_add) Get len bytes data from open blob */ PHP_FUNCTION(ibase_blob_get) { - zval **blob_arg, **len_arg; + zval *blob_arg, *len_arg; ibase_blob *ib_blob; RESET_ERRMSG; @@ -335,7 +339,7 @@ PHP_FUNCTION(ibase_blob_get) convert_to_long_ex(len_arg); - if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_PP(len_arg) TSRMLS_CC) != SUCCESS) { + if (_php_ibase_blob_get(return_value, ib_blob, Z_LVAL_P(len_arg) TSRMLS_CC) != SUCCESS) { RETURN_FALSE; } } @@ -343,8 +347,9 @@ PHP_FUNCTION(ibase_blob_get) static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ */ { - zval **blob_arg; + zval *blob_arg; ibase_blob *ib_blob; + char *s; RESET_ERRMSG; @@ -364,7 +369,10 @@ static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ } ib_blob->bl_handle = NULL; - RETVAL_STRINGL(_php_ibase_quad_to_string(ib_blob->bl_qd), BLOB_ID_LEN, 0); + s = _php_ibase_quad_to_string(ib_blob->bl_qd); + // TODO: avoid double reallocation??? + RETVAL_STRINGL(s, BLOB_ID_LEN); + efree(s); } else { /* discard created blob */ if (isc_cancel_blob(IB_STATUS, &ib_blob->bl_handle)) { _php_ibase_error(TSRMLS_C); @@ -373,7 +381,7 @@ static void _php_ibase_blob_end(INTERNAL_FUNCTION_PARAMETERS, int bl_end) /* {{{ ib_blob->bl_handle = NULL; RETVAL_TRUE; } - zend_list_delete(Z_LVAL_PP(blob_arg)); + zend_list_delete(Z_RES_P(blob_arg)); } /* }}} */ @@ -544,6 +552,7 @@ PHP_FUNCTION(ibase_blob_import) ibase_trans *trans = NULL; char bl_data[IBASE_BLOB_SEG]; php_stream *stream; + char *s; RESET_ERRMSG; @@ -554,7 +563,7 @@ PHP_FUNCTION(ibase_blob_import) PHP_IBASE_LINK_TRANS(link, ib_link, trans); - php_stream_from_zval(stream, &file); + php_stream_from_zval(stream, file); do { if (isc_create_blob(IB_STATUS, &ib_link->handle, &trans->handle, &ib_blob.bl_handle, @@ -571,7 +580,11 @@ PHP_FUNCTION(ibase_blob_import) if (isc_close_blob(IB_STATUS, &ib_blob.bl_handle)) { break; } - RETURN_STRINGL( _php_ibase_quad_to_string(ib_blob.bl_qd), BLOB_ID_LEN, 0); + s = _php_ibase_quad_to_string(ib_blob.bl_qd); + // TODO: avoid double reallocation??? + RETVAL_STRINGL(s, BLOB_ID_LEN); + efree(s); + return; } while (0); _php_ibase_error(TSRMLS_C); diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c index ac3c328a0b..8f519dae2c 100644 --- a/ext/interbase/ibase_events.c +++ b/ext/interbase/ibase_events.c @@ -55,10 +55,9 @@ void _php_ibase_free_event(ibase_event *event TSRMLS_DC) /* {{{ */ *node = event->event_next; } - if (event->callback) { - zval_dtor(event->callback); - FREE_ZVAL(event->callback); - event->callback = NULL; + if (Z_TYPE(event->callback) != IS_UNDEF) { + zval_dtor(&event->callback); + ZVAL_UNDEF(&event->callback); _php_ibase_event_free(event->event_buffer,event->result_buffer); @@ -70,7 +69,7 @@ void _php_ibase_free_event(ibase_event *event TSRMLS_DC) /* {{{ */ } /* }}} */ -static void _php_ibase_free_event_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_free_event_rsrc(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_event *e = (ibase_event *) rsrc->ptr; @@ -124,7 +123,7 @@ static void _php_ibase_event_block(ibase_db_link *ib_link, unsigned short count, Waits for any one of the passed Interbase events to be posted by the database, and returns its name */ PHP_FUNCTION(ibase_wait_event) { - zval ***args; + zval *args; ibase_db_link *ib_link; int num_args; char *event_buffer, *result_buffer, *events[15]; @@ -142,8 +141,8 @@ PHP_FUNCTION(ibase_wait_event) return; } - if (Z_TYPE_PP(args[0]) == IS_RESOURCE) { - if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, args[0], -1, "InterBase link", le_link, le_plink)) { + if (Z_TYPE(args[0]) == IS_RESOURCE) { + if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) { efree(args); RETURN_FALSE; } @@ -160,8 +159,8 @@ PHP_FUNCTION(ibase_wait_event) } for (; i < ZEND_NUM_ARGS(); ++i) { - convert_to_string_ex(args[i]); - events[event_count++] = Z_STRVAL_PP(args[i]); + convert_to_string_ex(&args[i]); + events[event_count++] = Z_STRVAL(args[i]); } /* fills the required data structure with information about the events */ @@ -179,10 +178,10 @@ PHP_FUNCTION(ibase_wait_event) isc_event_counts(occurred_event, buffer_size, event_buffer, result_buffer); for (i = 0; i < event_count; ++i) { if (occurred_event[i]) { - char *result = estrdup(events[i]); + zend_string *result = STR_INIT(events[i], strlen(events[i]), 0); _php_ibase_event_free(event_buffer,result_buffer); efree(args); - RETURN_STRING(result,0); + RETURN_STR(result); } } @@ -197,6 +196,8 @@ PHP_FUNCTION(ibase_wait_event) static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */ unsigned short buffer_size, char *result_buf) { + zval *res; + /* this function is called asynchronously by the Interbase client library. */ TSRMLS_FETCH_FROM_CTX(event->thread_ctx); @@ -208,38 +209,35 @@ static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */ switch (event->state) { unsigned short i; unsigned long occurred_event[15]; - zval event_name, link_id, return_value, *args[2]; + zval return_value, args[2]; default: /* == DEAD */ break; case ACTIVE: - args[0] = &event_name; - args[1] = &link_id; - /* copy the updated results into the result buffer */ memcpy(event->result_buffer, result_buf, buffer_size); - INIT_ZVAL(event_name); - INIT_ZVAL(link_id); - ZVAL_RESOURCE(&link_id, event->link_res_id); + res = zend_hash_index_find(&EG(regular_list), event->link_res_id); + ZVAL_RES(&args[1], Z_RES_P(res)); /* find out which event occurred */ isc_event_counts(occurred_event, buffer_size, event->event_buffer, event->result_buffer); for (i = 0; i < event->event_count; ++i) { if (occurred_event[i]) { - ZVAL_STRING(&event_name,event->events[i],0); + ZVAL_STRING(&args[0], event->events[i]); + efree(event->events[i]); break; } } /* call the callback provided by the user */ if (SUCCESS != call_user_function(EG(function_table), NULL, - event->callback, &return_value, 2, args TSRMLS_CC)) { - _php_ibase_module_error("Error calling callback %s" TSRMLS_CC, Z_STRVAL_P(event->callback)); + &event->callback, &return_value, 2, args TSRMLS_CC)) { + _php_ibase_module_error("Error calling callback %s" TSRMLS_CC, Z_STRVAL(event->callback)); break; } - if (Z_TYPE(return_value) == IS_BOOL && !Z_BVAL(return_value)) { + if (Z_TYPE(return_value) == IS_FALSE) { event->state = DEAD; break; } @@ -265,8 +263,8 @@ PHP_FUNCTION(ibase_set_event_handler) * link resource id (int) as arguments. The value returned from the function is * used to determine if the event handler should remain set. */ - char *cb_name; - zval ***args, **cb_arg; + zend_string *cb_name; + zval *args, *cb_arg; ibase_db_link *ib_link; ibase_event *event; unsigned short i = 1, buffer_size; @@ -284,7 +282,7 @@ PHP_FUNCTION(ibase_set_event_handler) } /* get a working link */ - if (Z_TYPE_PP(args[0]) != IS_STRING) { + if (Z_TYPE(args[0]) != IS_STRING) { /* resource, callback, event_1 [, ... event_15] * No more than 15 events */ @@ -293,16 +291,16 @@ PHP_FUNCTION(ibase_set_event_handler) WRONG_PARAM_COUNT; } - cb_arg = args[1]; + cb_arg = &args[1]; i = 2; - if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, args[0], -1, "InterBase link", le_link, le_plink)) { + if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, &args[0], -1, "InterBase link", le_link, le_plink)) { efree(args); RETURN_FALSE; } - convert_to_long_ex(args[0]); - link_res_id = Z_LVAL_PP(args[0]); + convert_to_long_ex(&args[0]); + link_res_id = Z_LVAL(args[0]); } else { /* callback, event_1 [, ... event_15] @@ -313,7 +311,7 @@ PHP_FUNCTION(ibase_set_event_handler) WRONG_PARAM_COUNT; } - cb_arg = args[0]; + cb_arg = &args[0]; if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link, ibase_db_link *, NULL, IBG(default_link), "InterBase link", le_link, le_plink)) { efree(args); @@ -323,13 +321,13 @@ PHP_FUNCTION(ibase_set_event_handler) } /* get the callback */ - if (!zend_is_callable(*cb_arg, 0, &cb_name TSRMLS_CC)) { - _php_ibase_module_error("Callback argument %s is not a callable function" TSRMLS_CC, cb_name); - efree(cb_name); + if (!zend_is_callable(cb_arg, 0, &cb_name TSRMLS_CC)) { + _php_ibase_module_error("Callback argument %s is not a callable function" TSRMLS_CC, cb_name->val); + STR_RELEASE(cb_name); efree(args); RETURN_FALSE; } - efree(cb_name); + STR_RELEASE(cb_name); /* allocate the event resource */ event = (ibase_event *) safe_emalloc(sizeof(ibase_event), 1, 0); @@ -340,14 +338,11 @@ PHP_FUNCTION(ibase_set_event_handler) event->state = NEW; event->events = (char **) safe_emalloc(sizeof(char *),ZEND_NUM_ARGS()-i,0); - ALLOC_ZVAL(event->callback); - *event->callback = **cb_arg; - INIT_PZVAL(event->callback); - zval_copy_ctor(event->callback); + ZVAL_DUP(&event->callback, cb_arg); for (; i < ZEND_NUM_ARGS(); ++i) { - convert_to_string_ex(args[i]); - event->events[event->event_count++] = estrdup(Z_STRVAL_PP(args[i])); + convert_to_string_ex(&args[i]); + event->events[event->event_count++] = estrdup(Z_STRVAL(args[i])); } /* fills the required data structure with information about the events */ @@ -368,7 +363,7 @@ PHP_FUNCTION(ibase_set_event_handler) ib_link->event_head = event; ZEND_REGISTER_RESOURCE(return_value, event, le_event); - zend_list_addref(Z_LVAL_P(return_value)); + Z_ADDREF_P(return_value); efree(args); } /* }}} */ @@ -384,11 +379,11 @@ PHP_FUNCTION(ibase_free_event_handler) if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &event_arg)) { ibase_event *event; - ZEND_FETCH_RESOURCE(event, ibase_event *, &event_arg, -1, "Interbase event", le_event); + ZEND_FETCH_RESOURCE(event, ibase_event *, event_arg, -1, "Interbase event", le_event); event->state = DEAD; - zend_list_delete(Z_LVAL_P(event_arg)); + zend_list_delete(Z_RES_P(event_arg)); RETURN_TRUE; } else { RETURN_FALSE; diff --git a/ext/interbase/ibase_query.c b/ext/interbase/ibase_query.c index 4914dcd596..1899e5aae1 100644 --- a/ext/interbase/ibase_query.c +++ b/ext/interbase/ibase_query.c @@ -134,7 +134,7 @@ static void _php_ibase_free_stmt_handle(ibase_db_link *link, isc_stmt_handle stm } /* }}} */ -static void _php_ibase_free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_free_result(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_result *ib_result = (ibase_result *) rsrc->ptr; @@ -180,7 +180,7 @@ static void _php_ibase_free_query(ibase_query *ib_query TSRMLS_DC) /* {{{ */ } /* }}} */ -static void php_ibase_free_query_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void php_ibase_free_query_rsrc(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_query *ib_query = (ibase_query *)rsrc->ptr; @@ -443,7 +443,7 @@ static int _php_ibase_bind_array(zval *val, char *buf, unsigned long buf_size, / if (dim < array->ar_desc.array_desc_dimensions) { unsigned long slice_size = buf_size / dim_len; unsigned short i; - zval **subval = &val; + zval *subval = val; if (Z_TYPE_P(val) == IS_ARRAY) { zend_hash_internal_pointer_reset(Z_ARRVAL_P(val)); @@ -452,12 +452,12 @@ static int _php_ibase_bind_array(zval *val, char *buf, unsigned long buf_size, / for (i = 0; i < dim_len; ++i) { if (Z_TYPE_P(val) == IS_ARRAY && - zend_hash_get_current_data(Z_ARRVAL_P(val), (void *) &subval) == FAILURE) + (subval = zend_hash_get_current_data(Z_ARRVAL_P(val))) == NULL) { - subval = &pnull_val; + subval = pnull_val; } - if (_php_ibase_bind_array(*subval, buf, slice_size, array, dim+1 TSRMLS_CC) == FAILURE) + if (_php_ibase_bind_array(subval, buf, slice_size, array, dim+1 TSRMLS_CC) == FAILURE) { return FAILURE; } @@ -634,14 +634,14 @@ static int _php_ibase_bind_array(zval *val, char *buf, unsigned long buf_size, / } /* }}} */ -static int _php_ibase_bind(XSQLDA *sqlda, zval ***b_vars, BIND_BUF *buf, /* {{{ */ +static int _php_ibase_bind(XSQLDA *sqlda, zval *b_vars, BIND_BUF *buf, /* {{{ */ ibase_query *ib_query TSRMLS_DC) { int i, array_cnt = 0, rv = SUCCESS; for (i = 0; i < sqlda->sqld; ++i) { /* bound vars */ - zval *b_var = *b_vars[i]; + zval *b_var = &b_vars[i]; XSQLVAR *var = &sqlda->sqlvar[i]; var->sqlind = &buf[i].sqlind; @@ -745,7 +745,7 @@ static int _php_ibase_bind(XSQLDA *sqlda, zval ***b_vars, BIND_BUF *buf, /* {{{ return FAILURE; } - if (_php_ibase_blob_add(&b_var, &ib_blob TSRMLS_CC) != SUCCESS) { + if (_php_ibase_blob_add(b_var, &ib_blob TSRMLS_CC) != SUCCESS) { return FAILURE; } @@ -860,7 +860,7 @@ static void _php_ibase_alloc_xsqlda(XSQLDA *sqlda) /* {{{ */ /* }}} */ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resultp, /* {{{ */ - ibase_query *ib_query, zval ***args) + ibase_query *ib_query, zval *args) { XSQLDA *in_sqlda = NULL, *out_sqlda = NULL; BIND_BUF *bind_buf = NULL; @@ -873,7 +873,7 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul RESET_ERRMSG; for (i = 0; i < argc; ++i) { - SEPARATE_ZVAL(args[i]); + SEPARATE_ZVAL(&args[i]); } switch (ib_query->statement_type) { @@ -911,6 +911,7 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul (*l)->next = NULL; ZEND_REGISTER_RESOURCE(return_value, trans, le_trans); + Z_ADDREF_P(return_value); return SUCCESS; @@ -926,7 +927,8 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul if (ib_query->trans->handle == NULL && ib_query->trans_res_id != 0) { /* transaction was released by the query and was a registered resource, so we have to release it */ - zend_list_delete(ib_query->trans_res_id); + zval *res = zend_hash_index_find(&EG(regular_list), ib_query->trans_res_id); + zend_list_delete(Z_RES_P(res)); } RETVAL_TRUE; @@ -1058,7 +1060,7 @@ _php_ibase_exec_error: Execute a query */ PHP_FUNCTION(ibase_query) { - zval *zlink, *ztrans, ***bind_args = NULL; + zval *zlink, *ztrans, *bind_args = NULL; char *query; int bind_i, query_len, bind_num; long trans_res_id = 0; @@ -1078,20 +1080,20 @@ PHP_FUNCTION(ibase_query) if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 3 TSRMLS_CC, "rrs", &zlink, &ztrans, &query, &query_len)) { - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link*, &zlink, -1, LE_LINK, le_link, le_plink); - ZEND_FETCH_RESOURCE(trans, ibase_trans*, &ztrans, -1, LE_TRANS, le_trans); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link*, zlink, -1, LE_LINK, le_link, le_plink); + ZEND_FETCH_RESOURCE(trans, ibase_trans*, ztrans, -1, LE_TRANS, le_trans); - trans_res_id = Z_LVAL_P(ztrans); + trans_res_id = Z_RES_P(ztrans)->handle; bind_i = 3; break; } case 2: if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, 2 TSRMLS_CC, "rs", &zlink, &query, &query_len)) { - _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, &zlink, &ib_link, &trans); + _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, zlink, &ib_link, &trans); if (trans != NULL) { - trans_res_id = Z_LVAL_P(zlink); + trans_res_id = Z_RES_P(zlink)->handle; } bind_i = 2; break; @@ -1130,8 +1132,8 @@ PHP_FUNCTION(ibase_query) ib_link->event_head = NULL; ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link); - zend_list_addref(Z_LVAL_P(return_value)); - IBG(default_link) = Z_LVAL_P(return_value); + Z_ADDREF_P(return_value); + IBG(default_link) = Z_RES_P(return_value)->handle; ++IBG(num_links); } return; @@ -1185,14 +1187,12 @@ PHP_FUNCTION(ibase_query) ib_query.stmt = NULL; /* keep stmt when free query */ } ZEND_REGISTER_RESOURCE(return_value, result, le_result); + Z_ADDREF_P(return_value); } } while (0); _php_ibase_free_query(&ib_query TSRMLS_CC); - if (bind_args) { - efree(bind_args); - } } /* }}} */ @@ -1218,9 +1218,9 @@ PHP_FUNCTION(ibase_affected_rows) trans = ib_link->tr_list->trans; } else { /* one id was passed, could be db or trans id */ - _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, &arg, &ib_link, &trans); + _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, arg, &ib_link, &trans); if (trans == NULL) { - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink); if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) { RETURN_FALSE; @@ -1323,7 +1323,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{ data = ((IBVARY *) data)->vary_string; /* no break */ case SQL_TEXT: - ZVAL_STRINGL(val,(char *) data,len,1); + ZVAL_STRINGL(val, (char*)data, len); break; case SQL_SHORT: n = *(short *) data; @@ -1365,7 +1365,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{ } else { l = slprintf(string_data, sizeof(string_data), "-0.%0*ld", -scale, -n % f); } - ZVAL_STRINGL(val,string_data,l,1); + ZVAL_STRINGL(val, string_data, l); } break; case SQL_FLOAT: @@ -1414,7 +1414,7 @@ format_date_time: break; } #endif - ZVAL_STRINGL(val,string_data,l,1); + ZVAL_STRINGL(val, string_data, l); break; } } /* switch (type) */ @@ -1440,17 +1440,16 @@ static int _php_ibase_arr_zval(zval *ar_zval, char *data, unsigned long data_siz array_init(ar_zval); for (i = 0; i < dim_len; ++i) { - zval *slice_zval; - ALLOC_INIT_ZVAL(slice_zval); + zval slice_zval; /* recursion here */ - if (FAILURE == _php_ibase_arr_zval(slice_zval, data, slice_size, ib_array, dim + 1, + if (FAILURE == _php_ibase_arr_zval(&slice_zval, data, slice_size, ib_array, dim + 1, flag TSRMLS_CC)) { return FAILURE; } data += slice_size; - add_index_zval(ar_zval,l_bound+i,slice_zval); + add_index_zval(ar_zval, l_bound + i, &slice_zval); } } else { /* data at last */ @@ -1483,7 +1482,7 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) return; } - ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result); + ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result); if (ib_result->out_sqlda == NULL || !ib_result->has_more_rows) { RETURN_FALSE; @@ -1522,8 +1521,8 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) i = 1; base = alias; - while (SUCCESS == zend_symtable_find( - Z_ARRVAL_P(return_value),alias,strlen(alias)+1,&p)) { + while ((p = zend_symtable_str_find_ptr( + Z_ARRVAL_P(return_value), alias, strlen(alias))) != NULL) { case '\0': snprintf(alias = buf, sizeof(buf), "%s_%02d", base, i++); @@ -1532,13 +1531,12 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) } if (((var->sqltype & 1) == 0) || *var->sqlind != -1) { - zval *result; - ALLOC_INIT_ZVAL(result); + zval result; switch (var->sqltype & ~1) { default: - _php_ibase_var_zval(result, var->sqldata, var->sqltype, var->sqllen, + _php_ibase_var_zval(&result, var->sqldata, var->sqltype, var->sqllen, var->sqlscale, flag TSRMLS_CC); break; case SQL_BLOB: @@ -1588,8 +1586,8 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) } if (max_len == 0) { - ZVAL_STRING(result, "", 1); - } else if (SUCCESS != _php_ibase_blob_get(result, &blob_handle, + ZVAL_STRING(&result, ""); + } else if (SUCCESS != _php_ibase_blob_get(&result, &blob_handle, max_len TSRMLS_CC)) { goto _php_ibase_fetch_error; } @@ -1600,8 +1598,11 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) } } else { /* blob id only */ + char *s; ISC_QUAD bl_qd = *(ISC_QUAD *) var->sqldata; - ZVAL_STRINGL(result,_php_ibase_quad_to_string(bl_qd), BLOB_ID_LEN, 0); + s = _php_ibase_quad_to_string(bl_qd); + ZVAL_STRINGL(&result, s, BLOB_ID_LEN); + efree(s); } break; case SQL_ARRAY: @@ -1618,7 +1619,7 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) goto _php_ibase_fetch_error; } - if (FAILURE == _php_ibase_arr_zval(result, ar_data, ib_array->ar_size, ib_array, + if (FAILURE == _php_ibase_arr_zval(&result, ar_data, ib_array->ar_size, ib_array, 0, flag TSRMLS_CC)) { efree(ar_data); goto _php_ibase_fetch_error; @@ -1626,20 +1627,21 @@ static void _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int fetch_type) efree(ar_data); } else { /* blob id only */ + char *s; ISC_QUAD ar_qd = *(ISC_QUAD *) var->sqldata; - ZVAL_STRINGL(result,_php_ibase_quad_to_string(ar_qd), BLOB_ID_LEN, 0); + s = _php_ibase_quad_to_string(ar_qd); + ZVAL_STRINGL(&result, s, BLOB_ID_LEN); } break; _php_ibase_fetch_error: - zval_dtor(result); - FREE_ZVAL(result); + zval_dtor(&result); RETURN_FALSE; } /* switch */ if (fetch_type & FETCH_ROW) { - add_index_zval(return_value, i, result); + add_index_zval(return_value, i, &result); } else { - add_assoc_zval(return_value, alias, result); + add_assoc_zval(return_value, alias, &result); } } else { if (fetch_type & FETCH_ROW) { @@ -1675,7 +1677,7 @@ PHP_FUNCTION(ibase_fetch_object) _php_ibase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FETCH_ARRAY); if (Z_TYPE_P(return_value) == IS_ARRAY) { - object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value)); + convert_to_object(return_value); } } /* }}} */ @@ -1696,7 +1698,7 @@ PHP_FUNCTION(ibase_name_result) return; } - ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result); + ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result); if (isc_dsql_set_cursor_name(IB_STATUS, &ib_result->stmt, name_arg, 0)) { _php_ibase_error(TSRMLS_C); @@ -1720,8 +1722,8 @@ PHP_FUNCTION(ibase_free_result) return; } - ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result); - zend_list_delete(Z_RESVAL_P(result_arg)); + ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result); + zend_list_delete(Z_RES_P(result_arg)); RETURN_TRUE; } /* }}} */ @@ -1748,18 +1750,18 @@ PHP_FUNCTION(ibase_prepare) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &link_arg, &query, &query_len) == FAILURE) { return; } - _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, &link_arg, &ib_link, &trans); + _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, link_arg, &ib_link, &trans); if (trans != NULL) { - trans_res_id = Z_RESVAL_P(link_arg); + trans_res_id = Z_RES_P(link_arg)->handle; } } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrs", &link_arg, &trans_arg, &query, &query_len) == FAILURE) { return; } - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, -1, LE_LINK, le_link, le_plink); - ZEND_FETCH_RESOURCE(trans, ibase_trans *, &trans_arg, -1, LE_TRANS, le_trans); - trans_res_id = Z_RESVAL_P(trans_arg); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, -1, LE_LINK, le_link, le_plink); + ZEND_FETCH_RESOURCE(trans, ibase_trans *, trans_arg, -1, LE_TRANS, le_trans); + trans_res_id = Z_RES_P(trans_arg)->handle; } if (FAILURE == _php_ibase_def_trans(ib_link, &trans TSRMLS_CC)) { @@ -1773,6 +1775,7 @@ PHP_FUNCTION(ibase_prepare) RETURN_FALSE; } ZEND_REGISTER_RESOURCE(return_value, ib_query, le_query); + Z_ADDREF_P(return_value); } /* }}} */ @@ -1780,24 +1783,23 @@ PHP_FUNCTION(ibase_prepare) Execute a previously prepared query */ PHP_FUNCTION(ibase_execute) { - zval *query, ***args = NULL; + zval *query, *args = NULL; ibase_query *ib_query; ibase_result *result = NULL; - ALLOCA_FLAG(use_heap) + int bind_n = 0; RESET_ERRMSG; RETVAL_FALSE; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() ? 1 : 0 TSRMLS_CC, "r", &query)) { + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r*", &query, &args, &bind_n)) { return; } - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &query, -1, LE_QUERY, le_query); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query, -1, LE_QUERY, le_query); do { - int bind_n = ZEND_NUM_ARGS() - 1, - expected_n = ib_query->in_sqlda ? ib_query->in_sqlda->sqld : 0; + int expected_n = ib_query->in_sqlda ? ib_query->in_sqlda->sqld : 0; if (bind_n != expected_n) { php_error_docref(NULL TSRMLS_CC, (bind_n < expected_n) ? E_WARNING : E_NOTICE, @@ -1808,16 +1810,11 @@ PHP_FUNCTION(ibase_execute) } } - /* have variables to bind */ - args = (zval ***) do_alloca((expected_n + 1) * sizeof(zval **), use_heap); - - if (FAILURE == zend_get_parameters_array_ex((expected_n + 1), args)) { - break; - } - /* Have we used this cursor before and it's still open (exec proc has no cursor) ? */ if (ib_query->result_res_id != 0 && ib_query->statement_type != isc_info_sql_stmt_exec_procedure) { + zval *res; + IBDEBUG("Implicitly closing a cursor"); if (isc_dsql_free_statement(IB_STATUS, &ib_query->stmt, DSQL_close)) { @@ -1825,32 +1822,37 @@ PHP_FUNCTION(ibase_execute) break; } /* invalidate previous results returned by this query (not necessary for exec proc) */ - zend_list_delete(ib_query->result_res_id); + res = zend_hash_index_find(&EG(regular_list), ib_query->result_res_id); + if (res) { + zend_list_delete(Z_RES_P(res)); + } } if (FAILURE == _php_ibase_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, &result, ib_query, - &args[1])) { + args)) { break; } /* free the query if trans handle was released */ if (ib_query->trans->handle == NULL) { - zend_list_delete(Z_LVAL_P(query)); + zend_list_delete(Z_RES_P(query)); } if (result != NULL) { + zval *ret; + result->type = EXECUTE_RESULT; if (ib_query->statement_type == isc_info_sql_stmt_exec_procedure) { result->stmt = NULL; } - ib_query->result_res_id = zend_list_insert(result, le_result TSRMLS_CC); - RETVAL_RESOURCE(ib_query->result_res_id); + + ret = zend_list_insert(result, le_result TSRMLS_CC); + ib_query->result_res_id = Z_RES_HANDLE_P(ret); + ZVAL_COPY_VALUE(return_value, ret); + Z_ADDREF_P(return_value); + Z_ADDREF_P(return_value); } } while (0); - - if (args) { - free_alloca(args, use_heap); - } } /* }}} */ @@ -1867,8 +1869,8 @@ PHP_FUNCTION(ibase_free_query) return; } - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &query_arg, -1, LE_QUERY, le_query); - zend_list_delete(Z_RESVAL_P(query_arg)); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, query_arg, -1, LE_QUERY, le_query); + zend_list_close(Z_RES_P(query_arg)); RETURN_TRUE; } /* }}} */ @@ -1887,17 +1889,17 @@ PHP_FUNCTION(ibase_num_fields) return; } - zend_list_find(Z_RESVAL_P(result), &type); + type = Z_RES_P(result)->type; if (type == le_query) { ibase_query *ib_query; - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &result, -1, LE_QUERY, le_query); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query); sqlda = ib_query->out_sqlda; } else { ibase_result *ib_result; - ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result, -1, LE_RESULT, le_result); + ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result, -1, LE_RESULT, le_result); sqlda = ib_result->out_sqlda; } @@ -2011,17 +2013,17 @@ PHP_FUNCTION(ibase_field_info) return; } - zend_list_find(Z_RESVAL_P(result_arg), &type); + type = Z_RES_P(result_arg)->type; if (type == le_query) { ibase_query *ib_query; - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &result_arg, -1, LE_QUERY, le_query); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query); sqlda = ib_query->out_sqlda; } else { ibase_result *ib_result; - ZEND_FETCH_RESOURCE(ib_result, ibase_result *, &result_arg, -1, LE_RESULT, le_result); + ZEND_FETCH_RESOURCE(ib_result, ibase_result *, result_arg, -1, LE_RESULT, le_result); sqlda = ib_result->out_sqlda; } @@ -2050,7 +2052,7 @@ PHP_FUNCTION(ibase_num_params) return; } - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &result, -1, LE_QUERY, le_query); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result, -1, LE_QUERY, le_query); if (ib_query->in_sqlda == NULL) { RETURN_LONG(0); @@ -2074,7 +2076,7 @@ PHP_FUNCTION(ibase_param_info) return; } - ZEND_FETCH_RESOURCE(ib_query, ibase_query *, &result_arg, -1, LE_QUERY, le_query); + ZEND_FETCH_RESOURCE(ib_query, ibase_query *, result_arg, -1, LE_QUERY, le_query); if (ib_query->in_sqlda == NULL) { RETURN_FALSE; diff --git a/ext/interbase/ibase_service.c b/ext/interbase/ibase_service.c index 2de77bc353..95f068e7ff 100644 --- a/ext/interbase/ibase_service.c +++ b/ext/interbase/ibase_service.c @@ -31,12 +31,12 @@ typedef struct { isc_svc_handle handle; char *hostname; char *username; - long res_id; + zend_resource *res; } ibase_service; static int le_service; -static void _php_ibase_free_service(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_free_service(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_service *sv = (ibase_service *) rsrc->ptr; @@ -58,7 +58,7 @@ static void _php_ibase_free_service(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ /* the svc api seems to get confused after an error has occurred, so invalidate the handle on errors */ #define IBASE_SVC_ERROR(svm) \ - do { zend_list_delete(svm->res_id); _php_ibase_error(TSRMLS_C); } while (0) + do { zend_list_delete(svm->res); _php_ibase_error(TSRMLS_C); } while (0) void php_ibase_service_minit(INIT_FUNC_ARGS) /* {{{ */ @@ -151,7 +151,7 @@ static void _php_ibase_user(INTERNAL_FUNCTION_PARAMETERS, char operation) /* {{{ RETURN_FALSE; } - ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, "Interbase service manager handle", + ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle", le_service); buf[0] = operation; @@ -246,7 +246,8 @@ PHP_FUNCTION(ibase_service_attach) svm->username = estrdup(user); ZEND_REGISTER_RESOURCE(return_value, svm, le_service); - svm->res_id = Z_LVAL_P(return_value); + Z_ADDREF_P(return_value); + svm->res = Z_RES_P(return_value); } /* }}} */ @@ -262,7 +263,7 @@ PHP_FUNCTION(ibase_service_detach) RETURN_FALSE; } - zend_list_delete(Z_LVAL_P(res)); + zend_list_delete(Z_RES_P(res)); RETURN_TRUE; } @@ -304,7 +305,9 @@ query_loop: if (! (line_len = isc_vax_integer(result, 2))) { /* done */ if (heap_buf) { - RETURN_STRING(heap_buf,0); + RETVAL_STRING(heap_buf); + efree(heap_buf); + return; } else { RETURN_TRUE; } @@ -330,7 +333,7 @@ query_loop: case isc_info_svc_get_env_lock: case isc_info_svc_get_env_msg: case isc_info_svc_user_dbpath: - RETURN_STRINGL(result + 2, isc_vax_integer(result, 2), 1); + RETURN_STRINGL(result + 2, isc_vax_integer(result, 2)); case isc_info_svc_svr_db_info: array_init(return_value); @@ -358,7 +361,7 @@ query_loop: return; case isc_info_svc_get_users: { - zval *user; + zval user; array_init(return_value); while (*result != isc_info_end) { @@ -368,40 +371,39 @@ query_loop: case isc_spb_sec_username: /* it appears that the username is always first */ - ALLOC_INIT_ZVAL(user); - array_init(user); - add_next_index_zval(return_value, user); + array_init(&user); + add_next_index_zval(return_value, &user); len = isc_vax_integer(result,2); - add_assoc_stringl(user, "user_name", result +2, len); + add_assoc_stringl(&user, "user_name", result +2, len); result += len+2; break; case isc_spb_sec_firstname: len = isc_vax_integer(result,2); - add_assoc_stringl(user, "first_name", result +2, len); + add_assoc_stringl(&user, "first_name", result +2, len); result += len+2; break; case isc_spb_sec_middlename: len = isc_vax_integer(result,2); - add_assoc_stringl(user, "middle_name", result +2, len); + add_assoc_stringl(&user, "middle_name", result +2, len); result += len+2; break; case isc_spb_sec_lastname: len = isc_vax_integer(result,2); - add_assoc_stringl(user, "last_name", result +2, len); + add_assoc_stringl(&user, "last_name", result +2, len); result += len+2; break; case isc_spb_sec_userid: - add_assoc_long(user, "user_id", isc_vax_integer(result, 4)); + add_assoc_long(&user, "user_id", isc_vax_integer(result, 4)); result += 4; break; case isc_spb_sec_groupid: - add_assoc_long(user, "group_id", isc_vax_integer(result, 4)); + add_assoc_long(&user, "group_id", isc_vax_integer(result, 4)); result += 4; break; } @@ -435,7 +437,7 @@ static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operati RETURN_FALSE; } - ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, + ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle", le_service); /* fill the param buffer */ @@ -498,7 +500,7 @@ static void _php_ibase_service_action(INTERNAL_FUNCTION_PARAMETERS, char svc_act RETURN_FALSE; } - ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, + ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle", le_service); if (svc_action == isc_action_svc_db_stats) { @@ -604,7 +606,7 @@ PHP_FUNCTION(ibase_server_info) RETURN_FALSE; } - ZEND_FETCH_RESOURCE(svm, ibase_service *, &res, -1, + ZEND_FETCH_RESOURCE(svm, ibase_service *, res, -1, "Interbase service manager handle", le_service); _php_ibase_service_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, svm, (char)action); diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c index 19f061b17f..c6c108f377 100644 --- a/ext/interbase/interbase.c +++ b/ext/interbase/interbase.c @@ -479,7 +479,7 @@ PHP_FUNCTION(ibase_errmsg) } if (IBG(sql_code) != 0) { - RETURN_STRING(IBG(errmsg), 1); + RETURN_STRING(IBG(errmsg)); } RETURN_FALSE; @@ -550,25 +550,21 @@ typedef struct { /* Fill ib_link and trans with the correct database link and transaction. */ void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, /* {{{ */ - zval **link_id, ibase_db_link **ib_link, ibase_trans **trans) + zval *link_id, ibase_db_link **ib_link, ibase_trans **trans) { - int type; - IBDEBUG("Transaction or database link?"); - if (zend_list_find(Z_LVAL_PP(link_id), &type)) { - if (type == le_trans) { - /* Transaction resource: make sure it refers to one link only, then - fetch it; database link is stored in ib_trans->db_link[]. */ - IBDEBUG("Type is le_trans"); - ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans); - if ((*trans)->link_cnt > 1) { - _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections." - TSRMLS_CC); - return; - } - *ib_link = (*trans)->db_link[0]; + if (Z_RES_P(link_id)->type == le_trans) { + /* Transaction resource: make sure it refers to one link only, then + fetch it; database link is stored in ib_trans->db_link[]. */ + IBDEBUG("Type is le_trans"); + ZEND_FETCH_RESOURCE(*trans, ibase_trans *, link_id, -1, LE_TRANS, le_trans); + if ((*trans)->link_cnt > 1) { + _php_ibase_module_error("Link id is ambiguous: transaction spans multiple connections." + TSRMLS_CC); return; - } + } + *ib_link = (*trans)->db_link[0]; + return; } IBDEBUG("Type is le_[p]link or id not found"); /* Database link resource, use default transaction. */ @@ -627,7 +623,7 @@ static void _php_ibase_commit_link(ibase_db_link *link TSRMLS_DC) /* {{{ */ /* }}} */ -static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void php_ibase_commit_link_rsrc(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_db_link *link = (ibase_db_link *) rsrc->ptr; @@ -635,7 +631,7 @@ static void php_ibase_commit_link_rsrc(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* } /* }}} */ -static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_close_link(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_db_link *link = (ibase_db_link *) rsrc->ptr; @@ -649,7 +645,7 @@ static void _php_ibase_close_link(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ * } /* }}} */ -static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_close_plink(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_db_link *link = (ibase_db_link *) rsrc->ptr; @@ -664,7 +660,7 @@ static void _php_ibase_close_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ } /* }}} */ -static void _php_ibase_free_trans(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +static void _php_ibase_free_trans(zend_resource *rsrc TSRMLS_DC) /* {{{ */ { ibase_trans *trans = (ibase_trans *)rsrc->ptr; unsigned short i; @@ -781,8 +777,8 @@ PHP_MSHUTDOWN_FUNCTION(ibase) * be unloaded automatically when the process exits. */ zend_module_entry *ibase_entry; - if (SUCCESS == zend_hash_find(&module_registry, ibase_module_entry.name, - strlen(ibase_module_entry.name) +1, (void*) &ibase_entry)) { + if ((ibase_entry = zend_hash_str_find_ptr(&module_registry, ibase_module_entry.name, + strlen(ibase_module_entry.name))) != NULL) { ibase_entry->handle = NULL; } #endif @@ -890,7 +886,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* int i, len[] = { 0, 0, 0, 0, 0 }; long largs[] = { 0, 0, 0 }; PHP_MD5_CTX hash_context; - zend_rsrc_list_entry new_index_ptr, *le; + zend_resource new_index_ptr, *le; isc_db_handle db_handle = NULL; ibase_db_link *ib_link; @@ -929,48 +925,52 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* for (i = 0; i < sizeof(largs)/sizeof(long); ++i) { PHP_MD5Update(&hash_context,(char*)&largs[i],sizeof(long)); } - PHP_MD5Final(hash, &hash_context); + PHP_MD5Final((unsigned char*)hash, &hash_context); /* try to reuse a connection */ - if (SUCCESS == zend_hash_find(&EG(regular_list), hash, sizeof(hash), (void *) &le)) { - long xlink; - int type; + if ((le = zend_hash_str_find_ptr(&EG(regular_list), hash, sizeof(hash)-1)) != NULL) { + zend_resource *xlink; - if (Z_TYPE_P(le) != le_index_ptr) { + if (le->type != le_index_ptr) { RETURN_FALSE; } - xlink = (long) le->ptr; - if (zend_list_find(xlink, &type) && ((!persistent && type == le_link) || type == le_plink)) { - zend_list_addref(xlink); - RETURN_RESOURCE(IBG(default_link) = xlink); + xlink = (zend_resource*) le->ptr; + if ((!persistent && xlink->type == le_link) || xlink->type == le_plink) { + if (IBG(default_link) > 0) { + zval *link = zend_hash_index_find(&EG(regular_list), IBG(default_link)); + if (link) { + zend_list_delete(Z_RES_P(link)); + } + } + xlink->gc.refcount++; + xlink->gc.refcount++; + IBG(default_link) = xlink->handle; + RETURN_RES(xlink); } else { - zend_hash_del(&EG(regular_list), hash, sizeof(hash)); + zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1); } } /* ... or a persistent one */ - switch (zend_hash_find(&EG(persistent_list), hash, sizeof(hash), (void *) &le)) { + do { long l; - static char info[] = { isc_info_base_level, isc_info_end }; char result[8]; ISC_STATUS status[20]; - case SUCCESS: - - 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(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) { - ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink); - break; + if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hash, sizeof(hash)-1)) != NULL) { + if (le->type != le_plink) { + RETURN_FALSE; + } + /* check if connection has timed out */ + ib_link = (ibase_db_link *) le->ptr; + if (!isc_database_info(status, &ib_link->handle, sizeof(info), info, sizeof(result), result)) { + ZEND_REGISTER_RESOURCE(return_value, ib_link, le_plink); + break; + } + zend_hash_str_del(&EG(persistent_list), hash, sizeof(hash)-1); } - zend_hash_del(&EG(persistent_list), hash, sizeof(hash)); - - default: /* no link found, so we have to open one */ @@ -989,7 +989,7 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* ib_link = (ibase_db_link *) emalloc(sizeof(ibase_db_link)); ZEND_REGISTER_RESOURCE(return_value, ib_link, le_link); } else { - zend_rsrc_list_entry new_le; + zend_resource new_le; ib_link = (ibase_db_link *) malloc(sizeof(ibase_db_link)); if (!ib_link) { @@ -997,10 +997,10 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* } /* hash it up */ - Z_TYPE(new_le) = le_plink; + new_le.type = le_plink; new_le.ptr = ib_link; - if (FAILURE == zend_hash_update(&EG(persistent_list), hash, sizeof(hash), - (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)) { + if (zend_hash_str_update_mem(&EG(persistent_list), hash, sizeof(hash)-1, + (void *) &new_le, sizeof(zend_resource)) == NULL) { free(ib_link); RETURN_FALSE; } @@ -1013,16 +1013,24 @@ static void _php_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) /* ib_link->event_head = NULL; ++IBG(num_links); - } + } while (0); /* add it to the hash */ - new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); - Z_TYPE(new_index_ptr) = le_index_ptr; - if (FAILURE == zend_hash_update(&EG(regular_list), hash, sizeof(hash), - (void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)) { + new_index_ptr.ptr = (void *) Z_RES_P(return_value); + new_index_ptr.type = le_index_ptr; + if (zend_hash_str_update_mem(&EG(regular_list), hash, sizeof(hash)-1, + (void *) &new_index_ptr, sizeof(zend_resource)) == NULL) { RETURN_FALSE; } - zend_list_addref(IBG(default_link) = Z_LVAL_P(return_value)); + if (IBG(default_link) > 0) { + zval *link = zend_hash_index_find(&EG(regular_list), IBG(default_link)); + if (link) { + zend_list_delete(Z_RES_P(link)); + } + } + IBG(default_link) = Z_RES_P(return_value)->handle; + Z_ADDREF_P(return_value); + Z_ADDREF_P(return_value); } /* }}} */ @@ -1061,11 +1069,20 @@ PHP_FUNCTION(ibase_close) CHECK_LINK(link_id); IBG(default_link) = -1; } else { - link_id = Z_RESVAL_P(link_arg); + link_id = Z_RES_P(link_arg)->handle; } - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink); - zend_list_delete(link_id); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink); + if (!link_arg) { + link_arg = zend_hash_index_find(&EG(regular_list), link_id); + zend_list_delete(Z_RES_P(link_arg)); + } + /* we have at least 3 additional references to this resource ??? */ + if (GC_REFCOUNT(Z_RES_P(link_arg)) < 4) { + zend_list_close(Z_RES_P(link_arg)); + } else { + zend_list_delete(Z_RES_P(link_arg)); + } RETURN_TRUE; } /* }}} */ @@ -1090,10 +1107,10 @@ PHP_FUNCTION(ibase_drop_db) CHECK_LINK(link_id); IBG(default_link) = -1; } else { - link_id = Z_RESVAL_P(link_arg); + link_id = Z_RES_P(link_arg)->handle; } - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &link_arg, link_id, LE_LINK, le_link, le_plink); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, link_arg, link_id, LE_LINK, le_link, le_plink); if (isc_drop_database(IB_STATUS, &ib_link->handle)) { _php_ibase_error(TSRMLS_C); @@ -1105,7 +1122,11 @@ PHP_FUNCTION(ibase_drop_db) if (l->trans != NULL) l->trans->handle = NULL; } - zend_list_delete(link_id); + if (!link_arg) { + link_arg = zend_hash_index_find(&EG(regular_list), link_id); + zend_list_delete(Z_RES_P(link_arg)); + } + zend_list_delete(Z_RES_P(link_arg)); RETURN_TRUE; } /* }}} */ @@ -1136,10 +1157,9 @@ PHP_FUNCTION(ibase_trans) long trans_argl = 0; char *tpb; ISC_TEB *teb; - zval ***args = NULL; + zval *args = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argn) == FAILURE) { - efree(args); efree(ib_link); RETURN_FALSE; } @@ -1151,13 +1171,12 @@ PHP_FUNCTION(ibase_trans) specifies modifiers for the link ids that follow it */ for (i = 0; i < argn; ++i) { - if (Z_TYPE_PP(args[i]) == IS_RESOURCE) { + if (Z_TYPE(args[i]) == IS_RESOURCE) { - if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, args[i], -1, LE_LINK, le_link, le_plink)) { + if (!ZEND_FETCH_RESOURCE2_NO_RETURN(ib_link[link_cnt], ibase_db_link *, &args[i], -1, LE_LINK, le_link, le_plink)) { efree(teb); efree(tpb); efree(ib_link); - efree(args); RETURN_FALSE; } @@ -1175,8 +1194,8 @@ PHP_FUNCTION(ibase_trans) tpb_len = 0; - convert_to_long_ex(args[i]); - trans_argl = Z_LVAL_PP(args[i]); + convert_to_long_ex(&args[i]); + trans_argl = Z_LVAL(args[i]); if (trans_argl != PHP_IBASE_DEFAULT) { last_tpb[tpb_len++] = isc_tpb_version3; @@ -1216,7 +1235,6 @@ PHP_FUNCTION(ibase_trans) result = isc_start_multiple(IB_STATUS, &tr_handle, link_cnt, teb); } - efree(args); efree(tpb); efree(teb); } @@ -1261,6 +1279,7 @@ PHP_FUNCTION(ibase_trans) } efree(ib_link); ZEND_REGISTER_RESOURCE(return_value, ib_trans, le_trans); + Z_ADDREF_P(return_value); } /* }}} */ @@ -1308,7 +1327,6 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{ ISC_STATUS result; ibase_db_link *ib_link; zval *arg = NULL; - int type; RESET_ERRMSG; @@ -1326,11 +1344,11 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{ trans = ib_link->tr_list->trans; } else { /* one id was passed, could be db or trans id */ - if (zend_list_find(Z_RESVAL_P(arg), &type) && type == le_trans) { - ZEND_FETCH_RESOURCE(trans, ibase_trans *, &arg, -1, LE_TRANS, le_trans); - res_id = Z_RESVAL_P(arg); + if (Z_RES_P(arg)->type == le_trans) { + ZEND_FETCH_RESOURCE(trans, ibase_trans *, arg, -1, LE_TRANS, le_trans); + res_id = Z_RES_P(arg)->handle; } else { - ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, &arg, -1, LE_LINK, le_link, le_plink); + ZEND_FETCH_RESOURCE2(ib_link, ibase_db_link *, arg, -1, LE_LINK, le_link, le_plink); if (ib_link->tr_list == NULL || ib_link->tr_list->trans == NULL) { /* this link doesn't have a default transaction */ @@ -1363,7 +1381,7 @@ static void _php_ibase_trans_end(INTERNAL_FUNCTION_PARAMETERS, int commit) /* {{ /* Don't try to destroy implicitly opened transaction from list... */ if ((commit & RETAIN) == 0 && res_id != 0) { - zend_list_delete(res_id); + zend_list_delete(Z_RES_P(arg)); } RETURN_TRUE; } diff --git a/ext/interbase/php_ibase_includes.h b/ext/interbase/php_ibase_includes.h index 6671c9162d..72eb0702a6 100644 --- a/ext/interbase/php_ibase_includes.h +++ b/ext/interbase/php_ibase_includes.h @@ -101,7 +101,7 @@ typedef struct event { unsigned short event_count; char **events; char *event_buffer, *result_buffer; - zval *callback; + zval callback; void **thread_ctx; struct event *event_next; enum event_state { NEW, ACTIVE, DEAD } state; @@ -155,17 +155,17 @@ void _php_ibase_module_error(char * TSRMLS_DC, ...) PHP_ATTRIBUTE_FORMAT(printf,1,PHP_ATTR_FMT_OFFSET +2); /* determine if a resource is a link or transaction handle */ -#define PHP_IBASE_LINK_TRANS(pzval, lh, th) \ - do { if (!pzval) { \ +#define PHP_IBASE_LINK_TRANS(zv, lh, th) \ + do { if (!zv) { \ ZEND_FETCH_RESOURCE2(lh, ibase_db_link *, NULL, IBG(default_link), \ "InterBase link", le_link, le_plink) } \ else \ - _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, &pzval, &lh, &th); \ + _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAM_PASSTHRU, zv, &lh, &th); \ if (SUCCESS != _php_ibase_def_trans(lh, &th TSRMLS_CC)) { RETURN_FALSE; } \ } while (0) int _php_ibase_def_trans(ibase_db_link *ib_link, ibase_trans **trans TSRMLS_DC); -void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, zval **link_id, +void _php_ibase_get_link_trans(INTERNAL_FUNCTION_PARAMETERS, zval *link_id, ibase_db_link **ib_link, ibase_trans **trans); /* provided by ibase_query.c */ @@ -176,7 +176,7 @@ void php_ibase_blobs_minit(INIT_FUNC_ARGS); int _php_ibase_string_to_quad(char const *id, ISC_QUAD *qd); char *_php_ibase_quad_to_string(ISC_QUAD const qd); int _php_ibase_blob_get(zval *return_value, ibase_blob *ib_blob, unsigned long max_len TSRMLS_DC); -int _php_ibase_blob_add(zval **string_arg, ibase_blob *ib_blob TSRMLS_DC); +int _php_ibase_blob_add(zval *string_arg, ibase_blob *ib_blob TSRMLS_DC); /* provided by ibase_events.c */ void php_ibase_events_minit(INIT_FUNC_ARGS); diff --git a/ext/interbase/php_ibase_udf.c b/ext/interbase/php_ibase_udf.c index e96b734291..5a53df8b6b 100644 --- a/ext/interbase/php_ibase_udf.c +++ b/ext/interbase/php_ibase_udf.c @@ -183,12 +183,11 @@ static ISC_INT64 const scales[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10 static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) { do { - zval callback, args[4], *argp[4], return_value; + zval callback, args[4], return_value; PARAMVARY *res = (PARAMVARY*)r->dsc_address; int i; - INIT_ZVAL(callback); - ZVAL_STRING(&callback,name,0); + ZVAL_STRING(&callback, name); LOCK(); @@ -202,12 +201,9 @@ static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) /* create the argument array */ for (i = 0; i < argc; ++i) { - INIT_ZVAL(args[i]); - argp[i] = &args[i]; - /* test arg for null */ if (argv[i]->dsc_flags & DSC_null) { - ZVAL_NULL(argp[i]); + ZVAL_NULL(&args[i]); continue; } @@ -218,32 +214,35 @@ static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) char d[64]; case dtype_cstring: - ZVAL_STRING(argp[i], (char*)argv[i]->dsc_address,0); +//??? + ZVAL_STRING(&args[i], (char*)argv[i]->dsc_address); break; case dtype_text: - ZVAL_STRINGL(argp[i], (char*)argv[i]->dsc_address, argv[i]->dsc_length,0); +//??? + ZVAL_STRINGL(&args[i], (char*)argv[i]->dsc_address, argv[i]->dsc_length); break; case dtype_varying: - ZVAL_STRINGL(argp[i], ((PARAMVARY*)argv[i]->dsc_address)->vary_string, - ((PARAMVARY*)argv[i]->dsc_address)->vary_length,0); +//??? + ZVAL_STRINGL(&args[i], ((PARAMVARY*)argv[i]->dsc_address)->vary_string, + ((PARAMVARY*)argv[i]->dsc_address)->vary_length); break; case dtype_short: if (argv[i]->dsc_scale == 0) { - ZVAL_LONG(argp[i], *(short*)argv[i]->dsc_address); + ZVAL_LONG(&args[i], *(short*)argv[i]->dsc_address); } else { - ZVAL_DOUBLE(argp[i], + ZVAL_DOUBLE(&args[i], ((double)*(short*)argv[i]->dsc_address)/scales[-argv[i]->dsc_scale]); } break; case dtype_long: if (argv[i]->dsc_scale == 0) { - ZVAL_LONG(argp[i], *(ISC_LONG*)argv[i]->dsc_address); + ZVAL_LONG(&args[i], *(ISC_LONG*)argv[i]->dsc_address); } else { - ZVAL_DOUBLE(argp[i], + ZVAL_DOUBLE(&args[i], ((double)*(ISC_LONG*)argv[i]->dsc_address)/scales[-argv[i]->dsc_scale]); } break; @@ -252,33 +251,33 @@ static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) l = *(ISC_INT64*)argv[i]->dsc_address; if (argv[i]->dsc_scale == 0 && l <= LONG_MAX && l >= LONG_MIN) { - ZVAL_LONG(argp[i], (long)l); + ZVAL_LONG(&args[i], (long)l); } else { - ZVAL_DOUBLE(argp[i], ((double)l)/scales[-argv[i]->dsc_scale]); + ZVAL_DOUBLE(&args[i], ((double)l)/scales[-argv[i]->dsc_scale]); } break; case dtype_real: - ZVAL_DOUBLE(argp[i], *(float*)argv[i]->dsc_address); + ZVAL_DOUBLE(&args[i], *(float*)argv[i]->dsc_address); break; case dtype_double: - ZVAL_DOUBLE(argp[i], *(double*)argv[i]->dsc_address); + ZVAL_DOUBLE(&args[i], *(double*)argv[i]->dsc_address); break; case dtype_sql_date: isc_decode_sql_date((ISC_DATE*)argv[i]->dsc_address, &t); - ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.dateformat"), &t),1); + ZVAL_STRINGL(&args[i], d, strftime(d, sizeof(d), INI_STR("ibase.dateformat"), &t),1); break; case dtype_sql_time: isc_decode_sql_time((ISC_TIME*)argv[i]->dsc_address, &t); - ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.timeformat"), &t),1); + ZVAL_STRINGL(&args[i], d, strftime(d, sizeof(d), INI_STR("ibase.timeformat"), &t),1); break; case dtype_timestamp: isc_decode_timestamp((ISC_TIMESTAMP*)argv[i]->dsc_address, &t); - ZVAL_STRINGL(argp[i], d, strftime(d, sizeof(d), INI_STR("ibase.timestampformat"), &t),1); + ZVAL_STRINGL(&args[i], d, strftime(d, sizeof(d), INI_STR("ibase.timestampformat"), &t)); break; } } @@ -287,7 +286,7 @@ static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) /* now call the function */ if (FAILURE == call_user_function(EG(function_table), NULL, - &callback, &return_value, argc, argp TSRMLS_CC)) { + &callback, &return_value, argc, args TSRMLS_CC)) { UNLOCK(); break; } @@ -299,11 +298,12 @@ static void call_php(char *name, PARAMDSC *r, int argc, PARAMDSC **argv) case dtype_sql_date: case dtype_sql_time: case dtype_timestamp: - zval_dtor(argp[i]); - + zval_dtor(&args[i]); } } + zval_dtor(&callback); + /* return whatever type we got back from the callback: let DB handle conversion */ switch (Z_TYPE(return_value)) { diff --git a/ext/interbase/tests/ibase_close_001.phpt b/ext/interbase/tests/ibase_close_001.phpt index 6e31916abe..f74d109109 100644 --- a/ext/interbase/tests/ibase_close_001.phpt +++ b/ext/interbase/tests/ibase_close_001.phpt @@ -18,7 +18,7 @@ var_dump(ibase_close('foo')); bool(true) bool(true) -Warning: ibase_close(): %d is not a valid Firebird/InterBase link resource in %s on line %d +Warning: ibase_close(): supplied resource is not a valid Firebird/InterBase link resource in %s on line %d bool(false) Warning: ibase_close() expects parameter 1 to be resource,%string given in %s on line %d diff --git a/ext/interbase/tests/ibase_free_query_001.phpt b/ext/interbase/tests/ibase_free_query_001.phpt index bedec71731..069f0f0424 100644 --- a/ext/interbase/tests/ibase_free_query_001.phpt +++ b/ext/interbase/tests/ibase_free_query_001.phpt @@ -21,7 +21,7 @@ var_dump(ibase_free_query($x)); --EXPECTF-- bool(true) -Warning: ibase_free_query(): 11 is not a valid Firebird/InterBase query resource in %s on line %d +Warning: ibase_free_query(): supplied resource is not a valid Firebird/InterBase query resource in %s on line %d bool(false) Warning: ibase_free_query(): supplied resource is not a valid Firebird/InterBase query resource in %s on line %d