0 Star 0 Fork 346

changfangfang / swoole-src

forked from swoole / swoole-src 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
swoole_mysql.h 22.14 KB
一键复制 编辑 原始数据 按行查看 历史
韩天峰 提交于 2017-03-29 11:58 . warning free.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
/*
+----------------------------------------------------------------------+
| Swoole |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2015 The Swoole Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.0 of the Apache 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.apache.org/licenses/LICENSE-2.0.html |
| If you did not receive a copy of the Apache2.0 license and are unable|
| to obtain it through the world-wide-web, please send a note to |
| license@swoole.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
+----------------------------------------------------------------------+
*/
#ifndef SWOOLE_MYSQL_H_
#define SWOOLE_MYSQL_H_
//#define SW_MYSQL_STRICT_TYPE
//#define SW_MYSQL_DEBUG
enum mysql_command
{
SW_MYSQL_COM_SLEEP = 0,
SW_MYSQL_COM_QUIT,
SW_MYSQL_COM_INIT_DB,
SW_MYSQL_COM_QUERY = 3,
SW_MYSQL_COM_FIELD_LIST,
SW_MYSQL_COM_CREATE_DB,
SW_MYSQL_COM_DROP_DB,
SW_MYSQL_COM_REFRESH,
SW_MYSQL_COM_SHUTDOWN,
SW_MYSQL_COM_STATISTICS,
SW_MYSQL_COM_PROCESS_INFO,
SW_MYSQL_COM_CONNECT,
SW_MYSQL_COM_PROCESS_KILL,
SW_MYSQL_COM_DEBUG,
SW_MYSQL_COM_PING,
SW_MYSQL_COM_TIME,
SW_MYSQL_COM_DELAYED_INSERT,
SW_MYSQL_COM_CHANGE_USER,
SW_MYSQL_COM_BINLOG_DUMP,
SW_MYSQL_COM_TABLE_DUMP,
SW_MYSQL_COM_CONNECT_OUT,
SW_MYSQL_COM_REGISTER_SLAVE,
SW_MYSQL_COM_STMT_PREPARE,
SW_MYSQL_COM_STMT_EXECUTE,
SW_MYSQL_COM_STMT_SEND_LONG_DATA,
SW_MYSQL_COM_STMT_CLOSE,
SW_MYSQL_COM_STMT_RESET,
SW_MYSQL_COM_SET_OPTION,
SW_MYSQL_COM_STMT_FETCH,
SW_MYSQL_COM_DAEMON,
SW_MYSQL_COM_END
};
enum mysql_handshake_state
{
SW_MYSQL_HANDSHAKE_WAIT_REQUEST,
SW_MYSQL_HANDSHAKE_WAIT_RESULT,
SW_MYSQL_HANDSHAKE_COMPLETED,
};
enum mysql_read_state
{
SW_MYSQL_STATE_QUERY,
SW_MYSQL_STATE_READ_START,
SW_MYSQL_STATE_READ_FIELD,
SW_MYSQL_STATE_READ_ROW,
SW_MYSQL_STATE_READ_END,
SW_MYSQL_STATE_CLOSED,
};
enum mysql_error_code
{
SW_MYSQL_ERR_PROTOCOL_ERROR = 1,
SW_MYSQL_ERR_BUFFER_OVERSIZE,
SW_MYSQL_ERR_PACKET_CORRUPT,
SW_MYSQL_ERR_WANT_READ,
SW_MYSQL_ERR_WANT_WRITE,
SW_MYSQL_ERR_UNKNOWN_ERROR,
SW_MYSQL_ERR_MYSQL_ERROR,
SW_MYSQL_ERR_SERVER_LOST,
SW_MYSQL_ERR_BAD_PORT,
SW_MYSQL_ERR_RESOLV_HOST,
SW_MYSQL_ERR_SYSTEM,
SW_MYSQL_ERR_CANT_CONNECT,
SW_MYSQL_ERR_BUFFER_TOO_SMALL,
SW_MYSQL_ERR_UNEXPECT_R_STATE,
SW_MYSQL_ERR_STRFIELD_CORRUPT,
SW_MYSQL_ERR_BINFIELD_CORRUPT,
SW_MYSQL_ERR_BAD_LCB,
SW_MYSQL_ERR_LEN_OVER_BUFFER,
SW_MYSQL_ERR_CONVLONG,
SW_MYSQL_ERR_CONVLONGLONG,
SW_MYSQL_ERR_CONVFLOAT,
SW_MYSQL_ERR_CONVDOUBLE,
SW_MYSQL_ERR_CONVTIME,
SW_MYSQL_ERR_CONVTIMESTAMP,
SW_MYSQL_ERR_CONVDATE
};
enum mysql_field_types
{
SW_MYSQL_TYPE_DECIMAL,
SW_MYSQL_TYPE_TINY,
SW_MYSQL_TYPE_SHORT,
SW_MYSQL_TYPE_LONG,
SW_MYSQL_TYPE_FLOAT,
SW_MYSQL_TYPE_DOUBLE,
SW_MYSQL_TYPE_NULL,
SW_MYSQL_TYPE_TIMESTAMP,
SW_MYSQL_TYPE_LONGLONG,
SW_MYSQL_TYPE_INT24,
SW_MYSQL_TYPE_DATE,
SW_MYSQL_TYPE_TIME,
SW_MYSQL_TYPE_DATETIME,
SW_MYSQL_TYPE_YEAR,
SW_MYSQL_TYPE_NEWDATE,
SW_MYSQL_TYPE_VARCHAR,
SW_MYSQL_TYPE_BIT,
SW_MYSQL_TYPE_NEWDECIMAL = 246,
SW_MYSQL_TYPE_ENUM = 247,
SW_MYSQL_TYPE_SET = 248,
SW_MYSQL_TYPE_TINY_BLOB = 249,
SW_MYSQL_TYPE_MEDIUM_BLOB = 250,
SW_MYSQL_TYPE_LONG_BLOB = 251,
SW_MYSQL_TYPE_BLOB = 252,
SW_MYSQL_TYPE_VAR_STRING = 253,
SW_MYSQL_TYPE_STRING = 254,
SW_MYSQL_TYPE_GEOMETRY = 255
};
#define SW_MYSQL_CLIENT_CONNECT_WITH_DB 8
#define SW_MYSQL_CLIENT_PROTOCOL_41 512
#define SW_MYSQL_CLIENT_PLUGIN_AUTH (1UL << 19)
#define SW_MYSQL_CLIENT_CONNECT_ATTRS (1UL << 20)
#define SW_MYSQL_CLIENT_SECURE_CONNECTION 32768
typedef struct
{
int packet_length;
int packet_number;
uint8_t protocol_version;
char *server_version;
int connection_id;
char auth_plugin_data[21];
uint8_t l_auth_plugin_data;
char filler;
int capability_flags;
char character_set;
int16_t status_flags;
char reserved[10];
char *auth_plugin_name;
uint8_t l_auth_plugin_name;
} mysql_handshake_request;
typedef struct
{
char *host;
char *user;
char *password;
char *database;
zend_size_t host_len;
zend_size_t user_len;
zend_size_t password_len;
zend_size_t database_len;
long port;
double timeout;
int capability_flags;
int max_packet_size;
char character_set;
int packet_length;
char buf[512];
uint16_t error_code;
char *error_msg;
uint16_t error_length;
} mysql_connector;
typedef struct
{
char *buffer;
char *name; /* Name of column */
char *org_name; /* Original column name, if an alias */
char *table; /* Table of column if column was a field */
char *org_table; /* Org table name, if table was an alias */
char *db; /* Database for table */
char *catalog; /* Catalog for table */
char *def; /* Default value (set by mysql_list_fields) */
ulong_t length; /* Width of column (create length) */
ulong_t max_length; /* Max width for selected set */
uint32_t name_length;
uint32_t org_name_length;
uint32_t table_length;
uint32_t org_table_length;
uint32_t db_length;
uint32_t catalog_length;
uint32_t def_length;
uint32_t flags; /* Div flags */
uint32_t decimals; /* Number of decimals in field */
uint32_t charsetnr; /* Character set */
enum mysql_field_types type; /* Type of field. See mysql_com.h for types */
void *extension;
} mysql_field;
typedef union
{
signed char stiny;
uchar utiny;
uchar mbool;
short ssmall;
unsigned short small;
int sint;
uint32_t uint;
long long sbigint;
unsigned long long ubigint;
float mfloat;
double mdouble;
} mysql_row;
typedef struct
{
mysql_field *columns;
ulong_t num_column;
ulong_t index_column;
uint32_t num_row;
uint8_t wait_recv;
uint8_t response_type;
uint32_t packet_length :24;
uint32_t packet_number :8;
uint32_t error_code;
uint32_t warnings;
uint16_t status_code;
char status_msg[6];
char *server_msg;
uint16_t l_server_msg;
ulong_t affected_rows;
ulong_t insert_id;
zval *result_array;
} mysql_response_t;
typedef struct
{
uint8_t state;
uint8_t handshake;
swString *buffer;
swClient *cli;
zval *object;
zval *callback;
zval *onClose;
int fd;
mysql_connector connector;
#if PHP_MAJOR_VERSION >= 7
zval _object;
zval _onClose;
#endif
mysql_response_t response;
} mysql_client;
#define mysql_uint2korr(A) (uint16_t) (((uint16_t) ((zend_uchar) (A)[0])) +\
((uint16_t) ((zend_uchar) (A)[1]) << 8))
#define mysql_uint3korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
(((uint32_t) ((zend_uchar) (A)[2])) << 16))
#define mysql_uint4korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
(((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
(((uint32_t) ((zend_uchar) (A)[3])) << 24))
#define mysql_uint8korr(A) ((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\
(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
(((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
(((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\
(((uint64_t) (((uint32_t) ((zend_uchar) (A)[4])) +\
(((uint32_t) ((zend_uchar) (A)[5])) << 8) +\
(((uint32_t) ((zend_uchar) (A)[6])) << 16) +\
(((uint32_t) ((zend_uchar) (A)[7])) << 24))) << 32))
static sw_inline void mysql_pack_length(int length, char *buf)
{
buf[2] = length >> 16;
buf[1] = length >> 8;
buf[0] = length;
}
static sw_inline int mysql_lcb_ll(char *m, ulong_t *r, char *nul, int len)
{
if (len < 1)
{
return -1;
}
switch ((uchar) m[0])
{
case 251: /* fb : 1 octet */
*r = 0;
*nul = 1;
return 1;
case 252: /* fc : 2 octets */
if (len < 3)
{
return -1;
}
*r = mysql_uint2korr(m + 1);
*nul = 0;
return 3;
case 253: /* fd : 3 octets */
if (len < 5)
{
return -1;
}
*r = mysql_uint3korr(m + 1);
*nul = 0;
return 4;
case 254: /* fe */
if (len < 9)
{
return -1;
}
*r = mysql_uint8korr(m + 1);
*nul = 0;
return 9;
default:
*r = (uchar) m[0];
*nul = 0;
return 1;
}
}
static sw_inline int mysql_length_coded_binary(char *m, ulong_t *r, char *nul, int len)
{
ulong_t val = 0;
int retcode = mysql_lcb_ll(m, &val, nul, len);
*r = val;
return retcode;
}
static sw_inline int mysql_decode_field(char *buf, int len, mysql_field *col)
{
int i;
ulong_t size;
char nul;
char *wh;
int tmp_len;
/**
* string buffer
*/
char *_buffer = (char*)emalloc(len);
if (!_buffer)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
col->buffer = _buffer;
wh = buf;
i = 0;
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->catalog_length = size;
col->catalog = _buffer;
_buffer += (size + 1);
memcpy(col->catalog, &buf[i], size);
col->catalog[size] = '\0';
wh += size + 1;
i += size;
/* n (Length Coded String) db */
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->db_length = size;
col->db = _buffer;
_buffer += (size + 1);
memcpy(col->db, &buf[i], size);
col->db[size] = '\0';
wh += size + 1;
i += size;
/* n (Length Coded String) table */
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->table_length = size;
col->table = _buffer;
_buffer += (size + 1);
memcpy(col->table, &buf[i], size);
col->table[size] = '\0';
wh += size + 1;
i += size;
/* n (Length Coded String) org_table */
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->org_table_length = size;
col->org_table = _buffer;
_buffer += (size + 1);
memcpy(col->org_table, &buf[i], size);
col->org_table[size] = '\0';
wh += size + 1;
i += size;
/* n (Length Coded String) name */
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->name_length = size;
col->name = _buffer;
_buffer += (size + 1);
memcpy(col->name, &buf[i], size);
col->name[size] = '\0';
wh += size + 1;
i += size;
/* n (Length Coded String) org_name */
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->org_name_length = size;
col->org_name = _buffer;
_buffer += (size + 1);
memcpy(col->org_name, &buf[i], size);
col->org_name[size] = '\0';
wh += size + 1;
i += size;
/* check len */
if (i + 13 > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
/* (filler) */
i += 1;
/* charset */
col->charsetnr = mysql_uint2korr(&buf[i]);
i += 2;
/* length */
col->length = mysql_uint4korr(&buf[i]);
i += 4;
/* type */
col->type = (enum mysql_field_types) (uchar)buf[i];
i += 1;
/* flags */
col->flags = mysql_uint2korr(&buf[i]);
i += 2;
/* decimals */
col->decimals = buf[i];
i += 1;
/* filler */
i += 2;
/* default - a priori facultatif */
if (len - i > 0)
{
tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
i += tmp_len;
if (i + size > len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
col->def_length = size;
col->def = _buffer;
//_buffer += (size + 1);
memcpy(col->def, &buf[i], size);
col->def[size] = '\0';
wh += size + 1;
i += size;
}
else
{
col->def = NULL;
col->def_length = 0;
}
/* set write pointer */
return wh - buf;
}
static sw_inline int mysql_decode_row(mysql_client *client, char *buf, int packet_len)
{
int read_n = 0, i;
int tmp_len;
ulong_t len;
char nul;
#ifdef SW_MYSQL_STRICT_TYPE
mysql_row row;
char value_buffer[32];
bzero(&row, sizeof(row));
char *error;
char mem;
#endif
zval *result_array = client->response.result_array;
zval *row_array = NULL;
SW_ALLOC_INIT_ZVAL(row_array);
array_init(row_array);
for (i = 0; i < client->response.num_column; i++)
{
tmp_len = mysql_length_coded_binary(&buf[read_n], &len, &nul, packet_len - read_n);
if (tmp_len == -1)
{
return -SW_MYSQL_ERR_BAD_LCB;
}
read_n += tmp_len;
if (read_n + len > packet_len)
{
return -SW_MYSQL_ERR_LEN_OVER_BUFFER;
}
swTrace("n=%d, fname=%s, name_length=%d\n", i, client->response.columns[i].name, client->response.columns[i].name_length);
if (nul == 1)
{
add_assoc_null(row_array, client->response.columns[i].name);
continue;
}
int type = client->response.columns[i].type;
switch (type)
{
case SW_MYSQL_TYPE_NULL:
add_assoc_null(row_array, client->response.columns[i].name);
break;
/* String */
case SW_MYSQL_TYPE_TINY_BLOB:
case SW_MYSQL_TYPE_MEDIUM_BLOB:
case SW_MYSQL_TYPE_LONG_BLOB:
case SW_MYSQL_TYPE_BLOB:
case SW_MYSQL_TYPE_DECIMAL:
case SW_MYSQL_TYPE_NEWDECIMAL:
case SW_MYSQL_TYPE_BIT:
case SW_MYSQL_TYPE_STRING:
case SW_MYSQL_TYPE_VAR_STRING:
case SW_MYSQL_TYPE_VARCHAR:
case SW_MYSQL_TYPE_NEWDATE:
/* Date Time */
case SW_MYSQL_TYPE_TIME:
case SW_MYSQL_TYPE_YEAR:
case SW_MYSQL_TYPE_TIMESTAMP:
case SW_MYSQL_TYPE_DATETIME:
case SW_MYSQL_TYPE_DATE:
sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1);
break;
/* Integer */
case SW_MYSQL_TYPE_TINY:
case SW_MYSQL_TYPE_SHORT:
case SW_MYSQL_TYPE_INT24:
case SW_MYSQL_TYPE_LONG:
#ifdef SW_MYSQL_STRICT_TYPE
memcpy(value_buffer, buf + read_n, len);
value_buffer[len] = 0;
row.sint = strtol(value_buffer, &error, 10);
if (*error != '\0')
{
return -SW_MYSQL_ERR_CONVLONG;
}
add_assoc_long(row_array, client->response.columns[i].name, row.sint);
#else
sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1);
#endif
break;
case SW_MYSQL_TYPE_LONGLONG:
#ifdef SW_MYSQL_STRICT_TYPE
memcpy(value_buffer, buf + read_n, len);
value_buffer[len] = 0;
row.sbigint = strtoll(value_buffer, &error, 10);
if (*error != '\0')
{
return -SW_MYSQL_ERR_CONVLONG;
}
add_assoc_long(row_array, client->response.columns[i].name, row.sbigint);
#else
sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1);
#endif
break;
case SW_MYSQL_TYPE_FLOAT:
#ifdef SW_MYSQL_STRICT_TYPE
memcpy(value_buffer, buf + read_n, len);
value_buffer[len] = 0;
row.mfloat = strtof(value_buffer, &error);
if (*error != '\0')
{
return -SW_MYSQL_ERR_CONVFLOAT;
}
add_assoc_double(row_array, client->response.columns[i].name, row.mfloat);
#else
sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1);
#endif
break;
case SW_MYSQL_TYPE_DOUBLE:
#ifdef SW_MYSQL_STRICT_TYPE
memcpy(value_buffer, buf + read_n, len);
value_buffer[len] = 0;
row.mdouble = strtod(value_buffer, &error);
if (*error != '\0')
{
return -SW_MYSQL_ERR_CONVDOUBLE;
}
add_assoc_double(row_array, client->response.columns[i].name, row.mdouble);
#else
sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1);
#endif
break;
}
read_n += len;
}
add_next_index_zval(result_array, row_array);
#if PHP_MAJOR_VERSION > 5
if (row_array)
{
efree(row_array);
}
#endif
return read_n;
}
static sw_inline int mysql_read_eof(mysql_client *client, char *buffer, int n_buf)
{
//EOF, length (3byte) + id(1byte) + 0xFE + warning(2byte) + status(2byte)
if (n_buf < 9)
{
client->response.wait_recv = 1;
return SW_ERR;
}
client->response.packet_length = mysql_uint3korr(buffer);
client->response.packet_number = buffer[3];
//not EOF packet
uint8_t eof = buffer[4];
if (eof != 0xfe)
{
return SW_ERR;
}
client->response.warnings = mysql_uint2korr(buffer + 5);
client->response.status_code = mysql_uint2korr(buffer + 7);
return SW_OK;
}
static sw_inline int mysql_read_columns(mysql_client *client)
{
char *buffer = client->buffer->str + client->buffer->offset;
uint32_t n_buf = client->buffer->length - client->buffer->offset;
int ret;
for (; client->response.index_column < client->response.num_column; client->response.index_column++)
{
if (n_buf < 4)
{
return SW_ERR;
}
client->response.packet_length = mysql_uint3korr(buffer);
//no enough data
if (n_buf - 4 < client->response.packet_length)
{
return SW_ERR;
}
client->response.packet_number = buffer[3];
buffer += 4;
n_buf -= 4;
ret = mysql_decode_field(buffer, client->response.packet_length, &client->response.columns[client->response.index_column]);
if (ret > 0)
{
buffer += client->response.packet_length;
n_buf -= client->response.packet_length;
client->buffer->offset += (client->response.packet_length + 4);
}
else
{
swWarn("mysql_decode_field failed, code=%d.", ret);
break;
}
}
if (mysql_read_eof(client, buffer, n_buf) < 0)
{
return SW_ERR;
}
buffer += 9;
n_buf -= 9;
zval *result_array = client->response.result_array;
if (!result_array)
{
SW_ALLOC_INIT_ZVAL(result_array);
array_init(result_array);
client->response.result_array = result_array;
}
client->buffer->offset += buffer - (client->buffer->str + client->buffer->offset);
return SW_OK;
}
static sw_inline int mysql_read_rows(mysql_client *client)
{
char *buffer = client->buffer->str + client->buffer->offset;
uint32_t n_buf = client->buffer->length - client->buffer->offset;
int ret;
//RecordSet parse
while (n_buf > 0)
{
if (n_buf < 4)
{
client->response.wait_recv = 1;
return SW_ERR;
}
//RecordSet end
else if (n_buf == 9 && mysql_read_eof(client, buffer, n_buf) == 0)
{
if (client->response.columns)
{
int i;
for (i = 0; i < client->response.num_column; i++)
{
if (client->response.columns[i].buffer)
{
efree(client->response.columns[i].buffer);
client->response.columns[i].buffer = NULL;
}
}
efree(client->response.columns);
}
return SW_OK;
}
client->response.packet_length = mysql_uint3korr(buffer);
client->response.packet_number = buffer[3];
buffer += 4;
n_buf -= 4;
//no enough data
if (n_buf < client->response.packet_length)
{
client->response.wait_recv = 1;
return SW_ERR;
}
//decode
ret = mysql_decode_row(client, buffer, client->response.packet_length);
if (ret < 0)
{
break;
}
//next row
client->response.num_row++;
buffer += client->response.packet_length;
n_buf -= client->response.packet_length;
client->buffer->offset += client->response.packet_length + 4;
}
return SW_ERR;
}
#endif /* SWOOLE_MYSQL_H_ */
C
1
https://gitee.com/fang666/swoole.git
git@gitee.com:fang666/swoole.git
fang666
swoole
swoole-src
master

搜索帮助