Change of way the packet objects are created/initialised

If the protocol gets changed, ever, we can decide at runtime
easily which protocol to use by instantiating the right protocol
object. But this is restricted to the structure of the packets, not
the flow.
This commit is contained in:
Andrey Hristov 2010-01-07 19:44:59 +00:00
parent bb76666d4e
commit 81b0630f5a
9 changed files with 388 additions and 176 deletions

View File

@ -222,6 +222,12 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor)(MYSQLND *conn TSRMLS_DC)
conn->net = NULL;
}
if (conn->protocol) {
DBG_INF("Freeing protocol");
mysqlnd_protocol_free(conn->protocol TSRMLS_CC);
conn->protocol = NULL;
}
mnd_pefree(conn, conn->persistent);
DBG_VOID_RETURN;
@ -242,9 +248,8 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND *conn, enum
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))) {
php_mysql_packet_ok * ok_response = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
if (!silent) {
DBG_ERR_FMT("Error while reading %s's OK packet", mysqlnd_command_to_text[command]);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading %s's OK packet. PID=%d",
@ -252,10 +257,9 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND *conn, enum
}
} else {
DBG_INF_FMT("OK from server");
if (0xFF == ok_response.field_count) {
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);
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
@ -270,24 +274,23 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND *conn, enum
SET_ERROR_AFF_ROWS(conn);
} else {
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
ok_response.message, ok_response.message_len,
ok_response->message, ok_response->message_len,
conn->persistent);
if (!ignore_upsert_status) {
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;
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;
}
}
}
PACKET_FREE_ALLOCA(ok_response);
PACKET_FREE(ok_response);
break;
}
case PROT_EOF_PACKET:{
php_mysql_packet_eof ok_response;
PACKET_INIT_ALLOCA(ok_response, PROT_EOF_PACKET);
if (FAIL == (ret = PACKET_READ_ALLOCA(ok_response, conn))) {
php_mysql_packet_eof * ok_response = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
if (FAIL == (ret = PACKET_READ(ok_response, conn))) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
"Malformed packet");
if (!silent) {
@ -295,24 +298,23 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command_handle_response)(MYSQLND *conn, enum
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading %s's EOF packet. PID=%d",
mysqlnd_command_to_text[command], getpid());
}
} else if (0xFF == ok_response.field_count) {
} else 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);
SET_CLIENT_ERROR(conn->error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
SET_ERROR_AFF_ROWS(conn);
} else if (0xFE != ok_response.field_count) {
} else if (0xFE != ok_response->field_count) {
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE,
"Malformed packet");
if (!silent) {
DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", ok_response.field_count);
DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", ok_response->field_count);
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"EOF packet expected, field count wasn't 0xFE but 0x%2X",
ok_response.field_count);
ok_response->field_count);
}
} else {
DBG_INF_FMT("OK from server");
}
PACKET_FREE_ALLOCA(ok_response);
PACKET_FREE(ok_response);
break;
}
default:
@ -336,7 +338,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND *conn, enum php_mysqlnd_ser
zend_bool ignore_upsert_status TSRMLS_DC)
{
enum_func_status ret = PASS;
php_mysql_packet_command cmd_packet;
php_mysql_packet_command * cmd_packet;
DBG_ENTER("mysqlnd_conn::simple_command");
DBG_INF_FMT("command=%s ok_packet=%d silent=%d", mysqlnd_command_to_text[command], ok_packet, silent);
@ -362,16 +364,16 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND *conn, enum php_mysqlnd_ser
SET_ERROR_AFF_ROWS(conn);
SET_EMPTY_ERROR(conn->error_info);
PACKET_INIT_ALLOCA(cmd_packet, PROT_CMD_PACKET);
cmd_packet.command = command;
cmd_packet = conn->protocol->m.get_command_packet(conn->protocol, FALSE TSRMLS_CC);
cmd_packet->command = command;
if (arg && arg_len) {
cmd_packet.argument = arg;
cmd_packet.arg_len = arg_len;
cmd_packet->argument = arg;
cmd_packet->arg_len = arg_len;
}
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ );
if (! PACKET_WRITE_ALLOCA(cmd_packet, conn)) {
if (! PACKET_WRITE(cmd_packet, conn)) {
if (!silent) {
DBG_ERR_FMT("Error while sending %s packet", mysqlnd_command_to_text[command]);
php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
@ -382,12 +384,7 @@ MYSQLND_METHOD(mysqlnd_conn, simple_command)(MYSQLND *conn, enum php_mysqlnd_ser
ret = conn->m->simple_command_handle_response(conn, ok_packet, silent, command, ignore_upsert_status TSRMLS_CC);
}
/*
There is no need to call FREE_ALLOCA on cmd_packet as the
only allocated string is cmd_packet.argument and it was passed
to us. We should not free it.
*/
PACKET_FREE(cmd_packet);
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
@ -457,9 +454,9 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
zend_bool reconnect = FALSE;
zend_bool saved_compression = FALSE;
php_mysql_packet_greet greet_packet;
php_mysql_packet_auth *auth_packet;
php_mysql_packet_ok ok_packet;
php_mysql_packet_greet * greet_packet = NULL;
php_mysql_packet_auth * auth_packet = NULL;
php_mysql_packet_ok * ok_packet = NULL;
DBG_ENTER("mysqlnd_conn::connect");
@ -527,9 +524,9 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
DBG_INF_FMT("transport=%s", transport);
PACKET_INIT_ALLOCA(greet_packet, PROT_GREET_PACKET);
PACKET_INIT(auth_packet, PROT_AUTH_PACKET, php_mysql_packet_auth *, FALSE);
PACKET_INIT_ALLOCA(ok_packet, PROT_OK_PACKET);
greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
auth_packet = conn->protocol->m.get_auth_packet(conn->protocol, FALSE TSRMLS_CC);
ok_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
if (conn->persistent) {
conn->scheme = pestrndup(transport, transport_len, 1);
@ -545,30 +542,28 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
DBG_INF_FMT("stream=%p", conn->net->stream);
if (FAIL == PACKET_READ_ALLOCA(greet_packet, conn)) {
if (FAIL == PACKET_READ(greet_packet, conn)) {
DBG_ERR("Error while reading greeting packet");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
goto err;
} else if (greet_packet.error_no) {
DBG_ERR_FMT("errorno=%d error=%s", greet_packet.error_no, greet_packet.error);
SET_CLIENT_ERROR(conn->error_info, greet_packet.error_no,
greet_packet.sqlstate, greet_packet.error);
} else if (greet_packet->error_no) {
DBG_ERR_FMT("errorno=%d error=%s", greet_packet->error_no, greet_packet->error);
SET_CLIENT_ERROR(conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
goto err;
} else if (greet_packet.pre41) {
DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s",
greet_packet.server_version);
} else if (greet_packet->pre41) {
DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
" is not supported. Server is %-.32s", greet_packet.server_version);
" is not supported. Server is %-.32s", greet_packet->server_version);
SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
"Connecting to 3.22, 3.23 & 4.0 servers is not supported");
goto err;
}
conn->thread_id = greet_packet.thread_id;
conn->protocol_version = greet_packet.protocol_version;
conn->server_version = pestrdup(greet_packet.server_version, conn->persistent);
conn->thread_id = greet_packet->thread_id;
conn->protocol_version = greet_packet->protocol_version;
conn->server_version = pestrdup(greet_packet->server_version, conn->persistent);
conn->greet_charset = mysqlnd_find_charset_nr(greet_packet.charset_no);
conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
/* we allow load data local infile by default */
mysql_flags |= CLIENT_LOCAL_FILES | CLIENT_PS_MULTI_RESULTS;
#ifndef MYSQLND_COMPRESSION_ENABLED
@ -588,7 +583,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
#if PHP_MAJOR_VERSION >= 6
auth_packet->charset_no = 200;/* utf8 - swedish collation, check mysqlnd_charset.c */
#else
auth_packet->charset_no = greet_packet.charset_no;
auth_packet->charset_no = greet_packet->charset_no;
#endif
}
auth_packet->db = db;
@ -597,29 +592,28 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
auth_packet->client_flags= mysql_flags;
conn->scramble = auth_packet->server_scramble_buf = mnd_pemalloc(SCRAMBLE_LENGTH, conn->persistent);
memcpy(auth_packet->server_scramble_buf, greet_packet.scramble_buf, SCRAMBLE_LENGTH);
memcpy(auth_packet->server_scramble_buf, greet_packet->scramble_buf, SCRAMBLE_LENGTH);
if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto err;
}
if (FAIL == PACKET_READ_ALLOCA(ok_packet, conn) || ok_packet.field_count >= 0xFE) {
if (ok_packet.field_count == 0xFE) {
if (FAIL == PACKET_READ(ok_packet, conn) || ok_packet->field_count >= 0xFE) {
if (ok_packet->field_count == 0xFE) {
/* old authentication with new server !*/
DBG_ERR(mysqlnd_old_passwd);
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
} else if (ok_packet.field_count == 0xFF) {
if (ok_packet.sqlstate[0]) {
} else if (ok_packet->field_count == 0xFF) {
if (ok_packet->sqlstate[0]) {
if (!self_alloced) {
strlcpy(conn->error_info.sqlstate, ok_packet.sqlstate, sizeof(conn->error_info.sqlstate));
strlcpy(conn->error_info.sqlstate, ok_packet->sqlstate, sizeof(conn->error_info.sqlstate));
}
DBG_ERR_FMT("ERROR:%d [SQLSTATE:%s] %s",
ok_packet.error_no, ok_packet.sqlstate, ok_packet.error);
DBG_ERR_FMT("ERROR:%d [SQLSTATE:%s] %s", ok_packet->error_no, ok_packet->sqlstate, ok_packet->error);
}
if (!self_alloced) {
conn->error_info.error_no = ok_packet.error_no;
strlcpy(conn->error_info.error, ok_packet.error, sizeof(conn->error_info.error));
conn->error_info.error_no = ok_packet->error_no;
strlcpy(conn->error_info.error, ok_packet->error, sizeof(conn->error_info.error));
}
}
} else {
@ -663,12 +657,12 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
conn->max_packet_size = auth_packet->max_packet_size;
/* todo: check if charset is available */
conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
conn->server_capabilities = greet_packet.server_capabilities;
conn->server_capabilities = greet_packet->server_capabilities;
conn->upsert_status.warning_count = 0;
conn->upsert_status.server_status = greet_packet.server_status;
conn->upsert_status.server_status = greet_packet->server_status;
conn->upsert_status.affected_rows = 0;
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
ok_packet.message, ok_packet.message_len,
ok_packet->message, ok_packet->message_len,
conn->persistent);
SET_EMPTY_ERROR(conn->error_info);
@ -713,16 +707,16 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
}
}
PACKET_FREE_ALLOCA(greet_packet);
PACKET_FREE(greet_packet);
PACKET_FREE(auth_packet);
PACKET_FREE_ALLOCA(ok_packet);
PACKET_FREE(ok_packet);
DBG_RETURN(PASS);
}
err:
PACKET_FREE_ALLOCA(greet_packet);
PACKET_FREE(greet_packet);
PACKET_FREE(auth_packet);
PACKET_FREE_ALLOCA(ok_packet);
PACKET_FREE(ok_packet);
if (errstr) {
DBG_ERR_FMT("[%d] %.64s (trying to connect via %s)", errcode, errstr, conn->scheme);
@ -833,7 +827,8 @@ MYSQLND_METHOD(mysqlnd_conn, send_query)(MYSQLND *conn, const char *query, unsig
}
/* }}} */
/* {{{ mysqlnd_conn::send_query */
/* {{{ mysqlnd_conn::reap_query */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn, reap_query)(MYSQLND * conn TSRMLS_DC)
{
@ -843,6 +838,7 @@ MYSQLND_METHOD(mysqlnd_conn, reap_query)(MYSQLND * conn TSRMLS_DC)
if (state <= CONN_READY || state == CONN_QUIT_SENT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not opened, clear or has been closed");
DBG_ERR_FMT("Connection not opened, clear or has been closed. State=%d", state);
DBG_RETURN(FAIL);
}
DBG_RETURN(conn->m->query_read_result_set_header(conn, NULL TSRMLS_CC));
@ -991,6 +987,7 @@ _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long s
if (!sets) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, *dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_ERR_FMT(*dont_poll ? "All arrays passed are clear":"No stream arrays were passed");
DBG_RETURN(FAIL);
}
@ -1244,7 +1241,7 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_conn, stat)(MYSQLND *conn, char **message, unsigned int * message_len TSRMLS_DC)
{
enum_func_status ret;
php_mysql_packet_stats stats_header;
php_mysql_packet_stats * stats_header;
DBG_ENTER("mysqlnd_conn::stat");
DBG_INF_FMT("conn=%llu", conn->thread_id);
@ -1253,15 +1250,15 @@ MYSQLND_METHOD(mysqlnd_conn, stat)(MYSQLND *conn, char **message, unsigned int *
if (FAIL == ret) {
DBG_RETURN(FAIL);
}
PACKET_INIT_ALLOCA(stats_header, PROT_STATS_PACKET);
if (FAIL == (ret = PACKET_READ_ALLOCA(stats_header, conn))) {
stats_header = conn->protocol->m.get_stats_packet(conn->protocol, FALSE TSRMLS_CC);
if (FAIL == (ret = PACKET_READ(stats_header, conn))) {
DBG_RETURN(FAIL);
}
*message = stats_header.message;
*message_len = stats_header.message_len;
*message = stats_header->message;
*message_len = stats_header->message_len;
/* Ownership transfer */
stats_header.message = NULL;
PACKET_FREE_ALLOCA(stats_header);
stats_header->message = NULL;
PACKET_FREE(stats_header);
DBG_INF(*message);
DBG_RETURN(PASS);
@ -1752,7 +1749,7 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
*/
size_t user_len;
enum_func_status ret;
php_mysql_packet_chg_user_resp chg_user_resp;
php_mysql_packet_chg_user_resp * chg_user_resp;
char buffer[MYSQLND_MAX_ALLOWED_USER_LEN + 1 + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1];
char *p = buffer;
@ -1799,10 +1796,10 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
DBG_RETURN(FAIL);
}
PACKET_INIT_ALLOCA(chg_user_resp, PROT_CHG_USER_PACKET);
ret = PACKET_READ_ALLOCA(chg_user_resp, conn);
conn->error_info = chg_user_resp.error_info;
PACKET_FREE_ALLOCA(chg_user_resp);
chg_user_resp = conn->protocol->m.get_change_user_response_packet(conn->protocol, FALSE TSRMLS_CC);
ret = PACKET_READ(chg_user_resp, conn);
conn->error_info = chg_user_resp->error_info;
PACKET_FREE(chg_user_resp);
if (conn->error_info.error_no) {
ret = FAIL;
@ -1814,10 +1811,9 @@ MYSQLND_METHOD(mysqlnd_conn, change_user)(MYSQLND * const conn,
if (mysqlnd_get_server_version(conn) > 50113L &&
mysqlnd_get_server_version(conn) < 50118L)
{
php_mysql_packet_ok redundant_error_packet;
PACKET_INIT_ALLOCA(redundant_error_packet, PROT_OK_PACKET);
PACKET_READ_ALLOCA(redundant_error_packet, conn);
PACKET_FREE_ALLOCA(redundant_error_packet);
php_mysql_packet_ok * redundant_error_packet = conn->protocol->m.get_ok_packet(conn->protocol, FALSE TSRMLS_CC);
PACKET_READ(redundant_error_packet, conn);
PACKET_FREE(redundant_error_packet);
DBG_INF_FMT("Server is %d, buggy, sends two ERR messages", mysqlnd_get_server_version(conn));
}
}
@ -2095,6 +2091,7 @@ MYSQLND_METHOD(mysqlnd_conn, init)(MYSQLND * conn TSRMLS_DC)
{
DBG_ENTER("mysqlnd_conn::init");
conn->net = mysqlnd_net_init(conn->persistent TSRMLS_CC);
conn->protocol = mysqlnd_protocol_init(conn->persistent TSRMLS_CC);
SET_ERROR_AFF_ROWS(conn);

View File

@ -687,9 +687,9 @@ mysqlnd_net_init(zend_bool persistent TSRMLS_DC)
/* }}} */
/* {{{ mysqlnd_net_init */
/* {{{ mysqlnd_net_free */
void
mysqlnd_net_free(MYSQLND_NET * net TSRMLS_DC)
mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC)
{
zend_bool pers = net->persistent;

View File

@ -24,7 +24,7 @@
#define MYSQLND_NET_H
MYSQLND_NET * mysqlnd_net_init(zend_bool persistent TSRMLS_DC);
void mysqlnd_net_free(MYSQLND_NET * net TSRMLS_DC);
void mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC);
#endif /* MYSQLND_NET_H */

View File

@ -218,20 +218,20 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT *stmt TSRMLS_DC)
/* Follows parameter metadata, we have just to skip it, as libmysql does */
unsigned int i = 0;
enum_func_status ret = PASS;
php_mysql_packet_res_field field_packet;
php_mysql_packet_res_field * field_packet;
DBG_ENTER("mysqlnd_stmt_skip_metadata");
DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
PACKET_INIT_ALLOCA(field_packet, PROT_RSET_FLD_PACKET);
field_packet.skip_parsing = TRUE;
field_packet = stmt->conn->protocol->m.get_result_field_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
field_packet->skip_parsing = TRUE;
for (;i < stmt->param_count; i++) {
if (FAIL == PACKET_READ_ALLOCA(field_packet, stmt->conn)) {
if (FAIL == PACKET_READ(field_packet, stmt->conn)) {
ret = FAIL;
break;
}
}
PACKET_FREE_ALLOCA(field_packet);
PACKET_FREE(field_packet);
DBG_RETURN(ret);
}
@ -242,31 +242,31 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT *stmt TSRMLS_DC)
static enum_func_status
mysqlnd_stmt_read_prepare_response(MYSQLND_STMT *stmt TSRMLS_DC)
{
php_mysql_packet_prepare_response prepare_resp;
php_mysql_packet_prepare_response * prepare_resp;
enum_func_status ret = PASS;
DBG_ENTER("mysqlnd_stmt_read_prepare_response");
DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
PACKET_INIT_ALLOCA(prepare_resp, PROT_PREPARE_RESP_PACKET);
if (FAIL == PACKET_READ_ALLOCA(prepare_resp, stmt->conn)) {
prepare_resp = stmt->conn->protocol->m.get_prepare_response_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
if (FAIL == PACKET_READ(prepare_resp, stmt->conn)) {
ret = FAIL;
goto done;
}
if (0xFF == prepare_resp.error_code) {
stmt->error_info = stmt->conn->error_info = prepare_resp.error_info;
if (0xFF == prepare_resp->error_code) {
stmt->error_info = stmt->conn->error_info = prepare_resp->error_info;
ret = FAIL;
goto done;
}
stmt->stmt_id = prepare_resp.stmt_id;
stmt->warning_count = stmt->conn->upsert_status.warning_count = prepare_resp.warning_count;
stmt->field_count = stmt->conn->field_count = prepare_resp.field_count;
stmt->param_count = prepare_resp.param_count;
PACKET_FREE_ALLOCA(prepare_resp);
stmt->stmt_id = prepare_resp->stmt_id;
stmt->warning_count = stmt->conn->upsert_status.warning_count = prepare_resp->warning_count;
stmt->field_count = stmt->conn->field_count = prepare_resp->field_count;
stmt->param_count = prepare_resp->param_count;
done:
PACKET_FREE(prepare_resp);
DBG_RETURN(ret);
}
/* }}} */
@ -276,14 +276,14 @@ done:
static enum_func_status
mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT *stmt TSRMLS_DC)
{
php_mysql_packet_eof fields_eof;
php_mysql_packet_eof * fields_eof;
enum_func_status ret;
DBG_ENTER("mysqlnd_stmt_prepare_read_eof");
DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
PACKET_INIT_ALLOCA(fields_eof, PROT_EOF_PACKET);
if (FAIL == (ret = PACKET_READ_ALLOCA(fields_eof, stmt->conn))) {
fields_eof = stmt->conn->protocol->m.get_eof_packet(stmt->conn->protocol, FALSE TSRMLS_CC);
if (FAIL == (ret = PACKET_READ(fields_eof, stmt->conn))) {
if (stmt->result) {
stmt->result->m.free_result_contents(stmt->result TSRMLS_CC);
mnd_efree(stmt->result);
@ -291,11 +291,11 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT *stmt TSRMLS_DC)
stmt->state = MYSQLND_STMT_INITTED;
}
} else {
stmt->upsert_status.server_status = fields_eof.server_status;
stmt->upsert_status.warning_count = fields_eof.warning_count;
stmt->upsert_status.server_status = fields_eof->server_status;
stmt->upsert_status.warning_count = fields_eof->warning_count;
stmt->state = MYSQLND_STMT_PREPARED;
}
PACKET_FREE_ALLOCA(fields_eof);
PACKET_FREE(fields_eof);
DBG_RETURN(ret);
}
@ -794,7 +794,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
stmt->result_bind[i].zv->value = data->value;
// copied data, thus also the ownership. Thus null data
/* copied data, thus also the ownership. Thus null data */
ZVAL_NULL(data);
}
}
@ -973,7 +973,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
stmt->result_bind[i].zv->value = data->value;
// copied data, thus also the ownership. Thus null data
/* copied data, thus also the ownership. Thus null data */
ZVAL_NULL(data);
}
}

View File

@ -354,21 +354,21 @@ enum_func_status
mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC)
{
enum_func_status ret;
php_mysql_packet_rset_header rset_header;
php_mysql_packet_rset_header * rset_header;
DBG_ENTER("mysqlnd_query_read_result_set_header");
DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
ret = FAIL;
PACKET_INIT_ALLOCA(rset_header, PROT_RSET_HEADER_PACKET);
rset_header = conn->protocol->m.get_rset_header_packet(conn->protocol, FALSE TSRMLS_CC);
do {
SET_ERROR_AFF_ROWS(conn);
if (FAIL == (ret = PACKET_READ_ALLOCA(rset_header, conn))) {
if (FAIL == (ret = PACKET_READ(rset_header, conn))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error reading result set's header");
break;
}
if (rset_header.error_info.error_no) {
if (rset_header->error_info.error_no) {
/*
Cover a protocol design error: error packet does not
contain the server status. Therefore, the client has no way
@ -383,7 +383,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
This will copy the error code and the messages, as they
are buffers in the struct
*/
conn->error_info = rset_header.error_info;
conn->error_info = rset_header->error_info;
ret = FAIL;
/* Return back from CONN_QUERY_SENT */
CONN_SET_STATE(conn, CONN_READY);
@ -391,13 +391,13 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
}
conn->error_info.error_no = 0;
switch (rset_header.field_count) {
switch (rset_header->field_count) {
case MYSQLND_NULL_LENGTH: { /* LOAD DATA LOCAL INFILE */
zend_bool is_warning;
DBG_INF("LOAD DATA");
conn->last_query_type = QUERY_LOAD_LOCAL;
CONN_SET_STATE(conn, CONN_SENDING_LOAD_DATA);
ret = mysqlnd_handle_local_infile(conn, rset_header.info_or_local_file, &is_warning TSRMLS_CC);
ret = mysqlnd_handle_local_infile(conn, rset_header->info_or_local_file, &is_warning TSRMLS_CC);
CONN_SET_STATE(conn, (ret == PASS || is_warning == TRUE)? CONN_READY:CONN_QUIT_SENT);
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_NON_RSET_QUERY);
break;
@ -405,13 +405,13 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
case 0: /* UPSERT */
DBG_INF("UPSERT");
conn->last_query_type = QUERY_UPSERT;
conn->field_count = rset_header.field_count;
conn->upsert_status.warning_count = rset_header.warning_count;
conn->upsert_status.server_status = rset_header.server_status;
conn->upsert_status.affected_rows = rset_header.affected_rows;
conn->upsert_status.last_insert_id = rset_header.last_insert_id;
conn->field_count = rset_header->field_count;
conn->upsert_status.warning_count = rset_header->warning_count;
conn->upsert_status.server_status = rset_header->server_status;
conn->upsert_status.affected_rows = rset_header->affected_rows;
conn->upsert_status.last_insert_id = rset_header->last_insert_id;
SET_NEW_MESSAGE(conn->last_message, conn->last_message_len,
rset_header.info_or_local_file, rset_header.info_or_local_file_len,
rset_header->info_or_local_file, rset_header->info_or_local_file_len,
conn->persistent);
/* Result set can follow UPSERT statement, check server_status */
if (conn->upsert_status.server_status & SERVER_MORE_RESULTS_EXISTS) {
@ -423,7 +423,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_NON_RSET_QUERY);
break;
default:{ /* Result set */
php_mysql_packet_eof fields_eof;
php_mysql_packet_eof * fields_eof;
MYSQLND_RES *result;
enum_mysqlnd_collected_stats stat = STAT_LAST;
@ -438,9 +438,9 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
conn->last_query_type = QUERY_SELECT;
CONN_SET_STATE(conn, CONN_FETCHING_DATA);
/* PS has already allocated it */
conn->field_count = rset_header.field_count;
conn->field_count = rset_header->field_count;
if (!stmt) {
result = conn->current_result = mysqlnd_result_init(rset_header.field_count TSRMLS_CC);
result = conn->current_result = mysqlnd_result_init(rset_header->field_count TSRMLS_CC);
} else {
if (!stmt->result) {
DBG_INF("This is 'SHOW'/'EXPLAIN'-like query.");
@ -449,7 +449,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
prepared statements can't send result set metadata for these queries
on prepare stage. Read it now.
*/
result = stmt->result = mysqlnd_result_init(rset_header.field_count TSRMLS_CC);
result = stmt->result = mysqlnd_result_init(rset_header->field_count TSRMLS_CC);
} else {
/*
Update result set metadata if it for some reason changed between
@ -478,8 +478,8 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
}
/* Check for SERVER_STATUS_MORE_RESULTS if needed */
PACKET_INIT_ALLOCA(fields_eof, PROT_EOF_PACKET);
if (FAIL == (ret = PACKET_READ_ALLOCA(fields_eof, conn))) {
fields_eof = conn->protocol->m.get_eof_packet(conn->protocol, FALSE TSRMLS_CC);
if (FAIL == (ret = PACKET_READ(fields_eof, conn))) {
DBG_ERR("Error ocurred while reading the EOF packet");
result->m.free_result_contents(result TSRMLS_CC);
mnd_efree(result);
@ -492,9 +492,9 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
}
} else {
unsigned int to_log = MYSQLND_G(log_mask);
to_log &= fields_eof.server_status;
DBG_INF_FMT("warnings=%u server_status=%u", fields_eof.warning_count, fields_eof.server_status);
conn->upsert_status.warning_count = fields_eof.warning_count;
to_log &= fields_eof->server_status;
DBG_INF_FMT("warnings=%u server_status=%u", fields_eof->warning_count, fields_eof->server_status);
conn->upsert_status.warning_count = fields_eof->warning_count;
/*
If SERVER_MORE_RESULTS_EXISTS is set then this is either MULTI_QUERY or a CALL()
The first packet after sending the query/com_execute has the bit set only
@ -502,12 +502,12 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
will include many result sets. What actually matters are the bits set at the end
of every result set (the EOF packet).
*/
conn->upsert_status.server_status = fields_eof.server_status;
if (fields_eof.server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
conn->upsert_status.server_status = fields_eof->server_status;
if (fields_eof->server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
stat = STAT_BAD_INDEX_USED;
} else if (fields_eof.server_status & SERVER_QUERY_NO_INDEX_USED) {
} else if (fields_eof->server_status & SERVER_QUERY_NO_INDEX_USED) {
stat = STAT_NO_INDEX_USED;
} else if (fields_eof.server_status & SERVER_QUERY_WAS_SLOW) {
} else if (fields_eof->server_status & SERVER_QUERY_WAS_SLOW) {
stat = STAT_QUERY_WAS_SLOW;
}
if (to_log) {
@ -520,13 +520,13 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC
MYSQLND_INC_CONN_STATISTIC(&conn->stats, stat);
}
PACKET_FREE_ALLOCA(fields_eof);
PACKET_FREE(fields_eof);
break;
}
}
} while (0);
PACKET_FREE_ALLOCA(rset_header);
PACKET_FREE(rset_header);
DBG_INF(ret == PASS? "PASS":"FAIL");
DBG_RETURN(ret);
@ -866,7 +866,7 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, zend_bool ps
this to be not NULL.
*/
/* FALSE = non-persistent */
PACKET_INIT(result->row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, FALSE);
result->row_packet = result->conn->protocol->m.get_row_packet(result->conn->protocol, FALSE TSRMLS_CC);
result->row_packet->result_set_memory_pool = result->result_set_memory_pool;
result->row_packet->field_count = result->field_count;
result->row_packet->binary_protocol = ps;
@ -1072,7 +1072,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND * const conn, MYSQL
php_mysqlnd_rowp_read_text_protocol;
/* non-persistent */
PACKET_INIT(row_packet, PROT_ROW_PACKET, php_mysql_packet_row *, FALSE);
row_packet = conn->protocol->m.get_row_packet(conn->protocol, FALSE TSRMLS_CC);
row_packet->result_set_memory_pool = result->result_set_memory_pool;
row_packet->field_count = meta->field_count;
row_packet->binary_protocol = binary_protocol;

View File

@ -142,7 +142,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
MYSQLND *conn TSRMLS_DC)
{
unsigned int i = 0;
php_mysql_packet_res_field field_packet;
php_mysql_packet_res_field * field_packet;
#if PHP_MAJOR_VERSION >= 6
UChar *ustr;
int ulen;
@ -150,7 +150,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
DBG_ENTER("mysqlnd_res_meta::read_metadata");
PACKET_INIT_ALLOCA(field_packet, PROT_RSET_FLD_PACKET);
field_packet = conn->protocol->m.get_result_field_packet(conn->protocol, FALSE TSRMLS_CC);
for (;i < meta->field_count; i++) {
long idx;
@ -160,19 +160,19 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
meta->fields[i].root = NULL;
}
field_packet.metadata = &(meta->fields[i]);
if (FAIL == PACKET_READ_ALLOCA(field_packet, conn)) {
PACKET_FREE_ALLOCA(field_packet);
field_packet->metadata = &(meta->fields[i]);
if (FAIL == PACKET_READ(field_packet, conn)) {
PACKET_FREE(field_packet);
DBG_RETURN(FAIL);
}
if (field_packet.error_info.error_no) {
conn->error_info = field_packet.error_info;
if (field_packet->error_info.error_no) {
conn->error_info = field_packet->error_info;
/* Return back from CONN_QUERY_SENT */
PACKET_FREE_ALLOCA(field_packet);
PACKET_FREE(field_packet);
DBG_RETURN(FAIL);
}
if (field_packet.stupid_list_fields_eof == TRUE) {
if (field_packet->stupid_list_fields_eof == TRUE) {
meta->field_count = i;
break;
}
@ -184,7 +184,7 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
"Unknown type %d sent by the server. "
"Please send a report to the developers",
meta->fields[i].type);
PACKET_FREE_ALLOCA(field_packet);
PACKET_FREE(field_packet);
DBG_RETURN(FAIL);
}
if (meta->fields[i].type == MYSQL_TYPE_BIT) {
@ -240,19 +240,19 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
#else
/* For BC we have to check whether the key is numeric and use it like this */
if ((meta->zend_hash_keys[i].is_numeric =
mysqlnd_is_key_numeric(field_packet.metadata->name,
field_packet.metadata->name_length + 1,
mysqlnd_is_key_numeric(field_packet->metadata->name,
field_packet->metadata->name_length + 1,
&idx)))
{
meta->zend_hash_keys[i].key = idx;
} else {
meta->zend_hash_keys[i].key =
zend_get_hash_value(field_packet.metadata->name,
field_packet.metadata->name_length + 1);
zend_get_hash_value(field_packet->metadata->name,
field_packet->metadata->name_length + 1);
}
#endif
}
PACKET_FREE_ALLOCA(field_packet);
PACKET_FREE(field_packet);
DBG_RETURN(PASS);
}

View File

@ -184,6 +184,7 @@ typedef struct st_mysqlnd_net_options
typedef struct st_mysqlnd_connection MYSQLND;
typedef struct st_mysqlnd_net MYSQLND_NET;
typedef struct st_mysqlnd_protocol MYSQLND_PROTOCOL;
typedef struct st_mysqlnd_res MYSQLND_RES;
typedef char** MYSQLND_ROW_C; /* return data as array of strings */
typedef struct st_mysqlnd_stmt MYSQLND_STMT;
@ -243,6 +244,35 @@ struct st_mysqlnd_net_methods
};
struct st_php_mysql_packet_greet;
struct st_php_mysql_packet_greet;
struct st_php_mysql_packet_auth;
struct st_php_mysql_packet_ok;
struct st_php_mysql_packet_command;
struct st_php_mysql_packet_eof;
struct st_php_mysql_packet_rset_header;
struct st_php_mysql_packet_res_field;
struct st_php_mysql_packet_row;
struct st_php_mysql_packet_stats;
struct st_php_mysql_packet_prepare_response;
struct st_php_mysql_packet_chg_user_resp;
struct st_mysqlnd_protocol_methods
{
struct st_php_mysql_packet_greet * (*get_greet_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_auth * (*get_auth_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_ok * (*get_ok_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_command * (*get_command_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_eof * (*get_eof_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_rset_header *(*get_rset_header_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_res_field * (*get_result_field_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_row * (*get_row_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_stats * (*get_stats_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_prepare_response *(*get_prepare_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_php_mysql_packet_chg_user_resp*(*get_change_user_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
};
struct st_mysqlnd_conn_methods
{
void (*init)(MYSQLND * conn TSRMLS_DC);
@ -434,10 +464,18 @@ struct st_mysqlnd_net
};
struct st_mysqlnd_protocol
{
struct st_mysqlnd_protocol_methods m;
zend_bool persistent;
};
struct st_mysqlnd_connection
{
/* Operation related */
MYSQLND_NET * net;
MYSQLND_PROTOCOL * protocol;
/* Information related */
char *host;

View File

@ -1786,6 +1786,194 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
/* }}} */
/* {{{ mysqlnd_protocol::get_greet_packet */
static struct st_php_mysql_packet_greet *
MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_greet * packet = pecalloc(1, packet_methods[PROT_GREET_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_greet_packet");
packet->header.m = &packet_methods[PROT_GREET_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_auth_packet */
static struct st_php_mysql_packet_auth *
MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_auth * packet = pecalloc(1, packet_methods[PROT_AUTH_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_auth_packet");
packet->header.m = &packet_methods[PROT_AUTH_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_ok_packet */
static struct st_php_mysql_packet_ok *
MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_ok * packet = pecalloc(1, packet_methods[PROT_OK_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_ok_packet");
packet->header.m = &packet_methods[PROT_OK_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_eof_packet */
static struct st_php_mysql_packet_eof *
MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_eof * packet = pecalloc(1, packet_methods[PROT_EOF_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_eof_packet");
packet->header.m = &packet_methods[PROT_EOF_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_command_packet */
static struct st_php_mysql_packet_command *
MYSQLND_METHOD(mysqlnd_protocol, get_command_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_command * packet = pecalloc(1, packet_methods[PROT_CMD_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_command_packet");
packet->header.m = &packet_methods[PROT_CMD_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_rset_packet */
static struct st_php_mysql_packet_rset_header *
MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_rset_header * packet = pecalloc(1, packet_methods[PROT_RSET_HEADER_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_rset_header_packet");
packet->header.m = &packet_methods[PROT_RSET_HEADER_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_result_field_packet */
static struct st_php_mysql_packet_res_field *
MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_res_field * packet = pecalloc(1, packet_methods[PROT_RSET_FLD_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_result_field_packet");
packet->header.m = &packet_methods[PROT_RSET_FLD_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_row_packet */
static struct st_php_mysql_packet_row *
MYSQLND_METHOD(mysqlnd_protocol, get_row_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_row * packet = pecalloc(1, packet_methods[PROT_ROW_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_row_packet");
packet->header.m = &packet_methods[PROT_ROW_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_stats_packet */
static struct st_php_mysql_packet_stats *
MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_stats * packet = pecalloc(1, packet_methods[PROT_STATS_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_stats_packet");
packet->header.m = &packet_methods[PROT_STATS_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_prepare_response_packet */
static struct st_php_mysql_packet_prepare_response *
MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_prepare_response * packet = pecalloc(1, packet_methods[PROT_PREPARE_RESP_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_prepare_response_packet");
packet->header.m = &packet_methods[PROT_PREPARE_RESP_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol::get_change_user_response_packet */
static struct st_php_mysql_packet_chg_user_resp*
MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
{
struct st_php_mysql_packet_chg_user_resp * packet = pecalloc(1, packet_methods[PROT_CHG_USER_PACKET].struct_size, persistent);
DBG_ENTER("mysqlnd_protocol::get_change_user_response_packet");
packet->header.m = &packet_methods[PROT_CHG_USER_PACKET];
packet->header.persistent = persistent;
DBG_RETURN(packet);
}
/* }}} */
/* {{{ mysqlnd_protocol_init */
MYSQLND_PROTOCOL *
mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC)
{
size_t alloc_size = sizeof(MYSQLND_PROTOCOL) + mysqlnd_plugin_count() * sizeof(void *);
MYSQLND_PROTOCOL *ret = mnd_pecalloc(1, alloc_size, persistent);
DBG_ENTER("mysqlnd_protocol_init");
DBG_INF_FMT("persistent=%d", persistent);
ret->persistent = persistent;
ret->m.get_greet_packet = MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet);
ret->m.get_auth_packet = MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet);
ret->m.get_ok_packet = MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet);
ret->m.get_command_packet = MYSQLND_METHOD(mysqlnd_protocol, get_command_packet);
ret->m.get_eof_packet = MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet);
ret->m.get_rset_header_packet = MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet);
ret->m.get_result_field_packet = MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet);
ret->m.get_row_packet = MYSQLND_METHOD(mysqlnd_protocol, get_row_packet);
ret->m.get_stats_packet = MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet);
ret->m.get_prepare_response_packet = MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet);
ret->m.get_change_user_response_packet = MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet);
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_protocol_free */
void
mysqlnd_protocol_free(MYSQLND_PROTOCOL * const protocol TSRMLS_DC)
{
zend_bool pers = protocol->persistent;
DBG_ENTER("mysqlnd_protocol_free");
if (protocol) {
mnd_pefree(protocol, pers);
}
DBG_VOID_RETURN;
}
/* }}} */
/*
* Local variables:
* tab-width: 4

View File

@ -36,13 +36,6 @@ extern char * mysqlnd_read_body_name;
/* Packet handling */
#define PACKET_INIT(packet, enum_type, c_type, pers) \
{ \
packet = (c_type) pecalloc(1, packet_methods[(enum_type)].struct_size, (pers)); \
((c_type) (packet))->header.m = &packet_methods[(enum_type)]; \
((c_type) (packet))->header.persistent = (pers); \
DBG_INF_FMT("PACKET_INIT(%p, %d, %d)", packet, (int) enum_type, (int) pers); \
}
#define PACKET_WRITE(packet, conn) ((packet)->header.m->write_to_net((packet), (conn) TSRMLS_CC))
#define PACKET_READ(packet, conn) ((packet)->header.m->read_from_net((packet), (conn) TSRMLS_CC))
#define PACKET_FREE(packet) \
@ -51,15 +44,6 @@ extern char * mysqlnd_read_body_name;
((packet)->header.m->free_mem((packet), FALSE TSRMLS_CC)); \
} while (0);
#define PACKET_INIT_ALLOCA(packet, enum_type) \
{ \
memset(&(packet), 0, packet_methods[enum_type].struct_size); \
(packet).header.m = &packet_methods[enum_type]; \
}
#define PACKET_WRITE_ALLOCA(packet, conn) PACKET_WRITE(&(packet), (conn))
#define PACKET_READ_ALLOCA(packet, conn) PACKET_READ(&(packet), (conn))
#define PACKET_FREE_ALLOCA(packet) (packet.header.m->free_mem(&(packet), TRUE TSRMLS_CC))
extern const char * const mysqlnd_command_to_text[COM_END];
/* Low-level extraction functionality */
@ -285,6 +269,11 @@ void php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
zend_bool as_unicode, zend_bool as_int_or_float,
MYSQLND_STATS * stats TSRMLS_DC);
MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC);
void mysqlnd_protocol_free(MYSQLND_PROTOCOL * net TSRMLS_DC);
#endif /* MYSQLND_WIREPROTOCOL_H */
/*