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

📄 mysqlnd_ps.c

📁 linux下安装不上mysql5与php5的可用此关联
💻 C
📖 第 1 页 / 共 3 页
字号:
				}			}			efree(stmt->param_bind);		}		stmt->param_bind = param_bind;		for (i = 0; i < stmt->param_count; i++) {			/* The client will use stmt_send_long_data */			if (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB) {				/* Prevent from freeing */				ZVAL_ADDREF(stmt->param_bind[i].zv);				/* Don't update is_ref, or we will leak during conversion */			} else {				stmt->param_bind[i].zv = NULL;				stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;			}		}		stmt->send_types_to_server = 1;	}	return PASS;}/* }}} *//* {{{ _mysqlnd_stmt_bind_result */static enum_func_status_mysqlnd_stmt_bind_result(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind){	int i = 0;	if (stmt->state < MYSQLND_STMT_PREPARED) {		SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared);		return FAIL;	}	if (stmt->field_count) {		if (!result_bind) {			return FAIL;		}		mysqlnd_stmt_separate_result_bind(stmt);		stmt->result_bind = result_bind;		for (i = 0; i < stmt->field_count; i++) {			/* Prevent from freeing */			ZVAL_ADDREF(stmt->result_bind[i].zv);			/* Update as ZVAL_ADDREF does not do it */			stmt->result_bind[i].zv->is_ref = 1;			stmt->result_bind[i].bound = TRUE;		}	}	return PASS;}/* }}} *//* {{{ _mysqlnd_stmt_insert_id */staticmynd_ulonglong _mysqlnd_stmt_insert_id(const MYSQLND_STMT * const stmt){	return stmt->upsert_status.last_insert_id;}/* }}} *//* {{{ _mysqlnd_stmt_affected_rows */staticmynd_ulonglong _mysqlnd_stmt_affected_rows(const MYSQLND_STMT * const stmt){	return stmt->upsert_status.affected_rows;}/* }}} *//* {{{ _mysqlnd_stmt_num_rows */staticmynd_ulonglong _mysqlnd_stmt_num_rows(const MYSQLND_STMT * const stmt){	return stmt->result? mysqlnd_num_rows(stmt->result):0;}/* }}} *//* {{{ _mysqlnd_stmt_warning_count */staticunsigned int _mysqlnd_stmt_warning_count(const MYSQLND_STMT * const stmt){	return stmt->upsert_status.warning_count;}/* }}} *//* {{{ _mysqlnd_stmt_field_count */staticunsigned int _mysqlnd_stmt_field_count(const MYSQLND_STMT * const stmt){	return stmt->field_count;}/* }}} *//* {{{ _mysqlnd_stmt_param_count */staticunsigned int _mysqlnd_stmt_param_count(const MYSQLND_STMT * const stmt){	return stmt->param_count;}/* }}} *//* {{{ _mysqlnd_stmt_errno */staticunsigned int _mysqlnd_stmt_errno(const MYSQLND_STMT * const stmt){	return stmt->error_info.error_no;}/* }}} *//* {{{ _mysqlnd_stmt_error */staticconst char * _mysqlnd_stmt_error(const MYSQLND_STMT * const stmt){	return stmt->error_info.error;}/* }}} *//* {{{ _mysqlnd_stmt_sqlstate */staticconst char * _mysqlnd_stmt_sqlstate(const MYSQLND_STMT * const stmt){	return stmt->error_info.sqlstate[0] ? stmt->error_info.sqlstate:MYSQLND_SQLSTATE_NULL;}/* }}} *//* {{{ _mysqlnd_stmt_data_seek */static enum_func_status_mysqlnd_stmt_data_seek(const MYSQLND_STMT * const stmt, mynd_ulonglong row){	return stmt->result? stmt->result->m.seek_data(stmt->result, row) : FAIL;}/* }}} *//* {{{ _mysqlnd_stmt_param_metadata */staticMYSQLND_RES * _mysqlnd_stmt_param_metadata(MYSQLND_STMT * const stmt){	if (!stmt->param_count) {		return NULL;	}	return NULL;}/* }}} *//* {{{ _mysqlnd_stmt_param_metadata */staticMYSQLND_RES * _mysqlnd_stmt_result_metadata(MYSQLND_STMT * const stmt){	MYSQLND_RES *result;	MYSQLND_ZVAL_PCACHE * cache;	if (!stmt->field_count || !stmt->conn || !stmt->result) {		return NULL;	}	/*	  TODO: This implementation is kind of a hack,			find a better way to do it. In different functions I have put			fuses to check for result->m.fetch_row() being NULL. This should			be handled in a better way.		*/	cache = mysqlnd_palloc_get_cache_reference(stmt->conn->zval_cache);	result = mysqlnd_result_init(stmt->field_count, cache);	result->type = MYSQLND_RES_NORMAL;	result->m.fetch_row = result->m.fetch_row_normal_unbuffered;	result->unbuf = ecalloc(1, sizeof(MYSQLND_RES_UNBUFFERED));	result->unbuf->eof_reached = TRUE;	result->meta = stmt->result->m.clone_metadata(stmt->result->meta, FALSE);	return result;}/* }}} *//* {{{ _mysqlnd_stmt_attr_set */static enum_func_status_mysqlnd_stmt_attr_set(MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, const void * const value){	unsigned long val = *(unsigned long *) value;	switch (attr_type) {		case STMT_ATTR_UPDATE_MAX_LENGTH:			/*			  XXX : libmysql uses my_bool, but mysqli uses ulong as storage on the stack			  and mysqlnd won't be used out of the scope of PHP -> use ulong.			*/			stmt->update_max_length = val? TRUE:FALSE;			break;		case STMT_ATTR_CURSOR_TYPE: {			if (val > (unsigned long) CURSOR_TYPE_READ_ONLY) {				SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented");				return FAIL;			}			stmt->flags = val;			break;		}		case STMT_ATTR_PREFETCH_ROWS: {			if (val == 0) {				val = MYSQLND_DEFAULT_PREFETCH_ROWS;			} else if (val > 1) {				SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented");				return FAIL;				}			stmt->prefetch_rows = val;			break;		}		default:			SET_STMT_ERROR(stmt, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "Not implemented");			return FAIL;	}	return PASS;}/* }}} *//* {{{ _mysqlnd_stmt_attr_get */static enum_func_status_mysqlnd_stmt_attr_get(MYSQLND_STMT * const stmt, enum mysqlnd_stmt_attr attr_type, void * const value){	switch (attr_type) {		case STMT_ATTR_UPDATE_MAX_LENGTH:			*(zend_bool *) value= stmt->update_max_length;			break;		case STMT_ATTR_CURSOR_TYPE:			*(unsigned long *) value= stmt->flags;			break;		case STMT_ATTR_PREFETCH_ROWS:			*(unsigned long *) value= stmt->prefetch_rows;			break;		default:			return FAIL;	}	return PASS;}/* }}} *//* {{{ _mysqlnd_stmt_free_result */static enum_func_status_mysqlnd_stmt_free_result(MYSQLND_STMT * const stmt TSRMLS_DC){	if (!stmt->result) {		return PASS;	}	if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) {		/* Do implicit use_result and then flush the result */		stmt->default_rset_handler = _mysqlnd_stmt_use_result;		stmt->default_rset_handler(stmt TSRMLS_CC);	}	if (stmt->state > MYSQLND_STMT_WAITING_USE_OR_STORE) {		/* Flush if anything is left and unbuffered set */		stmt->result->m.skip_result(stmt->result TSRMLS_CC);		/*		  Separate the bound variables, which point to the result set, then		  destroy the set.		*/		mysqlnd_stmt_separate_result_bind(stmt);		/* Now we can destroy the result set */		stmt->result->m.free_result_buffers(stmt->result TSRMLS_CC);	}	/* As the buffers have been freed, we should go back to PREPARED */	stmt->state = MYSQLND_STMT_PREPARED;	/* Line is free! */	stmt->conn->state = CONN_READY;	return PASS;}/* }}} *//* {{{ mysqlnd_stmt_separate_result_bind */void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt){	int i;	if (!stmt->result_bind) {		return;	}	/*	  Because only the bound variables can point to our internal buffers, then	  separate or free only them. Free is possible because the user could have	  lost reference.	*/	for (i = 0; i < stmt->field_count; i++) {		/* Let's try with no cache */		if (stmt->result_bind[i].bound == TRUE) {			/*			  We have to separate the actual zval value of the bound			  variable from our allocated zvals or we will face double-free			*/			if (ZVAL_REFCOUNT(stmt->result_bind[i].zv) > 1) {				zval_copy_ctor(stmt->result_bind[i].zv);				zval_ptr_dtor(&stmt->result_bind[i].zv);			} else {				/*				  If it is a string, what is pointed will be freed				  later in free_result(). We need to remove the variable to				  which the user has lost reference.				*/				ZVAL_NULL(stmt->result_bind[i].zv);				zval_ptr_dtor(&stmt->result_bind[i].zv);			}		}	}	efree(stmt->result_bind);	stmt->result_bind = NULL;}/* }}} *//* {{{ mysqlnd_internal_free_stmt_content */staticvoid mysqlnd_internal_free_stmt_content(MYSQLND_STMT *stmt TSRMLS_DC){	/* Destroy the input bind */	if (stmt->param_bind) {		int i;		/*		  Because only the bound variables can point to our internal buffers, then		  separate or free only them. Free is possible because the user could have		  lost reference.		*/		for (i = 0; i < stmt->param_count; i++) {			/* For BLOBs zv is NULL */			if (stmt->param_bind[i].zv) {				zval_ptr_dtor(&stmt->param_bind[i].zv);			}		}		efree(stmt->param_bind);		stmt->param_bind = NULL;	}	/*	  First separate the bound variables, which point to the result set, then	  destroy the set.	*/	mysqlnd_stmt_separate_result_bind(stmt);	/* Not every statement has a result set attached */	if (stmt->result) {		mysqlnd_internal_free_result(stmt->result TSRMLS_CC);		stmt->result = NULL;	}	if (stmt->cmd_buffer.buffer) {		efree(stmt->cmd_buffer.buffer);		stmt->cmd_buffer.buffer = NULL;	}	if (stmt->conn) {		stmt->conn->m->free_reference(stmt->conn TSRMLS_CC);		stmt->conn = NULL;	}}/* }}} *//* {{{ _mysqlnd_stmt_close */static enum_func_status_mysqlnd_stmt_close(MYSQLND_STMT * const stmt, zend_bool implicit TSRMLS_DC){	MYSQLND * conn = stmt->conn;	zend_uchar cmd_buf[STMT_ID_LENGTH /* statement id */];	/*	  If the user decided to close the statement right after execute()	  We have to call the appropriate use_result() or store_result() and	  clean.	*/	if (stmt->state == MYSQLND_STMT_WAITING_USE_OR_STORE) {		stmt->default_rset_handler(stmt TSRMLS_CC);		stmt->state = MYSQLND_STMT_USER_FETCHING;	}	/* unbuffered set not fetched to the end ? Clean the line */	if (stmt->result) {		stmt->result->m.skip_result(stmt->result TSRMLS_CC);	}	/*	  After this point we are allowed to free the result set,	  as we have cleaned the line	*/	if (stmt->stmt_id) {			MYSQLND_INC_CONN_STATISTIC(NULL, implicit == TRUE?	STAT_FREE_RESULT_IMPLICIT:															STAT_FREE_RESULT_EXPLICIT);		int4store(cmd_buf, stmt->stmt_id);		if (conn->state == CONN_READY &&			FAIL == mysqlnd_simple_command(conn, COM_STMT_CLOSE, (char *)cmd_buf, sizeof(cmd_buf),										   PROT_LAST /* COM_STMT_CLOSE doesn't send an OK packet*/,										   FALSE TSRMLS_CC)) {			stmt->error_info = conn->error_info;			return FAIL;		}	}	mysqlnd_internal_free_stmt_content(stmt TSRMLS_CC);	return PASS;}/* }}} *//* {{{ _mysqlnd_stmt_close */static enum_func_status_mysqlnd_stmt_dtor(MYSQLND_STMT * const stmt, zend_bool implicit TSRMLS_DC){	enum_func_status ret;	MYSQLND_INC_CONN_STATISTIC(NULL, implicit == TRUE?	STAT_STMT_CLOSE_IMPLICIT:														STAT_STMT_CLOSE_EXPLICIT);	if (PASS == (ret = stmt->m->close(stmt, implicit TSRMLS_CC))) {		efree(stmt);	}	return ret;}/* }}} */staticstruct st_mysqlnd_stmt_methods mysqlnd_stmt_methods = {	_mysqlnd_stmt_prepare,	_mysqlnd_stmt_execute,	_mysqlnd_stmt_store_result,	_mysqlnd_stmt_free_result,	_mysqlnd_stmt_data_seek,	_mysqlnd_stmt_reset,	_mysqlnd_stmt_close,	_mysqlnd_stmt_dtor,	_mysqlnd_stmt_bind_param,	_mysqlnd_stmt_bind_result,	_mysqlnd_stmt_send_long_data,	_mysqlnd_stmt_param_metadata,	_mysqlnd_stmt_result_metadata,	_mysqlnd_stmt_insert_id,	_mysqlnd_stmt_affected_rows,	_mysqlnd_stmt_num_rows,	_mysqlnd_stmt_param_count,	_mysqlnd_stmt_field_count,	_mysqlnd_stmt_warning_count,	_mysqlnd_stmt_errno,	_mysqlnd_stmt_error,	_mysqlnd_stmt_sqlstate,	_mysqlnd_stmt_attr_get,	_mysqlnd_stmt_attr_set,	};/* {{{ _mysqlnd_stmt_init */MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn){	MYSQLND_STMT *stmt = ecalloc(1, sizeof(MYSQLND_STMT));	stmt->m = &mysqlnd_stmt_methods;	stmt->state = MYSQLND_STMT_INITTED;	stmt->cmd_buffer.length = 4096;	stmt->cmd_buffer.buffer = emalloc(stmt->cmd_buffer.length);	stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;	/*	  Mark that we reference the connection, thus it won't be	  be destructed till there is open statements. The last statement	  or normal query result will close it then.	*/	stmt->conn = conn->m->get_reference(conn);	return stmt;}/* }}} */

⌨️ 快捷键说明

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