Added multi statement support for mysql

This commit is contained in:
Luca Lindhorst 2018-12-11 15:05:52 +01:00
parent 21f99ce4da
commit 1f14378ad4
2 changed files with 86 additions and 3 deletions

View File

@ -381,11 +381,31 @@ the MySQL driver also offers these extra features:</p>
<dt><strong><code>cur:seek(row_number)</code></strong></dt>
<dd>Seeks to an arbitrary row in a query result set. The number of the first row is 1.<br/>
See also: <a href="#cursor_object">cursor objects</a><br/>
Returns: nothing.</dd>
Returns: nothing.</dd>
<a name="mysql_next_result"></a>
<dt><strong><code>cur:nextresult()</code></strong></dt>
<dd>Retrieves the next result set, if another result is available (e.g. multiple statements)<br/>
See also: <a href="#cursor_object">cursor objects</a><br/>
Returns: true, if next result was selected. false and -1 if no other result is available. false, errno and error message, if an error occured.<br/>
To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection.
Be aware that you need to iterate over all results otherwise you will receive an "out of sync" error.
</dd>
<a name="mysql_has_next_result"></a>
<dt><strong><code>cur:hasnextresult()</code></strong></dt>
<dd>Checks if next result is available<br/>
See also: <a href="#cursor_object">cursor objects</a><br/>
Returns: true or false<br/>
To use it you need to pass the <code>CLIENT_MULTI_STATEMENTS = 1<<16</code> flag on connection.
Be aware that you need to iterate over all results otherwise you will receive an "out of sync" error.
</dd>
</dl>
<p>Notes:</p>
<p>I </p>
<p>This driver is compatible with versions 4.0, 4.1 and 5.0 of the
MySQL API. Only from version 4.1 MySQL provides support for transactions by using
BDB or INNODB tables.

View File

@ -76,6 +76,7 @@ typedef struct {
int numcols; /* number of columns */
int colnames, coltypes; /* reference to column information tables */
MYSQL_RES *my_res;
MYSQL *my_conn;
} cur_data;
LUASQL_API int luaopen_luasql_mysql (lua_State *L);
@ -248,6 +249,64 @@ static int cur_fetch (lua_State *L) {
}
}
/*
** Get the next result from multiple statements
*/
static int cur_next_result (lua_State *L) {
cur_data *cur = getcursor (L);
MYSQL* con = cur->my_conn;
int status;
if(mysql_more_results(con)){
status = mysql_next_result(con);
if(status == 0){
mysql_free_result(cur->my_res);
cur->my_res = mysql_store_result(con);
if(cur->my_res != NULL){
lua_pushboolean(L, 1);
return 1;
}else{
lua_pushboolean(L, 0);
lua_pushinteger(L, mysql_errno(con));
lua_pushstring(L, mysql_error(con));
return 3;
}
}else{
lua_pushboolean(L, 0);
lua_pushinteger(L, status);
switch(status){
case CR_COMMANDS_OUT_OF_SYNC:
lua_pushliteral(L, "CR_COMMANDS_OUT_OF_SYNC");
break;
case CR_SERVER_GONE_ERROR:
lua_pushliteral(L, "CR_SERVER_GONE_ERROR");
break;
case CR_SERVER_LOST:
lua_pushliteral(L, "CR_SERVER_LOST");
break;
case CR_UNKNOWN_ERROR:
lua_pushliteral(L, "CR_UNKNOWN_ERROR");
break;
default:
lua_pushliteral(L, "Unknown");
}
return 3;
}
}else{
lua_pushboolean(L, 0);
lua_pushinteger(L, -1);
return 2;
}
}
/*
** Check if next result is available
*/
static int cur_has_next_result (lua_State *L) {
cur_data *cur = getcursor (L);
lua_pushboolean(L, mysql_more_results(cur->my_conn));
return 1;
}
/*
** Cursor object collector function
@ -336,7 +395,7 @@ static int cur_seek (lua_State *L) {
/*
** Create a new Cursor object and push it on top of the stack.
*/
static int create_cursor (lua_State *L, int conn, MYSQL_RES *result, int cols) {
static int create_cursor (lua_State *L, MYSQL *my_conn, int conn, MYSQL_RES *result, int cols) {
cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
luasql_setmeta (L, LUASQL_CURSOR_MYSQL);
@ -347,6 +406,7 @@ static int create_cursor (lua_State *L, int conn, MYSQL_RES *result, int cols) {
cur->colnames = LUA_NOREF;
cur->coltypes = LUA_NOREF;
cur->my_res = result;
cur->my_conn = my_conn;
lua_pushvalue (L, conn);
cur->conn = luaL_ref (L, LUA_REGISTRYINDEX);
@ -437,7 +497,7 @@ static int conn_execute (lua_State *L) {
unsigned int num_cols = mysql_field_count(conn->my_conn);
if (res) { /* tuples returned */
return create_cursor (L, 1, res, num_cols);
return create_cursor (L, conn->my_conn, 1, res, num_cols);
}
else { /* mysql_use_result() returned nothing; should it have? */
if(num_cols == 0) { /* no tuples returned */
@ -462,6 +522,7 @@ static int conn_commit (lua_State *L) {
}
/*
** Rollback the current transaction.
*/
@ -604,6 +665,8 @@ static void create_metatables (lua_State *L) {
{"fetch", cur_fetch},
{"numrows", cur_numrows},
{"seek", cur_seek},
{"nextresult", cur_next_result},
{"hasnextresult", cur_has_next_result},
{NULL, NULL},
};
luasql_createmeta (L, LUASQL_ENVIRONMENT_MYSQL, environment_methods);