Major changes for 4.1.2-alpha/4.1.3-beta:

- added container for mysql structure
- added load data infile callback functions (currently disabled under win)
Bug fixes:
- fixed property changes (4.1.1 -> 4.1.2)
- fixed memleak in mysqli_connect
- fixed bug #28100
- fixed bug #28205
- fixed bug #28430
This commit is contained in:
Georg Richter 2004-06-05 18:31:56 +00:00
parent 120625548d
commit 93bf6517df
6 changed files with 623 additions and 318 deletions

View File

@ -88,7 +88,7 @@ void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
/* }}} */
/* {{{ php_clear_stmt_bind */
void php_clear_stmt_bind(STMT *stmt)
void php_clear_stmt_bind(MY_STMT *stmt)
{
if (stmt->stmt) {
mysql_stmt_close(stmt->stmt);
@ -105,6 +105,22 @@ void php_clear_stmt_bind(STMT *stmt)
}
/* }}} */
/* {{{ php_clear_mysql */
void php_clear_mysql(MY_MYSQL *mysql) {
int i;
for (i=0; i < 3; i++) {
if (&mysql->callback_func[i]) {
zval_dtor(&mysql->callback_func[i]);
}
}
if (mysql->local_infile) {
zval_ptr_dtor(&mysql->local_infile);
}
}
/* }}} */
/* {{{ mysqli_objects_free_storage
*/
static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
@ -118,11 +134,15 @@ static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
/* link object */
if (intern->zo.ce == mysqli_link_class_entry) {
if (my_res && my_res->ptr) {
mysql_close(my_res->ptr);
MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
mysql_close(mysql->mysql);
php_clear_mysql(mysql);
}
} else if (intern->zo.ce == mysqli_stmt_class_entry) { /* stmt object */
if (my_res && my_res->ptr) {
php_clear_stmt_bind((STMT *)my_res->ptr);
php_clear_stmt_bind((MY_STMT *)my_res->ptr);
}
} else if (intern->zo.ce == mysqli_result_class_entry) { /* result object */
if (my_res && my_res->ptr) {
@ -134,14 +154,6 @@ static void mysqli_objects_free_storage(zend_object *object TSRMLS_DC)
}
/* }}} */
/* {{{ mysqli_objects_clone
*/
static void mysqli_objects_clone(void *object, void **object_clone TSRMLS_DC)
{
/* TODO */
}
/* }}} */
/* {{{ mysqli_read_na */
static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC)
{
@ -264,15 +276,20 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
zend_object_value retval;
mysqli_object *intern;
zval *tmp;
zend_class_entry *parent;
intern = emalloc(sizeof(mysqli_object));
memset(intern, 0, sizeof(mysqli_object));
intern->zo.ce = class_type;
intern->zo.in_get = 0;
intern->zo.in_set = 0;
intern->ptr = NULL;
intern->valid = 0;
intern->prop_handler = NULL;
if ((parent = class_type->parent))
{
zend_hash_find(&classes, parent->name, parent->name_length + 1, (void **) &intern->prop_handler);
}
zend_hash_find(&classes, class_type->name, class_type->name_length + 1, (void **) &intern->prop_handler);
ALLOC_HASHTABLE(intern->zo.properties);
@ -280,7 +297,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,
(void *) &tmp, sizeof(zval *));
retval.handle = zend_objects_store_put(intern, NULL, mysqli_objects_free_storage, NULL /*mysqli_objects_clone*/ TSRMLS_CC);
retval.handle = zend_objects_store_put(intern, NULL, mysqli_objects_free_storage, NULL TSRMLS_CC);
retval.handlers = &mysqli_object_handlers;
return retval;
@ -353,7 +370,7 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_INI_ENTRIES();
memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
mysqli_object_handlers.clone_obj = NULL /*zend_objects_store_clone_obj*/;
mysqli_object_handlers.clone_obj = NULL;
mysqli_object_handlers.read_property = mysqli_read_property;
mysqli_object_handlers.write_property = mysqli_write_property;
mysqli_object_handlers.get_property_ptr_ptr = NULL;
@ -684,6 +701,198 @@ PHP_MYSQLI_API void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRML
}
/* }}} */
#define ALLOC_CALLBACK_ARGS(a, b, c)\
if (c) {\
a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
for (i = b; i < c; i++) {\
a[i] = emalloc(sizeof(zval *));\
MAKE_STD_ZVAL(*a[i]);\
}\
}
#define FREE_CALLBACK_ARGS(a, b, c)\
if (a) {\
for (i=b; i < c; i++) {\
zval_ptr_dtor(a[i]);\
efree(a[i]);\
}\
efree(a);\
}
#define LOCAL_INFILE_ERROR_MSG(source,dest)\
memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
memcpy(source, dest, LOCAL_INFILE_ERROR_LEN-1);
/* {{{ php_local_infile_init
*/
int php_local_infile_init(void **ptr, const char *filename, void *userdata)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
zval ***callback_args;
int argc = 2;
int i, rc = 0;
/* save pointer to MY_MYSQL structure (userdata) */
if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
return 1;
}
if (!(mysql = data->userdata = userdata)) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
return 1;
}
ALLOC_CALLBACK_ARGS(callback_args, 0, argc);
ZVAL_STRING(*callback_args[0], (char *)filename, 1);
ZVAL_STRING(*callback_args[1], "", 1);
if (call_user_function_ex(EG(function_table),
NULL,
&mysql->callback_func[0],
&mysql->local_infile,
argc,
callback_args,
0,
NULL TSRMLS_CC) == SUCCESS) {
/* check if user callback function returned a valid filehandle */
convert_to_string_ex(callback_args[1]);
if (Z_TYPE_P(mysql->local_infile) != IS_RESOURCE) {
if (!strlen(Z_STRVAL_P(*callback_args[1]))) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
} else {
LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[1]));
}
rc = 1;
} else {
}
} else {
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
rc = 1;
}
FREE_CALLBACK_ARGS(callback_args, 0, argc);
return rc;
}
/* }}} */
int php_local_infile_read(void *ptr, char *buf, uint buf_len)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
zval ***callback_args;
zval *retval;
int argc = 4;
int i;
long rc;
data= (mysqli_local_infile *)ptr;
mysql = data->userdata;
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
/* set parameters: filepointer, buffer, buffer_len, errormsg */
callback_args[0] = &mysql->local_infile;
ZVAL_STRING(*callback_args[1], "", 1);
ZVAL_LONG(*callback_args[2], buf_len);
ZVAL_STRING(*callback_args[3], "", 1);
if (call_user_function_ex(EG(function_table),
NULL,
&mysql->callback_func[1],
&retval,
argc,
callback_args,
0,
NULL TSRMLS_CC) == SUCCESS) {
rc = Z_LVAL_P(retval);
zval_ptr_dtor(&retval);
if (rc > 0) {
if (rc > buf_len) {
/* check buffer overflow */
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Read buffer too large");
rc = -1;
} else {
memcpy(buf, Z_STRVAL_P(*callback_args[1]), rc);
}
}
if (rc < 0) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
}
} else {
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
rc = -1;
}
FREE_CALLBACK_ARGS(callback_args, 1, argc);
return rc;
}
/* {{{ php_local_infile_error
*/
int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
{
mysqli_local_infile *data = (mysqli_local_infile *) ptr;
if (data) {
strcpy(error_msg, data->error_msg);
return 2000;
}
strcpy(error_msg, ER(CR_OUT_OF_MEMORY));
return CR_OUT_OF_MEMORY;
}
/* }}} */
/* {{{ php_local_infile_end
*/
void php_local_infile_end(void *ptr)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
zval ***callback_args;
zval *retval;
int argc = 1;
int i;
data= (mysqli_local_infile *)ptr;
mysql = data->userdata;
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
/* set parameters: filepointer, buffer, buffer_len, errormsg */
callback_args[0] = &mysql->local_infile;
call_user_function_ex(EG(function_table),
NULL,
&mysql->callback_func[2],
&retval,
argc,
callback_args,
0,
NULL TSRMLS_CC);
if (retval) {
zval_ptr_dtor(&retval);
}
if (mysql->local_infile) {
zval_ptr_dtor(&mysql->local_infile);
}
FREE_CALLBACK_ARGS(callback_args, 1, argc);
// efree(data);
}
/* }}} */
/*
* Local variables:
* tab-width: 4

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,10 @@ function_entry mysqli_functions[] = {
PHP_FE(mysqli_info, NULL)
PHP_FE(mysqli_insert_id, NULL)
PHP_FE(mysqli_kill, NULL)
#ifndef PHP_WIN32
PHP_FE(mysqli_set_local_infile_default, NULL)
PHP_FE(mysqli_set_local_infile_handler, NULL)
#endif
PHP_FE(mysqli_master_query, NULL)
PHP_FE(mysqli_more_results, NULL)
PHP_FE(mysqli_multi_query, NULL)
@ -126,6 +130,7 @@ function_entry mysqli_functions[] = {
PHP_FE(mysqli_stmt_fetch, NULL)
#ifndef HAVE_MYSQLI_OLDAPI
PHP_FE(mysqli_stmt_free_result, NULL)
PHP_FE(mysqli_stmt_insert_id, NULL)
PHP_FE(mysqli_stmt_reset, NULL)
#endif
PHP_FE(mysqli_stmt_param_count, NULL)
@ -200,6 +205,10 @@ function_entry mysqli_link_methods[] = {
PHP_FALIAS(get_server_info,mysqli_get_server_info,NULL)
PHP_FALIAS(init,mysqli_init,NULL)
PHP_FALIAS(kill,mysqli_kill,NULL)
#ifndef PHP_WIN32
PHP_FALIAS(set_local_infile_default,mysqli_set_local_infile_default,NULL)
PHP_FALIAS(set_local_infile_handler,mysqli_set_local_infile_handler,NULL)
#endif
PHP_FALIAS(master_query,mysqli_master_query,NULL)
PHP_FALIAS(mysqli, mysqli_connect, NULL)
PHP_FALIAS(multi_query,mysqli_multi_query,NULL)

View File

@ -33,7 +33,7 @@
Open a connection to a mysql server */
PHP_FUNCTION(mysqli_connect)
{
MYSQL *mysql = NULL;
MY_MYSQL *mysql;
MYSQLI_RESOURCE *mysqli_resource;
zval *object = getThis();
char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
@ -64,26 +64,31 @@ PHP_FUNCTION(mysqli_connect)
}
}
mysql = mysql_init(NULL);
mysql = (MY_MYSQL *)calloc(1, sizeof(MY_MYSQL));
if (mysql_real_connect(mysql,hostname,username,passwd,dbname,port,socket,0) == NULL) {
if (!(mysql->mysql = mysql_init(NULL))) {
efree(mysql);
RETURN_FALSE;
}
if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,0) == NULL) {
/* Save error messages */
MYSQLI_REPORT_MYSQL_ERROR(mysql);
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->mysql));
}
/* free mysql structure */
mysql_close(mysql);
mysql_close(mysql->mysql);
RETURN_FALSE;
}
/* clear error */
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
mysql->reconnect = MyG(reconnect);
mysql->mysql->reconnect = MyG(reconnect);
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)mysql;
@ -102,7 +107,7 @@ PHP_FUNCTION(mysqli_connect)
Open a connection to a embedded mysql server */
PHP_FUNCTION(mysqli_embedded_connect)
{
MYSQL *mysql;
MY_MYSQL *mysql;
MYSQLI_RESOURCE *mysqli_resource;
zval *object = getThis();
char *dbname = NULL;
@ -117,21 +122,27 @@ PHP_FUNCTION(mysqli_embedded_connect)
return;
}
mysql = mysql_init(NULL);
mysql = (MY_MYSQL *) calloc(1, sizeof(MY_MYSQL));
if (mysql_real_connect(mysql, NULL, NULL, NULL, dbname, 0, NULL, 0) == NULL) {
MYSQLI_REPORT_MYSQL_ERROR(mysql);
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql));
}
/* free mysql structure */
mysql_close(mysql);
if (!(mysql = mysql_init(NULL))) {
efree(mysql);
RETURN_FALSE;
}
php_mysqli_set_error(mysql_errno(mysql), (char *) mysql_error(mysql) TSRMLS_CC);
if (mysql_real_connect(mysql, NULL, NULL, NULL, dbname, 0, NULL, 0) == NULL) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
if (!(MyG(report_mode) & MYSQLI_REPORT_ERROR)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->mysql));
}
/* free mysql structure */
mysql_close(mysql->mysql);
efree(mysql);
RETURN_FALSE;
}
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)mysql;
@ -193,7 +204,7 @@ PHP_FUNCTION(mysqli_fetch_object)
Binary-safe version of mysql_query() */
PHP_FUNCTION(mysqli_multi_query)
{
MYSQL *mysql;
MY_MYSQL *mysql;
zval *mysql_link;
char *query = NULL;
unsigned int query_len;
@ -201,11 +212,12 @@ PHP_FUNCTION(mysqli_multi_query)
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MYSQL *, &mysql_link, "mysqli_link");
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link");
MYSQLI_ENABLE_MQ;
if (mysql_real_query(mysql, query, query_len)) {
if (mysql_real_query(mysql->mysql, query, query_len)) {
MYSQLI_DISABLE_MQ;
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
}
RETURN_TRUE;
@ -215,7 +227,7 @@ PHP_FUNCTION(mysqli_multi_query)
/* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
PHP_FUNCTION(mysqli_query)
{
MYSQL *mysql;
MY_MYSQL *mysql;
zval *mysql_link;
MYSQLI_RESOURCE *mysqli_resource;
MYSQL_RES *result;
@ -226,31 +238,31 @@ PHP_FUNCTION(mysqli_query)
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MYSQL*, &mysql_link, "mysqli_link");
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link");
MYSQLI_DISABLE_MQ;
if (mysql_real_query(mysql, query, query_len)) {
MYSQLI_REPORT_MYSQL_ERROR(mysql);
if (mysql_real_query(mysql->mysql, query, query_len)) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
}
if (!mysql_field_count(mysql)) {
if (!mysql_field_count(mysql->mysql)) {
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
php_mysqli_report_index(query, mysql->server_status TSRMLS_CC);
php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
}
RETURN_TRUE;
}
result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql) : mysql_store_result(mysql);
result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql->mysql) : mysql_store_result(mysql->mysql);
if (!result) {
RETURN_FALSE;
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
php_mysqli_report_index(query, mysql->server_status TSRMLS_CC);
php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));

View File

@ -29,50 +29,50 @@
#include "ext/standard/info.h"
#include "php_mysqli.h"
#define MYSQLI_MAP_PROPERTY_LONG( __func, __type, __val)\
int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \
{\
__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \
ALLOC_ZVAL(*retval);\
if (!p) {\
ZVAL_NULL(*retval);\
} else {\
ZVAL_LONG(*retval, (long)p->__val);\
}\
return SUCCESS;\
}
#define MYSQLI_GET_MYSQL() \
MYSQL *p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;
#define MYSQLI_MAP_PROPERTY_LONG_LONG( __func, __type, __val)\
#define MYSQLI_GET_RESULT() \
MYSQL_RES *p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr
#define MYSQLI_GET_STMT() \
MYSQL_STMT *p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt
#define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type)\
int __func(mysqli_object *obj, zval **retval TSRMLS_DC) \
{\
__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \
__ret_type l;\
__get_type;\
ALLOC_ZVAL(*retval);\
if (!p) {\
ZVAL_NULL(*retval);\
} else {\
if (p->__val < LONG_MAX) { \
ZVAL_LONG(*retval, (long)p->__val); \
l = (__ret_type)__int_func(p);\
if (l < LONG_MAX) {\
ZVAL_LONG(*retval, l);\
} else { \
char ret[40]; \
sprintf(ret, "%llu", p->__val); \
sprintf(ret, "%llu", (my_ulonglong)l); \
ZVAL_STRING(*retval, ret, 1); \
} \
}\
return SUCCESS;\
}
#define MYSQLI_MAP_PROPERTY_STRING( __func, __type, __val)\
#define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\
int __func(mysqli_object *obj, zval **retval TSRMLS_DC)\
{\
__type *p = (__type *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;\
char *c;\
__get_type;\
ALLOC_ZVAL(*retval);\
if (!p) {\
ZVAL_NULL(*retval);\
} else {\
if (!p->__val) {\
c = (char *)__int_func(p);\
if (!c) {\
ZVAL_NULL(*retval);\
} else {\
ZVAL_STRING(*retval, p->__val, 1);\
ZVAL_STRING(*retval, c, 1);\
}\
}\
return SUCCESS;\
@ -96,16 +96,6 @@ int link_connect_errno_read(mysqli_object *obj, zval **retval TSRMLS_DC)
}
/* }}} */
/* {{{ property link_server_version_read */
int link_server_version_read(mysqli_object *obj, zval **retval TSRMLS_DC)
{
MYSQL *mysql = (MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
ALLOC_ZVAL(*retval);
ZVAL_LONG(*retval, mysql_get_server_version(mysql));
return SUCCESS;
}
/* }}} */
/* {{{ property link_connect_error_read */
int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC)
{
@ -115,27 +105,21 @@ int link_connect_error_read(mysqli_object *obj, zval **retval TSRMLS_DC)
}
/* }}} */
/* link properties */
MYSQLI_MAP_PROPERTY_LONG_LONG(link_affected_rows_read, MYSQL, last_used_con->affected_rows);
MYSQLI_MAP_PROPERTY_LONG(link_client_flags_read, MYSQL, client_flag);
MYSQLI_MAP_PROPERTY_LONG(link_errno_read, MYSQL, net.last_errno);
MYSQLI_MAP_PROPERTY_STRING(link_error_read, MYSQL, net.last_error);
MYSQLI_MAP_PROPERTY_LONG(link_field_count_read, MYSQL, field_count);
MYSQLI_MAP_PROPERTY_STRING(link_host_read, MYSQL, host);
MYSQLI_MAP_PROPERTY_STRING(link_host_info_read, MYSQL, host_info);
MYSQLI_MAP_PROPERTY_STRING(link_info_read, MYSQL, info);
MYSQLI_MAP_PROPERTY_LONG_LONG(link_insert_id_read, MYSQL, last_used_con->insert_id);
MYSQLI_MAP_PROPERTY_LONG(link_port_read, MYSQL, port);
MYSQLI_MAP_PROPERTY_LONG(link_protocol_version_read, MYSQL, protocol_version);
MYSQLI_MAP_PROPERTY_LONG(link_server_capabilities_read, MYSQL, server_capabilities);
MYSQLI_MAP_PROPERTY_LONG(link_server_language_read, MYSQL, server_language);
MYSQLI_MAP_PROPERTY_LONG(link_server_status_read, MYSQL, server_status);
MYSQLI_MAP_PROPERTY_STRING(link_server_info_read, MYSQL, server_version);
MYSQLI_MAP_PROPERTY_STRING(link_sqlstate_read, MYSQL, net.sqlstate);
MYSQLI_MAP_PROPERTY_LONG(link_thread_id_read, MYSQL, thread_id);
MYSQLI_MAP_PROPERTY_STRING(link_user_read, MYSQL, user);
MYSQLI_MAP_PROPERTY_LONG(link_warning_count_read, MYSQL, warning_count);
/* link properties */
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_affected_rows_read, mysql_affected_rows, MYSQLI_GET_MYSQL(), my_ulonglong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_errno_read, mysql_errno, MYSQLI_GET_MYSQL(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_error_read, mysql_error, MYSQLI_GET_MYSQL());
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_field_count_read, mysql_field_count, MYSQLI_GET_MYSQL(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_host_info_read, mysql_get_host_info, MYSQLI_GET_MYSQL());
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_info_read, mysql_info, MYSQLI_GET_MYSQL());
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_insert_id_read, mysql_insert_id, MYSQLI_GET_MYSQL(), my_ulonglong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_protocol_version_read, mysql_get_proto_info, MYSQLI_GET_MYSQL(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_server_info_read, mysql_get_server_info, MYSQLI_GET_MYSQL());
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_server_version_read, mysql_get_server_version, MYSQLI_GET_MYSQL(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_STRING(link_sqlstate_read, mysql_sqlstate, MYSQLI_GET_MYSQL());
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_MYSQL(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(), ulong);
/* result properties */
/* {{{ property result_type_read */
@ -177,48 +161,37 @@ int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC)
}
/* }}} */
MYSQLI_MAP_PROPERTY_LONG(result_current_field_read, MYSQL_RES, current_field);
MYSQLI_MAP_PROPERTY_LONG(result_field_count_read, MYSQL_RES, field_count);
MYSQLI_MAP_PROPERTY_LONG_LONG(result_num_rows_read, MYSQL_RES, row_count);
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_current_field_read, mysql_field_tell, MYSQLI_GET_RESULT(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_field_count_read, mysql_num_fields, MYSQLI_GET_RESULT(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_RESULT(), my_ulonglong);
/* statement properties */
#if MYSQL_VERSION_ID < 40102
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_affected_rows_read, STMT, stmt->mysql->last_used_con->affected_rows);
#else
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_affected_rows_read, STMT, stmt->affected_rows);
#endif
MYSQLI_MAP_PROPERTY_LONG_LONG(stmt_num_rows_read, STMT, stmt->result->row_count);
MYSQLI_MAP_PROPERTY_LONG(stmt_param_count_read, STMT, stmt->param_count);
MYSQLI_MAP_PROPERTY_LONG(stmt_field_count_read, STMT, stmt->field_count);
MYSQLI_MAP_PROPERTY_LONG(stmt_id_read, STMT, stmt->stmt_id);
MYSQLI_MAP_PROPERTY_LONG(stmt_errno_read, STMT, stmt->last_errno);
MYSQLI_MAP_PROPERTY_STRING(stmt_error_read, STMT, stmt->last_error);
MYSQLI_MAP_PROPERTY_STRING(stmt_sqlstate_read, STMT, stmt->sqlstate);
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_affected_rows_read, mysql_stmt_affected_rows, MYSQLI_GET_STMT(), my_ulonglong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_insert_id_read, mysql_stmt_insert_id, MYSQLI_GET_STMT(), my_ulonglong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_num_rows_read, mysql_stmt_num_rows, MYSQLI_GET_STMT(), my_ulonglong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_param_count_read, mysql_stmt_param_count, MYSQLI_GET_STMT(), ulong);
//MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_field_count_read, mysql_stmt_field_count, MYSQLI_GET_STMT(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_LONG(stmt_errno_read, mysql_stmt_errno, MYSQLI_GET_STMT(), ulong);
MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_STMT());
MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT());
mysqli_property_entry mysqli_link_property_entries[] = {
{"affected_rows", link_affected_rows_read, NULL},
{"client_flags", link_client_flags_read, NULL},
{"client_version", link_client_version_read, NULL},
{"connect_errno", link_connect_errno_read, NULL},
{"connect_error", link_connect_error_read, NULL},
{"errno", link_errno_read, NULL},
{"error", link_error_read, NULL},
{"field_count", link_field_count_read, NULL},
{"host", link_host_read, NULL},
{"host_info", link_host_info_read, NULL},
{"info", link_info_read, NULL},
{"insert_id", link_insert_id_read, NULL},
{"server_capabilities", link_server_capabilities_read, NULL},
{"server_status", link_server_status_read, NULL},
{"server_info", link_server_info_read, NULL},
{"server_version", link_server_version_read, NULL},
{"sqlstate", link_sqlstate_read, NULL},
{"port", link_port_read, NULL},
{"protocol_version", link_protocol_version_read, NULL},
{"server_language", link_protocol_version_read, NULL},
{"thread_id", link_thread_id_read, NULL},
{"user", link_user_read, NULL},
{"warning_count", link_warning_count_read, NULL},
{NULL, NULL, NULL}
};
@ -234,10 +207,15 @@ mysqli_property_entry mysqli_result_property_entries[] = {
mysqli_property_entry mysqli_stmt_property_entries[] = {
{"affected_rows", stmt_affected_rows_read, NULL},
{"insert_id", stmt_insert_id_read, NULL},
{"num_rows", stmt_num_rows_read, NULL},
{"param_count", stmt_param_count_read, NULL},
/* TODO: stmt->field_count doesn't work currently, remove comments until mysqli_stmt_field_count
is implemented in client library
{"field_count", stmt_field_count_read, NULL},
{"id", stmt_id_read, NULL},
*/
{"errno", stmt_errno_read, NULL},
{"error", stmt_error_read, NULL},
{"sqlstate", stmt_sqlstate_read, NULL},

View File

@ -26,6 +26,7 @@
#endif
#include <mysql.h>
#include <errmsg.h>
#ifndef PHP_MYSQLI_H
#define PHP_MYSQLI_H
@ -38,9 +39,9 @@ typedef struct {
typedef struct {
unsigned int var_cnt;
VAR_BUFFER *buf;
zval **vars;
char *is_null;
VAR_BUFFER *buf;
zval **vars;
char *is_null;
} BIND_BUFFER;
typedef struct {
@ -48,7 +49,14 @@ typedef struct {
BIND_BUFFER param;
BIND_BUFFER result;
char *query;
} STMT;
} MY_STMT;
typedef struct {
MYSQL *mysql;
/* callback functions for load data local infile support */
zval callback_func[3];
zval *local_infile;
} MY_MYSQL;
typedef struct {
int mode;
@ -58,6 +66,7 @@ typedef struct {
typedef struct {
void *ptr; /* resource: (mysql, result, stmt) */
void *info; /* additional buffer */
} MYSQLI_RESOURCE;
typedef struct _mysqli_object {
@ -73,13 +82,10 @@ typedef struct _mysqli_property_entry {
int (*w_func)(mysqli_object *obj, zval **retval TSRMLS_DC);
} mysqli_property_entry;
#define MYSQLI_PR_CONNECT 1
#define MYSQLI_PR_QUERY 2
#define MYSQLI_PR_QUERY_RESULT 3
#define MYSQLI_PR_STMT 4
#define MYSQLI_PR_STMT_RESULT 5
#define MYSQLI_PR_COMMAND 6
typedef struct {
char error_msg[LOCAL_INFILE_ERROR_LEN];
void *userdata;
} mysqli_local_infile;
#define phpext_mysqli_ptr &mysqli_module_entry
@ -105,10 +111,14 @@ extern mysqli_property_entry mysqli_result_property_entries[];
extern mysqli_property_entry mysqli_stmt_property_entries[];
extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
extern void php_clear_stmt_bind(STMT *stmt);
extern void php_clear_stmt_bind(MY_STMT *stmt);
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
extern void php_mysqli_report_error(char *sqlstate, int errorno, char *error TSRMLS_DC);
extern void php_mysqli_report_index(char *query, unsigned int status TSRMLS_DC);
extern int php_local_infile_init(void **, const char *, void *);
extern int php_local_infile_read(void *, char *, uint);
extern void php_local_infile_end(void *);
extern int php_local_infile_error(void *, char *, uint);
zend_class_entry *mysqli_link_class_entry;
zend_class_entry *mysqli_stmt_class_entry;
@ -121,12 +131,12 @@ zend_class_entry _mysqli_result_class_entry;
PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC);
#define MYSQLI_DISABLE_MQ if (MyG(multi_query)) { \
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
MyG(multi_query) = 0; \
}
#define MYSQLI_ENABLE_MQ if (!MyG(multi_query)) { \
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
MyG(multi_query) = 1; \
}
@ -170,7 +180,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRML
} \
__ptr = (__type)my_res->ptr; \
if (!strcmp((char *)__name, "mysqli_stmt")) {\
if (!((STMT *)__ptr)->stmt->mysql) {\
if (!((MYSQL_STMT *)__ptr)->mysql) {\
php_error(E_WARNING, "Statement isn't valid anymore");\
RETURN_NULL();\
}\
@ -300,6 +310,10 @@ PHP_FUNCTION(mysqli_info);
PHP_FUNCTION(mysqli_insert_id);
PHP_FUNCTION(mysqli_init);
PHP_FUNCTION(mysqli_kill);
#ifndef PHP_WIN32
PHP_FUNCTION(mysqli_set_local_infile_default);
PHP_FUNCTION(mysqli_set_local_infile_handler);
#endif
PHP_FUNCTION(mysqli_master_query);
PHP_FUNCTION(mysqli_more_results);
PHP_FUNCTION(mysqli_multi_query);
@ -352,6 +366,7 @@ PHP_FUNCTION(mysqli_stmt_error);
PHP_FUNCTION(mysqli_stmt_free_result);
PHP_FUNCTION(mysqli_stmt_reset);
#endif
PHP_FUNCTION(mysqli_stmt_insert_id);
PHP_FUNCTION(mysqli_stmt_num_rows);
#if MYSQL_VERSION_ID >= 40101
PHP_FUNCTION(mysqli_stmt_sqlstate);