2016-04-07 30 views
0

Bu kodda LuaSQL kodundan (LuaSQL kaynak dosyasındaki ls_OCI8.c dosyasında) ne olduğunu bilmek istiyorum.LuaSQL kodunda C/C++ değerini atama

Bu kod parçasının ne yaptığını anlamak istiyorum (daha spesifik olmak gerekirse: ASSERT işlevinin ne yaptığını anlamak istiyorum). Bildiğim kadarıyla, standart standart fonksiyon: void assert (int expression). Üç parametresi yok.

ASSERT (L, OCIParamGet (cur->stmthp, OCI_HTYPE_STMT, cur->errhp, 
     (dvoid **)&param, i), cur->errhp); 
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM, 
     (dvoid *)&(name), (ub4 *)&(col->namelen), 
     OCI_ATTR_NAME, cur->errhp), cur->errhp); 
    copy_column_name (col, name); 
ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM, 
     (dvoid *)&(col->type), (ub4 *)0, OCI_ATTR_DATA_TYPE, 
     cur->errhp), cur->errhp); 

tüm kaynak kodu: önceden

/* 
** LuaSQL, Oracle driver 
** Authors: Tomas Guisasola, Leonardo Godinho 
** See Copyright Notice in license.html 
** $Id: ls_oci8.c,v 1.31 2009/02/07 23:16:23 tomas Exp $ 
*/ 

#include <assert.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 

#include "oci.h" 
#include "oratypes.h" 
#include "ociapr.h" 
#include "ocidem.h" 

#include "lua.h" 
#include "lauxlib.h" 

#include "luasql.h" 

#define LUASQL_ENVIRONMENT_OCI8 "Oracle environment" 
#define LUASQL_CONNECTION_OCI8 "Oracle connection" 
#define LUASQL_CURSOR_OCI8 "Oracle cursor" 


typedef struct { 
    short   closed; 
    int   conn_counter; 
    OCIEnv  *envhp; 
    OCIError  *errhp; /* !!! */ 
} env_data; 


typedef struct { 
    short   closed; 
    short   loggedon; 
    short   auto_commit;  /* 0 for manual commit */ 
    int   cur_counter; 
    int   env;    /* reference to environment */ 
    OCISvcCtx *svchp;    /* service handle */ 
    OCIError  *errhp; /* !!! */ 
} conn_data; 


typedef union { 
    int  i; 
    char *s; 
    double d; 
} column_value; 


typedef struct { 
    ub2   type; /* database type */ 
    text   *name; /* column name */ 
    ub4   namelen; /* column name length */ 
    ub2   max;  /* maximum size */ 
    sb2   null; /* is null? */ 
    OCIDefine *define; /* define handle */ 
    column_value val; 
} column_data; 


typedef struct { 
    short   closed; 
    int   conn;    /* reference to connection */ 
    int   numcols;   /* number of columns */ 
    int   colnames, coltypes; /* reference to column info tables */ 
    int   curr_tuple;   /* next tuple to be read */ 
    char   *text;    /* text of SQL statement */ 
    OCIStmt  *stmthp;    /* statement handle */ 
    OCIError  *errhp; /* !!! */ 
    column_data *cols;    /* array of columns */ 
} cur_data; 


int checkerr (lua_State *L, sword status, OCIError *errhp); 
#define ASSERT(L,exp,err) {sword s = exp; if (s) return checkerr (L, s, err);} 
LUASQL_API int luaopen_luasql_oci8 (lua_State *L); 


/* 
** Check for valid environment. 
*/ 
static env_data *getenvironment (lua_State *L) { 
    env_data *env = (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_OCI8); 
    luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected"); 
    luaL_argcheck (L, !env->closed, 1, LUASQL_PREFIX"environment is closed"); 
    return env; 
} 


/* 
** Check for valid connection. 
*/ 
static conn_data *getconnection (lua_State *L) { 
    conn_data *conn = (conn_data *)luaL_checkudata (L, 1, LUASQL_CONNECTION_OCI8); 
    luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected"); 
    luaL_argcheck (L, !conn->closed, 1, LUASQL_PREFIX"connection is closed"); 
    return conn; 
} 


/* 
** Check for valid cursor. 
*/ 
static cur_data *getcursor (lua_State *L) { 
    cur_data *cur = (cur_data *)luaL_checkudata (L, 1, LUASQL_CURSOR_OCI8); 
    luaL_argcheck (L, cur != NULL, 1, LUASQL_PREFIX"cursor expected"); 
    luaL_argcheck (L, !cur->closed, 1, LUASQL_PREFIX"cursor is closed"); 
    return cur; 
} 


/* 
** Push nil plus an error message. 
*/ 
int checkerr (lua_State *L, sword status, OCIError *errhp) { 
    lua_pushnil (L); 
    switch (status) { 
     case OCI_SUCCESS: 
      lua_pushnil (L); /* !!!!!!!!!!!!! */ 
      break; 
     case OCI_SUCCESS_WITH_INFO: 
      lua_pushstring (L, LUASQL_PREFIX"Success with info!"); 
      break; 
     case OCI_NEED_DATA: 
      lua_pushstring (L, LUASQL_PREFIX"OCI_NEED_DATA"); 
      break; 
     case OCI_NO_DATA: 
      lua_pushstring (L, LUASQL_PREFIX"OCI_NODATA"); 
      break; 
     case OCI_ERROR: { 
      text errbuf[512]; 
      sb4 errcode = 0; 
      OCIErrorGet (errhp, (ub4) 1, (text *) NULL, &errcode, 
       errbuf, (ub4) sizeof (errbuf), OCI_HTYPE_ERROR); 
      lua_pushstring (L, LUASQL_PREFIX); 
      lua_pushstring (L, errbuf); 
      lua_concat (L, 2); 
      break; 
     } 
     case OCI_INVALID_HANDLE: 
      lua_pushstring (L, LUASQL_PREFIX"OCI_INVALID_HANDLE"); 
      break; 
     case OCI_STILL_EXECUTING: 
      lua_pushstring (L, LUASQL_PREFIX"OCI_STILL_EXECUTE"); 
      break; 
     case OCI_CONTINUE: 
      lua_pushstring (L, LUASQL_PREFIX"OCI_CONTINUE"); 
      break; 
    } 
    return 2; 
} 


/* 
** Copy the column name to the column structure and convert it to lower case. 
*/ 
static void copy_column_name (column_data *col, text *name) { 
    unsigned int i; 
    col->name = (text *)malloc (col->namelen); 
    memcpy (col->name, name, col->namelen); 
    for (i = 0; i < col->namelen; i++) 
     col->name[i] = tolower (col->name[i]); 
} 


/* 
** 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 */ 
    column_data *col = &(cur->cols[i-1]); 
    OCIParam *param; 
    text *name; 

    ASSERT (L, OCIParamGet (cur->stmthp, OCI_HTYPE_STMT, cur->errhp, 
     (dvoid **)&param, i), cur->errhp); 
    ASSERT (L, OCIAttrGet (param, OCI_DTYPE_PARAM, 
     (dvoid *)&(name), (ub4 *)&(col->namelen), 
     OCI_ATTR_NAME, cur->errhp), cur->errhp); 
    copy_column_name (col, name); 
    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), 0, OCI_ATTR_DATA_SIZE, 
       cur->errhp), cur->errhp); 
      col->val.s = calloc (col->max + 1, sizeof(col->val.s)); 
      ASSERT (L, OCIDefineByPos (cur->stmthp, &(col->define), 
       cur->errhp, (ub4)i, col->val.s, col->max+1, 
       SQLT_STR /*col->type*/, (dvoid *)&(col->null), (ub2 *)0, 
       (ub2 *)0, (ub4) OCI_DEFAULT), cur->errhp); 
      break; 
     case SQLT_NUM: 
     case SQLT_FLT: 
     case SQLT_INT: 
     /* case SQLT_UIN: */ 
      ASSERT (L, OCIDefineByPos (cur->stmthp, &(col->define), 
       cur->errhp, (ub4)i, &(col->val.d), sizeof(col->val.d), 
       SQLT_FLT, (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, (dvoid *)&(col->val.s), 
       OCI_DTYPE_LOB, (size_t)0, (dvoid **)0), cur->errhp); 
      ASSERT (L, OCIDefineByPos (cur->stmthp, &(col->define), 
       cur->errhp, (ub4)i, &(col->val.s), (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) { 
    /* column index ranges from 1 to numcols */ 
    /* C array index ranges from 0 to numcols-1 */ 
    column_data *col = &(cur->cols[i-1]); 
    free (col->name); 
    switch (col->type) { 
     case SQLT_INT: 
     case SQLT_FLT: 
     case SQLT_NUM: 
      break; 
     case SQLT_CHR: 
     case SQLT_STR: 
     case SQLT_VCS: 
     case SQLT_AFC: 
     case SQLT_AVC: 
      free(col->val.s); 
      break; 
     case SQLT_CLOB: 
      ASSERT (L, OCIDescriptorFree (col->val.s, 
       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; 
} 


/* 
** Push a value on top of the stack. 
*/ 
static int pushvalue (lua_State *L, cur_data *cur, int i) { 
    /* column index ranges from 1 to numcols */ 
    /* C array index ranges from 0 to numcols-1 */ 
    column_data *col = &(cur->cols[i-1]); 
    if (col->null) { 
     /* Oracle NULL => Lua nil */ 
     lua_pushnil (L); 
     return 1; 
    } 
    switch (col->type) { 
     case SQLT_NUM: 
     case SQLT_INT: 
     case SQLT_FLT: 
      lua_pushnumber (L, col->val.d); 
      break; 
     case SQLT_CHR: 
     case SQLT_STR: 
     case SQLT_VCS: 
     case SQLT_AFC: 
     case SQLT_AVC: 
      lua_pushstring (L, (char *)(col->val.s)); 
      break; 
     case SQLT_CLOB: { 
      ub4 lob_len; 
      conn_data *conn; 
      env_data *env; 
      lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn); 
      conn = lua_touserdata (L, -1); 
      lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env); 
      env = lua_touserdata (L, -1); 
      lua_pop (L, 2); 
      ASSERT (L, OCILobGetLength (conn->svchp, cur->errhp, 
       (OCILobLocator *)col->val.s, &lob_len), cur->errhp); 
      if (lob_len > 0) { 
       char *lob_buffer=malloc(lob_len); 
       ub4 amount = lob_len; 

       ASSERT(L, OCILobRead(conn->svchp, cur->errhp, 
        (OCILobLocator *) col->val.s, &amount, (ub4) 1, 
        (dvoid *) lob_buffer, (ub4) lob_len, (dvoid *)0, 
        (sb4 (*) (dvoid *, CONST dvoid *, ub4, ub1)) 0, 
        (ub2) 0, (ub1) SQLCS_IMPLICIT), cur->errhp); 
       lua_pushlstring (L, lob_buffer, amount); 
       free(lob_buffer); 
      } else { 
       lua_pushstring (L, ""); 
      } 
      break; 
     } 
     default: 
      luaL_error (L, LUASQL_PREFIX"unexpected error"); 
    } 
    return 1; 
} 


/* 
** Get another row of the given cursor. 
*/ 
static int cur_fetch (lua_State *L) { 
    cur_data *cur = getcursor (L); 
    sword status = OCIStmtFetch (cur->stmthp, cur->errhp, 1, 
     OCI_FETCH_NEXT, OCI_DEFAULT); 

    if (status == OCI_NO_DATA) { 
     /* No more rows */ 
     lua_pushnil (L); 
     return 1; 
    } else if (status != OCI_SUCCESS) { 
     /* Error */ 
     return checkerr (L, status, cur->errhp); 
    } 

    if (lua_istable (L, 2)) { 
     int i; 
     const char *opts = luaL_optstring (L, 3, "n"); 
     if (strchr (opts, 'n') != NULL) 
      /* Copy values to numerical indices */ 
      for (i = 1; i <= cur->numcols; i++) { 
       int ret = pushvalue (L, cur, i); 
       if (ret != 1) 
        return ret; 
       lua_rawseti (L, 2, i); 
      } 
     if (strchr (opts, 'a') != NULL) 
      /* Copy values to alphanumerical indices */ 
      for (i = 1; i <= cur->numcols; i++) { 
       column_data *col = &(cur->cols[i-1]); 
       int ret; 
       lua_pushlstring (L, col->name, col->namelen); 
       if ((ret = pushvalue (L, cur, i)) != 1) 
        return ret; 
       lua_rawset (L, 2); 
      } 
     lua_pushvalue(L, 2); 
     return 1; /* return table */ 
    } 
    else { 
     int i; 
     luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns"); 
     for (i = 1; i <= cur->numcols; i++) { 
      int ret = pushvalue (L, cur, i); 
      if (ret != 1) 
       return ret; 
     } 
     return cur->numcols; /* return #numcols values */ 
    } 
} 


/* 
** Close the cursor on top of the stack. 
** 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) { 
     lua_pushboolean (L, 0); 
     return 1; 
    } 

    /* 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); 
    /* Decrement cursor counter on connection object */ 
    lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn); 
    conn = lua_touserdata (L, -1); 
    conn->cur_counter--; 
    luaL_unref (L, LUA_REGISTRYINDEX, cur->conn); 
    luaL_unref (L, LUA_REGISTRYINDEX, cur->colnames); 
    luaL_unref (L, LUA_REGISTRYINDEX, cur->coltypes); 

    lua_pushboolean (L, 1); 
    return 1; 
} 


/* 
** Return the list of field names as a table on top of the stack. 
*/ 
static int cur_getcolnames (lua_State *L) { 
    cur_data *cur = getcursor (L); 
    if (cur->colnames != LUA_NOREF) 
     lua_rawgeti (L, LUA_REGISTRYINDEX, cur->colnames); 
    else { 
     int i; 
     lua_newtable (L); 
     for (i = 1; i <= cur->numcols; i++) { 
      column_data *col = &(cur->cols[i-1]); 
      lua_pushlstring (L, col->name, col->namelen); 
      lua_rawseti (L, -2, i); 
     } 
     lua_pushvalue (L, -1); 
     cur->colnames = luaL_ref (L, LUA_REGISTRYINDEX); 
    } 
    return 1; 
} 


/* 
** 
*/ 
static char *getcolumntype (column_data *col) { 
    switch (col->type) { 
     case SQLT_CHR: 
     case SQLT_STR: 
     case SQLT_VCS: 
     case SQLT_AFC: 
     case SQLT_AVC: 
      return "string"; 
     case SQLT_NUM: 
     case SQLT_FLT: 
     case SQLT_INT: 
     /* case SQLT_UIN: */ 
      return "number"; 
     case SQLT_CLOB: 
      return "string"; 
     default: 
      return ""; 
    } 
} 


/* 
** Return the list of field types as a table on top of the stack. 
*/ 
static int cur_getcoltypes (lua_State *L) { 
    cur_data *cur = getcursor (L); 
    if (cur->coltypes != LUA_NOREF) 
     lua_rawgeti (L, LUA_REGISTRYINDEX, cur->coltypes); 
    else { 
     int i; 
     lua_newtable (L); 
     for (i = 1; i <= cur->numcols; i++) { 
      column_data *col = &(cur->cols[i-1]); 
      lua_pushnumber (L, i); 
      lua_pushstring (L, getcolumntype (col)); 
      lua_rawset (L, -3); 
     } 
     lua_pushvalue (L, -1); 
     cur->coltypes = luaL_ref (L, LUA_REGISTRYINDEX); 
    } 
    return 1; 
} 


/* 
** Push the number of rows. 
*/ 
static int cur_numrows (lua_State *L) { 
    int n; 
    cur_data *cur = getcursor (L); 
    ASSERT (L, OCIAttrGet ((dvoid *) cur->stmthp, OCI_HTYPE_STMT, (dvoid *)&n, 
     (ub4)0, OCI_ATTR_NUM_ROWS, cur->errhp), cur->errhp); 
    lua_pushnumber (L, n); 
    return 1; 
} 


/* 
** Close a Connection object. 
*/ 
static int conn_close (lua_State *L) { 
    env_data *env; 
    conn_data *conn = (conn_data *)luaL_checkudata (L, 1, LUASQL_CONNECTION_OCI8); 
    luaL_argcheck (L, conn != NULL, 1, LUASQL_PREFIX"connection expected"); 
    if (conn->closed) { 
     lua_pushboolean (L, 0); 
     return 1; 
    } 
    if (conn->cur_counter > 0) 
     return luaL_error (L, LUASQL_PREFIX"there are open cursors"); 

    /* Nullify structure fields. */ 
    conn->closed = 1; 
    if (conn->svchp) { 
     if (conn->loggedon) 
      OCILogoff (conn->svchp, conn->errhp); 
     else 
      OCIHandleFree ((dvoid *)conn->svchp, OCI_HTYPE_SVCCTX); 
    } 
    if (conn->errhp) 
     OCIHandleFree ((dvoid *)conn->errhp, OCI_HTYPE_ERROR); 
    /* Decrement connection counter on environment object */ 
    lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env); 
    env = lua_touserdata (L, -1); 
    env->conn_counter--; 
    luaL_unref (L, LUA_REGISTRYINDEX, conn->env); 

    lua_pushboolean (L, 1); 
    return 1; 
} 


/* 
** 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, const char *text) { 
    int i; 
    env_data *env; 
    cur_data *cur = (cur_data *)lua_newuserdata(L, sizeof(cur_data)); 
    luasql_setmeta (L, LUASQL_CURSOR_OCI8); 

    conn->cur_counter++; 
    /* fill in structure */ 
    cur->closed = 0; 
    cur->numcols = 0; 
    cur->colnames = LUA_NOREF; 
    cur->coltypes = LUA_NOREF; 
    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); 

    /* error handler */ 
    lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env); 
    env = lua_touserdata (L, -1); 
    lua_pop (L, 1); 
    ASSERT (L, OCIHandleAlloc((dvoid *) env->envhp, 
     (dvoid **) &(cur->errhp), (ub4) OCI_HTYPE_ERROR, (size_t) 0, 
     (dvoid **) 0), conn->errhp); 
    /* get number of columns */ 
    ASSERT (L, OCIAttrGet ((dvoid *)stmt, (ub4)OCI_HTYPE_STMT, 
     (dvoid *)&cur->numcols, (ub4 *)0, (ub4)OCI_ATTR_PARAM_COUNT, 
     cur->errhp), cur->errhp); 
    cur->cols = (column_data *)malloc (sizeof(column_data) * cur->numcols); 
    /* define output variables */ 
    /* Oracle and Lua column indices ranges from 1 to numcols */ 
    /* C array indices ranges from 0 to numcols-1 */ 
    for (i = 1; i <= cur->numcols; i++) { 
     int ret = alloc_column_buffer (L, cur, i); 
     if (ret) 
      return ret; 
    } 

    return 1; 
} 


/* 
** Execute an SQL statement. 
** Return a Cursor object if the statement is a query, otherwise 
** return the number of tuples affected by the statement. 
*/ 
static int conn_execute (lua_State *L) { 
    env_data *env; 
    conn_data *conn = getconnection (L); 
    const char *statement = luaL_checkstring (L, 2); 
    sword status; 
    ub4 prefetch = 0; 
    ub4 iters; 
    ub4 mode; 
    ub2 type; 
    OCIStmt *stmthp; 

    /* get environment */ 
    lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env); 
    if (!lua_isuserdata (L, -1)) 
     luaL_error(L,LUASQL_PREFIX"invalid environment in connection!"); 
    env = (env_data *)lua_touserdata (L, -1); 
    /* statement handle */ 
    ASSERT (L, OCIHandleAlloc ((dvoid *)env->envhp, (dvoid **)&stmthp, 
     OCI_HTYPE_STMT, (size_t)0, (dvoid **)0), conn->errhp); 
    ASSERT (L, OCIAttrSet ((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, 
     (dvoid *)&prefetch, (ub4)0, (ub4)OCI_ATTR_PREFETCH_ROWS, 
     conn->errhp), conn->errhp); 
    ASSERT (L, OCIStmtPrepare (stmthp, conn->errhp, (text *)statement, 
     (ub4) strlen(statement), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT), 
     conn->errhp); 
    /* statement type */ 
    ASSERT (L, OCIAttrGet ((dvoid *)stmthp, (ub4) OCI_HTYPE_STMT, 
     (dvoid *)&type, (ub4 *)0, (ub4)OCI_ATTR_STMT_TYPE, conn->errhp), 
     conn->errhp); 
    if (type == OCI_STMT_SELECT) 
     iters = 0; 
    else 
     iters = 1; 
    if (conn->auto_commit) 
     mode = OCI_COMMIT_ON_SUCCESS; 
    else 
     mode = OCI_DEFAULT; 
    /* execute statement */ 
    status = OCIStmtExecute (conn->svchp, stmthp, conn->errhp, iters, 
     (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, mode); 
    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, 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; 
    } 
} 


/* 
** Commit the current transaction. 
*/ 
static int conn_commit (lua_State *L) { 
    conn_data *conn = getconnection (L); 
    ASSERT (L, OCITransCommit (conn->svchp, conn->errhp, OCI_DEFAULT), 
     conn->errhp); 
/* 
    if (conn->auto_commit == 0) 
     ASSERT (L, OCITransStart (conn->svchp, conn->errhp... 
*/ 
    return 0; 
} 


/* 
** Rollback the current transaction. 
*/ 
static int conn_rollback (lua_State *L) { 
    conn_data *conn = getconnection (L); 
    ASSERT (L, OCITransRollback (conn->svchp, conn->errhp, OCI_DEFAULT), 
     conn->errhp); 
/* 
    if (conn->auto_commit == 0) 
     sql_begin(conn); 
*/ 
    return 0; 
} 


/* 
** Set "auto commit" property of the connection. 
** If 'true', then rollback current transaction. 
** If 'false', then start a new transaction. 
*/ 
static int conn_setautocommit (lua_State *L) { 
    conn_data *conn = getconnection (L); 
    if (lua_toboolean (L, 2)) { 
     conn->auto_commit = 1; 
     /* Undo active transaction. */ 
     ASSERT (L, OCITransRollback (conn->svchp, conn->errhp, 
      OCI_DEFAULT), conn->errhp); 
    } 
    else { 
     conn->auto_commit = 0; 
     /* sql_begin(conn);*/ 
    } 
    lua_pushboolean(L, 1); 
    return 1; 
} 


/* 
** Connects to a data source. 
*/ 
static int env_connect (lua_State *L) { 
    env_data *env = getenvironment (L); 
    const char *sourcename = luaL_checkstring(L, 2); 
    const char *username = luaL_optstring(L, 3, NULL); 
    const char *password = luaL_optstring(L, 4, NULL); 
    /* Sizes of strings */ 
    size_t snlen = strlen(sourcename); 
    size_t userlen = (username) ? strlen(username) : 0; 
    size_t passlen = (password) ? strlen(password) : 0; 
    /* Alloc connection object */ 
    conn_data *conn = (conn_data *)lua_newuserdata(L, sizeof(conn_data)); 

    /* fill in structure */ 
    luasql_setmeta (L, LUASQL_CONNECTION_OCI8); 
    conn->env = LUA_NOREF; 
    conn->closed = 1; 
    conn->auto_commit = 1; 
    conn->cur_counter = 0; 
    conn->loggedon = 0; 
    conn->svchp = NULL; 
    conn->errhp = NULL; 
    lua_pushvalue (L, 1); 
    conn->env = luaL_ref (L, LUA_REGISTRYINDEX); 

    /* error handler */ 
    ASSERT (L, OCIHandleAlloc((dvoid *) env->envhp, 
     (dvoid **) &(conn->errhp), /* !!! */ 
     (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0), env->errhp); 
    /* service handler */ 
    /*ASSERT (L, OCIHandleAlloc((dvoid *) env->envhp, 
     (dvoid **) &(conn->svchp), 
     (ub4) OCI_HTYPE_SVCCTX, (size_t) 0, (dvoid **) 0), conn->errhp); 
*/ 
    /* login */ 
    ASSERT (L, OCILogon(env->envhp, conn->errhp, &(conn->svchp), 
     (CONST text*)username, userlen, 
     (CONST text*)password, passlen, 
     (CONST text*)sourcename, snlen), conn->errhp); 
    conn->closed = 0; 
    env->conn_counter++; 
    conn->loggedon = 1; 

    return 1; 
} 


/* 
** Close environment object. 
*/ 
static int env_close (lua_State *L) { 
    env_data *env = (env_data *)luaL_checkudata (L, 1, LUASQL_ENVIRONMENT_OCI8); 
    luaL_argcheck (L, env != NULL, 1, LUASQL_PREFIX"environment expected"); 
    if (env->closed) { 
     lua_pushboolean (L, 0); 
     return 1; 
    } 
    if (env->conn_counter > 0) 
     return luaL_error (L, LUASQL_PREFIX"there are open connections"); 

    env->closed = 1; 
    /* desalocar: env->errhp e env->envhp */ 
    if (env->envhp) 
     OCIHandleFree ((dvoid *)env->envhp, OCI_HTYPE_ENV); 
    if (env->errhp) 
     OCIHandleFree ((dvoid *)env->errhp, OCI_HTYPE_ERROR); 
    lua_pushboolean (L, 1); 
    return 1; 
} 


/* 
** Creates an Environment and returns it. 
*/ 
static int create_environment (lua_State *L) { 
    env_data *env = (env_data *)lua_newuserdata(L, sizeof(env_data)); 
    luasql_setmeta (L, LUASQL_ENVIRONMENT_OCI8); 
    /* fill in structure */ 
    env->closed = 0; 
    env->conn_counter = 0; 
    env->envhp = NULL; 
    env->errhp = NULL; 
/* maybe OCI_SHARED and OCI_THREADED ??? */ 
    if (OCIEnvCreate (&(env->envhp), (ub4)OCI_DEFAULT, (dvoid *)0, 
      (dvoid * (*)(dvoid *, size_t)) 0, 
      (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, 
      (void (*)(dvoid *, dvoid *)) 0, 
      (size_t) 0, 
      (dvoid **) 0)) 
     luasql_faildirect (L, "couldn't create environment"); 
    /* error handler */ 
    ASSERT (L, OCIHandleAlloc((dvoid *) env->envhp, 
     (dvoid **) &(env->errhp), /* !!! */ 
     (ub4) OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0), env->errhp); 
    return 1; 
} 


/* 
** Create metatables for each class of object. 
*/ 
static void create_metatables (lua_State *L) { 
    struct luaL_Reg environment_methods[] = { 
     {"__gc", env_close}, /* Should this method be changed? */ 
     {"close", env_close}, 
     {"connect", env_connect}, 
     {NULL, NULL}, 
    }; 
    struct luaL_Reg connection_methods[] = { 
     {"__gc", conn_close}, /* Should this method be changed? */ 
     {"close", conn_close}, 
     {"execute", conn_execute}, 
     {"commit", conn_commit}, 
     {"rollback", conn_rollback}, 
     {"setautocommit", conn_setautocommit}, 
     {NULL, NULL}, 
    }; 
    struct luaL_Reg cursor_methods[] = { 
     {"__gc", cur_close}, /* Should this method be changed? */ 
     {"close", cur_close}, 
     {"getcolnames", cur_getcolnames}, 
     {"getcoltypes", cur_getcoltypes}, 
     {"fetch", cur_fetch}, 
     {"numrows", cur_numrows}, 
     {NULL, NULL}, 
    }; 
    luasql_createmeta (L, LUASQL_ENVIRONMENT_OCI8, environment_methods); 
    luasql_createmeta (L, LUASQL_CONNECTION_OCI8, connection_methods); 
    luasql_createmeta (L, LUASQL_CURSOR_OCI8, cursor_methods); 
    lua_pop (L, 3); 
} 


/* 
** Creates the metatables for the objects and registers the 
** driver open method. 
*/ 
LUASQL_API int luaopen_luasql_oci8 (lua_State *L) { 
    struct luaL_Reg driver[] = { 
     {"oci8", create_environment}, 
     {NULL, NULL}, 
    }; 
    create_metatables (L); 
    lua_newtable (L); 
    luaL_setfuncs (L, driver, 0); 
    luasql_set_info (L); 
    return 1; 
} 

teşekkürler!

cevap

0

Bu bir işlev değildir.

int checkerr (lua_State *L, sword status, OCIError *errhp); 
#define ASSERT(L,exp,err) {sword s = exp; if (s) return checkerr (L, s, err);} 

Yani ilk biridir Lua devlet, ikincisi değerlendirmek için bazı ifade ve hatayı döndürülür sonuncusu: Bu sizin kodunda tanımlanan bir makrodur.