Added multi statement support for mysql
This commit is contained in:
parent
21f99ce4da
commit
1f14378ad4
@ -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.
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user