Browse Source
Added new classes:
Added new classes:
mysqli_driver mysqli_warning mysqli_exception mysqli_sql_exception Improved embedded server support changed testsuite to work also with embedded server Made statement and resultset classes extendable minor fixesPHP-5.1
25 changed files with 681 additions and 145 deletions
-
2ext/mysqli/config.m4
-
58ext/mysqli/mysqli.c
-
46ext/mysqli/mysqli_api.c
-
153ext/mysqli/mysqli_driver.c
-
124ext/mysqli/mysqli_embedded.c
-
74ext/mysqli/mysqli_exception.c
-
11ext/mysqli/mysqli_fe.c
-
72ext/mysqli/mysqli_nonapi.c
-
1ext/mysqli/mysqli_prop.c
-
4ext/mysqli/mysqli_report.c
-
172ext/mysqli/mysqli_warning.c
-
60ext/mysqli/php_mysqli.h
-
3ext/mysqli/tests/001.phpt
-
2ext/mysqli/tests/014.phpt
-
1ext/mysqli/tests/017.phpt
-
1ext/mysqli/tests/033.phpt
-
1ext/mysqli/tests/034.phpt
-
2ext/mysqli/tests/041.phpt
-
1ext/mysqli/tests/045.phpt
-
4ext/mysqli/tests/047.phpt
-
1ext/mysqli/tests/049.phpt
-
1ext/mysqli/tests/061.phpt
-
22ext/mysqli/tests/connect.inc
-
5ext/mysqli/tests/skipif.inc
-
5ext/mysqli/tests/skipifemb.inc
@ -0,0 +1,153 @@ |
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| Copyright (c) 1997-2004 The PHP Group | |
|||
+----------------------------------------------------------------------+ |
|||
| This source file is subject to version 3.0 of the PHP license, | |
|||
| that is bundled with this package in the file LICENSE, and is | |
|||
| available through the world-wide-web at the following url: | |
|||
| http://www.php.net/license/3_0.txt. | |
|||
| If you did not receive a copy of the PHP license and are unable to | |
|||
| obtain it through the world-wide-web, please send a note to | |
|||
| license@php.net so we can mail you a copy immediately. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: Georg Richter <georg@php.net> | |
|||
+----------------------------------------------------------------------+ |
|||
|
|||
*/ |
|||
#ifdef HAVE_CONFIG_H |
|||
#include "config.h" |
|||
#endif |
|||
|
|||
#include <signal.h> |
|||
|
|||
#include "php.h" |
|||
#include "php_ini.h" |
|||
#include "ext/standard/info.h" |
|||
#include "php_mysqli.h" |
|||
#include "zend_exceptions.h" |
|||
|
|||
|
|||
#define MAP_PROPERTY_MYG_BOOL_READ(name, value) \ |
|||
int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ |
|||
{ \ |
|||
ALLOC_ZVAL(*retval); \ |
|||
ZVAL_BOOL(*retval, MyG(value)); \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
#define MAP_PROPERTY_MYG_BOOL_WRITE(name, value) \ |
|||
int name(mysqli_object *obj, zval *value TSRMLS_DC) \ |
|||
{ \ |
|||
MyG(value) = Z_LVAL_P(value) > 0; \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
#define MAP_PROPERTY_MYG_LONG_READ(name, value) \ |
|||
int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ |
|||
{ \ |
|||
ALLOC_ZVAL(*retval); \ |
|||
ZVAL_LONG(*retval, MyG(value)); \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
#define MAP_PROPERTY_MYG_LONG_WRITE(name, value) \ |
|||
int name(mysqli_object *obj, zval *value TSRMLS_DC) \ |
|||
{ \ |
|||
MyG(value) = Z_LVAL_P(value); \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
#define MAP_PROPERTY_MYG_STRING_READ(name, value) \ |
|||
int name(mysqli_object *obj, zval **retval TSRMLS_DC) \ |
|||
{ \ |
|||
ALLOC_ZVAL(*retval); \ |
|||
ZVAL_STRING(*retval, MyG(value), 1); \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
#define MAP_PROPERTY_MYG_STRING_WRITE(name, value) \ |
|||
int name(mysqli_object *obj, zval *value TSRMLS_DC) \ |
|||
{ \ |
|||
MyG(value) = Z_STRVAL_P(value); \ |
|||
return SUCCESS; \ |
|||
} \ |
|||
|
|||
/* {{{ property driver_report_write */ |
|||
int driver_report_write(mysqli_object *obj, zval *value TSRMLS_DC) |
|||
{ |
|||
MyG(report_mode) = Z_LVAL_P(value); |
|||
php_set_error_handling(MyG(report_mode) & MYSQLI_REPORT_STRICT ? EH_THROW : EH_NORMAL, |
|||
zend_exception_get_default() TSRMLS_CC); |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property driver_embedded_read */ |
|||
int driver_embedded_read(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
ALLOC_ZVAL(*retval); |
|||
#ifdef HAVE_EMBEDDED_MYSQLI |
|||
ZVAL_BOOL(*retval, 1); |
|||
#else |
|||
ZVAL_BOOL(*retval, 0); |
|||
#endif |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property driver_client_version_read */ |
|||
int driver_client_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
ALLOC_ZVAL(*retval); |
|||
ZVAL_LONG(*retval, MYSQL_VERSION_ID); |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property driver_client_info_read */ |
|||
int driver_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
ALLOC_ZVAL(*retval); |
|||
ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1); |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property driver_driver_version_read */ |
|||
int driver_driver_version_read(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
ALLOC_ZVAL(*retval); |
|||
ZVAL_LONG(*retval, MYSQLI_VERSION_ID); |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
MAP_PROPERTY_MYG_BOOL_READ(driver_reconnect_read, reconnect); |
|||
MAP_PROPERTY_MYG_BOOL_WRITE(driver_reconnect_write, reconnect); |
|||
MAP_PROPERTY_MYG_LONG_READ(driver_report_read, report_mode); |
|||
|
|||
ZEND_FUNCTION(mysqli_driver_construct) |
|||
{ |
|||
|
|||
} |
|||
|
|||
mysqli_property_entry mysqli_driver_property_entries[] = { |
|||
{"client_info", driver_client_info_read, NULL}, |
|||
{"client_version", driver_client_version_read, NULL}, |
|||
{"driver_version", driver_driver_version_read, NULL}, |
|||
{"embedded", driver_embedded_read, NULL}, |
|||
{"reconnect", driver_reconnect_read, driver_reconnect_write}, |
|||
{"report_mode", driver_report_read, driver_report_write}, |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
|
|||
/* {{{ mysqli_driver_methods[] |
|||
*/ |
|||
function_entry mysqli_driver_methods[] = { |
|||
PHP_FALIAS(embedded_server_start, mysqli_embedded_server_start, NULL) |
|||
PHP_FALIAS(embedded_server_end, mysqli_embedded_server_end, NULL) |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
/* }}} */ |
|||
@ -0,0 +1,124 @@ |
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| Copyright (c) 1997-2004 The PHP Group | |
|||
+----------------------------------------------------------------------+ |
|||
| This source file is subject to version 3.0 of the PHP license, | |
|||
| that is bundled with this package in the file LICENSE, and is | |
|||
| available through the world-wide-web at the following url: | |
|||
| http://www.php.net/license/3_0.txt. | |
|||
| If you did not receive a copy of the PHP license and are unable to | |
|||
| obtain it through the world-wide-web, please send a note to | |
|||
| license@php.net so we can mail you a copy immediately. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: Georg Richter <georg@php.net> | |
|||
+----------------------------------------------------------------------+ |
|||
|
|||
*/ |
|||
#ifdef HAVE_CONFIG_H |
|||
#include "config.h" |
|||
#endif |
|||
|
|||
#include <signal.h> |
|||
|
|||
#include "php.h" |
|||
#include "php_ini.h" |
|||
#include "ext/standard/info.h" |
|||
#include "php_mysqli.h" |
|||
|
|||
/* {{{ proto bool mysqli_embedded_server_start(bool start, array arguments, array groups) |
|||
initialize and start embedded server */ |
|||
PHP_FUNCTION(mysqli_embedded_server_start) |
|||
{ |
|||
int argc = 0; |
|||
char **arguments; |
|||
char **groups; |
|||
zval **args, **grps, **start; |
|||
HashPosition pos; |
|||
int index, rc; |
|||
|
|||
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &start, &args, &grps) == FAILURE) { |
|||
ZEND_WRONG_PARAM_COUNT(); |
|||
} |
|||
|
|||
convert_to_long_ex(start); |
|||
convert_to_array_ex(args); |
|||
convert_to_array_ex(grps); |
|||
|
|||
if (!Z_LVAL_PP(start)) { |
|||
mysql_server_init(-1,NULL, NULL); |
|||
RETURN_TRUE; |
|||
} |
|||
|
|||
if (MyG(embedded)) { |
|||
/* get arguments */ |
|||
if ((argc = zend_hash_num_elements(HASH_OF(*args)))) { |
|||
arguments = safe_emalloc(sizeof(char *), argc + 1, 0); |
|||
arguments[0] = NULL; |
|||
|
|||
zend_hash_internal_pointer_reset_ex(HASH_OF(*args), &pos); |
|||
|
|||
for (index = 0;; zend_hash_move_forward_ex(HASH_OF(*args), &pos)) { |
|||
zval **item; |
|||
|
|||
if (zend_hash_get_current_data_ex(HASH_OF(*args), (void **) &item, &pos) == FAILURE) { |
|||
break; |
|||
} |
|||
|
|||
convert_to_string_ex(item); |
|||
|
|||
arguments[++index] = Z_STRVAL_PP(item); |
|||
} |
|||
argc++; |
|||
} |
|||
|
|||
/* get groups */ |
|||
if ((zend_hash_num_elements(HASH_OF(*grps)))) { |
|||
groups = safe_emalloc(sizeof(char *), zend_hash_num_elements(HASH_OF(*grps)) + 1, 0); |
|||
arguments[0] = NULL; |
|||
|
|||
zend_hash_internal_pointer_reset_ex(HASH_OF(*args), &pos); |
|||
|
|||
for (index = 0;; zend_hash_move_forward_ex(HASH_OF(*args), &pos)) { |
|||
zval ** item; |
|||
|
|||
if (zend_hash_get_current_data_ex(HASH_OF(*args), (void **) &item, &pos) == FAILURE) { |
|||
break; |
|||
} |
|||
|
|||
convert_to_string_ex(item); |
|||
|
|||
groups[++index] = Z_STRVAL_PP(item); |
|||
} |
|||
groups[index] = NULL; |
|||
} else { |
|||
groups = safe_emalloc(sizeof(char *), 1, 0); |
|||
groups[0] = NULL; |
|||
} |
|||
|
|||
rc = mysql_server_init(argc, arguments, NULL); |
|||
|
|||
if (argc) { |
|||
efree(arguments); |
|||
} |
|||
efree(groups); |
|||
|
|||
if (rc) { |
|||
RETURN_FALSE; |
|||
} |
|||
RETURN_TRUE; |
|||
} |
|||
|
|||
php_error_docref(NULL TSRMLS_CC, E_ERROR, |
|||
"Can't start embedded server. PHP wasn't configured with mysql embedded server support"); |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ proto void mysqli_embedded_server_end(void) |
|||
*/ |
|||
PHP_FUNCTION(mysqli_embedded_server_end) |
|||
{ |
|||
mysql_server_end(); |
|||
} |
|||
/* }}} */ |
|||
@ -0,0 +1,74 @@ |
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| Copyright (c) 1997-2004 The PHP Group | |
|||
+----------------------------------------------------------------------+ |
|||
| This source file is subject to version 3.0 of the PHP license, | |
|||
| that is bundled with this package in the file LICENSE, and is | |
|||
| available through the world-wide-web at the following url: | |
|||
| http://www.php.net/license/3_0.txt. | |
|||
| If you did not receive a copy of the PHP license and are unable to | |
|||
| obtain it through the world-wide-web, please send a note to | |
|||
| license@php.net so we can mail you a copy immediately. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: Georg Richter <georg@php.net> | |
|||
+----------------------------------------------------------------------+ |
|||
|
|||
*/ |
|||
#ifdef HAVE_CONFIG_H |
|||
#include "config.h" |
|||
#endif |
|||
|
|||
#include <signal.h> |
|||
|
|||
#include "php.h" |
|||
#include "php_ini.h" |
|||
#include "ext/standard/info.h" |
|||
#include "php_mysqli.h" |
|||
#include "zend_exceptions.h" |
|||
|
|||
/* {{{ mysqli_exception_methods[] |
|||
*/ |
|||
function_entry mysqli_exception_methods[] = { |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
/* }}} */ |
|||
|
|||
void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...) |
|||
{ |
|||
zval *sql_ex; |
|||
va_list arg; |
|||
char *message; |
|||
|
|||
va_start(arg, format); |
|||
zend_vspprintf(&message, 0, format, arg); |
|||
va_end(arg);; |
|||
|
|||
if (!(MyG(report_mode) & MYSQLI_REPORT_STRICT)) { |
|||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s/%d): %s", sqlstate, errorno, message); |
|||
return; |
|||
} |
|||
|
|||
MAKE_STD_ZVAL(sql_ex); |
|||
object_init_ex(sql_ex, mysqli_exception_class_entry); |
|||
|
|||
if (message) { |
|||
zend_update_property_string(mysqli_exception_class_entry, sql_ex, "message", sizeof("message") - 1, |
|||
message TSRMLS_CC); |
|||
} |
|||
|
|||
if (sqlstate) { |
|||
zend_update_property_string(mysqli_exception_class_entry, sql_ex, "sqlstate", sizeof("sqlstate") - 1, |
|||
sqlstate TSRMLS_CC); |
|||
} else { |
|||
zend_update_property_string(mysqli_exception_class_entry, sql_ex, "sqlstate", sizeof("sqlstate") - 1, |
|||
"00000" TSRMLS_CC); |
|||
} |
|||
|
|||
efree(message); |
|||
zend_update_property_long(mysqli_exception_class_entry, sql_ex, "code", sizeof("code") - 1, errorno TSRMLS_CC); |
|||
|
|||
zend_throw_exception_object(sql_ex); |
|||
} |
|||
|
|||
@ -0,0 +1,172 @@ |
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| Copyright (c) 1997-2004 The PHP Group | |
|||
+----------------------------------------------------------------------+ |
|||
| This source file is subject to version 3.0 of the PHP license, | |
|||
| that is bundled with this package in the file LICENSE, and is | |
|||
| available through the world-wide-web at the following url: | |
|||
| http://www.php.net/license/3_0.txt. | |
|||
| If you did not receive a copy of the PHP license and are unable to | |
|||
| obtain it through the world-wide-web, please send a note to | |
|||
| license@php.net so we can mail you a copy immediately. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: Georg Richter <georg@php.net> | |
|||
+----------------------------------------------------------------------+ |
|||
|
|||
*/ |
|||
#ifdef HAVE_CONFIG_H |
|||
#include "config.h" |
|||
#endif |
|||
|
|||
#include <signal.h> |
|||
|
|||
#include "php.h" |
|||
#include "php_ini.h" |
|||
#include "ext/standard/info.h" |
|||
#include "php_mysqli.h" |
|||
|
|||
/* {{{ void php_clear_warnings() */ |
|||
void php_clear_warnings(MYSQLI_WARNING *w) |
|||
{ |
|||
if (w->result) { |
|||
mysql_free_result(w->result); |
|||
} |
|||
efree(w); |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ void php_get_warnings(MYSQL *mysql) */ |
|||
MYSQLI_WARNING *php_get_warnings(MYSQL *mysql) |
|||
{ |
|||
MYSQLI_WARNING *w; |
|||
int cwarnings; |
|||
|
|||
if (!(cwarnings = mysql_warning_count(mysql))) { |
|||
return NULL; |
|||
} |
|||
|
|||
if (mysql_query(mysql, "SHOW WARNINGS")) { |
|||
return NULL; |
|||
} |
|||
|
|||
if (!(w = (MYSQLI_WARNING *)ecalloc(sizeof(MYSQLI_WARNING), 1))) { |
|||
return NULL; |
|||
} |
|||
|
|||
w->warning_count = cwarnings; |
|||
w->result = mysql_store_result(mysql); |
|||
if (!(w->row = mysql_fetch_row(w->result))) { |
|||
mysql_free_result(w->result); |
|||
efree(w); |
|||
return NULL; |
|||
} |
|||
|
|||
return w; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ mysqli_warning::__construct */ |
|||
ZEND_FUNCTION(mysqli_warning_construct) |
|||
{ |
|||
MYSQL *mysql = NULL; |
|||
MYSQLI_WARNING *w; |
|||
MYSQLI_RESOURCE *mysqli_resource; |
|||
mysqli_object *obj; |
|||
|
|||
if (!getThis()) { |
|||
RETURN_FALSE; |
|||
} |
|||
|
|||
obj = (mysqli_object *)zend_objects_get_address(getThis() TSRMLS_CC); |
|||
|
|||
if (obj->zo.ce == mysqli_link_class_entry) { |
|||
mysql = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql; |
|||
} else if (obj->zo.ce == mysqli_stmt_class_entry) { |
|||
mysql = (MYSQL *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt->mysql; |
|||
} |
|||
|
|||
if ((w = php_get_warnings(mysql))) { |
|||
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); |
|||
mysqli_resource->ptr = (void *)w; |
|||
obj->valid = 1; |
|||
|
|||
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry); |
|||
} else { |
|||
RETURN_FALSE; |
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ bool mysqli_warning::next */ |
|||
ZEND_FUNCTION(mysqli_warning_next) { |
|||
MYSQLI_WARNING *w; |
|||
zval *mysql_warning; |
|||
mysqli_object *obj = (mysqli_object *)zend_objects_get_address(getThis() TSRMLS_CC); |
|||
|
|||
if (obj->valid) { |
|||
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", |
|||
&mysql_warning, mysqli_warning_class_entry) == FAILURE) { |
|||
return; |
|||
} |
|||
|
|||
MYSQLI_FETCH_RESOURCE(w, MYSQLI_WARNING *, &mysql_warning, "mysqli_warning"); |
|||
|
|||
if (w->warning_count && (w->row = mysql_fetch_row(w->result))) { |
|||
RETURN_TRUE; |
|||
} |
|||
} |
|||
RETURN_FALSE; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property mysqli_warning_error */ |
|||
int mysqli_warning_error(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
MYSQLI_WARNING *w; |
|||
|
|||
ALLOC_ZVAL(*retval); |
|||
w = obj->valid ? (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr : NULL; |
|||
|
|||
if (w && w->row && w->row[2]) { |
|||
ZVAL_STRING(*retval, w->row[2], 1); |
|||
} else { |
|||
ZVAL_NULL(*retval); |
|||
} |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ property mysqli_warning_error */ |
|||
int mysqli_warning_errno(mysqli_object *obj, zval **retval TSRMLS_DC) |
|||
{ |
|||
MYSQLI_WARNING *w; |
|||
|
|||
ALLOC_ZVAL(*retval); |
|||
w = obj->valid ? (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr : NULL; |
|||
|
|||
if (w && w->row && w->row[1]) { |
|||
ZVAL_LONG(*retval, atoi(w->row[1])); |
|||
} else { |
|||
ZVAL_NULL(*retval); |
|||
} |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
/* {{{ mysqli_warning_methods[] |
|||
*/ |
|||
function_entry mysqli_warning_methods[] = { |
|||
PHP_FALIAS(__construct,mysqli_warning_construct, NULL) |
|||
PHP_FALIAS(next,mysqli_warning_next,NULL) |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
/* }}} */ |
|||
|
|||
|
|||
mysqli_property_entry mysqli_warning_property_entries[] = { |
|||
{"error", mysqli_warning_error, NULL}, |
|||
{"errno", mysqli_warning_errno, NULL}, |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
@ -1 +1,4 @@ |
|||
<?php if (!extension_loaded('mysqli')) die('skip mysqli extension not available');?> |
|||
<?php |
|||
if (!extension_loaded('mysqli')) |
|||
die('skip mysqli extension not available'); |
|||
?> |
|||
@ -0,0 +1,5 @@ |
|||
<?php |
|||
$driver = new mysqli_driver(); |
|||
if ($driver->embedded) |
|||
die("skip test doesn't run with embedded server"); |
|||
?> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue