georg Tue Jul 15 06:37:19 2003 EDT Modified files: /php-src/ext/mysqli php_mysqli.h mysqli.c mysqli_api.c Log: added support for rebind
Index: php-src/ext/mysqli/php_mysqli.h diff -u php-src/ext/mysqli/php_mysqli.h:1.17 php-src/ext/mysqli/php_mysqli.h:1.18 --- php-src/ext/mysqli/php_mysqli.h:1.17 Sun Jun 22 04:46:39 2003 +++ php-src/ext/mysqli/php_mysqli.h Tue Jul 15 06:37:19 2003 @@ -15,7 +15,7 @@ | Author: Georg Richter <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ - $Id: php_mysqli.h,v 1.17 2003/06/22 08:46:39 georg Exp $ + $Id: php_mysqli.h,v 1.18 2003/07/15 10:37:19 georg Exp $ */ /* A little hack to prevent build break, when mysql is used together with @@ -36,15 +36,19 @@ ulong buflen; char *buffer; ulong type; -} BIND_BUFFER; +} VAR_BUFFER; typedef struct { - MYSQL_STMT *stmt; unsigned int var_cnt; + VAR_BUFFER *buf; zval **vars; - BIND_BUFFER *bind; char *is_null; - char type; +} BIND_BUFFER; + +typedef struct { + MYSQL_STMT *stmt; + BIND_BUFFER param; + BIND_BUFFER result; } STMT; typedef struct { @@ -88,6 +92,7 @@ extern function_entry mysqli_result_methods[]; extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int flag); extern void php_clear_stmt_bind(STMT *stmt); +extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type); zend_class_entry *mysqli_link_class_entry; zend_class_entry *mysqli_stmt_class_entry; Index: php-src/ext/mysqli/mysqli.c diff -u php-src/ext/mysqli/mysqli.c:1.14 php-src/ext/mysqli/mysqli.c:1.15 --- php-src/ext/mysqli/mysqli.c:1.14 Tue Jun 10 16:03:33 2003 +++ php-src/ext/mysqli/mysqli.c Tue Jul 15 06:37:19 2003 @@ -15,7 +15,7 @@ | Author: Georg Richter <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ - $Id: mysqli.c,v 1.14 2003/06/10 20:03:33 imajes Exp $ + $Id: mysqli.c,v 1.15 2003/07/15 10:37:19 georg Exp $ */ #ifdef HAVE_CONFIG_H @@ -37,32 +37,52 @@ static zend_object_handlers mysqli_object_handlers; PR_MAIN *prmain; -/* {{{ php_clear_stmt_bind */ -void php_clear_stmt_bind(STMT *stmt) +/* {{{ php_free_stmt_bind_buffer */ +void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type) { unsigned int i; - if (stmt->stmt) { - mysql_stmt_close(stmt->stmt); + if (!bbuf.var_cnt) { + return; } - if (stmt->var_cnt) { - for (i = 0; i < stmt->var_cnt; i++) { - if (stmt->type == FETCH_RESULT) { - if (stmt->bind[i].type == IS_STRING) { - efree(stmt->bind[i].buffer); - } - } - if (stmt->vars[i]) { - ZVAL_DELREF(stmt->vars[i]); + if (bbuf.is_null) { + efree(bbuf.is_null); + } + + for (i=0; i < bbuf.var_cnt; i++) { + if (type == FETCH_RESULT) { + if (bbuf.buf[i].type == IS_STRING) { + efree(bbuf.buf[i].buffer); } } - if (stmt->type == FETCH_RESULT) { - efree(stmt->bind); - } - efree(stmt->vars); - efree(stmt->is_null); + if (bbuf.vars[i]) { + ZVAL_DELREF(bbuf.vars[i]); + } } + + if (bbuf.vars) { + efree(bbuf.vars); + } + + if (type == FETCH_RESULT) { + efree(bbuf.buf); + } + bbuf.var_cnt = 0; + return; +} +/* }}} */ + +/* {{{ php_clear_stmt_bind */ +void php_clear_stmt_bind(STMT *stmt) +{ + if (stmt->stmt) { + mysql_stmt_close(stmt->stmt); + } + + php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE); + php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT); + efree(stmt); return; } Index: php-src/ext/mysqli/mysqli_api.c diff -u php-src/ext/mysqli/mysqli_api.c:1.34 php-src/ext/mysqli/mysqli_api.c:1.35 --- php-src/ext/mysqli/mysqli_api.c:1.34 Sat Jun 28 17:27:08 2003 +++ php-src/ext/mysqli/mysqli_api.c Tue Jul 15 06:37:19 2003 @@ -15,7 +15,7 @@ | Author: Georg Richter <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ - $Id: mysqli_api.c,v 1.34 2003/06/28 21:27:08 georg Exp $ + $Id: mysqli_api.c,v 1.35 2003/07/15 10:37:19 georg Exp $ */ #ifdef HAVE_CONFIG_H @@ -120,18 +120,13 @@ if (zend_hash_num_elements(Z_ARRVAL_P(types)) != argc - start) { /* number of bind variables doesn't match number of elements in array */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type array doesn't match number of bind variables"); - } - + } + /* prevent leak if variables are already bound */ -#if HHOLZGRA_0 - /* this would prevent using both bind_param and bind_result on SELECT - queries so it is disabled for now */ - if (stmt->var_cnt) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variables already bound"); - efree(args); - RETURN_FALSE; + if (stmt->param.var_cnt) { + php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE); } -#endif + args = (zval ***)emalloc(argc * sizeof(zval **)); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { @@ -139,7 +134,7 @@ WRONG_PARAM_COUNT; } - stmt->is_null = ecalloc(num_vars, sizeof(char)); + stmt->param.is_null = ecalloc(num_vars, sizeof(char)); bind = (MYSQL_BIND *)ecalloc(num_vars, sizeof(MYSQL_BIND)); zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(types), &hpos); @@ -155,13 +150,13 @@ case MYSQLI_BIND_DOUBLE: bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; bind[ofs].buffer = (gptr)&Z_DVAL_PP(args[i]); - bind[ofs].is_null = &stmt->is_null[ofs]; + bind[ofs].is_null = &stmt->param.is_null[ofs]; break; case MYSQLI_BIND_INT: bind[ofs].buffer_type = MYSQL_TYPE_LONG; bind[ofs].buffer = (gptr)&Z_LVAL_PP(args[i]); - bind[ofs].is_null = &stmt->is_null[ofs]; + bind[ofs].is_null = &stmt->param.is_null[ofs]; break; case MYSQLI_BIND_SEND_DATA: @@ -174,7 +169,7 @@ bind[ofs].buffer_type = MYSQL_TYPE_VAR_STRING; bind[ofs].buffer = NULL; bind[ofs].buffer_length = 0; - bind[ofs].is_null = &stmt->is_null[ofs]; + bind[ofs].is_null = &stmt->param.is_null[ofs]; break; default: @@ -198,15 +193,14 @@ RETURN_FALSE; } - stmt->var_cnt = num_vars; - stmt->type = FETCH_SIMPLE; - stmt->vars = (zval **)emalloc(num_vars * sizeof(zval)); + stmt->param.var_cnt = num_vars; + stmt->param.vars = (zval **)emalloc(num_vars * sizeof(zval)); for (i = 0; i < num_vars; i++) { if (bind[i].buffer_type != MYSQLI_BIND_SEND_DATA) { ZVAL_ADDREF(*args[i+start]); - stmt->vars[i] = *args[i+start]; + stmt->param.vars[i] = *args[i+start]; } else { - stmt->vars[i] = NULL; + stmt->param.vars[i] = NULL; } } efree(args); @@ -263,24 +257,17 @@ var_cnt = argc - start; /* prevent leak if variables are already bound */ -#if HHOLZGRA_0 - /* this would prevent using both bind_param and bind_result on SELECT - queries so it is disabled for now */ - if (stmt->var_cnt) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Variables already bound"); - efree(args); - RETURN_FALSE; + if (stmt->result.var_cnt) { + php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT); } -#endif bind = (MYSQL_BIND *)ecalloc(var_cnt, sizeof(MYSQL_BIND)); - stmt->bind = (BIND_BUFFER *)ecalloc(var_cnt,sizeof(BIND_BUFFER)); - stmt->is_null = (char *)ecalloc(var_cnt, sizeof(char)); - stmt->type = FETCH_RESULT; + stmt->result.buf = (VAR_BUFFER *)ecalloc(var_cnt,sizeof(VAR_BUFFER)); + stmt->result.is_null = (char *)ecalloc(var_cnt, sizeof(char)); for (i=start; i < var_cnt + start ; i++) { ofs = i - start; - stmt->is_null[ofs] = 0; + stmt->result.is_null[ofs] = 0; col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING; @@ -289,11 +276,11 @@ case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_FLOAT: convert_to_double_ex(args[i]); - stmt->bind[ofs].type = IS_DOUBLE; - stmt->bind[ofs].buflen = 0; + stmt->result.buf[ofs].type = IS_DOUBLE; + stmt->result.buf[ofs].buflen = 0; bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE; bind[ofs].buffer = (gptr)&Z_DVAL_PP(args[i]); - bind[ofs].is_null = &stmt->is_null[ofs]; + bind[ofs].is_null = &stmt->result.is_null[ofs]; break; case MYSQL_TYPE_SHORT: @@ -302,22 +289,23 @@ case MYSQL_TYPE_INT24: case MYSQL_TYPE_YEAR: convert_to_long_ex(args[i]); - stmt->bind[ofs].type = IS_LONG; - stmt->bind[ofs].buflen = 0; + stmt->result.buf[ofs].type = IS_LONG; + stmt->result.buf[ofs].buflen = 0; bind[ofs].buffer_type = MYSQL_TYPE_LONG; bind[ofs].buffer = (gptr)&Z_LVAL_PP(args[i]); - bind[ofs].is_null = &stmt->is_null[ofs]; + bind[ofs].is_null = &stmt->result.is_null[ofs]; break; case MYSQL_TYPE_LONGLONG: - stmt->bind[ofs].type = IS_STRING; - stmt->bind[ofs].buflen = sizeof(my_ulonglong); - stmt->bind[ofs].buffer = (char *)emalloc(stmt->bind[ofs].buflen); + stmt->result.buf[ofs].type = IS_STRING; + stmt->result.buf[ofs].buflen = sizeof(my_ulonglong); + stmt->result.buf[ofs].buffer = (char *)emalloc(stmt->result.buf[ofs].buflen); bind[ofs].buffer_type = MYSQL_TYPE_LONGLONG; - bind[ofs].buffer = stmt->bind[ofs].buffer; - bind[ofs].is_null = &stmt->is_null[ofs]; - bind[ofs].buffer_length = stmt->bind[ofs].buflen; + bind[ofs].buffer = stmt->result.buf[ofs].buffer; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; break; + case MYSQL_TYPE_DATE: case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: @@ -326,14 +314,14 @@ case MYSQL_TYPE_STRING: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_TIMESTAMP: - stmt->bind[ofs].type = IS_STRING; - stmt->bind[ofs].buflen = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].length + 1: 256; - stmt->bind[ofs].buffer = (char *)emalloc(stmt->bind[ofs].buflen); + stmt->result.buf[ofs].type = IS_STRING; + stmt->result.buf[ofs].buflen = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].length + 1: 256; + stmt->result.buf[ofs].buffer = (char *)emalloc(stmt->result.buf[ofs].buflen); bind[ofs].buffer_type = MYSQL_TYPE_STRING; - bind[ofs].buffer = stmt->bind[ofs].buffer; - bind[ofs].is_null = &stmt->is_null[ofs]; - bind[ofs].buffer_length = stmt->bind[ofs].buflen; - bind[ofs].length = &stmt->bind[ofs].buflen; + bind[ofs].buffer = stmt->result.buf[ofs].buffer; + bind[ofs].is_null = &stmt->result.is_null[ofs]; + bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; + bind[ofs].length = &stmt->result.buf[ofs].buflen; break; } } @@ -349,12 +337,12 @@ RETURN_FALSE; } - stmt->var_cnt = var_cnt; - stmt->vars = (zval **)emalloc((var_cnt) * sizeof(zval)); + stmt->result.var_cnt = var_cnt; + stmt->result.vars = (zval **)emalloc((var_cnt) * sizeof(zval)); for (i = start; i < var_cnt+start; i++) { ofs = i-start; ZVAL_ADDREF(*args[i]); - stmt->vars[ofs] = *args[i]; + stmt->result.vars[ofs] = *args[i]; } efree(args); @@ -667,29 +655,27 @@ } MYSQLI_FETCH_RESOURCE(stmt, STMT *, prstmt, PR_STMT *, &mysql_stmt, "mysqli_stmt"); - if (stmt->type == FETCH_SIMPLE) { - for (i = 0; i < stmt->var_cnt; i++) { - if (stmt->vars[i]) { - stmt->is_null[i] = (stmt->vars[i]->type == IS_NULL); - - switch (stmt->stmt->params[i].buffer_type) { - case MYSQL_TYPE_VAR_STRING: - convert_to_string_ex(&stmt->vars[i]); - stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->vars[i]); - stmt->stmt->params[i].buffer_length = strlen(Z_STRVAL_PP(&stmt->vars[i])); - break; - case MYSQL_TYPE_DOUBLE: - convert_to_double_ex(&stmt->vars[i]); - stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->vars[i]); - break; - case MYSQL_TYPE_LONG: - convert_to_long_ex(&stmt->vars[i]); - stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->vars[i]); - break; - default: - break; - } - } + for (i = 0; i < stmt->param.var_cnt; i++) { + if (stmt->param.vars[i]) { + stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL); + + switch (stmt->stmt->params[i].buffer_type) { + case MYSQL_TYPE_VAR_STRING: + convert_to_string_ex(&stmt->param.vars[i]); + stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->param.vars[i]); + stmt->stmt->params[i].buffer_length = strlen(Z_STRVAL_PP(&stmt->param.vars[i])); + break; + case MYSQL_TYPE_DOUBLE: + convert_to_double_ex(&stmt->param.vars[i]); + stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->param.vars[i]); + break; + case MYSQL_TYPE_LONG: + convert_to_long_ex(&stmt->param.vars[i]); + stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->param.vars[i]); + break; + default: + break; + } } } @@ -715,50 +701,50 @@ /* reset buffers */ - for (i = 0; i < stmt->var_cnt; i++) { - if (stmt->bind[i].type == IS_STRING) { - memset(stmt->bind[i].buffer, 0, stmt->bind[i].buflen); + for (i = 0; i < stmt->result.var_cnt; i++) { + if (stmt->result.buf[i].type == IS_STRING) { + memset(stmt->result.buf[i].buffer, 0, stmt->result.buf[i].buflen); } } if (!(ret = mysql_fetch(stmt->stmt))) { - for (i = 0; i < stmt->var_cnt; i++) { - if (!stmt->is_null[i]) { - switch (stmt->bind[i].type) { + for (i = 0; i < stmt->result.var_cnt; i++) { + if (!stmt->result.is_null[i]) { + switch (stmt->result.buf[i].type) { case IS_LONG: - stmt->vars[i]->type = IS_LONG; + stmt->result.vars[i]->type = IS_LONG; break; case IS_DOUBLE: - stmt->vars[i]->type = IS_DOUBLE; + stmt->result.vars[i]->type = IS_DOUBLE; break; case IS_STRING: if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG) { char tmp[50]; my_ulonglong lval; - memcpy (&lval, stmt->bind[i].buffer, sizeof(my_ulonglong)); + memcpy (&lval, stmt->result.buf[i].buffer, sizeof(my_ulonglong)); if (lval != (long)lval) { /* even though lval is declared as unsigned, the value * may be negative. Therefor we cannot use %llu and must * user %lld. */ sprintf((char *)&tmp, "%lld", lval); - ZVAL_STRING(stmt->vars[i], tmp, 1); + ZVAL_STRING(stmt->result.vars[i], tmp, 1); } else { - ZVAL_LONG(stmt->vars[i], lval); + ZVAL_LONG(stmt->result.vars[i], lval); } } else { - if (stmt->vars[i]->type == IS_STRING) { - efree(stmt->vars[i]->value.str.val); + if (stmt->result.vars[i]->type == IS_STRING) { + efree(stmt->result.vars[i]->value.str.val); } - ZVAL_STRING(stmt->vars[i], stmt->bind[i].buffer, 1); + ZVAL_STRING(stmt->result.vars[i], stmt->result.buf[i].buffer, 1); } break; default: break; } } else { - stmt->vars[i]->type = IS_NULL; + stmt->result.vars[i]->type = IS_NULL; } } } @@ -1304,7 +1290,6 @@ MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, prmysql, PR_MYSQL *, &mysql_link, "mysqli_link"); stmt = (STMT *)ecalloc(1,sizeof(STMT)); - stmt->var_cnt = 0; /* profiling information */ if (MyG(profiler)) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php