Merge branch 'master' of github.com:keplerproject/luasql
This commit is contained in:
commit
48d33e4109
@ -41,6 +41,7 @@ typedef struct {
|
||||
env_data* env; /* the DB enviroment this is in */
|
||||
conn_data* conn; /* the DB connection this cursor is from */
|
||||
isc_stmt_handle stmt; /* the statement handle */
|
||||
int stmt_type; /* the type of the statment */
|
||||
XSQLDA *out_sqlda; /* the cursor data array */
|
||||
} cur_data;
|
||||
|
||||
@ -126,6 +127,31 @@ static void free_cur(cur_data* cur)
|
||||
free(cur->out_sqlda);
|
||||
}
|
||||
|
||||
/*
|
||||
** Shuts down a cursor
|
||||
*/
|
||||
static int cur_shut(lua_State *L, cur_data *cur)
|
||||
{
|
||||
isc_dsql_free_statement(cur->env->status_vector, &cur->stmt,
|
||||
DSQL_close);
|
||||
if ( CHECK_DB_ERROR(cur->env->status_vector) ) {
|
||||
return return_db_error(L, cur->env->status_vector);
|
||||
}
|
||||
|
||||
/* free the cursor data */
|
||||
free_cur(cur);
|
||||
|
||||
/* remove cursor from lock count and check if statment can be unregistered */
|
||||
cur->closed = 1;
|
||||
--cur->conn->lock;
|
||||
|
||||
/* check if connection can be unregistered */
|
||||
if(cur->conn->lock == 0)
|
||||
lua_unregisterobj(L, cur->conn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check for valid environment.
|
||||
*/
|
||||
@ -300,7 +326,7 @@ static int conn_execute (lua_State *L) {
|
||||
|
||||
XSQLVAR *var;
|
||||
long dtype;
|
||||
int i, n, count, stmt_type;
|
||||
int i, n, count;
|
||||
|
||||
cur_data cur;
|
||||
|
||||
@ -328,14 +354,22 @@ static int conn_execute (lua_State *L) {
|
||||
}
|
||||
|
||||
/* what type of SQL statement is it? */
|
||||
stmt_type = get_statement_type(&cur);
|
||||
if(stmt_type < 0) {
|
||||
cur.stmt_type = get_statement_type(&cur);
|
||||
if(cur.stmt_type < 0) {
|
||||
free(cur.out_sqlda);
|
||||
return return_db_error(L, conn->env->status_vector);
|
||||
}
|
||||
|
||||
/* an unsupported SQL statement (something like COMMIT) */
|
||||
if(stmt_type > 5) {
|
||||
switch(cur.stmt_type) {
|
||||
case isc_info_sql_stmt_select:
|
||||
case isc_info_sql_stmt_insert:
|
||||
case isc_info_sql_stmt_update:
|
||||
case isc_info_sql_stmt_delete:
|
||||
case isc_info_sql_stmt_ddl:
|
||||
case isc_info_sql_stmt_exec_procedure:
|
||||
break;
|
||||
default:
|
||||
free(cur.out_sqlda);
|
||||
return luasql_faildirect(L, "unsupported SQL statement");
|
||||
}
|
||||
@ -411,7 +445,7 @@ static int conn_execute (lua_State *L) {
|
||||
}
|
||||
|
||||
/* if autocommit is set and it's a non SELECT query, commit change */
|
||||
if(conn->autocommit != 0 && stmt_type > 1) {
|
||||
if(conn->autocommit != 0 && cur.stmt_type > 1) {
|
||||
isc_commit_retaining(conn->env->status_vector, &conn->transaction);
|
||||
if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
|
||||
free_cur(&cur);
|
||||
@ -700,12 +734,18 @@ static void push_column(lua_State *L, int i, cur_data *cur) {
|
||||
*/
|
||||
static int cur_fetch (lua_State *L) {
|
||||
ISC_STATUS fetch_stat;
|
||||
int i;
|
||||
cur_data *cur = getcursor(L,1);
|
||||
int i, res;
|
||||
cur_data *cur = (cur_data *)luaL_checkudata (L, 1, LUASQL_CURSOR_FIREBIRD);
|
||||
const char *opts = luaL_optstring (L, 3, "n");
|
||||
int num = strchr(opts, 'n') != NULL;
|
||||
int alpha = strchr(opts, 'a') != NULL;
|
||||
|
||||
/* check cursor status */
|
||||
luaL_argcheck (L, cur != NULL, 1, "cursor expected");
|
||||
if (cur->closed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) {
|
||||
if (lua_istable (L, 2)) {
|
||||
/* remove the option string */
|
||||
@ -715,13 +755,13 @@ static int cur_fetch (lua_State *L) {
|
||||
for (i = 0; i < cur->out_sqlda->sqld; i++) {
|
||||
push_column(L, i, cur);
|
||||
|
||||
if( num ) {
|
||||
if (num) {
|
||||
lua_pushnumber(L, i+1);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, 2);
|
||||
}
|
||||
|
||||
if( alpha ) {
|
||||
if (alpha) {
|
||||
lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, 2);
|
||||
@ -731,14 +771,22 @@ static int cur_fetch (lua_State *L) {
|
||||
}
|
||||
|
||||
/* returning given table */
|
||||
return 1;
|
||||
res = 1;
|
||||
} else {
|
||||
for (i = 0; i < cur->out_sqlda->sqld; i++)
|
||||
push_column(L, i, cur);
|
||||
|
||||
/* returning a list of values */
|
||||
return cur->out_sqlda->sqld;
|
||||
res = cur->out_sqlda->sqld;
|
||||
}
|
||||
|
||||
/* close cursor for procedures/returnings as they (currently) only
|
||||
return one result, and error on subsequent fetches */
|
||||
if (cur->stmt_type == isc_info_sql_stmt_exec_procedure) {
|
||||
cur_shut(L, cur);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* isc_dsql_fetch returns 100 if no more rows remain to be retrieved
|
||||
@ -839,22 +887,13 @@ static int cur_coltypes (lua_State *L) {
|
||||
static int cur_close (lua_State *L) {
|
||||
cur_data *cur = (cur_data *)luaL_checkudata(L,1,LUASQL_CURSOR_FIREBIRD);
|
||||
luaL_argcheck (L, cur != NULL, 1, "cursor expected");
|
||||
int shut_res;
|
||||
|
||||
if(cur->closed == 0) {
|
||||
isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop);
|
||||
if ( CHECK_DB_ERROR(cur->env->status_vector) )
|
||||
return return_db_error(L, cur->env->status_vector);
|
||||
|
||||
/* free the cursor data */
|
||||
free_cur(cur);
|
||||
|
||||
/* remove cursor from lock count */
|
||||
cur->closed = 1;
|
||||
--cur->conn->lock;
|
||||
|
||||
/* check if connection can be unregistered */
|
||||
if(cur->conn->lock == 0)
|
||||
lua_unregisterobj(L, cur->conn);
|
||||
shut_res = cur_shut(L, cur);
|
||||
if(shut_res > 0) {
|
||||
return shut_res;
|
||||
}
|
||||
|
||||
/* return sucsess */
|
||||
lua_pushboolean(L, 1);
|
||||
@ -873,18 +912,7 @@ static int cur_gc (lua_State *L) {
|
||||
luaL_argcheck (L, cur != NULL, 1, "cursor expected");
|
||||
|
||||
if(cur->closed == 0) {
|
||||
isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop);
|
||||
|
||||
/* free the cursor data */
|
||||
free_cur(cur);
|
||||
|
||||
/* remove cursor from lock count */
|
||||
cur->closed = 1;
|
||||
--cur->conn->lock;
|
||||
|
||||
/* check if connection can be unregistered */
|
||||
if(cur->conn->lock == 0)
|
||||
lua_unregisterobj(L, cur->conn);
|
||||
cur_shut(L, cur);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
763
src/ls_odbc.c
763
src/ls_odbc.c
File diff suppressed because it is too large
Load Diff
@ -19,9 +19,36 @@ function create_table ()
|
||||
end
|
||||
|
||||
function drop_table ()
|
||||
-- Firebird prefers to keep DDL stuff (CREATE TABLE, etc.)
|
||||
-- seperate. So we need a new transaction i.e. connection
|
||||
-- to work in
|
||||
assert(CONN:close ())
|
||||
CONN = assert(ENV:connect (datasource, username, password))
|
||||
orig_drop_table()
|
||||
CONN:commit()
|
||||
end
|
||||
|
||||
table.insert (CONN_METHODS, "escape")
|
||||
table.insert (EXTENSIONS, escape)
|
||||
|
||||
-- Check RETURNING support
|
||||
table.insert (EXTENSIONS, function()
|
||||
local cur = assert (CONN:execute[[
|
||||
EXECUTE BLOCK
|
||||
RETURNS (A INTEGER, B INTEGER)
|
||||
AS
|
||||
BEGIN
|
||||
A = 123;
|
||||
B = 321;
|
||||
SUSPEND;
|
||||
END
|
||||
]])
|
||||
|
||||
local f1, f2 = cur:fetch ()
|
||||
assert2 (123, f1)
|
||||
assert2 (321, f2)
|
||||
cur:close ()
|
||||
|
||||
io.write (" returning")
|
||||
end)
|
||||
|
||||
|
@ -14,10 +14,11 @@ DROP_TABLE_RETURN_VALUE = -1
|
||||
table.insert (EXTENSIONS, function ()
|
||||
assert2 (CREATE_TABLE_RETURN_VALUE, CONN:execute"create table test_dt (f1 integer, f2 varchar(30), f3 bit )")
|
||||
-- Inserts a number, a string value and a "bit" value.
|
||||
assert2 (1, CONN:execute"insert into test_dt values (10, 'ABCDE', 1)")
|
||||
assert2 (1, CONN:execute("insert into test_dt values (?, ?, ?)", 10, "ABCDE", true))
|
||||
|
||||
-- Checks the results with the inserted values.
|
||||
local cur = CUR_OK (CONN:execute"select * from test_dt")
|
||||
local stmt = assert(CONN:prepare"select * from test_dt where f1 = ?")
|
||||
local cur = CUR_OK (stmt:execute(10))
|
||||
local row, err = cur:fetch ({}, "a")
|
||||
assert2 ("table", type(row), err)
|
||||
|
||||
@ -25,6 +26,9 @@ table.insert (EXTENSIONS, function ()
|
||||
assert2 ("ABCDE", row.f2, "Wrong string representation")
|
||||
assert2 (true, row.f3, "Wrong bit representation")
|
||||
|
||||
cur:close()
|
||||
stmt:close()
|
||||
|
||||
-- Drops the table
|
||||
assert2 (DROP_TABLE_RETURN_VALUE, CONN:execute("drop table test_dt") )
|
||||
assert2 (DROP_TABLE_RETURN_VALUE, CONN:execute("drop table test_dt") )
|
||||
end)
|
||||
|
Loading…
x
Reference in New Issue
Block a user