/* {{{ ps_fetch_date */ static void ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { struct st_mysqlnd_time t = {0}; zend_ulong length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_date"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type= MYSQLND_TIMESTAMP_DATE; t.neg= 0; t.second_part = t.hour = t.minute = t.second = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATE; } length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day); DBG_INF_FMT("%s", value); ZVAL_STRINGL(zv, value, length); mnd_sprintf_free(value); DBG_VOID_RETURN; }
/* {{{ ps_fetch_datetime */ static void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_datetime"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; t.neg = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; if (length > 4) { t.hour = (unsigned int) to[4]; t.minute = (unsigned int) to[5]; t.second = (unsigned int) to[6]; } else { t.hour = t.minute = t.second= 0; } t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATETIME; } length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); #if MYSQLND_UNICODE if (!as_unicode) { #endif ZVAL_STRINGL(zv, value, length, 1); mnd_sprintf_free(value); #if MYSQLND_UNICODE } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }
/* {{{ ps_fetch_time */ static void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_time"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; t.day = (unsigned long) sint4korr(to+1); t.hour = (unsigned int) to[5]; t.minute = (unsigned int) to[6]; t.second = (unsigned int) to[7]; t.second_part = (length > 8) ? (unsigned long) sint4korr(to+8) : 0; t.year = t.month= 0; if (t.day) { /* Convert days to hours at once */ t.hour += t.day*24; t.day = 0; } (*row) += length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_TIME; } length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); #if MYSQLND_UNICODE if (!as_unicode) { #endif ZVAL_STRINGL(zv, value, length, 1); mnd_sprintf_free(value); #if MYSQLND_UNICODE } else { ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }
/* {{{ mysqlnd_vio::open_tcp_or_unix */ static php_stream * MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { #if PHP_API_VERSION < 20100412 unsigned int streams_options = ENFORCE_SAFE_MODE; #else unsigned int streams_options = 0; #endif unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT; char * hashed_details = NULL; int hashed_details_len = 0; zend_string *errstr = NULL; int errcode = 0; struct timeval tv; dtor_func_t origin_dtor; php_stream * net_stream = NULL; DBG_ENTER("mysqlnd_vio::open_tcp_or_unix"); vio->data->stream = NULL; if (persistent) { hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", vio); DBG_INF_FMT("hashed_details=%s", hashed_details); } if (vio->data->options.timeout_connect) { tv.tv_sec = vio->data->options.timeout_connect; tv.tv_usec = 0; } DBG_INF_FMT("calling php_stream_xport_create"); net_stream = php_stream_xport_create(scheme.s, scheme.l, streams_options, streams_flags, hashed_details, (vio->data->options.timeout_connect) ? &tv : NULL, NULL /*ctx*/, &errstr, &errcode); if (errstr || !net_stream) { DBG_ERR("Error"); if (hashed_details) { mnd_sprintf_free(hashed_details); } errcode = CR_CONNECTION_ERROR; SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, errstr? ZSTR_VAL(errstr):"Unknown error while connecting"); if (errstr) { zend_string_release(errstr); } DBG_RETURN(NULL); } if (hashed_details) { /* If persistent, the streams register it in EG(persistent_list). This is unwanted. ext/mysql or ext/mysqli are responsible to clean, whatever they have to. */ zend_resource *le; if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_details_len))) { origin_dtor = EG(persistent_list).pDestructor; /* in_free will let streams code skip destructing - big HACK, but STREAMS suck big time regarding persistent streams. Just not compatible for extensions that need persistency. */ EG(persistent_list).pDestructor = NULL; zend_hash_str_del(&EG(persistent_list), hashed_details, hashed_details_len); EG(persistent_list).pDestructor = origin_dtor; pefree(le, 1); } #if ZEND_DEBUG /* Shut-up the streams, they don't know what they are doing */ net_stream->__exposed = 1; #endif mnd_sprintf_free(hashed_details); } /* Streams are not meant for C extensions! Thus we need a hack. Every connected stream will be registered as resource (in EG(regular_list). So far, so good. However, it won't be unregistered until the script ends. So, we need to take care of that. */ origin_dtor = EG(regular_list).pDestructor; EG(regular_list).pDestructor = NULL; zend_hash_index_del(&EG(regular_list), net_stream->res->handle); /* ToDO: should it be res->handle, do streams register with addref ?*/ efree(net_stream->res); net_stream->res = NULL; EG(regular_list).pDestructor = origin_dtor; DBG_RETURN(net_stream); }