static int env_destroy (lua_State *L) { lodbc_env *env = (lodbc_env *)lutil_checkudatap (L, 1, LODBC_ENV); luaL_argcheck (L, env != NULL, 1, LODBC_PREFIX "environment expected"); if(!(env->flags & LODBC_FLAG_DESTROYED)){ //! @todo autoclose connections if (env->conn_counter > 0) return luaL_error (L, LODBC_PREFIX"there are open connections"); if(!(env->flags & LODBC_FLAG_DONT_DESTROY)){ #ifdef LODBC_CHECK_ERROR_ON_DESTROY SQLRETURN ret = #endif SQLFreeHandle (hENV, env->handle); #ifdef LODBC_CHECK_ERROR_ON_DESTROY if (lodbc_iserror(ret)) return lodbc_fail(L, hENV, env->handle); #endif env->handle = SQL_NULL_HANDLE; } env->flags |= LODBC_FLAG_DESTROYED; } lua_pushnil(L); lodbc_set_user_value(L, 1); return lodbc_pass(L); }
int lodbc_environment_create(lua_State *L, SQLHENV henv, uchar own){ lodbc_env *env; uchar is_new = 0; if(henv == SQL_NULL_HANDLE){ SQLRETURN ret = SQLAllocHandle(hENV, SQL_NULL_HANDLE, &henv); if (lodbc_iserror(ret)) return lodbc_faildirect(L, "error creating environment."); own = 1; is_new = 1; } env = lutil_newudatap(L, lodbc_env, LODBC_ENV); memset(env, 0, sizeof(lodbc_env)); if(!own)env->flags |= LODBC_FLAG_DONT_DESTROY; env->handle = henv; if(is_new){ int top = lua_gettop(L); SQLRETURN ret = env_set_uint_attr_(L, env, SQL_ATTR_ODBC_VERSION, LODBC_ODBC3_C(SQL_OV_ODBC3, SQL_OV_ODBC2) ); if(lodbc_is_fail(L,ret)){ SQLFreeHandle (hENV, henv); env->flags &= ~LODBC_FLAG_DESTROYED; return ret; } lua_settop(L, top); } return 1; }
static int env_connection(lua_State *L) { lodbc_env *env = lodbc_getenv(L); SQLHDBC hdbc; SQLRETURN ret = SQLAllocHandle (hDBC, env->handle, &hdbc); if(lodbc_iserror(ret)) return lodbc_fail(L, hENV, env->handle); return lodbc_connection_create(L, hdbc, env, 1, 1); }
int lodbc_set_str_attr_(lua_State*L, SQLSMALLINT HandleType, SQLHANDLE Handle, SQLINTEGER optnum, const char* value, size_t len) { SQLRETURN ret; #if (LODBC_ODBCVER >= 0x0300) ret = select_set_attr_v3(HandleType)(Handle,optnum,(SQLPOINTER)value,len); #else if(HandleType == hENV) return lodbc_faildirect(L, "not supported."); ret = select_set_attr (HandleType)(Handle,optnum,(SQLUINTEGER)value); #endif if(lodbc_iserror(ret)) return lodbc_fail(L, HandleType, Handle); return lodbc_pass(L); }
int lodbc_get_str_attr_(lua_State*L, SQLSMALLINT HandleType, SQLHANDLE Handle, SQLINTEGER optnum){ #if (LODBC_ODBCVER >= 0x0300) SQLINTEGER got; char buffer[256]; #else char buffer[SQL_MAX_OPTION_STRING_LENGTH+1]; #endif SQLRETURN ret; #if (LODBC_ODBCVER >= 0x0300) ret = select_get_attr_v3(HandleType)(Handle, optnum, (SQLPOINTER)buffer, 255, &got); #else if(HandleType == hENV) return lodbc_faildirect(L, "not supported."); ret = select_get_attr (HandleType)(Handle, optnum, (SQLPOINTER)&buffer); #endif if(ret == LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND)) return 0; if(lodbc_iserror(ret)) return lodbc_fail(L, HandleType, Handle); #if (LODBC_ODBCVER >= 0x0300) if(got > 255){ char* tmp = malloc(got+1); if(!tmp) return LODBC_ALLOCATE_ERROR(L); ret = select_get_attr_v3(HandleType)(Handle, optnum, (SQLPOINTER)tmp, got, &got); if(lodbc_iserror(ret)){ free(tmp); if(ret == SQL_NO_DATA) return 0; return lodbc_fail(L, HandleType, Handle); } lua_pushstring(L, tmp); free(tmp); } else #endif lua_pushstring(L, buffer); return 1; }
static int env_getdatasources (lua_State *L) { lodbc_env *env = lodbc_getenv (L); SQLRETURN ret; SQLSMALLINT dsnlen,desclen; char dsn[SQL_MAX_DSN_LENGTH+1]; char desc[256]; int i = 1; int is_cb = lua_isfunction(L,2); int top = lua_gettop(L); ret = SQLDataSources( env->handle,SQL_FETCH_FIRST, (SQLPOINTER)dsn, SQL_MAX_DSN_LENGTH+1,&dsnlen, (SQLPOINTER)desc,sizeof(desc),&desclen ); if(!is_cb) top++, lua_newtable(L); if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) return is_cb ? 0 : 1; while(!lodbc_iserror(ret)) { assert(top == lua_gettop(L)); if(is_cb) lua_pushvalue(L, 2); if(!is_cb) { lua_newtable(L); lua_pushstring(L,dsn); lua_rawseti(L,-2,1); lua_pushstring(L,desc); lua_rawseti(L,-2,2); lua_rawseti(L,-2,i++); } else { int ret; lua_pushstring(L,dsn); lua_pushstring(L,desc); lua_call(L,2,LUA_MULTRET); ret = lua_gettop(L) - top; assert(ret >= 0); if(ret) return ret; } ret = SQLDataSources( env->handle,SQL_FETCH_NEXT, (SQLPOINTER)dsn, SQL_MAX_DSN_LENGTH+1,&dsnlen, (SQLPOINTER)desc,256,&desclen ); if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) return is_cb ? 0 : 1; } return lodbc_fail(L, hENV, env->handle); }
int lodbc_get_uint_attr_(lua_State*L, SQLSMALLINT HandleType, SQLHANDLE Handle, SQLINTEGER optnum){ SQLUINTEGER res; SQLRETURN ret; #if (LODBC_ODBCVER >= 0x0300) SQLINTEGER dummy; ret = select_get_attr_v3(HandleType)(Handle, optnum, (SQLPOINTER)&res, sizeof(res), &dummy); #else if(HandleType == hENV) return lodbc_faildirect(L, "not supported."); ret = select_get_attr (HandleType)(Handle, optnum, (SQLPOINTER)&res); #endif if(ret == LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND)) return 0; if(lodbc_iserror(ret)) return lodbc_fail(L, HandleType, Handle); lua_pushnumber(L,res); return 1; }
static int env_destroy (lua_State *L) { lodbc_env *env = (lodbc_env *)lutil_checkudatap (L, 1, LODBC_ENV); luaL_argcheck (L, env != NULL, 1, LODBC_PREFIX "environment expected"); if(!(env->flags & LODBC_FLAG_DESTROYED)) { if(LUA_NOREF != env->conn_list_ref) { lua_rawgeti(L, LODBC_LUA_REGISTRY, env->conn_list_ref); assert(lua_istable(L, -1)); lua_pushnil(L); while(lua_next(L, -2)) { lua_pop(L, 1); // we do not need value call_cnn_destroy(L); } } if (env->conn_counter > 0) return luaL_error (L, LODBC_PREFIX"there are open connections"); if(!(env->flags & LODBC_FLAG_DONT_DESTROY)) { #ifdef LODBC_CHECK_ERROR_ON_DESTROY SQLRETURN ret = #endif SQLFreeHandle (hENV, env->handle); #ifdef LODBC_CHECK_ERROR_ON_DESTROY if (lodbc_iserror(ret)) return lodbc_fail(L, hENV, env->handle); #endif env->handle = SQL_NULL_HANDLE; } luaL_unref(L, LODBC_LUA_REGISTRY, env->conn_list_ref); env->conn_list_ref = LUA_NOREF; env->flags |= LODBC_FLAG_DESTROYED; } lua_pushnil(L); lodbc_set_user_value(L, 1); return lodbc_pass(L); }
int lodbc_environment_create(lua_State *L, SQLHENV henv, uchar own) { lodbc_env *env; uchar is_new = 0; if(henv == SQL_NULL_HANDLE) { SQLRETURN ret = SQLAllocHandle(hENV, SQL_NULL_HANDLE, &henv); if (lodbc_iserror(ret)) return lodbc_faildirect(L, "error creating environment."); own = 1; is_new = 1; } env = lutil_newudatap(L, lodbc_env, LODBC_ENV); memset(env, 0, sizeof(lodbc_env)); if(!own)env->flags |= LODBC_FLAG_DONT_DESTROY; env->handle = henv; env->conn_list_ref = LUA_NOREF; if(LODBC_OPT_INT(ENV_AUTOCLOSECNN)) { int top = lua_gettop(L); lua_pushvalue(L, -1); lua_pushboolean(L, 1); lodbc_pcall_method(L, "setautoclosecnn", 1, 0, 0); lua_settop(L, top); } if(is_new) { int top = lua_gettop(L); SQLRETURN ret = env_set_uint_attr_(L, env, SQL_ATTR_ODBC_VERSION, LODBC_ODBC3_C(SQL_OV_ODBC3, SQL_OV_ODBC2) ); if(lodbc_is_fail(L,ret)) { SQLFreeHandle (hENV, henv); env->flags &= ~LODBC_FLAG_DESTROYED; return ret; } lua_settop(L, top); } return 1; }
int lodbc_push_column_value(lua_State *L, SQLHSTMT hstmt, SQLUSMALLINT i, const char type){ int top = lua_gettop(L); switch (type) {/* deal with data according to type */ case 'u': { /* nUmber */ lua_Number num; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, LODBC_C_NUMBER, &num, 0, &got); if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lodbc_pushnull(L); else lua_pushnumber(L, num); break; } case 'o': { /* bOol */ unsigned char b; SQLLEN got; SQLRETURN rc = SQLGetData(hstmt, i, SQL_C_BIT, &b, 0, &got); if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); if (got == SQL_NULL_DATA) lodbc_pushnull(L); else lua_pushboolean(L, b); break; } case 't': case 'i': {/* sTring, bInary */ SQLSMALLINT stype = (type == 't') ? SQL_C_CHAR : SQL_C_BINARY; SQLLEN got; char *buffer; luaL_Buffer b; SQLRETURN rc; luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); if (got == SQL_NULL_DATA){ lodbc_pushnull(L); break; } while (rc == SQL_SUCCESS_WITH_INFO) {/* concat intermediary chunks */ if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); buffer = luaL_prepbuffer(&b); rc = SQLGetData(hstmt, i, stype, buffer, LUAL_BUFFERSIZE, &got); } if (rc == SQL_SUCCESS) {/* concat last chunk */ if (got >= LUAL_BUFFERSIZE || got == SQL_NO_TOTAL) { got = LUAL_BUFFERSIZE; /* get rid of null termination in string block */ if (stype == SQL_C_CHAR) got--; } luaL_addsize(&b, got); } if (lodbc_iserror(rc)) return lodbc_fail(L, hSTMT, hstmt); /* return everything we got */ luaL_pushresult(&b); break; } default:{ // unsupported type ? assert(0); } } assert(1 == (lua_gettop(L)-top)); return 0; }
static int env_getdrivers (lua_State *L) { lodbc_env *env = (lodbc_env *) lodbc_getenv (L); SQLRETURN ret; SQLSMALLINT attrlen,desclen; int i = 1; char desc[MAX_DESC_LEN]; char *attr = malloc(MAX_ATTR_LEN+1); int is_cb = lua_isfunction(L,2); int top = lua_gettop(L); if(!attr) return LODBC_ALLOCATE_ERROR(L); ret = SQLDrivers(env->handle,SQL_FETCH_FIRST, (SQLPOINTER)desc,MAX_DESC_LEN,&desclen, (SQLPOINTER)attr,MAX_ATTR_LEN,&attrlen); if(!is_cb) top++,lua_newtable(L); if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) { free(attr); return is_cb ? 0 : 1; } while(!lodbc_iserror(ret)) { assert(top == lua_gettop(L)); if(is_cb) lua_pushvalue(L, 2); //find our attributes if(attr[0]!=0) { size_t i=0, last=0, n=1; lua_newtable(L); do { char *p,*a; while(attr[++i] != 0); a = &(attr[last]); p = strchr(a,'='); if(p) { lua_pushlstring(L, a, p-a); lua_pushlstring(L, p + 1, (i-last)-(p-a)-1); lua_settable(L,-3); } else { lua_pushlstring(L,a,(i-last)); lua_rawseti(L,-2,n++); } last=i+1; } while(attr[last]!=0); } else lua_pushnil(L); if(!is_cb) { lua_newtable(L); lua_insert(L,-2); lua_rawseti(L,-2,2); lua_pushstring(L,desc); lua_rawseti(L,-2,1); lua_rawseti(L,-2,i++); } else { int ret; lua_pushstring(L,desc); lua_insert(L,-2); lua_call(L,2,LUA_MULTRET); ret = lua_gettop(L) - top; assert(ret >= 0); if(ret) { free(attr); return ret; } } ret = SQLDrivers(env->handle,SQL_FETCH_NEXT, (SQLPOINTER)desc,MAX_DESC_LEN,&desclen, (SQLPOINTER)attr,MAX_ATTR_LEN,&attrlen); if(LODBC_ODBC3_C(SQL_NO_DATA,SQL_NO_DATA_FOUND) == ret) { free(attr); return is_cb ? 0 : 1; } } free(attr); return lodbc_fail(L, hENV, env->handle); }