Correcao na alocacao/desalocacao do vetor de colunas.
Correcao na lista de tipos de colunas tratados.
This commit is contained in:
parent
75bbc61cbe
commit
b6e9dbd8bc
189
src/ls_oci8.c
189
src/ls_oci8.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
** LuaSQL, Oracle driver
|
||||
** Authors: Tomas Guisasola, Leonardo Godinho
|
||||
** $Id: ls_oci8.c,v 1.4 2003/05/30 10:04:59 tomas Exp $
|
||||
** $Id: ls_oci8.c,v 1.5 2003/05/30 15:18:08 tomas Exp $
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
@ -46,11 +46,11 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ub2 type;
|
||||
ub4 max;
|
||||
sb2 null;
|
||||
OCIDefine *define;
|
||||
void *buffer;
|
||||
ub2 type; /* database type */
|
||||
ub2 max; /* maximum size */
|
||||
sb2 null; /* is null? */
|
||||
OCIDefine *define; /* define handle */
|
||||
void *buffer; /* data buffer */
|
||||
} col_info;
|
||||
|
||||
|
||||
@ -60,9 +60,10 @@ typedef struct {
|
||||
int numcols; /* number of columns */
|
||||
int colnames, coltypes; /* reference to column information tables */
|
||||
int curr_tuple; /* next tuple to be read */
|
||||
OCIStmt *stmthp;
|
||||
char *text; /* text of SQL statement */
|
||||
OCIStmt *stmthp; /* statement handle */
|
||||
OCIError *errhp; /* !!! */
|
||||
col_info *cols;
|
||||
col_info *cols; /* array of columns */
|
||||
} cur_data;
|
||||
|
||||
|
||||
@ -148,6 +149,97 @@ int checkerr (lua_State *L, sword status, OCIError *errhp) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Alloc buffers for column values.
|
||||
*/
|
||||
static int alloc_column_buffer (lua_State *L, cur_data *cur, int i) {
|
||||
/* column index ranges from 1 to numcols */
|
||||
/* C array index ranges from 0 to numcols-1 */
|
||||
col_info *col = &(cur->cols[i-1]);
|
||||
OCIParam *param;
|
||||
|
||||
ASSERT (L, OCIParamGet (cur->stmthp, OCI_HTYPE_STMT, cur->errhp,
|
||||
(dvoid **)¶m, i), cur->errhp);
|
||||
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM,
|
||||
(dvoid *)&(col->type), (ub4 *)0, OCI_ATTR_DATA_TYPE,
|
||||
cur->errhp), cur->errhp);
|
||||
switch (col->type) {
|
||||
case SQLT_CHR:
|
||||
case SQLT_STR:
|
||||
case SQLT_VCS:
|
||||
case SQLT_AFC:
|
||||
case SQLT_AVC:
|
||||
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM,
|
||||
(dvoid *)&(col->max), (ub4 *)0, OCI_ATTR_DATA_SIZE,
|
||||
cur->errhp), cur->errhp);
|
||||
col->buffer = calloc (col->max + 1, sizeof(char));
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp, &(col->define),
|
||||
cur->errhp, (ub4)i, col->buffer, col->max,
|
||||
SQLT_STR, (dvoid *)&(col->null), (ub2 *)0,
|
||||
(ub2 *)0, (ub4) OCI_DEFAULT), cur->errhp);
|
||||
break;
|
||||
case SQLT_NUM:
|
||||
col->buffer = malloc (sizeof(int));
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp, &(col->define),
|
||||
cur->errhp, (ub4)i, col->buffer, (sb4)sizeof(int),
|
||||
SQLT_INT, (dvoid *)&(col->null), (ub2 *)0,
|
||||
(ub2 *)0, (ub4) OCI_DEFAULT), cur->errhp);
|
||||
break;
|
||||
case SQLT_CLOB: {
|
||||
env_data *env;
|
||||
conn_data *conn;
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn);
|
||||
conn = (conn_data *)lua_touserdata (L, -1);
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env);
|
||||
env = (env_data *)lua_touserdata (L, -1);
|
||||
lua_pop (L, 2);
|
||||
ASSERT (L, OCIDescriptorAlloc (env->envhp,
|
||||
&(col->buffer), OCI_DTYPE_LOB, (size_t)0,
|
||||
(dvoid **)0), cur->errhp);
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp,
|
||||
&(col->define), cur->errhp, (ub4)i,
|
||||
&(col->buffer), (sb4)sizeof(dvoid *),
|
||||
SQLT_CLOB, (dvoid *)&(col->null),
|
||||
(ub2 *)0, (ub2 *)0, OCI_DEFAULT),
|
||||
cur->errhp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
luaL_error (L, LUASQL_PREFIX"invalid type %d #%d", col->type, i);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Deallocate column buffers.
|
||||
*/
|
||||
static int free_column_buffers (lua_State *L, cur_data *cur, int i) {
|
||||
col_info *col = &(cur->cols[i-1]);
|
||||
switch (col->type) {
|
||||
case SQLT_NUM:
|
||||
/* case SQLT_FLT: */
|
||||
case SQLT_CHR:
|
||||
case SQLT_STR:
|
||||
case SQLT_VCS:
|
||||
case SQLT_AFC:
|
||||
case SQLT_AVC:
|
||||
free(col->buffer);
|
||||
break;
|
||||
case SQLT_CLOB:
|
||||
ASSERT (L, OCIDescriptorFree (col->buffer, OCI_DTYPE_LOB),
|
||||
cur->errhp);
|
||||
break;
|
||||
default:
|
||||
luaL_error (L, LUASQL_PREFIX"unknown type");
|
||||
/*printf("free_buffers(): Unknow Type: %d count: %d\n",cols.item[count].type, count );*/
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Get another row of the given cursor.
|
||||
*/
|
||||
@ -196,19 +288,28 @@ static int cur_fetch (lua_State *L) {
|
||||
** Return 1
|
||||
*/
|
||||
static int cur_close (lua_State *L) {
|
||||
int i;
|
||||
conn_data *conn;
|
||||
cur_data *cur = (cur_data *)luaL_checkudata (L, 1, LUASQL_CURSOR_OCI8);
|
||||
luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected");
|
||||
if (cur->closed)
|
||||
return 0;
|
||||
|
||||
/* Deallocate buffers. */
|
||||
for (i = 1; i <= cur->numcols; i++) {
|
||||
int ret = free_column_buffers (L, cur, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
free (cur->cols);
|
||||
free (cur->text);
|
||||
|
||||
/* Nullify structure fields. */
|
||||
cur->closed = 1;
|
||||
if (cur->stmthp)
|
||||
OCIHandleFree ((dvoid *)cur->stmthp, OCI_HTYPE_STMT);
|
||||
if (cur->errhp)
|
||||
OCIHandleFree ((dvoid *)cur->errhp, OCI_HTYPE_ERROR);
|
||||
free (cur->cols);
|
||||
/* Decrement cursor counter on connection object */
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn);
|
||||
conn = lua_touserdata (L, -1);
|
||||
@ -247,6 +348,7 @@ static int cur_colinfo (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int cur_getcolnames (lua_State *L) {
|
||||
cur_data *cur = getcursor (L);
|
||||
if (cur->colnames != LUA_NOREF)
|
||||
@ -263,6 +365,7 @@ static int cur_getcolnames (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int cur_getcoltypes (lua_State *L) {
|
||||
cur_data *cur = getcursor (L);
|
||||
if (cur->coltypes != LUA_NOREF)
|
||||
@ -359,65 +462,10 @@ static char *oracle2luatypa (ub2 data_type) {
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Obtain column information.
|
||||
*/
|
||||
static int prepare_buffers (lua_State *L, cur_data *cur, int i) {
|
||||
OCIParam *param;
|
||||
|
||||
ASSERT (L, OCIParamGet (cur->stmthp, OCI_HTYPE_STMT, cur->errhp,
|
||||
(dvoid **)¶m, i), cur->errhp);
|
||||
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM,
|
||||
(dvoid *)&(cur->cols[i].type), (ub4 *)0, OCI_ATTR_DATA_TYPE,
|
||||
cur->errhp), cur->errhp);
|
||||
switch (cur->cols[i].type) {
|
||||
case SQLT_CHR:
|
||||
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM,
|
||||
(dvoid *)&(cur->cols[i].max), (ub4 *)0, OCI_ATTR_DATA_SIZE,
|
||||
cur->errhp), cur->errhp);
|
||||
cur->cols[i].buffer = calloc (cur->cols[i].max + 1, sizeof(char));
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp, &(cur->cols[i].define),
|
||||
cur->errhp, (ub4)i, cur->cols[i].buffer, cur->cols[i].max,
|
||||
SQLT_STR, (dvoid *)&(cur->cols[i].null), (ub2 *)0,
|
||||
(ub2 *)0, (ub4) OCI_DEFAULT), cur->errhp);
|
||||
break;
|
||||
case SQLT_NUM:
|
||||
cur->cols[i].buffer = malloc (sizeof(int));
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp, &(cur->cols[i].define),
|
||||
cur->errhp, (ub4)i, cur->cols[i].buffer, (sb4)sizeof(int),
|
||||
SQLT_INT, (dvoid *)&(cur->cols[i].null), (ub2 *)0,
|
||||
(ub2 *)0, (ub4) OCI_DEFAULT), cur->errhp);
|
||||
break;
|
||||
case SQLT_CLOB: {
|
||||
env_data *env;
|
||||
conn_data *conn;
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn);
|
||||
conn = (conn_data *)lua_touserdata (L, -1);
|
||||
lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env);
|
||||
env = (env_data *)lua_touserdata (L, -1);
|
||||
lua_pop (L, 2);
|
||||
ASSERT (L, OCIDescriptorAlloc (env->envhp,
|
||||
&(cur->cols[i].buffer), OCI_DTYPE_LOB, (size_t)0,
|
||||
(dvoid **)0), cur->errhp);
|
||||
ASSERT (L, OCIDefineByPos (cur->stmthp,
|
||||
&(cur->cols[i].define), cur->errhp, (ub4)i,
|
||||
&(cur->cols[i].buffer), (sb4)sizeof(dvoid *),
|
||||
SQLT_CLOB, (dvoid *)&(cur->cols[i].null),
|
||||
(ub2 *)0, (ub2 *)0, OCI_DEFAULT),
|
||||
cur->errhp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Create a new Cursor object and push it on top of the stack.
|
||||
*/
|
||||
static int create_cursor (lua_State *L, int o, conn_data *conn, OCIStmt *stmt) {
|
||||
static int create_cursor (lua_State *L, int o, conn_data *conn, OCIStmt *stmt, const char *text) {
|
||||
int i;
|
||||
env_data *env;
|
||||
cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data));
|
||||
@ -432,6 +480,8 @@ static int create_cursor (lua_State *L, int o, conn_data *conn, OCIStmt *stmt) {
|
||||
cur->curr_tuple = 0;
|
||||
cur->stmthp = stmt;
|
||||
cur->errhp = NULL;
|
||||
cur->cols = NULL;
|
||||
cur->text = strdup (text);
|
||||
lua_pushvalue (L, o);
|
||||
cur->conn = luaL_ref (L, LUA_REGISTRYINDEX);
|
||||
|
||||
@ -449,7 +499,7 @@ static int create_cursor (lua_State *L, int o, conn_data *conn, OCIStmt *stmt) {
|
||||
cur->cols = (col_info *)malloc (sizeof(col_info) * cur->numcols);
|
||||
/* define output variables */
|
||||
for (i = 1; i <= cur->numcols; i++) {
|
||||
int ret = prepare_buffers (L, cur, i);
|
||||
int ret = alloc_column_buffer (L, cur, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -503,17 +553,20 @@ static int conn_execute (lua_State *L) {
|
||||
/* execute statement */
|
||||
status = OCIStmtExecute (conn->svchp, stmthp, conn->errhp, iters,
|
||||
(ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, mode);
|
||||
if (status && (status != OCI_NO_DATA))
|
||||
if (status && (status != OCI_NO_DATA)) {
|
||||
OCIHandleFree ((dvoid *)stmthp, OCI_HTYPE_STMT);
|
||||
return checkerr (L, status, conn->errhp);
|
||||
}
|
||||
if (type == OCI_STMT_SELECT) {
|
||||
/* create cursor */
|
||||
return create_cursor (L, 1, conn, stmthp);
|
||||
return create_cursor (L, 1, conn, stmthp, statement);
|
||||
} else {
|
||||
/* return number of rows */
|
||||
int rows_affected;
|
||||
ASSERT (L, OCIAttrGet ((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT,
|
||||
(dvoid *)&rows_affected, (ub4 *)0,
|
||||
(ub4)OCI_ATTR_ROW_COUNT, conn->errhp), conn->errhp);
|
||||
OCIHandleFree ((dvoid *)stmthp, OCI_HTYPE_STMT);
|
||||
lua_pushnumber (L, rows_affected);
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user