⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysqlnd.c

📁 linux下安装不上mysql5与php5的可用此关联
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  +----------------------------------------------------------------------+  | PHP Version 6                                                        |  +----------------------------------------------------------------------+  | Copyright (c) 2006-2007 The PHP Group                                |  +----------------------------------------------------------------------+  | This source file is subject to version 3.01 of the PHP license,      |  | that is bundled with this package in the file LICENSE, and is        |  | available through the world-wide-web at the following url:           |  | http://www.php.net/license/3_01.txt                                  |  | If you did not receive a copy of the PHP license and are unable to   |  | obtain it through the world-wide-web, please send a note to          |  | license@php.net so we can mail you a copy immediately.               |  +----------------------------------------------------------------------+  | Authors: Georg Richter <georg@mysql.com>                             |  |          Andrey Hristov <andrey@mysql.com>                           |  |          Ulf Wendel <uwendel@mysql.com>                              |  +----------------------------------------------------------------------+*//* $Id: header,v 1.17 2006/01/01 13:09:48 sniper Exp $ */#include "php.h"#include "mysqlnd.h"#include "mysqlnd_wireprotocol.h"#include "mysqlnd_priv.h"#include "mysqlnd_statistics.h"#include "ext/standard/basic_functions.h"#define MYSQLND_SILENT/* the server doesn't support 4byte utf8, but let's make it forward compatible */#define MYSQLND_MAX_ALLOWED_USER_LEN	256  /* 64 char * 4byte */#define MYSQLND_MAX_ALLOWED_DB_LEN		256  /* 64 char * 4byte *//*  TODO :  - Don't bind so tightly the metadata with the result set. This means    that the metadata reading should not expect a MYSQLND_RES pointer, it	does not need it, but return a pointer to the metadata (MYSQLND_FIELD *).	For normal statements we will then just assign it to a member of	MYSQLND_RES. For PS statements, it will stay as part of the statement	(MYSQLND_STMT) between prepare and execute. At execute the new metadata	will be sent by the server, so we will discard the old one and then	finally attach it to the result set. This will make the code more clean,	as a prepared statement won't have anymore stmt->result != NULL, as it	is now, just to have where to store the metadata. - Change mysqlnd_simple_command to accept a heap dynamic array of MYSQLND_STRING   terminated by a string with ptr being NULL. Thus, multi-part messages can be   sent to the network like writev() and this can save at least for   mysqlnd_stmt_send_long_data() new malloc. This change will probably make the   code in few other places cleaner.*/extern MYSQLND_CHARSET *mysqlnd_charsets;static const char * mysqlnd_server_gone = "MySQL server has gone away";const char * mysqlnd_out_of_sync = "Commands out of sync; you can't run this command now";MYSQLND_STATS *mysqlnd_global_stats = NULL;static zend_bool mysqlnd_library_initted = FALSE;/* {{{ mysqlnd_library_init */PHPAPI void mysqlnd_library_init(){	if (mysqlnd_library_initted == FALSE) {		mysqlnd_library_initted = TRUE; 		_mysqlnd_init_ps_subsystem();		mysqlnd_global_stats = calloc(1, sizeof(MYSQLND_STATS));#ifdef ZTS		mysqlnd_global_stats->LOCK_access = tsrm_mutex_alloc();#endif	}}/* }}} *//* {{{ mysqlnd_library_end */PHPAPI void mysqlnd_library_end(){	if (mysqlnd_library_initted == TRUE) {#ifdef ZTS		tsrm_mutex_free(mysqlnd_global_stats->LOCK_access);#endif		free(mysqlnd_global_stats);		mysqlnd_global_stats = NULL;		mysqlnd_library_initted = FALSE;	}}/* }}} *//* {{{ php_mysqlnd_free_field_metadata */staticvoid php_mysqlnd_free_field_metadata(MYSQLND_FIELD *meta, zend_bool persistent){	if (meta) {		if (meta->root) {			pefree(meta->root, persistent);			meta->root = NULL;		}		if (meta->def) {			pefree(meta->def, persistent);			meta->def = NULL;		}	}}/* }}} *//* {{{ mysqlnd_unbuffered_free_last_data */void mysqlnd_unbuffered_free_last_data(MYSQLND_RES *result TSRMLS_DC){	MYSQLND_RES_UNBUFFERED *unbuf = result->unbuf;	if (!unbuf) {		return;	}	if (unbuf->last_row_data) {		int i;		zend_bool copy_ctor_called;		for (i = 0; i < result->field_count; i++) {			if (result->type == MYSQLND_RES_PS) {				/* Do nothing, before assigning we will clean */				zval_ptr_dtor(&unbuf->last_row_data[i]);			} else {				mysqlnd_palloc_zval_ptr_dtor(&(unbuf->last_row_data[i]),											 result->zval_cache, FALSE,											 &copy_ctor_called TSRMLS_CC);				if (copy_ctor_called) {					MYSQLND_INC_CONN_STATISTIC(&result->conn->stats,											   STAT_COPY_ON_WRITE_PERFORMED);					/* Increase global stats */				} else {					MYSQLND_INC_CONN_STATISTIC(&result->conn->stats,											   STAT_COPY_ON_WRITE_SAVED);				}			}		}		/* Free last row's zvals */		efree(unbuf->last_row_data);		unbuf->last_row_data = NULL;	}	if (unbuf->last_row_buffer) {		/* Nothing points to this buffer now, free it */		efree(unbuf->last_row_buffer);		unbuf->last_row_buffer = NULL;	}}/* }}} *//* {{{ mysqlnd_free_buffered_data */void mysqlnd_free_buffered_data(MYSQLND_RES *result TSRMLS_DC){	MYSQLND_ZVAL_PCACHE  *zval_cache = result->zval_cache;	MYSQLND_RES_BUFFERED *set = result->data;	enum_mysqlnd_res_type result_type = result->type;	unsigned int field_count = result->field_count;	unsigned int row;	for (row = 0; row < result->data->row_count; row++) {		unsigned int col;		zval **current_row = current_row = set->data[row];		zend_uchar *current_buffer = set->row_buffers[row];		for (col = 0; col < field_count; col++) {			if (result_type == MYSQLND_RES_PS) {				/* For now PS always does create copies when fetching data */				zval_ptr_dtor(&current_row[col]);				MYSQLND_INC_CONN_STATISTIC(NULL, STAT_COPY_ON_WRITE_PERFORMED);			} else {				zend_bool copy_ctor_called;				/* Free only if we haven't referenced it */				mysqlnd_palloc_zval_ptr_dtor(&(current_row[col]), zval_cache,											 FALSE, &copy_ctor_called TSRMLS_CC);				MYSQLND_INC_CONN_STATISTIC(NULL, copy_ctor_called? STAT_COPY_ON_WRITE_PERFORMED:																   STAT_COPY_ON_WRITE_SAVED);			}		}		pefree(current_row, set->persistent);		pefree(current_buffer, set->persistent);	}	pefree(set->data, set->persistent);	pefree(set->row_buffers, set->persistent);	set->data			= NULL;	set->row_buffers	= NULL;	set->data_cursor	= NULL;	set->row_count	= 0;	if (set->persistent) {		mysqlnd_qcache_free_cache_reference(&set->qcache);	}	pefree(set, set->persistent);	result->data		= NULL;}/* }}} *//* {{{ mysqlnd_internal_free_result_buffers */void mysqlnd_internal_free_result_buffers(MYSQLND_RES *result TSRMLS_DC){	if (!result->data) {		mysqlnd_unbuffered_free_last_data(result TSRMLS_CC);		if (result->unbuf) {			efree(result->unbuf);			result->unbuf = NULL;		}	} else {		mysqlnd_free_buffered_data(result TSRMLS_CC);	}	if (result->lengths) {		efree(result->lengths);		result->lengths = NULL;	}}/* }}} *//* {{{ mysqlnd_internal_free_result_metadata */staticvoid mysqlnd_internal_free_result_metadata(MYSQLND_RES_METADATA *meta, zend_bool persistent TSRMLS_DC){	int i;	MYSQLND_FIELD *fields;	if ((fields = meta->fields)) {		i = meta->field_count;		while (i--) {			php_mysqlnd_free_field_metadata(fields++, persistent);		}		pefree(meta->fields, persistent);		meta->fields = NULL;	}	if (meta->zend_hash_keys) {#if PHP_MAJOR_VERSION >= 6		if (UG(unicode)) {			for (i = 0; i < meta->field_count; i++) {				if (meta->zend_hash_keys[i].ustr.v) {					pefree(meta->zend_hash_keys[i].ustr.v, persistent);				}			}		}#endif		pefree(meta->zend_hash_keys, persistent);		meta->zend_hash_keys = NULL;	}	pefree(meta, persistent);}/* }}} *//* {{{ mysqlnd_internal_free_result_contents */void mysqlnd_internal_free_result_contents(MYSQLND_RES *result TSRMLS_DC){	result->m.free_result_buffers(result TSRMLS_CC);	if (result->row_packet) {		if (result->type == MYSQLND_RES_NORMAL) {			PACKET_FREE(result->row_packet);		} else {			PACKET_FREE(result->row_packet);		}		result->row_packet = NULL;	}	result->conn = NULL;	if (result->meta) {		mysqlnd_internal_free_result_metadata(result->meta, FALSE TSRMLS_CC);		result->meta = NULL;	}	if (result->zval_cache) {		mysqlnd_palloc_free_cache_reference(&result->zval_cache);	}}/* }}} *//* {{{ mysqlnd_internal_free_result */void mysqlnd_internal_free_result(MYSQLND_RES *result TSRMLS_DC){	/*	  result->conn is an address if this is an unbuffered query.	  In this case, decrement the reference counter in the connection	  object and if needed free the latter. If quit_sent is no	*/	if (result->conn) {		result->conn->m->free_reference(result->conn TSRMLS_CC);		result->conn = NULL;	}	mysqlnd_internal_free_result_contents(result TSRMLS_CC);	efree(result);}/* }}} *//* {{{ mysqlnd_conn_free_contents */staticvoid mysqlnd_conn_free_contents(MYSQLND *conn TSRMLS_DC){	mysqlnd_local_infile_default(conn);	if (conn->current_result) {		mysqlnd_internal_free_result_contents(conn->current_result TSRMLS_CC);		efree(conn->current_result);		conn->current_result = NULL;	}	if (conn->net.stream) {		php_stream_free(conn->net.stream, (conn->persistent) ? PHP_STREAM_FREE_RSRC_DTOR : PHP_STREAM_FREE_CLOSE);		conn->net.stream = NULL;	}	if (conn->host) {		pefree(conn->host, conn->persistent);		conn->host = NULL;	}	if (conn->user) {		pefree(conn->user, conn->persistent);		conn->user = NULL;	}	if (conn->passwd) {		pefree(conn->passwd, conn->persistent);		conn->passwd = NULL;	}	if (conn->unix_socket) {		pefree(conn->unix_socket, conn->persistent);		conn->unix_socket = NULL;	}	if (conn->scheme) {		pefree(conn->scheme, conn->persistent);		conn->scheme = NULL;	}	if (conn->server_version) {		pefree(conn->server_version, conn->persistent);		conn->server_version = NULL;	}	if (conn->host_info) {		pefree(conn->host_info, conn->persistent);		conn->host_info = NULL;	}	if (conn->scramble) {		pefree(conn->scramble, conn->persistent);		conn->scramble = NULL;	}	if (conn->last_message) {		pefree(conn->last_message, conn->persistent);		conn->last_message = NULL;	}	if (conn->options.num_commands) {		unsigned int i;		for (i=0; i < conn->options.num_commands; i++) {			pefree(conn->options.init_commands[i], conn->persistent);		}		pefree(conn->options.init_commands, conn->persistent);		conn->options.init_commands = NULL;	}	if (conn->options.cfg_file) {		pefree(conn->options.cfg_file, conn->persistent);		conn->options.cfg_file = NULL;	}	if (conn->options.cfg_section) {		pefree(conn->options.cfg_section, conn->persistent);		conn->options.cfg_section = NULL;	}	if (conn->options.ssl_key) {		pefree(conn->options.ssl_key, conn->persistent);		conn->options.ssl_key = NULL;	}	if (conn->options.ssl_cert) {		pefree(conn->options.ssl_cert, conn->persistent);		conn->options.ssl_cert = NULL;	}	if (conn->options.ssl_ca) {		pefree(conn->options.ssl_ca, conn->persistent);		conn->options.ssl_ca = NULL;	}	if (conn->options.ssl_capath) {		pefree(conn->options.ssl_capath, conn->persistent);		conn->options.ssl_capath = NULL;	}	if (conn->options.ssl_cipher) {		pefree(conn->options.ssl_cipher, conn->persistent);		conn->options.ssl_cipher = NULL;	}	if (conn->zval_cache) {		mysqlnd_palloc_free_cache_reference(&conn->zval_cache);		conn->zval_cache = NULL;	}	if (conn->qcache) {		mysqlnd_qcache_free_cache_reference(&conn->qcache);		conn->qcache = NULL;	}	if (conn->net.cmd_buffer.buffer) {		pefree(conn->net.cmd_buffer.buffer, conn->persistent);		conn->net.cmd_buffer.buffer = NULL;	}}/* }}} *//* {{{ _mysqlnd_conn_dtor */staticvoid _mysqlnd_conn_dtor(MYSQLND *conn TSRMLS_DC){	conn->m->free_contents(conn TSRMLS_CC);	pefree(conn, conn->persistent);}/* }}} *//* {{{ mysqlnd_simple_command_handle_response */enum_func_statusmysqlnd_simple_command_handle_response(MYSQLND *conn, enum php_mysql_packet_type ok_packet,									   zend_bool silent, enum php_mysqlnd_server_command command									   TSRMLS_DC){	enum_func_status ret;	switch (ok_packet) {		case PROT_OK_PACKET:{			php_mysql_packet_ok ok_response;			PACKET_INIT_ALLOCA(ok_response, PROT_OK_PACKET);			if (FAIL == (ret = PACKET_READ_ALLOCA(ok_response, conn))) {				if (!silent) {					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading %s's OK packet",									 mysqlnd_command_to_text[command]);				}			} else {#ifndef MYSQLND_SILENT				php_printf("\tOK from server\n");#endif				if (0xFF == ok_response.field_count) {					/* The server signalled error. Set the error */					SET_CLIENT_ERROR(conn->error_info, ok_response.error_no,									 ok_response.sqlstate, ok_response.error); 					ret = FAIL;					/*					  Cover a protocol design error: error packet does not					  contain the server status. Therefore, the client has no way					  to find out whether there are more result sets of					  a multiple-result-set statement pending. Luckily, in 5.0 an					  error always aborts execution of a statement, wherever it is					  a multi-statement or a stored procedure, so it should be					  safe to unconditionally turn off the flag here.					*/					conn->upsert_status.server_status &= ~SERVER_MORE_RESULTS_EXISTS;					conn->upsert_status.affected_rows = (mynd_ulonglong) ~0;				} else {					SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,									ok_response.message, ok_response.message_len);					conn->upsert_status.warning_count = ok_response.warning_count;					conn->upsert_status.server_status = ok_response.server_status;					conn->upsert_status.affected_rows = ok_response.affected_rows;					conn->upsert_status.last_insert_id = ok_response.last_insert_id;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -