PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/mysqli - mysqli_nonapi.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 437 475 92.0 %
Date: 2014-11-10 Functions: 30 30 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2014 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Georg Richter <georg@php.net>                               |
      16             :   |          Andrey Hristov <andrey@php.net>                             |
      17             :   |          Ulf Wendel <uw@php.net>                                     |
      18             :   +----------------------------------------------------------------------+
      19             : 
      20             :   $Id$
      21             : */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include <signal.h>
      28             : 
      29             : #include "php.h"
      30             : #include "php_ini.h"
      31             : #include "ext/standard/info.h"
      32             : #include "zend_smart_str.h"
      33             : #include "php_mysqli_structs.h"
      34             : #include "mysqli_priv.h"
      35             : 
      36             : #define SAFE_STR(a) ((a)?a:"")
      37             : 
      38             : #ifndef zend_parse_parameters_none
      39             : #define zend_parse_parameters_none()    \
      40             :         zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")
      41             : #endif
      42             : 
      43             : /* {{{ php_mysqli_set_error
      44             :  */
      45        1186 : static void php_mysqli_set_error(zend_long mysql_errno, char *mysql_err TSRMLS_DC)
      46             : {
      47        1186 :         MyG(error_no) = mysql_errno;
      48        1186 :         if (MyG(error_msg)) {
      49          17 :                 efree(MyG(error_msg));
      50             :         }
      51        1211 :         if(mysql_err && *mysql_err) {
      52          25 :                 MyG(error_msg) = estrdup(mysql_err);
      53             :         } else {
      54        1161 :                 MyG(error_msg) = NULL;
      55             :         }
      56        1186 : }
      57             : /* }}} */
      58             : 
      59        1266 : void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor) /* {{{ */
      60             : {
      61        1266 :         MY_MYSQL                        *mysql = NULL;
      62        1266 :         MYSQLI_RESOURCE         *mysqli_resource = NULL;
      63        1266 :         zval                            *object = getThis();
      64        1266 :         char                            *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
      65        1266 :         size_t                                  hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
      66        1266 :         zend_bool                       persistent = FALSE;
      67        1266 :         zend_long                               port = 0, flags = 0;
      68        1266 :         zend_string                     *hash_key = NULL;
      69        1266 :         zend_bool                       new_connection = FALSE;
      70             :         zend_resource           *le;
      71        1266 :         mysqli_plist_entry *plist = NULL;
      72        1266 :         zend_bool                       self_alloced = 0;
      73             : 
      74             : 
      75             : #if !defined(MYSQL_USE_MYSQLND)
      76             :         if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
      77             :                 php_error_docref(NULL TSRMLS_CC, E_WARNING,
      78             :                                                 "Headers and client library minor version mismatch. Headers:%d Library:%ld",
      79             :                                                 MYSQL_VERSION_ID, mysql_get_client_version());
      80             :         }
      81             : #endif
      82             : 
      83        1266 :         if (getThis() && !ZEND_NUM_ARGS() && in_ctor) {
      84          16 :                 php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
      85          16 :                 return;
      86             :         }
      87        1250 :         hostname = username = dbname = passwd = socket = NULL;
      88             : 
      89        1250 :         if (!is_real_connect) {
      90          71 :                 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len,
      91             :                                                                         &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
      92           1 :                         return;
      93             :                 }
      94             : 
      95          70 :                 if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
      96          39 :                         mysqli_resource = (Z_MYSQLI_P(object))->ptr;
      97          39 :                         if (mysqli_resource && mysqli_resource->ptr) {
      98           7 :                                 mysql = (MY_MYSQL*) mysqli_resource->ptr;
      99             :                         }
     100             :                 }
     101          70 :                 if (!mysql) {
     102          63 :                         mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
     103          63 :                         self_alloced = 1;
     104             :                 }
     105          70 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     106             :         } else {
     107             :                 /* We have flags too */
     108        1179 :                 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &object, mysqli_link_class_entry,
     109             :                                                                                 &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len,
     110             :                                                                                 &flags) == FAILURE) {
     111           8 :                         return;
     112             :                 }
     113             : 
     114        1171 :                 mysqli_resource = (Z_MYSQLI_P(object))->ptr;
     115        1171 :                 MYSQLI_FETCH_RESOURCE_CONN(mysql, object, MYSQLI_STATUS_INITIALIZED);
     116             : 
     117             :                 /* set some required options */
     118        1170 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     119             :                 /* remove some insecure options */
     120        1170 :                 flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
     121        1170 :                 if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
     122           1 :                         flags &= ~CLIENT_LOCAL_FILES;
     123             :                 }
     124             :         }
     125             : 
     126        1240 :         if (!socket_len || !socket) {
     127          47 :                 socket = MyG(default_socket);
     128             :         }
     129        1240 :         if (!port){
     130          38 :                 port = MyG(default_port);
     131             :         }
     132        1240 :         if (!passwd) {
     133          26 :                 passwd = MyG(default_pw);
     134          26 :                 passwd_len = strlen(SAFE_STR(passwd));
     135             :         }
     136        1240 :         if (!username){
     137          19 :                 username = MyG(default_user);
     138             :         }
     139        1240 :         if (!hostname || !hostname_len) {
     140          17 :                 hostname = MyG(default_host);
     141             :         }
     142             : 
     143        2417 :         if (mysql->mysql && mysqli_resource &&
     144        1177 :                 (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED))
     145             :         {
     146             :                 /* already connected, we should close the connection */
     147          13 :                 php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status TSRMLS_CC);
     148             :         }
     149             : 
     150        1240 :         if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) {
     151          87 :                 hostname += 2;
     152          87 :                 if (!MyG(allow_persistent)) {
     153           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Persistent connections are disabled. Downgrading to normal");
     154             :                 } else {
     155          87 :                         mysql->persistent = persistent = TRUE;
     156             : 
     157         261 :                         hash_key = strpprintf(0, "mysqli_%s_%s%ld%s%s%s", SAFE_STR(hostname), SAFE_STR(socket),
     158         174 :                                                                 port, SAFE_STR(username), SAFE_STR(dbname),
     159          87 :                                                                 SAFE_STR(passwd));
     160             : 
     161          87 :                         mysql->hash_key = hash_key;
     162             : 
     163             :                         /* check if we can reuse exisiting connection ... */
     164          87 :                         if ((le = zend_hash_find_ptr(&EG(persistent_list), hash_key)) != NULL) {
     165          73 :                                 if (le->type == php_le_pmysqli()) {
     166          73 :                                         plist = (mysqli_plist_entry *) le->ptr;
     167             : 
     168             :                                         do {
     169          73 :                                                 if (zend_ptr_stack_num_elements(&plist->free_links)) {
     170          96 :                                                         mysql->mysql = zend_ptr_stack_pop(&plist->free_links);
     171             : 
     172          48 :                                                         MyG(num_inactive_persistent)--;
     173             :                                                         /* reset variables */
     174             : 
     175             : #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT
     176          48 :                                                         if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) {
     177             : #else
     178             :                                                         if (!mysql_ping(mysql->mysql)) {
     179             : #endif
     180             : #ifdef MYSQLI_USE_MYSQLND
     181          47 :                                                                 mysqlnd_restart_psession(mysql->mysql);
     182             : #endif
     183          47 :                                                                 MyG(num_active_persistent)++;
     184          47 :                                                                 goto end;
     185             :                                                         } else {
     186           1 :                                                                 mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
     187           1 :                                                                 mysql->mysql = NULL;
     188             :                                                         }
     189             :                                                 }
     190             :                                         } while (0);
     191             :                                 }
     192             :                         } else {
     193             :                                 zend_resource le;
     194          14 :                                 le.type = php_le_pmysqli();
     195          14 :                                 le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
     196             : 
     197          14 :                                 zend_ptr_stack_init_ex(&plist->free_links, 1);
     198          14 :                                 zend_hash_str_update_mem(&EG(persistent_list), hash_key->val, hash_key->len, &le, sizeof(le));
     199             :                         }
     200             :                 }
     201             :         }
     202        1193 :         if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) {
     203           5 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%pd)", MyG(num_links));
     204           5 :                 goto err;
     205             :         }
     206             : 
     207        1198 :         if (persistent && MyG(max_persistent) != -1 &&
     208          10 :                 (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent))
     209             :         {
     210           2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%pd)",
     211           2 :                                                                 MyG(num_active_persistent) + MyG(num_inactive_persistent));
     212           2 :                 goto err;
     213             :         }
     214        1186 :         if (!mysql->mysql) {
     215             : #if !defined(MYSQLI_USE_MYSQLND)
     216             :                 if (!(mysql->mysql = mysql_init(NULL))) {
     217             : #else
     218          69 :                 if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent))) {
     219             : #endif
     220           0 :                         goto err;
     221             :                 }
     222          69 :                 new_connection = TRUE;
     223             :         }
     224             : 
     225             : #ifdef HAVE_EMBEDDED_MYSQLI
     226             :         if (hostname_len) {
     227             :                 unsigned int external=1;
     228             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
     229             :         } else {
     230             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
     231             :         }
     232             : #endif
     233             : 
     234             : #if !defined(MYSQLI_USE_MYSQLND)
     235             :         /* BC for prior to bug fix #53425 */
     236             :         flags |= CLIENT_MULTI_RESULTS;
     237             : 
     238             :         if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
     239             : #else
     240        1186 :         if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
     241             :                                                 port, socket, flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
     242             : #endif
     243             :         {
     244             :                 /* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
     245          28 :                 php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
     246          56 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
     247          56 :                                                                                 "%s", mysql_error(mysql->mysql));
     248          28 :                 if (!is_real_connect) {
     249             :                         /* free mysql structure */
     250          13 :                         mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED);
     251          13 :                         mysql->mysql = NULL;
     252             :                 }
     253          28 :                 goto err;
     254             :         }
     255             : 
     256             :         /* clear error */
     257        1158 :         php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
     258             : 
     259             : #if !defined(MYSQLI_USE_MYSQLND)
     260             :         mysql->mysql->reconnect = MyG(reconnect);
     261             : #endif
     262             : 
     263        1158 :         mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
     264             : 
     265             : end:
     266        1205 :         if (!mysqli_resource) {
     267          50 :                 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     268          50 :                 mysqli_resource->ptr = (void *)mysql;
     269             :         }
     270        1205 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     271             : 
     272             :         /* store persistent connection */
     273        1205 :         if (persistent && (new_connection || is_real_connect)) {
     274          79 :                 MyG(num_active_persistent)++;
     275             :         }
     276             : 
     277        1205 :         MyG(num_links)++;
     278             : 
     279        1205 :         mysql->multi_query = 0;
     280             : 
     281        1227 :         if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
     282          22 :                 MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
     283             :         } else {
     284        1183 :                 (Z_MYSQLI_P(object))->ptr = mysqli_resource;
     285             :         }
     286        1205 :         if (!is_real_connect) {
     287          57 :                 return;
     288             :         } else {
     289        1148 :                 RETURN_TRUE;
     290             :         }
     291             : 
     292             : err:
     293          35 :         if (mysql->hash_key) {
     294           4 :                 zend_string_release(mysql->hash_key);
     295           4 :                 mysql->hash_key = NULL;
     296           4 :                 mysql->persistent = FALSE;
     297             :         }
     298          35 :         if (!is_real_connect && self_alloced) {
     299          13 :                 efree(mysql);
     300             :         }
     301          35 :         RETVAL_FALSE;
     302             : } /* }}} */
     303             : 
     304             : /* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
     305             :    Open a connection to a mysql server */
     306          45 : PHP_FUNCTION(mysqli_connect)
     307             : {
     308          45 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, FALSE);
     309          45 : }
     310             : /* }}} */
     311             : 
     312             : /* {{{ proto object mysqli_link_construct()
     313             :   */
     314          42 : PHP_FUNCTION(mysqli_link_construct)
     315             : {
     316          42 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, TRUE);
     317          42 : }
     318             : /* }}} */
     319             : 
     320             : /* {{{ proto int mysqli_connect_errno(void)
     321             :    Returns the numerical value of the error message from last connect command */
     322          24 : PHP_FUNCTION(mysqli_connect_errno)
     323             : {
     324          24 :         RETURN_LONG(MyG(error_no));
     325             : }
     326             : /* }}} */
     327             : 
     328             : /* {{{ proto string mysqli_connect_error(void)
     329             :    Returns the text of the error message from previous MySQL operation */
     330          17 : PHP_FUNCTION(mysqli_connect_error)
     331             : {
     332          17 :         if (MyG(error_msg)) {
     333          14 :                 RETURN_STRING(MyG(error_msg));
     334             :         } else {
     335          10 :                 RETURN_NULL();
     336             :         }
     337             : }
     338             : /* }}} */
     339             : 
     340             : /* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
     341             :    Fetch a result row as an associative array, a numeric array, or both */
     342       49479 : PHP_FUNCTION(mysqli_fetch_array)
     343             : {
     344       49479 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
     345       49479 : }
     346             : /* }}} */
     347             : 
     348             : /* {{{ proto mixed mysqli_fetch_assoc (object result)
     349             :    Fetch a result row as an associative array */
     350       18281 : PHP_FUNCTION(mysqli_fetch_assoc)
     351             : {
     352       18281 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
     353       18281 : }
     354             : /* }}} */
     355             : 
     356             : /* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype])
     357             :    Fetches all result rows as an associative array, a numeric array, or both */
     358             : #if defined(MYSQLI_USE_MYSQLND)
     359         213 : PHP_FUNCTION(mysqli_fetch_all)
     360             : {
     361             :         MYSQL_RES       *result;
     362             :         zval            *mysql_result;
     363         213 :         zend_long               mode = MYSQLND_FETCH_NUM;
     364             : 
     365         213 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
     366           2 :                 return;
     367             :         }
     368         211 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
     369             : 
     370         211 :         if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
     371           2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
     372             :                                  "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
     373           2 :                 RETURN_FALSE;
     374             :         }
     375             : 
     376         209 :         mysqlnd_fetch_all(result, mode, return_value);
     377             : }
     378             : /* }}} */
     379             : 
     380             : /* {{{ proto array mysqli_get_client_stats(void)
     381             :    Returns statistics about the zval cache */
     382          50 : PHP_FUNCTION(mysqli_get_client_stats)
     383             : {
     384          50 :         if (zend_parse_parameters_none() == FAILURE) {
     385           1 :                 return;
     386             :         }
     387          49 :         mysqlnd_get_client_stats(return_value);
     388             : }
     389             : /* }}} */
     390             : 
     391             : /* {{{ proto array mysqli_get_connection_stats(void)
     392             :    Returns statistics about the zval cache */
     393           7 : PHP_FUNCTION(mysqli_get_connection_stats)
     394             : {
     395             :         MY_MYSQL        *mysql;
     396             :         zval            *mysql_link;
     397             : 
     398           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
     399             :                                                                          &mysql_link, mysqli_link_class_entry) == FAILURE) {
     400           2 :                 return;
     401             :         }
     402           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     403             : 
     404           5 :         mysqlnd_get_connection_stats(mysql->mysql, return_value);
     405             : }
     406             : #endif
     407             : /* }}} */
     408             : 
     409             : /* {{{ proto mixed mysqli_error_list (object connection)
     410             :    Fetches all client errors */
     411           1 : PHP_FUNCTION(mysqli_error_list)
     412             : {
     413             :         MY_MYSQL        *mysql;
     414             :         zval            *mysql_link;
     415             : 
     416           1 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     417           0 :                 return;
     418             :         }
     419           1 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     420           1 :         array_init(return_value);
     421             : #if defined(MYSQLI_USE_MYSQLND)
     422           1 :         if (mysql->mysql->data->error_info->error_list) {
     423             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     424             :                 zend_llist_position pos;
     425           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos);
     426             :                          message;
     427           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) 
     428             :                 {
     429             :                         zval single_error;
     430           0 :                         array_init(&single_error);
     431           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     432           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     433           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     434           0 :                         add_next_index_zval(return_value, &single_error);
     435             :                 }
     436             :         }
     437             : #else
     438             :         if (mysql_errno(mysql->mysql)) {
     439             :                 zval single_error;
     440             :                 array_init(&single_error);
     441             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
     442             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
     443             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
     444             :                 add_next_index_zval(return_value, &single_error);
     445             :         }
     446             : #endif
     447             : }
     448             : /* }}} */
     449             : 
     450             : /* {{{ proto string mysqli_stmt_error_list(object stmt)
     451             : */
     452           1 : PHP_FUNCTION(mysqli_stmt_error_list)
     453             : {
     454             :         MY_STMT *stmt;
     455             :         zval    *mysql_stmt;
     456             : 
     457           1 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     458           0 :                 return;
     459             :         }
     460           1 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
     461           1 :         array_init(return_value);
     462             : #if defined(MYSQLI_USE_MYSQLND)
     463           1 :         if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
     464             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     465             :                 zend_llist_position pos;
     466           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
     467             :                          message;
     468           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) 
     469             :                 {
     470             :                         zval single_error;
     471           0 :                         array_init(&single_error);
     472           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     473           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     474           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     475           0 :                         add_next_index_zval(return_value, &single_error);
     476             :                 }
     477             :         }
     478             : #else
     479             :         if (mysql_stmt_errno(stmt->stmt)) {
     480             :                 zval single_error;
     481             :                 array_init(&single_error);
     482             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
     483             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
     484             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
     485             :                 add_next_index_zval(return_value, &single_error);
     486             :         }
     487             : #endif
     488             : }
     489             : /* }}} */
     490             : 
     491             : /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
     492             :    Fetch a result row as an object */
     493          33 : PHP_FUNCTION(mysqli_fetch_object)
     494             : {
     495          33 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
     496          31 : }
     497             : /* }}} */
     498             : 
     499             : /* {{{ proto bool mysqli_multi_query(object link, string query)
     500             :    allows to execute multiple queries  */
     501          28 : PHP_FUNCTION(mysqli_multi_query)
     502             : {
     503             :         MY_MYSQL        *mysql;
     504             :         zval            *mysql_link;
     505          28 :         char            *query = NULL;
     506             :         size_t          query_len;
     507             : 
     508          28 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
     509           2 :                 return;
     510             :         }
     511          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     512             : 
     513          25 :         MYSQLI_ENABLE_MQ;
     514          25 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     515             : #ifndef MYSQLI_USE_MYSQLND
     516             :                 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
     517             :                 unsigned int s_errno;
     518             :                 /* we have to save error information, cause
     519             :                 MYSQLI_DISABLE_MQ will reset error information */
     520             :                 strcpy(s_error, mysql_error(mysql->mysql));
     521             :                 strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
     522             :                 s_errno = mysql_errno(mysql->mysql);
     523             : #else
     524           6 :                 MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
     525             : #endif
     526           6 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     527           6 :                 MYSQLI_DISABLE_MQ;
     528             : 
     529             : #ifndef MYSQLI_USE_MYSQLND
     530             :                 /* restore error information */
     531             :                 strcpy(mysql->mysql->net.last_error, s_error);
     532             :                 strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
     533             :                 mysql->mysql->net.last_errno = s_errno;
     534             : #else
     535           6 :                 *mysql->mysql->data->error_info = error_info;
     536             : #endif
     537           6 :                 RETURN_FALSE;
     538             :         }
     539          19 :         RETURN_TRUE;
     540             : }
     541             : /* }}} */
     542             : 
     543             : /* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
     544       19626 : PHP_FUNCTION(mysqli_query)
     545             : {
     546             :         MY_MYSQL                        *mysql;
     547             :         zval                            *mysql_link;
     548             :         MYSQLI_RESOURCE         *mysqli_resource;
     549       19626 :         MYSQL_RES                       *result = NULL;
     550       19626 :         char                            *query = NULL;
     551             :         size_t                          query_len;
     552       19626 :         zend_long                               resultmode = MYSQLI_STORE_RESULT;
     553             : 
     554       19626 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
     555          13 :                 return;
     556             :         }
     557             : 
     558       19613 :         if (!query_len) {
     559           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query");
     560           1 :                 RETURN_FALSE;
     561             :         }
     562             : #ifdef MYSQLI_USE_MYSQLND
     563       19612 :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) {
     564             : #else
     565             :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
     566             : #endif
     567           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
     568           1 :                 RETURN_FALSE;
     569             :         }
     570             : 
     571       19611 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     572             : 
     573       19602 :         MYSQLI_DISABLE_MQ;
     574             : 
     575             : 
     576             : #ifdef MYSQLI_USE_MYSQLND
     577       19602 :         if (resultmode & MYSQLI_ASYNC) {
     578          29 :                 if (mysqli_async_query(mysql->mysql, query, query_len)) {
     579           2 :                         MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     580           2 :                         RETURN_FALSE;
     581             :                 }
     582          27 :                 mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC;
     583          27 :                 RETURN_TRUE;
     584             :         }
     585             : #endif
     586             : 
     587       19573 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     588          63 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     589          63 :                 RETURN_FALSE;
     590             :         }
     591             : 
     592       19510 :         if (!mysql_field_count(mysql->mysql)) {
     593             :                 /* no result set - not a SELECT */
     594       18001 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     595           0 :                         php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
     596             :                 }
     597       18001 :                 RETURN_TRUE;
     598             :         }
     599             : 
     600             : #ifdef MYSQLI_USE_MYSQLND
     601        1509 :         switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) {
     602             : #else
     603             :         switch (resultmode & ~MYSQLI_ASYNC) {
     604             : #endif
     605             :                 case MYSQLI_STORE_RESULT:
     606             : #ifdef MYSQLI_USE_MYSQLND
     607        1496 :                         if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) {
     608           0 :                                 result = mysqlnd_store_result_ofs(mysql->mysql);
     609             :                         } else
     610             : #endif
     611        1496 :                                 result = mysql_store_result(mysql->mysql);
     612        1496 :                         break;
     613             :                 case MYSQLI_USE_RESULT:
     614          13 :                         result = mysql_use_result(mysql->mysql);
     615             :                         break;
     616             :         }
     617        1509 :         if (!result) {
     618           0 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
     619           0 :                                                                                 "%s", mysql_error(mysql->mysql));
     620           0 :                 RETURN_FALSE;
     621             :         }
     622             : 
     623        1509 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     624           2 :                 php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
     625             :         }
     626             : 
     627        1509 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     628        1509 :         mysqli_resource->ptr = (void *)result;
     629        1509 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     630        1509 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     631             : }
     632             : /* }}} */
     633             : 
     634             : #if defined(MYSQLI_USE_MYSQLND)
     635             : #include "php_network.h"
     636             : /* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */
     637          65 : static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array TSRMLS_DC)
     638             : {
     639             :         zval *elem;
     640          65 :         int i = 0, current = 0;
     641             : 
     642          65 :         if (Z_TYPE_P(in_array) != IS_ARRAY) {
     643           0 :                 return 0;
     644             :         }
     645          65 :         *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *));
     646         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_array), elem) {
     647         123 :                 i++;
     648         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT ||
     649         123 :                         !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry TSRMLS_CC)) {
     650           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter %d not a mysqli object", i);
     651             :                 } else {
     652             :                         MY_MYSQL *mysql;
     653             :                         MYSQLI_RESOURCE *my_res;
     654         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     655         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     656           2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] Couldn't fetch %s", i, intern->zo.ce->name->val);
     657           2 :                                 continue;
     658             :                         }
     659         121 :                         mysql = (MY_MYSQL*) my_res->ptr;
     660         121 :                         if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) {
     661           0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object %d or resource %s", i, intern->zo.ce->name->val);
     662           0 :                                 continue;
     663             :                         }
     664         121 :                         (*out_array)[current++] = mysql->mysql;
     665             :                 }
     666             :         } ZEND_HASH_FOREACH_END();
     667          65 :         return 0;
     668             : }
     669             : /* }}} */
     670             : 
     671             : /* {{{ mysqlnd_zval_array_from_mysqlnd_array */
     672          65 : static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_array TSRMLS_DC)
     673             : {
     674          65 :         MYSQLND **p = in_array;
     675             :         zval dest_array;
     676             :         zval *elem, *dest_elem;
     677          65 :         int ret = 0, i = 0;
     678             : 
     679          65 :         array_init_size(&dest_array, zend_hash_num_elements(Z_ARRVAL_P(out_array)));
     680             : 
     681         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(out_array), elem) {
     682         123 :                 i++;
     683         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT || 
     684         123 :                                 !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry TSRMLS_CC)) {
     685           0 :                         continue;
     686             :                 }
     687             :                 {
     688             :                         MY_MYSQL *mysql;
     689             :                         MYSQLI_RESOURCE *my_res;
     690         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     691         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     692           2 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] Couldn't fetch %s", i, intern->zo.ce->name->val);
     693           2 :                                 continue;
     694             :                         }
     695         121 :                         mysql = (MY_MYSQL *) my_res->ptr;
     696         121 :                         if (mysql->mysql == *p) {
     697          28 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(dest_array), elem);
     698          28 :                                 if (dest_elem) {
     699          28 :                                         zval_add_ref(dest_elem);
     700             :                                 }
     701          28 :                                 ret++;
     702          28 :                                 p++;
     703             :                         }
     704             :                 }
     705             :         } ZEND_HASH_FOREACH_END();
     706             : 
     707             :         /* destroy old array and add new one */
     708          65 :         zval_ptr_dtor(out_array);
     709          65 :         ZVAL_COPY_VALUE(out_array, &dest_array);
     710             : 
     711          65 :         return 0;
     712             : }
     713             : /* }}} */
     714             : 
     715             : /* {{{ mysqlnd_dont_poll_zval_array_from_mysqlnd_array */
     716          33 : static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *in_zval_array, zval *out_array TSRMLS_DC)
     717             : {
     718          33 :         MYSQLND **p = in_array;
     719             :         zval proxy, *elem, *dest_elem;
     720          33 :         int ret = 0;
     721             : 
     722          33 :         array_init(&proxy);
     723          33 :         if (in_array) {
     724          76 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_zval_array), elem) {
     725             :                         MY_MYSQL *mysql;
     726          29 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     727          29 :                         mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)intern->ptr)->ptr;
     728          29 :                         if (mysql->mysql == *p) {
     729          20 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(proxy), elem);
     730          20 :                                 if (dest_elem) {
     731          20 :                                         zval_add_ref(dest_elem);
     732             :                                 }
     733          20 :                                 ret++;
     734          20 :                                 p++;
     735             :                         }
     736             :                 } ZEND_HASH_FOREACH_END();
     737             :         }
     738             : 
     739             :         /* destroy old array and add new one */
     740          33 :         zval_ptr_dtor(out_array);
     741          33 :         ZVAL_COPY_VALUE(out_array, &proxy);
     742             : 
     743          33 :         return 0;
     744             : }
     745             : /* }}} */
     746             : 
     747             : /* {{{ proto int mysqli_poll(array read, array write, array error, long sec [, long usec]) U
     748             :    Poll connections */
     749          42 : PHP_FUNCTION(mysqli_poll)
     750             : {
     751             :         zval                    *r_array, *e_array, *dont_poll_array;
     752          42 :         MYSQLND                 **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL;
     753          42 :         zend_long                       sec = 0, usec = 0;
     754             :         enum_func_status ret;
     755             :         int                     desc_num;
     756             : 
     757          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) {
     758           6 :                 return;
     759             :         }
     760          36 :         if (sec < 0 || usec < 0) {
     761           2 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Negative values passed for sec and/or usec");
     762           2 :                 RETURN_FALSE;
     763             :         }
     764             : 
     765          34 :         if (!r_array && !e_array) {
     766           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No stream arrays were passed");
     767           1 :                 RETURN_FALSE;
     768             :         }
     769             : 
     770          33 :         if (r_array != NULL) {
     771          33 :                 mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array TSRMLS_CC);
     772             :         }
     773          33 :         if (e_array != NULL) {
     774          32 :                 mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array TSRMLS_CC);
     775             :         }
     776             : 
     777          33 :         ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num);
     778             : 
     779          33 :         mysqlnd_dont_poll_zval_array_from_mysqlnd_array(r_array != NULL ? new_dont_poll_array:NULL, r_array, dont_poll_array TSRMLS_CC);
     780             : 
     781          33 :         if (r_array != NULL) {
     782          33 :                 mysqlnd_zval_array_from_mysqlnd_array(new_r_array, r_array TSRMLS_CC);
     783             :         }
     784          33 :         if (e_array != NULL) {
     785          32 :                 mysqlnd_zval_array_from_mysqlnd_array(new_e_array, e_array TSRMLS_CC);
     786             :         }
     787             : 
     788          33 :         if (new_dont_poll_array) {
     789          18 :                 efree(new_dont_poll_array);
     790             :         }
     791          33 :         if (new_r_array) {
     792          33 :                 efree(new_r_array);
     793             :         }
     794          33 :         if (new_e_array) {
     795          32 :                 efree(new_e_array);
     796             :         }
     797          33 :         if (ret == PASS) {
     798          29 :                 RETURN_LONG(desc_num);
     799             :         } else {
     800           4 :                 RETURN_FALSE;
     801             :         }
     802             : }
     803             : /* }}} */
     804             : 
     805             : /* {{{ proto int mysqli_reap_async_query(object link) U
     806             :    Poll connections */
     807          29 : PHP_FUNCTION(mysqli_reap_async_query)
     808             : {
     809             :         MY_MYSQL                *mysql;
     810             :         zval                    *mysql_link;
     811             :         MYSQLI_RESOURCE         *mysqli_resource;
     812          29 :         MYSQL_RES                       *result = NULL;
     813             : 
     814          29 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     815           3 :                 return;
     816             :         }
     817             : 
     818          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     819             : 
     820          26 :         if (FAIL == mysqlnd_reap_async_query(mysql->mysql)) {
     821           4 :                 RETURN_FALSE;
     822             :         }
     823             : 
     824          22 :         if (!mysql_field_count(mysql->mysql)) {
     825             :                 /* no result set - not a SELECT */
     826           7 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     827             : /*                      php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */
     828             :                 }
     829           7 :                 RETURN_TRUE;
     830             :         }
     831             : 
     832          15 :         switch (mysql->async_result_fetch_type) {
     833             :                 case MYSQLI_STORE_RESULT:
     834           1 :                         result = mysql_store_result(mysql->mysql);
     835           1 :                         break;
     836             :                 case MYSQLI_USE_RESULT:
     837          14 :                         result = mysql_use_result(mysql->mysql);
     838             :                         break;
     839             :         }
     840             : 
     841          15 :         if (!result) {
     842           0 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
     843           0 :                                                                                 "%s", mysql_error(mysql->mysql));
     844           0 :                 RETURN_FALSE;
     845             :         }
     846             : 
     847          15 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     848             : /*              php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */
     849             :         }
     850             : 
     851          15 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     852          15 :         mysqli_resource->ptr = (void *)result;
     853          15 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     854          15 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     855             : }
     856             : /* }}} */
     857             : 
     858             : /* {{{ proto object mysqli_stmt_get_result(object link) U
     859             :    Buffer result set on client */
     860         592 : PHP_FUNCTION(mysqli_stmt_get_result)
     861             : {
     862             :         MYSQL_RES               *result;
     863             :         MYSQLI_RESOURCE *mysqli_resource;
     864             :         MY_STMT                 *stmt;
     865             :         zval                    *mysql_stmt;
     866             : 
     867         592 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     868           5 :                 return;
     869             :         }
     870         587 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     871             : 
     872         585 :         if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
     873           6 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     874           6 :                 RETURN_FALSE;
     875             :         }
     876             : 
     877         579 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     878         579 :         mysqli_resource->ptr = (void *)result;
     879         579 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     880         579 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     881             : }
     882             : /* }}} */
     883             : #endif
     884             : 
     885             : /* {{{ proto object mysqli_get_warnings(object link) */
     886           5 : PHP_FUNCTION(mysqli_get_warnings)
     887             : {
     888             :         MY_MYSQL                        *mysql;
     889             :         zval                            *mysql_link;
     890             :         MYSQLI_RESOURCE         *mysqli_resource;
     891             :         MYSQLI_WARNING          *w;
     892             : 
     893           5 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     894           0 :                 return;
     895             :         }
     896           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     897             : 
     898           5 :         if (mysql_warning_count(mysql->mysql)) {
     899             : #ifdef MYSQLI_USE_MYSQLND
     900           5 :                 w = php_get_warnings(mysql->mysql->data TSRMLS_CC);
     901             : #else
     902             :                 w = php_get_warnings(mysql->mysql TSRMLS_CC);
     903             : #endif
     904             :         } else {
     905           0 :                 RETURN_FALSE;
     906             :         }
     907           5 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     908           5 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     909           5 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     910           5 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     911             : }
     912             : /* }}} */
     913             : 
     914             : /* {{{ proto object mysqli_stmt_get_warnings(object link) */
     915           7 : PHP_FUNCTION(mysqli_stmt_get_warnings)
     916             : {
     917             :         MY_STMT                         *stmt;
     918             :         zval                            *stmt_link;
     919             :         MYSQLI_RESOURCE         *mysqli_resource;
     920             :         MYSQLI_WARNING          *w;
     921             : 
     922           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
     923           2 :                 return;
     924             :         }
     925           5 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, stmt_link, MYSQLI_STATUS_VALID);
     926             : 
     927           3 :         if (mysqli_stmt_warning_count(stmt->stmt)) {
     928           1 :                 w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC);
     929             :         } else {
     930           2 :                 RETURN_FALSE;
     931             :         }
     932           1 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     933           1 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     934           1 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     935           1 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     936             : }
     937             : /* }}} */
     938             : 
     939             : #ifdef HAVE_MYSQLI_SET_CHARSET
     940             : /* {{{ proto bool mysqli_set_charset(object link, string csname)
     941             :    sets client character set */
     942         103 : PHP_FUNCTION(mysqli_set_charset)
     943             : {
     944             :         MY_MYSQL        *mysql;
     945             :         zval            *mysql_link;
     946             :         char            *cs_name;
     947             :         size_t          csname_len;
     948             : 
     949         103 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &csname_len) == FAILURE) {
     950           4 :                 return;
     951             :         }
     952          99 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     953             : 
     954          97 :         if (mysql_set_character_set(mysql->mysql, cs_name)) {
     955           2 :                 RETURN_FALSE;
     956             :         }
     957          95 :         RETURN_TRUE;
     958             : }
     959             : /* }}} */
     960             : #endif
     961             : 
     962             : #ifdef HAVE_MYSQLI_GET_CHARSET
     963             : /* {{{ proto object mysqli_get_charset(object link) U
     964             :    returns a character set object */
     965          10 : PHP_FUNCTION(mysqli_get_charset)
     966             : {
     967             :         MY_MYSQL                                *mysql;
     968             :         zval                                    *mysql_link;
     969          10 :         const char                              *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL;
     970             :         uint                                    minlength, maxlength, number, state;
     971             : #if !defined(MYSQLI_USE_MYSQLND)
     972             :         MY_CHARSET_INFO                 cs;
     973             : #else
     974             :         const MYSQLND_CHARSET   *cs;
     975             : #endif
     976             : 
     977          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     978           2 :                 return;
     979             :         }
     980           8 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     981             : 
     982             : 
     983             : #if !defined(MYSQLI_USE_MYSQLND)
     984             :         mysql_get_character_set_info(mysql->mysql, &cs);
     985             :         name = (char *)cs.csname;
     986             :         collation = (char *)cs.name;
     987             :         dir = (char *)cs.dir;
     988             :         minlength = cs.mbminlen;
     989             :         maxlength = cs.mbmaxlen;
     990             :         number = cs.number;
     991             :         state = cs.state;
     992             :         comment = cs.comment;
     993             : #else
     994           7 :         cs = mysql->mysql->data->charset;
     995           7 :         if (!cs) {
     996           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The connection has no charset associated");
     997           0 :                 RETURN_NULL();
     998             :         }
     999           7 :         name = cs->name;
    1000           7 :         collation = cs->collation;
    1001           7 :         minlength = cs->char_minlen;
    1002           7 :         maxlength = cs->char_maxlen;
    1003           7 :         number = cs->nr;
    1004           7 :         comment = cs->comment;
    1005           7 :         state = 1;      /* all charsets are compiled in */
    1006             : #endif
    1007           7 :         object_init(return_value);
    1008             : 
    1009           7 :         add_property_string(return_value, "charset", (name) ? (char *)name : "");
    1010           7 :         add_property_string(return_value, "collation",(collation) ? (char *)collation : "");
    1011           7 :         add_property_string(return_value, "dir", (dir) ? (char *)dir : "");
    1012           7 :         add_property_long(return_value, "min_length", minlength);
    1013           7 :         add_property_long(return_value, "max_length", maxlength);
    1014           7 :         add_property_long(return_value, "number", number);
    1015           7 :         add_property_long(return_value, "state", state);
    1016           7 :         add_property_string(return_value, "comment", (comment) ? (char *)comment : "");
    1017             : }
    1018             : /* }}} */
    1019             : #endif
    1020             : 
    1021             : #if !defined(MYSQLI_USE_MYSQLND)
    1022             : extern char * mysqli_escape_string_for_tx_name_in_comment(const char * const name TSRMLS_DC);
    1023             : 
    1024             : /* {{{ proto bool mysqli_begin_transaction_libmysql */
    1025             : static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name TSRMLS_DC)
    1026             : {
    1027             :         int ret;
    1028             :         zend_bool err = FALSE;
    1029             :         smart_str tmp_str = {0};
    1030             :         if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
    1031             :                 if (tmp_str.s) {
    1032             :                         smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1033             :                 }
    1034             :                 smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
    1035             :         }
    1036             :         if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
    1037             :                 if (mysql_get_server_version(conn) < 50605L) {
    1038             :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
    1039             :                         err = TRUE;
    1040             :                 } else if (mode & TRANS_START_READ_WRITE) {
    1041             :                         if (tmp_str.s) {
    1042             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1043             :                         }
    1044             :                         smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
    1045             :                 } else if (mode & TRANS_START_READ_ONLY) {
    1046             :                         if (tmp_str.s) {
    1047             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1048             :                         }
    1049             :                         smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
    1050             :                 }
    1051             :         }
    1052             :         smart_str_0(&tmp_str);
    1053             : 
    1054             :         if (err == FALSE){
    1055             :                 char * name_esc = mysqli_escape_string_for_tx_name_in_comment(name TSRMLS_CC);
    1056             :                 char * query;
    1057             :                 unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
    1058             :                                                                                   name_esc? name_esc:"", tmp_str.s? tmp_str.s->val:"");
    1059             : 
    1060             :                 smart_str_free(&tmp_str);
    1061             :                 if (name_esc) {
    1062             :                         efree(name_esc);
    1063             :                 }
    1064             : 
    1065             :                 ret = mysql_real_query(conn, query, query_len);
    1066             :                 efree(query);
    1067             :         }
    1068             :         return ret;
    1069             : }
    1070             : /* }}} */
    1071             : #endif
    1072             : 
    1073             : /* {{{ proto bool mysqli_begin_transaction(object link, [int flags [, string name]])
    1074             :    Starts a transaction */
    1075           9 : PHP_FUNCTION(mysqli_begin_transaction)
    1076             : {
    1077             :         MY_MYSQL        *mysql;
    1078             :         zval            *mysql_link;
    1079           9 :         zend_long               flags = TRANS_START_NO_OPT;
    1080           9 :         char *          name = NULL;
    1081           9 :         size_t                  name_len = -1;
    1082           9 :         zend_bool       err = FALSE;
    1083             : 
    1084           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
    1085           6 :                 return;
    1086             :         }
    1087           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1088           3 :         if (flags < 0) {
    1089           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for parameter flags (%pd)", flags);
    1090           1 :                 err = TRUE;
    1091             :         }
    1092           3 :         if (!name_len) {
    1093           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
    1094           0 :                 err = TRUE;
    1095             :         }
    1096           3 :         if (TRUE == err) {
    1097           1 :                 RETURN_FALSE;                   
    1098             :         }
    1099             :         
    1100             : #if !defined(MYSQLI_USE_MYSQLND)
    1101             :         if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name TSRMLS_CC)) {
    1102             :                 RETURN_FALSE;
    1103             :         }
    1104             : #else
    1105           2 :         if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
    1106           0 :                 RETURN_FALSE;
    1107             :         }
    1108             : #endif
    1109           2 :         RETURN_TRUE;
    1110             : }
    1111             : /* }}} */
    1112             : 
    1113             : #if !defined(MYSQLI_USE_MYSQLND)
    1114             : /* {{{ proto bool mysqli_savepoint_libmysql */
    1115             : static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, zend_bool release)
    1116             : {
    1117             :         int ret;
    1118             :         char * query;
    1119             :         unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
    1120             :         ret = mysql_real_query(conn, query, query_len);
    1121             :         efree(query);
    1122             :         return ret;
    1123             : }
    1124             : /* }}} */
    1125             : #endif
    1126             : 
    1127             : /* {{{ proto bool mysqli_savepoint(object link, string name)
    1128             :    Starts a transaction */
    1129           7 : PHP_FUNCTION(mysqli_savepoint)
    1130             : {
    1131             :         MY_MYSQL        *mysql;
    1132             :         zval            *mysql_link;
    1133           7 :         char *          name = NULL;
    1134           7 :         size_t                  name_len = -1;
    1135             : 
    1136           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1137           4 :                 return;
    1138             :         }
    1139           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1140           3 :         if (!name || !name_len) {
    1141           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
    1142           1 :                 RETURN_FALSE;   
    1143             :         }
    1144             : 
    1145             : #if !defined(MYSQLI_USE_MYSQLND)
    1146             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, FALSE)) {
    1147             : #else
    1148           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1149             : #endif
    1150           0 :                 RETURN_FALSE;
    1151             :         }
    1152           2 :         RETURN_TRUE;
    1153             : }
    1154             : /* }}} */
    1155             : 
    1156             : /* {{{ proto bool mysqli_release_savepoint(object link, string name)
    1157             :    Starts a transaction */
    1158           7 : PHP_FUNCTION(mysqli_release_savepoint)
    1159             : {
    1160             :         MY_MYSQL        *mysql;
    1161             :         zval            *mysql_link;
    1162           7 :         char *          name = NULL;
    1163           7 :         size_t                  name_len = -1;
    1164             : 
    1165           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1166           4 :                 return;
    1167             :         }
    1168           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1169           3 :         if (!name || !name_len) {
    1170           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");        
    1171           1 :                 RETURN_FALSE;
    1172             :         }
    1173             : #if !defined(MYSQLI_USE_MYSQLND)
    1174             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {
    1175             : #else
    1176           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1177             : #endif
    1178           0 :                 RETURN_FALSE;
    1179             :         }
    1180           2 :         RETURN_TRUE;
    1181             : }
    1182             : /* }}} */
    1183             : 
    1184             : /* {{{ proto bool mysqli_get_links_stats()
    1185             :    Returns information about open and cached links */
    1186           7 : PHP_FUNCTION(mysqli_get_links_stats)
    1187             : {
    1188           7 :         if (ZEND_NUM_ARGS()) {
    1189           1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "no parameters expected");
    1190           1 :                 return; 
    1191             :         }
    1192           6 :         array_init(return_value);
    1193           6 :         add_assoc_long_ex(return_value, "total", sizeof("total") - 1, MyG(num_links));
    1194           6 :         add_assoc_long_ex(return_value, "active_plinks", sizeof("active_plinks") - 1, MyG(num_active_persistent));
    1195           6 :         add_assoc_long_ex(return_value, "cached_plinks", sizeof("cached_plinks") - 1, MyG(num_inactive_persistent));
    1196             : }
    1197             : /* }}} */
    1198             : 
    1199             : 
    1200             : /*
    1201             :  * Local variables:
    1202             :  * tab-width: 4
    1203             :  * c-basic-offset: 4
    1204             :  * End:
    1205             :  * vim600: noet sw=4 ts=4 fdm=marker
    1206             :  * vim<600: noet sw=4 ts=4
    1207             :  */

Generated by: LCOV version 1.10

Generated at Mon, 10 Nov 2014 22:46:42 +0000 (11 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.