conn->current_result = NULL;
}
-#ifdef MYSQLND_COMPRESSION_ENABLED
- if (conn->net->uncompressed_data) {
- conn->net->uncompressed_data->free_buffer(&conn->net->uncompressed_data TSRMLS_CC);
- }
-#endif
+ conn->net->m.free_contents(conn->net TSRMLS_CC);
+
DBG_INF("Freeing memory of members");
if (conn->host) {
CONN_SET_STATE(conn, CONN_ALLOCED);
conn->net->packet_no = conn->net->compressed_envelope_packet_no = 0;
- if (conn->options.timeout_connect) {
- tv.tv_sec = conn->options.timeout_connect;
+ if (conn->net->options.timeout_connect) {
+ tv.tv_sec = conn->net->options.timeout_connect;
tv.tv_usec = 0;
}
if (conn->persistent) {
DBG_INF(conn->scheme);
conn->net->stream = php_stream_xport_create(conn->scheme, transport_len, streams_options, streams_flags,
hashed_details,
- (conn->options.timeout_connect) ? &tv : NULL,
+ (conn->net->options.timeout_connect) ? &tv : NULL,
NULL /*ctx*/, &errstr, &errcode);
DBG_INF_FMT("stream=%p", conn->net->stream);
mnd_efree(hashed_details);
}
- if (!conn->options.timeout_read) {
+ if (!conn->net->options.timeout_read) {
/* should always happen because read_timeout cannot be set via API */
- conn->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout);
+ conn->net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout);
}
- if (conn->options.timeout_read)
+ if (conn->net->options.timeout_read)
{
- tv.tv_sec = conn->options.timeout_read;
+ tv.tv_sec = conn->net->options.timeout_read;
tv.tv_usec = 0;
php_stream_set_option(conn->net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
}
DBG_ENTER("mysqlnd_conn::set_client_option");
DBG_INF_FMT("conn=%llu option=%d", conn->thread_id, option);
switch (option) {
+#ifdef WHEN_SUPPORTED_BY_MYSQLI
+ case MYSQL_OPT_COMPRESS:
+#endif
+#ifdef WHEN_SUPPORTED_BY_MYSQLI
+ case MYSQL_OPT_READ_TIMEOUT:
+ case MYSQL_OPT_WRITE_TIMEOUT:
+#endif
+ case MYSQL_OPT_CONNECT_TIMEOUT:
+ case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
+ case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
+ conn->net->m.set_client_option(conn->net, option, value TSRMLS_CC);
+ break;
#if PHP_MAJOR_VERSION >= 6
case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
conn->options.numeric_and_datetime_as_unicode = *(unsigned int*) value;
break;
#endif
- case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
- DBG_INF("MYSQLND_OPT_NET_CMD_BUFFER_SIZE");
- if (*(unsigned int*) value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) {
- DBG_RETURN(FAIL);
- }
- conn->net->cmd_buffer.length = *(unsigned int*) value;
- DBG_INF_FMT("new_length=%u", conn->net->cmd_buffer.length);
- if (!conn->net->cmd_buffer.buffer) {
- conn->net->cmd_buffer.buffer = mnd_pemalloc(conn->net->cmd_buffer.length, conn->net->persistent);
- } else {
- conn->net->cmd_buffer.buffer = mnd_perealloc(conn->net->cmd_buffer.buffer,
- conn->net->cmd_buffer.length,
- conn->net->persistent);
- }
- break;
- case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
- DBG_INF("MYSQLND_OPT_NET_READ_BUFFER_SIZE");
- conn->options.net_read_buffer_size = *(unsigned int*) value;
- DBG_INF_FMT("new_length=%u", conn->options.net_read_buffer_size);
- break;
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
DBG_INF("MYSQLND_OPT_INT_AND_FLOAT_NATIVE");
conn->options.int_and_float_native = *(unsigned int*) value;
break;
-#endif
- case MYSQL_OPT_CONNECT_TIMEOUT:
- DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT");
- conn->options.timeout_connect = *(unsigned int*) value;
- break;
-#ifdef WHEN_SUPPORTED_BY_MYSQLI
- case MYSQL_OPT_READ_TIMEOUT:
- DBG_INF("MYSQL_OPT_READ_TIMEOUT");
- conn->options.timeout_read = *(unsigned int*) value;
- break;
- case MYSQL_OPT_WRITE_TIMEOUT:
- DBG_INF("MYSQL_OPT_WRITE_TIMEOUT");
- conn->options.timeout_write = *(unsigned int*) value;
- break;
#endif
case MYSQL_OPT_LOCAL_INFILE:
DBG_INF("MYSQL_OPT_LOCAL_INFILE");
conn->options.init_commands[conn->options.num_commands] = pestrdup(value, conn->persistent);
++conn->options.num_commands;
break;
-#ifdef WHEN_SUPPORTED_BY_MYSQLI
- case MYSQL_OPT_COMPRESS:
-#endif
case MYSQL_READ_DEFAULT_FILE:
case MYSQL_READ_DEFAULT_GROUP:
#ifdef WHEN_SUPPORTED_BY_MYSQLI
void *userdata;
} MYSQLND_INFILE;
-typedef struct st_mysqlnd_option
+typedef struct st_mysqlnd_options
{
- /* timeouts */
- unsigned int timeout_connect;
- unsigned int timeout_read;
- unsigned int timeout_write;
-
ulong flags;
/* init commands - we need to send them to server directly after connect */
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
zend_bool int_and_float_native;
#endif
+} MYSQLND_OPTIONS;
+
+typedef struct st_mysqlnd_net_options
+{
+ /* timeouts */
+ unsigned int timeout_connect;
+ unsigned int timeout_read;
+ unsigned int timeout_write;
+
unsigned int net_read_buffer_size;
-} MYSQLND_OPTION;
+} MYSQLND_NET_OPTIONS;
typedef struct st_mysqlnd_connection MYSQLND;
+typedef struct st_mysqlnd_net MYSQLND_NET;
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;
} MYSQLND_READ_BUFFER;
-typedef struct st_mysqlnd_net
+struct st_mysqlnd_net_methods
{
- php_stream *stream;
enum_func_status (*stream_read)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC);
size_t (*stream_write)(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC);
-
- /* sequence for simple checking of correct packets */
- zend_uchar packet_no;
- zend_bool compressed;
- zend_uchar compressed_envelope_packet_no;
-#ifdef MYSQLND_COMPRESSION_ENABLED
- MYSQLND_READ_BUFFER * uncompressed_data;
-#endif
-#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
- zend_uchar last_command;
-#endif
- /* cmd buffer */
- MYSQLND_CMD_BUFFER cmd_buffer;
-
- zend_bool persistent;
-} MYSQLND_NET;
+ enum_func_status (*set_client_option)(MYSQLND_NET * const net, enum_mysqlnd_option option, const char * const value TSRMLS_DC);
+ void (*free_contents)(MYSQLND_NET * net TSRMLS_DC);
+};
struct st_mysqlnd_conn_methods
};
+struct st_mysqlnd_net
+{
+ php_stream *stream;
+ struct st_mysqlnd_net_methods m;
+
+ /* sequence for simple checking of correct packets */
+ zend_uchar packet_no;
+ zend_bool compressed;
+ zend_uchar compressed_envelope_packet_no;
+#ifdef MYSQLND_COMPRESSION_ENABLED
+ MYSQLND_READ_BUFFER * uncompressed_data;
+#endif
+#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
+ zend_uchar last_command;
+#endif
+ /* cmd buffer */
+ MYSQLND_CMD_BUFFER cmd_buffer;
+
+ MYSQLND_NET_OPTIONS options;
+
+ zend_bool persistent;
+};
+
+
struct st_mysqlnd_connection
{
/* Operation related */
zend_bool persistent;
/* options */
- MYSQLND_OPTION options;
+ MYSQLND_OPTIONS options;
/* stats */
MYSQLND_STATS stats;
/* }}} */
-/* {{{ mysqlnd_stream_write */
+/* {{{ mysqlnd_net::stream_write */
static size_t
-mysqlnd_stream_write(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_net, stream_write)(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC)
{
size_t ret;
- DBG_ENTER("mysqlnd_stream_write");
+ DBG_ENTER("mysqlnd_net::stream_write");
ret = php_stream_write(conn->net->stream, (char *)buf, count);
DBG_RETURN(ret);
}
int3store(compress_buf, payload_size);
int1store(compress_buf + 3, net->packet_no);
DBG_INF_FMT("writing %d bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE);
- ret = conn->net->stream_write(conn, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE TSRMLS_CC);
+ ret = conn->net->m.stream_write(conn, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE TSRMLS_CC);
net->compressed_envelope_packet_no++;
} else
#endif /* MYSQLND_COMPRESSION_ENABLED */
STORE_HEADER_SIZE(safe_storage, p);
int3store(p, MYSQLND_MAX_PACKET_SIZE);
int1store(p + 3, net->packet_no);
- ret = conn->net->stream_write(conn, p, MYSQLND_MAX_PACKET_SIZE + MYSQLND_HEADER_SIZE TSRMLS_CC);
+ ret = conn->net->m.stream_write(conn, p, MYSQLND_MAX_PACKET_SIZE + MYSQLND_HEADER_SIZE TSRMLS_CC);
RESTORE_HEADER_SIZE(p, safe_storage);
net->compressed_envelope_packet_no++;
}
int3store(compress_buf, payload_size);
int1store(compress_buf + 3, net->packet_no);
DBG_INF_FMT("writing %d bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE);
- ret = conn->net->stream_write(conn, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE TSRMLS_CC);
+ ret = conn->net->m.stream_write(conn, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE TSRMLS_CC);
net->compressed_envelope_packet_no++;
#if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
STORE_HEADER_SIZE(safe_storage, p);
int3store(p, left);
int1store(p + 3, net->packet_no);
- ret = conn->net->stream_write(conn, p, left + MYSQLND_HEADER_SIZE TSRMLS_CC);
+ ret = conn->net->m.stream_write(conn, p, left + MYSQLND_HEADER_SIZE TSRMLS_CC);
RESTORE_HEADER_SIZE(p, safe_storage);
}
net->packet_no++;
/* }}} */
-/* {{{ mysqlnd_read_from_stream */
+/* {{{ mysqlnd_net::read_from_stream */
static enum_func_status
-mysqlnd_read_from_stream(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_net, read_from_stream)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC)
{
size_t to_read = count, ret;
size_t old_chunk_size = conn->net->stream->chunk_size;
- DBG_ENTER("mysqlnd_read_from_stream");
+ DBG_ENTER("mysqlnd_net::read_from_stream");
DBG_INF_FMT("count=%u", count);
- conn->net->stream->chunk_size = MIN(to_read, conn->options.net_read_buffer_size);
+ conn->net->stream->chunk_size = MIN(to_read, conn->net->options.net_read_buffer_size);
while (to_read) {
if (!(ret = php_stream_read(conn->net->stream, (char *) buffer, to_read))) {
DBG_ERR_FMT("Error while reading header from socket");
DBG_ENTER("mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer");
/* Read the compressed header */
- if (FAIL == conn->net->stream_read(conn, comp_header, COMPRESSED_HEADER_SIZE TSRMLS_CC)) {
+ if (FAIL == conn->net->m.stream_read(conn, comp_header, COMPRESSED_HEADER_SIZE TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
decompressed_size = uint3korr(comp_header);
int error;
uLongf tmp_complen = decompressed_size;
compressed_data = emalloc(net_payload_size);
- if (FAIL == conn->net->stream_read(conn, compressed_data, net_payload_size TSRMLS_CC)) {
+ if (FAIL == conn->net->m.stream_read(conn, compressed_data, net_payload_size TSRMLS_CC)) {
ret = FAIL;
goto end;
}
} else {
DBG_INF_FMT("The server decided not to compress the data. Our job is easy. Copying %u bytes", net_payload_size);
net->uncompressed_data = mysqlnd_create_read_buffer(net_payload_size TSRMLS_CC);
- if (FAIL == conn->net->stream_read(conn, net->uncompressed_data->data, net_payload_size TSRMLS_CC)) {
+ if (FAIL == conn->net->m.stream_read(conn, net->uncompressed_data->data, net_payload_size TSRMLS_CC)) {
ret = FAIL;
goto end;
}
size_t net_payload_size;
zend_uchar packet_no;
- if (FAIL == conn->net->stream_read(conn, net_header, MYSQLND_HEADER_SIZE TSRMLS_CC)) {
+ if (FAIL == conn->net->m.stream_read(conn, net_header, MYSQLND_HEADER_SIZE TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
net_payload_size = uint3korr(net_header);
DBG_RETURN(PASS);
}
#endif /* MYSQLND_COMPRESSION_ENABLED */
- DBG_RETURN(conn->net->stream_read(conn, p, to_read TSRMLS_CC));
+ DBG_RETURN(conn->net->m.stream_read(conn, p, to_read TSRMLS_CC));
}
/* }}} */
/* }}} */
+/* {{{ mysqlnd_net::set_client_option */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mysqlnd_option option, const char * const value TSRMLS_DC)
+{
+ DBG_ENTER("mysqlnd_net::set_client_option");
+ DBG_INF_FMT("option=%d", option);
+ switch (option) {
+ case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
+ DBG_INF("MYSQLND_OPT_NET_CMD_BUFFER_SIZE");
+ if (*(unsigned int*) value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) {
+ DBG_RETURN(FAIL);
+ }
+ net->cmd_buffer.length = *(unsigned int*) value;
+ DBG_INF_FMT("new_length=%u", net->cmd_buffer.length);
+ if (!net->cmd_buffer.buffer) {
+ net->cmd_buffer.buffer = mnd_pemalloc(net->cmd_buffer.length, net->persistent);
+ } else {
+ net->cmd_buffer.buffer = mnd_perealloc(net->cmd_buffer.buffer, net->cmd_buffer.length, net->persistent);
+ }
+ break;
+ case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
+ DBG_INF("MYSQLND_OPT_NET_READ_BUFFER_SIZE");
+ net->options.net_read_buffer_size = *(unsigned int*) value;
+ DBG_INF_FMT("new_length=%u", net->options.net_read_buffer_size);
+ break;
+ case MYSQL_OPT_CONNECT_TIMEOUT:
+ DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT");
+ net->options.timeout_connect = *(unsigned int*) value;
+ break;
+#ifdef WHEN_SUPPORTED_BY_MYSQLI
+ case MYSQL_OPT_READ_TIMEOUT:
+ DBG_INF("MYSQL_OPT_READ_TIMEOUT");
+ net->options.timeout_read = *(unsigned int*) value;
+ break;
+ case MYSQL_OPT_WRITE_TIMEOUT:
+ DBG_INF("MYSQL_OPT_WRITE_TIMEOUT");
+ net->options.timeout_write = *(unsigned int*) value;
+ break;
+#endif
+#ifdef WHEN_SUPPORTED_BY_MYSQLI
+ case MYSQL_OPT_COMPRESS:
+#endif
+ /* currently not supported. Todo!! */
+ break;
+ default:
+ DBG_RETURN(FAIL);
+ }
+ DBG_RETURN(PASS);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_net::set_client_option */
+static void
+MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
+{
+ DBG_ENTER("mysqlnd_net::free_contents");
+
+#ifdef MYSQLND_COMPRESSION_ENABLED
+ if (net->uncompressed_data) {
+ net->uncompressed_data->free_buffer(&net->uncompressed_data TSRMLS_CC);
+ }
+#endif
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
+
/* {{{ mysqlnd_net_init */
MYSQLND_NET *
mysqlnd_net_init(zend_bool persistent TSRMLS_DC)
DBG_INF_FMT("persistent=%d", persistent);
net->persistent = persistent;
- net->stream_read = mysqlnd_read_from_stream;
- net->stream_write = mysqlnd_stream_write;
+ net->m.stream_read = MYSQLND_METHOD(mysqlnd_net, read_from_stream);
+ net->m.stream_write = MYSQLND_METHOD(mysqlnd_net, stream_write);
+ net->m.set_client_option = MYSQLND_METHOD(mysqlnd_net, set_client_option);
+ net->m.free_contents = MYSQLND_METHOD(mysqlnd_net, free_contents);
{
- size_t buffer_size = MYSQLND_G(net_cmd_buffer_size) > MYSQLND_NET_CMD_BUFFER_MIN_SIZE?
- MYSQLND_G(net_cmd_buffer_size):
- MYSQLND_NET_CMD_BUFFER_MIN_SIZE;
- net->cmd_buffer.length = buffer_size;
- net->cmd_buffer.buffer = mnd_pemalloc(buffer_size, persistent);
+ unsigned int buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/
+ net->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC);
}
DBG_RETURN(net);
}