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/mysqlnd - mysqlnd_result_meta.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 149 185 80.5 %
Date: 2014-10-22 Functions: 10 12 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 2006-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: Andrey Hristov <andrey@mysql.com>                           |
      16             :   |          Ulf Wendel <uwendel@mysql.com>                              |
      17             :   |          Georg Richter <georg@mysql.com>                             |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : #include "php.h"
      23             : #include "mysqlnd.h"
      24             : #include "mysqlnd_priv.h"
      25             : #include "mysqlnd_result.h"
      26             : #include "mysqlnd_wireprotocol.h"
      27             : #include "mysqlnd_debug.h"
      28             : #include "ext/standard/basic_functions.h"
      29             : 
      30             : 
      31             : /* {{{ php_mysqlnd_free_field_metadata */
      32             : static void
      33       32146 : php_mysqlnd_free_field_metadata(MYSQLND_FIELD *meta, zend_bool persistent TSRMLS_DC)
      34             : {
      35       32146 :         if (meta) {
      36       32146 :                 if (meta->root) {
      37       27146 :                         mnd_pefree(meta->root, persistent);
      38       27146 :                         meta->root = NULL;
      39             :                 }
      40       32146 :                 if (meta->def) {
      41           3 :                         mnd_pefree(meta->def, persistent);
      42           3 :                         meta->def = NULL;
      43             :                 }
      44       32146 :                 if (meta->sname) {
      45       27146 :                         zend_string_release(meta->sname);
      46             :                 }
      47             :         }
      48       32146 : }
      49             : /* }}} */
      50             : 
      51             : /* {{{ mysqlnd_res_meta::read_metadata */
      52             : static enum_func_status
      53        7063 : MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn TSRMLS_DC)
      54             : {
      55        7063 :         unsigned int i = 0;
      56             :         MYSQLND_PACKET_RES_FIELD * field_packet;
      57             : 
      58        7063 :         DBG_ENTER("mysqlnd_res_meta::read_metadata");
      59             : 
      60        7063 :         field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
      61        7063 :         if (!field_packet) {
      62           0 :                 SET_OOM_ERROR(*conn->error_info);
      63           0 :                 DBG_RETURN(FAIL);
      64             :         }
      65        7063 :         field_packet->persistent_alloc = meta->persistent;
      66       30768 :         for (;i < meta->field_count; i++) {
      67             :                 zend_ulong idx;
      68             : 
      69       23709 :                 if (meta->fields[i].root) {
      70             :                         /* We re-read metadata for PS */
      71           0 :                         mnd_pefree(meta->fields[i].root, meta->persistent);
      72           0 :                         meta->fields[i].root = NULL;
      73             :                 }
      74             : 
      75       23709 :                 field_packet->metadata = &(meta->fields[i]);
      76       23709 :                 if (FAIL == PACKET_READ(field_packet, conn)) {
      77           0 :                         PACKET_FREE(field_packet);
      78           0 :                         DBG_RETURN(FAIL);
      79             :                 }
      80       23709 :                 if (field_packet->error_info.error_no) {
      81           1 :                         COPY_CLIENT_ERROR(*conn->error_info, field_packet->error_info);
      82             :                         /* Return back from CONN_QUERY_SENT */
      83           1 :                         PACKET_FREE(field_packet);
      84           1 :                         DBG_RETURN(FAIL);
      85             :                 }
      86             : 
      87       23708 :                 if (field_packet->stupid_list_fields_eof == TRUE) {
      88           3 :                         meta->field_count = i;
      89           3 :                         break;
      90             :                 }
      91             : 
      92       23705 :                 if (mysqlnd_ps_fetch_functions[meta->fields[i].type].func == NULL) {
      93           0 :                         DBG_ERR_FMT("Unknown type %u sent by the server.  Please send a report to the developers",
      94           0 :                                                 meta->fields[i].type);
      95           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING,
      96             :                                                          "Unknown type %u sent by the server. "
      97             :                                                          "Please send a report to the developers",
      98           0 :                                                          meta->fields[i].type);
      99           0 :                         PACKET_FREE(field_packet);
     100           0 :                         DBG_RETURN(FAIL);
     101             :                 }
     102       23705 :                 if (meta->fields[i].type == MYSQL_TYPE_BIT) {
     103             :                         size_t field_len;
     104        5739 :                         DBG_INF("BIT");
     105        5739 :                         ++meta->bit_fields_count;
     106             :                         /* .length is in bits */
     107        5739 :                         field_len = meta->fields[i].length / 8;
     108             :                         /*
     109             :                           If there is rest, add one byte :
     110             :                           8 bits = 1 byte but 9 bits = 2 bytes
     111             :                         */
     112        5739 :                         if (meta->fields[i].length % 8) {
     113        5115 :                                 ++field_len;
     114             :                         }
     115        5739 :                         switch (field_len) {
     116             :                                 case 8:
     117             :                                 case 7:
     118             :                                 case 6:
     119             :                                 case 5:
     120        1400 :                                         meta->bit_fields_total_len += 20;/* 21 digis, no sign*/
     121        1400 :                                         break;
     122             :                                 case 4:
     123        1080 :                                         meta->bit_fields_total_len += 10;/* 2 000 000 000*/
     124        1080 :                                         break;
     125             :                                 case 3:
     126        1120 :                                         meta->bit_fields_total_len += 8;/*  12 000 000*/
     127        1120 :                                         break;
     128             :                                 case 2:
     129        1120 :                                         meta->bit_fields_total_len += 5;/* 32 500 */
     130        1120 :                                         break;
     131             :                                 case 1:
     132        1019 :                                         meta->bit_fields_total_len += 3;/* 120 */
     133             :                                         break;
     134             :                         }
     135             :                 }
     136             : 
     137             :                 /* For BC we have to check whether the key is numeric and use it like this */
     138       47410 :                 if ((meta->zend_hash_keys[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet->metadata->sname, idx))) {
     139          70 :                         meta->zend_hash_keys[i].key = idx;
     140             :                 } 
     141             :         }
     142        7062 :         PACKET_FREE(field_packet);
     143             : 
     144        7062 :         DBG_RETURN(PASS);
     145             : }
     146             : /* }}} */
     147             : 
     148             : 
     149             : /* {{{ mysqlnd_res_meta::free */
     150             : static void
     151        8297 : MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA * meta TSRMLS_DC)
     152             : {
     153             :         int i;
     154             :         MYSQLND_FIELD *fields;
     155        8297 :         DBG_ENTER("mysqlnd_res_meta::free");
     156        8297 :         DBG_INF_FMT("persistent=%u", meta->persistent);
     157             : 
     158        8297 :         if ((fields = meta->fields)) {
     159        8297 :                 DBG_INF("Freeing fields metadata");
     160        8297 :                 i = meta->field_count;
     161       48740 :                 while (i--) {
     162       32146 :                         php_mysqlnd_free_field_metadata(fields++, meta->persistent TSRMLS_CC);
     163             :                 }
     164        8297 :                 mnd_pefree(meta->fields, meta->persistent);
     165        8297 :                 meta->fields = NULL;
     166             :         }
     167             : 
     168        8297 :         if (meta->zend_hash_keys) {
     169        8297 :                 DBG_INF("Freeing zend_hash_keys");
     170        8297 :                 mnd_pefree(meta->zend_hash_keys, meta->persistent);
     171        8297 :                 meta->zend_hash_keys = NULL;
     172             :         }
     173        8297 :         DBG_INF("Freeing metadata structure");
     174        8297 :         mnd_pefree(meta, meta->persistent);
     175             : 
     176        8297 :         DBG_VOID_RETURN;
     177             : }
     178             : /* }}} */
     179             : 
     180             : 
     181             : /* {{{ mysqlnd_res::clone_metadata */
     182             : static MYSQLND_RES_METADATA *
     183        1232 : MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * const meta, zend_bool persistent TSRMLS_DC)
     184             : {
     185             :         unsigned int i;
     186             :         /* +1 is to have empty marker at the end */
     187        1232 :         MYSQLND_RES_METADATA * new_meta = NULL;
     188             :         MYSQLND_FIELD * new_fields;
     189        1232 :         MYSQLND_FIELD * orig_fields = meta->fields;
     190        1232 :         size_t len = meta->field_count * sizeof(struct mysqlnd_field_hash_key);
     191             : 
     192        1232 :         DBG_ENTER("mysqlnd_res_meta::clone_metadata");
     193        1232 :         DBG_INF_FMT("persistent=%u", persistent);
     194             : 
     195        1232 :         new_meta = mnd_pecalloc(1, sizeof(MYSQLND_RES_METADATA), persistent);
     196        1232 :         if (!new_meta) {
     197           0 :                 goto oom;
     198             :         }
     199        1232 :         new_meta->persistent = persistent;
     200        1232 :         new_meta->m = meta->m;
     201             : 
     202        1232 :         new_fields = mnd_pecalloc(meta->field_count + 1, sizeof(MYSQLND_FIELD), persistent);
     203        1232 :         if (!new_fields) {
     204           0 :                 goto oom;
     205             :         }
     206             : 
     207        1232 :         new_meta->zend_hash_keys = mnd_pemalloc(len, persistent);
     208        1232 :         if (!new_meta->zend_hash_keys) {
     209           0 :                 goto oom;
     210             :         }
     211        1232 :         memcpy(new_meta->zend_hash_keys, meta->zend_hash_keys, len);
     212             : 
     213             :         /*
     214             :           This will copy also the strings and the root, which we will have
     215             :           to adjust in the loop
     216             :         */
     217        1232 :         memcpy(new_fields, orig_fields, (meta->field_count) * sizeof(MYSQLND_FIELD));
     218        4670 :         for (i = 0; i < meta->field_count; i++) {
     219             :                 /* First copy the root, then field by field adjust the pointers */
     220        3438 :                 new_fields[i].root = mnd_pemalloc(orig_fields[i].root_len, persistent);
     221             : 
     222        3438 :                 if (!new_fields[i].root) {
     223           0 :                         goto oom;
     224             :                 }
     225             : 
     226        3438 :                 memcpy(new_fields[i].root, orig_fields[i].root, new_fields[i].root_len);
     227             : 
     228        3438 :                 if (orig_fields[i].sname) {
     229        6876 :                         new_fields[i].sname = zend_string_copy(orig_fields[i].sname);
     230        3438 :                         new_fields[i].name = new_fields[i].sname->val;
     231        3438 :                         new_fields[i].name_length = new_fields[i].sname->len;
     232             :                 }
     233             : 
     234        3438 :                 if (orig_fields[i].org_name && orig_fields[i].org_name != mysqlnd_empty_string) {
     235        5714 :                         new_fields[i].org_name = new_fields[i].root +
     236        2857 :                                 (orig_fields[i].org_name - orig_fields[i].root);
     237             :                 }
     238        3438 :                 if (orig_fields[i].table && orig_fields[i].table != mysqlnd_empty_string) {
     239        5698 :                         new_fields[i].table     = new_fields[i].root +
     240        2849 :                                 (orig_fields[i].table - orig_fields[i].root);
     241             :                 }
     242        3438 :                 if (orig_fields[i].org_table && orig_fields[i].org_table != mysqlnd_empty_string) {
     243        5642 :                         new_fields[i].org_table = new_fields[i].root +
     244        2821 :                                 (orig_fields[i].org_table - orig_fields[i].root);
     245             :                 }
     246        3438 :                 if (orig_fields[i].db && orig_fields[i].db != mysqlnd_empty_string) {
     247        2821 :                         new_fields[i].db = new_fields[i].root + (orig_fields[i].db - orig_fields[i].root);
     248             :                 }
     249        3438 :                 if (orig_fields[i].catalog && orig_fields[i].catalog != mysqlnd_empty_string) {
     250        3438 :                         new_fields[i].catalog = new_fields[i].root + (orig_fields[i].catalog - orig_fields[i].root);
     251             :                 }
     252             :                 /* def is not on the root, if allocated at all */
     253        3438 :                 if (orig_fields[i].def) {
     254           0 :                         new_fields[i].def = mnd_pemalloc(orig_fields[i].def_length + 1, persistent);
     255           0 :                         if (!new_fields[i].def) {
     256           0 :                                 goto oom;
     257             :                         }
     258             :                         /* copy the trailing \0 too */
     259           0 :                         memcpy(new_fields[i].def, orig_fields[i].def, orig_fields[i].def_length + 1);
     260             :                 }
     261             :         }
     262        1232 :         new_meta->current_field = 0;
     263        1232 :         new_meta->field_count = meta->field_count;
     264             : 
     265        1232 :         new_meta->fields = new_fields;
     266             : 
     267        1232 :         DBG_RETURN(new_meta);
     268             : oom:
     269           0 :         if (new_meta) {
     270           0 :                 new_meta->m->free_metadata(new_meta TSRMLS_CC);
     271           0 :                 new_meta = NULL;
     272             :         }
     273           0 :         DBG_RETURN(NULL);
     274             : }
     275             : /* }}} */
     276             : 
     277             : 
     278             : /* {{{ mysqlnd_res_meta::fetch_field */
     279             : static const MYSQLND_FIELD *
     280         320 : MYSQLND_METHOD(mysqlnd_res_meta, fetch_field)(MYSQLND_RES_METADATA * const meta TSRMLS_DC)
     281             : {
     282         320 :         DBG_ENTER("mysqlnd_res_meta::fetch_field");
     283         320 :         if (meta->current_field >= meta->field_count) {
     284          18 :                 DBG_INF("no more fields");
     285          18 :                 DBG_RETURN(NULL);
     286             :         }
     287         906 :         DBG_INF_FMT("name=%s max_length=%u",
     288         604 :                 meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
     289         302 :                 meta->fields[meta->current_field].max_length);
     290         302 :         DBG_RETURN(&meta->fields[meta->current_field++]);
     291             : }
     292             : /* }}} */
     293             : 
     294             : 
     295             : /* {{{ mysqlnd_res_meta::fetch_field_direct */
     296             : static const MYSQLND_FIELD *
     297        1080 : MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct)(const MYSQLND_RES_METADATA * const meta, const MYSQLND_FIELD_OFFSET fieldnr TSRMLS_DC)
     298             : {
     299        1080 :         DBG_ENTER("mysqlnd_res_meta::fetch_field_direct");
     300        1080 :         DBG_INF_FMT("fieldnr=%u", fieldnr);
     301        3228 :         DBG_INF_FMT("name=%s max_length=%u",
     302        2148 :                 meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"",
     303        1080 :                 meta->fields[meta->current_field].max_length);
     304        1080 :         DBG_RETURN(&meta->fields[fieldnr]);
     305             : }
     306             : /* }}} */
     307             : 
     308             : 
     309             : /* {{{ mysqlnd_res_meta::fetch_fields */
     310             : static const MYSQLND_FIELD *
     311         952 : MYSQLND_METHOD(mysqlnd_res_meta, fetch_fields)(MYSQLND_RES_METADATA * const meta TSRMLS_DC)
     312             : {
     313         952 :         DBG_ENTER("mysqlnd_res_meta::fetch_fields");
     314         952 :         DBG_RETURN(meta->fields);
     315             : }
     316             : /* }}} */
     317             : 
     318             : 
     319             : /* {{{ mysqlnd_res_meta::field_tell */
     320             : static MYSQLND_FIELD_OFFSET
     321         161 : MYSQLND_METHOD(mysqlnd_res_meta, field_tell)(const MYSQLND_RES_METADATA * const meta TSRMLS_DC)
     322             : {
     323         161 :         return meta->current_field;
     324             : }
     325             : /* }}} */
     326             : 
     327             : 
     328             : /* {{{ mysqlnd_res_meta::field_seek */
     329             : static MYSQLND_FIELD_OFFSET
     330         219 : MYSQLND_METHOD(mysqlnd_res_meta, field_seek)(MYSQLND_RES_METADATA * const meta, const MYSQLND_FIELD_OFFSET field_offset TSRMLS_DC)
     331             : {
     332         219 :         MYSQLND_FIELD_OFFSET return_value = 0;
     333         219 :         DBG_ENTER("mysqlnd_res_meta::fetch_fields");
     334         219 :         return_value = meta->current_field;
     335         219 :         meta->current_field = field_offset;
     336         219 :         DBG_RETURN(return_value);
     337             : }
     338             : /* }}} */
     339             : 
     340             : static
     341             : MYSQLND_CLASS_METHODS_START(mysqlnd_res_meta)
     342             :         MYSQLND_METHOD(mysqlnd_res_meta, fetch_field),
     343             :         MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct),
     344             :         MYSQLND_METHOD(mysqlnd_res_meta, fetch_fields),
     345             :         MYSQLND_METHOD(mysqlnd_res_meta, field_tell),
     346             :         MYSQLND_METHOD(mysqlnd_res_meta, field_seek),
     347             :         MYSQLND_METHOD(mysqlnd_res_meta, read_metadata),
     348             :         MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata),
     349             :         MYSQLND_METHOD(mysqlnd_res_meta, free),
     350             : MYSQLND_CLASS_METHODS_END;
     351             : 
     352             : 
     353             : /* {{{ mysqlnd_result_meta_init */
     354             : PHPAPI MYSQLND_RES_METADATA *
     355        7063 : mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent TSRMLS_DC)
     356             : {
     357        7063 :         size_t alloc_size = sizeof(MYSQLND_RES_METADATA) + mysqlnd_plugin_count() * sizeof(void *);
     358        7063 :         MYSQLND_RES_METADATA *ret = mnd_pecalloc(1, alloc_size, persistent);
     359        7063 :         DBG_ENTER("mysqlnd_result_meta_init");
     360        7063 :         DBG_INF_FMT("persistent=%u", persistent);
     361             : 
     362             :         do {
     363        7063 :                 if (!ret) {
     364           0 :                         break;
     365             :                 }
     366        7063 :                 ret->m = & mysqlnd_mysqlnd_res_meta_methods;
     367             : 
     368        7063 :                 ret->persistent = persistent;
     369        7063 :                 ret->field_count = field_count;
     370             :                 /* +1 is to have empty marker at the end */
     371        7063 :                 ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent);
     372        7063 :                 ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent);
     373        7063 :                 if (!ret->fields || !ret->zend_hash_keys) {
     374             :                         break;
     375             :                 }
     376        7063 :                 DBG_INF_FMT("meta=%p", ret);
     377        7063 :                 DBG_RETURN(ret);
     378             :         } while (0);
     379           0 :         if (ret) {
     380           0 :                 ret->m->free_metadata(ret TSRMLS_CC);
     381             :         }
     382           0 :         DBG_RETURN(NULL);
     383             : }
     384             : /* }}} */
     385             : 
     386             : 
     387             : /* {{{ mysqlnd_res_meta_get_methods */
     388             : PHPAPI struct st_mysqlnd_res_meta_methods *
     389           0 : mysqlnd_result_metadata_get_methods()
     390             : {
     391           0 :         return &mysqlnd_mysqlnd_res_meta_methods;
     392             : }
     393             : /* }}} */
     394             : 
     395             : 
     396             : /* {{{ _mysqlnd_plugin_get_plugin_result_metadata_data */
     397             : PHPAPI void **
     398           0 : _mysqlnd_plugin_get_plugin_result_metadata_data(const MYSQLND_RES_METADATA * meta, unsigned int plugin_id TSRMLS_DC)
     399             : {
     400           0 :         DBG_ENTER("_mysqlnd_plugin_get_plugin_result_metadata_data");
     401           0 :         DBG_INF_FMT("plugin_id=%u", plugin_id);
     402           0 :         if (!meta || plugin_id >= mysqlnd_plugin_count()) {
     403           0 :                 return NULL;
     404             :         }
     405           0 :         DBG_RETURN((void *)((char *)meta + sizeof(MYSQLND_RES_METADATA) + plugin_id * sizeof(void *)));
     406             : }
     407             : /* }}} */
     408             : 
     409             : /*
     410             :  * Local variables:
     411             :  * tab-width: 4
     412             :  * c-basic-offset: 4
     413             :  * End:
     414             :  * vim600: noet sw=4 ts=4 fdm=marker
     415             :  * vim<600: noet sw=4 ts=4
     416             :  */

Generated by: LCOV version 1.10

Generated at Wed, 22 Oct 2014 07:24:52 +0000 (2 days ago)

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