pax_global_header00006660000000000000000000000064122015035540014507gustar00rootroot0000000000000052 comment=94f2f7a4f6fddcbfa114d258fec15b6c83991a28 lua-dbi-0.5.hg5ba1dd988961/000077500000000000000000000000001220150355400147575ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/COPYING000066400000000000000000000020671220150355400160170ustar00rootroot00000000000000Copyright (c) 2008-2010 Neil Richardson (nrich@ii.net) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. lua-dbi-0.5.hg5ba1dd988961/DBI.lua000066400000000000000000000035771220150355400160740ustar00rootroot00000000000000#!/usr/bin/lua module('DBI', package.seeall) -- Driver to module mapping local name_to_module = { MySQL = 'dbdmysql', PostgreSQL = 'dbdpostgresql', SQLite3 = 'dbdsqlite3', DB2 = 'dbddb2', Oracle = 'dbdoracle', } local string = require('string') -- Returns a list of available drivers -- based on run time loading local function available_drivers() local available = {} for driver, modulefile in pairs(name_to_module) do local m, err = pcall(require, modulefile) if m then table.insert(available, driver) end end -- no drivers available if table.maxn(available) < 1 then available = {'(None)'} end return available end -- High level DB connection function -- This should be used rather than DBD.{Driver}.New function Connect(driver, ...) local modulefile = name_to_module[driver] if not modulefile then local available = table.concat(available_drivers(), ',') error(string.format("Driver '%s' not found. Available drivers are: %s", driver, available)) end local m, err = pcall(require, modulefile) if not m then -- cannot load the module, we cannot continue local available = table.concat(available_drivers(), ',') error(string.format('Cannot load driver %s. Available drivers are: %s', driver, available)) end local class_str = string.format('DBD.%s.Connection', driver) local connection_class = package.loaded[class_str] -- Calls DBD.{Driver}.New(...) return connection_class.New(...) end -- Help function to do prepare and execute in -- a single step function Do(dbh, sql, ...) local sth,err = dbh:prepare(sql) if not sth then return false, err end local ok, err = sth:execute(...) if not ok then return false, err end return sth:affected() end -- Lit drivers available on this system function Drivers() return available_drivers() end lua-dbi-0.5.hg5ba1dd988961/INSTALL000066400000000000000000000020071220150355400160070ustar00rootroot00000000000000= Dependencies = Before attempting to build LuaDBI the development libaries for each database must be installed. For Debian/Ubuntu systems, the list of required dependancies are: * libsqlite3-dev * libmysqlclient15-dev * libpq-dev * db2exc (optional for DB2 support) * oracle-xe-client (optional for Oracle support) = Building = Run `make` (or `make free`) in the source directory to build the Open Source database drivers. To build the drivers for DB2 and Oracle, run `make all`. == Windows == Inside the vc++ directory are build projects for Visual C++ to build LuaDBI for Windows. = Make Targets = * make free - builds MySQL, PostgreSQL and SQLite3 drivers * make all - as above, but also builds DB2 and Oracle drivers * make mysql * make psql * make sqlite3 * make db2 * make oracle = Installation = Please consult your distributions documentation on installing Lua modules. Please note that both the database binary driver packages (*.so|*.dll) and DBI.lua must be installed correctly to use LuaDBI lua-dbi-0.5.hg5ba1dd988961/Makefile000066400000000000000000000074321220150355400164250ustar00rootroot00000000000000CC=gcc CFLAGS=-g -pedantic -Wall -O2 -shared -fpic -I /usr/include/lua5.1 -I /usr/include/mysql -I /usr/include/postgresql/ -I /opt/ibm/db2exc/V9.5/include/ -I /usr/lib/oracle/xe/app/oracle/product/10.2.0/client/rdbms/public/ -I . AR=ar rcu RANLIB=ranlib RM=rm -rf MKDIR=mkdir -p COMMON_LDFLAGS= MYSQL_LDFLAGS=$(COMMON_LDFLAGS) -lmysqlclient PSQL_LDFLAGS=$(COMMON_LDFLAGS) -lpq SQLITE3_LDFLAGS=$(COMMON_LDFLAGS) -lsqlite3 DB2_LDFLAGS=$(COMMON_LDFLAGS) -L/opt/ibm/db2exc/V9.5/lib64 -L/opt/ibm/db2exc/V9.5/lib32 -ldb2 ORACLE_LDFLAGS=$(COMMON_LDFLAGS) -L/usr/lib/oracle/xe/app/oracle/product/10.2.0/client/lib/ -locixe BUILDDIR=build DBDMYSQL=dbdmysql.so DBDPSQL=dbdpostgresql.so DBDSQLITE3=dbdsqlite3.so DBDDB2=dbddb2.so DBDORACLE=dbdoracle.so OBJS=build/dbd_common.o MYSQL_OBJS=$(OBJS) build/dbd_mysql_main.o build/dbd_mysql_connection.o build/dbd_mysql_statement.o PSQL_OBJS=$(OBJS) build/dbd_postgresql_main.o build/dbd_postgresql_connection.o build/dbd_postgresql_statement.o SQLITE3_OBJS=$(OBJS) build/dbd_sqlite3_main.o build/dbd_sqlite3_connection.o build/dbd_sqlite3_statement.o DB2_OBJS=$(OBJS) build/dbd_db2_main.o build/dbd_db2_connection.o build/dbd_db2_statement.o ORACLE_OBJS=$(OBJS) build/dbd_oracle_main.o build/dbd_oracle_connection.o build/dbd_oracle_statement.o free: mysql psql sqlite3 all: mysql psql sqlite3 db2 oracle mysql: $(BUILDDIR) $(MYSQL_OBJS) $(CC) $(CFLAGS) $(MYSQL_OBJS) -o $(DBDMYSQL) $(MYSQL_LDFLAGS) psql: $(BUILDDIR) $(PSQL_OBJS) $(CC) $(CFLAGS) $(PSQL_OBJS) -o $(DBDPSQL) $(PSQL_LDFLAGS) sqlite3: $(BUILDDIR) $(SQLITE3_OBJS) $(CC) $(CFLAGS) $(SQLITE3_OBJS) -o $(DBDSQLITE3) $(SQLITE3_LDFLAGS) db2: $(BUILDDIR) $(DB2_OBJS) $(CC) $(CFLAGS) $(DB2_OBJS) -o $(DBDDB2) $(DB2_LDFLAGS) oracle: $(BUILDDIR) $(ORACLE_OBJS) $(CC) $(CFLAGS) $(ORACLE_OBJS) -o $(DBDORACLE) $(ORACLE_LDFLAGS) clean: $(RM) $(BUILDDIR) $(MYSQL_OBJS) $(PSQL_OBJS) $(SQLITE3_OBJS) $(DB2_OBJS) $(ORACLE_OBJS) $(DBDMYSQL) $(DBDPSQL) $(DBDSQLITE3) $(DBDDB2) $(DBDORACLE) build/dbd_common.o: dbd/common.c dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_mysql_connection.o: dbd/mysql/connection.c dbd/mysql/dbd_mysql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_mysql_main.o: dbd/mysql/main.c dbd/mysql/dbd_mysql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_mysql_statement.o: dbd/mysql/statement.c dbd/mysql/dbd_mysql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_postgresql_connection.o: dbd/postgresql/connection.c dbd/postgresql/dbd_postgresql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_postgresql_main.o: dbd/postgresql/main.c dbd/postgresql/dbd_postgresql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_postgresql_statement.o: dbd/postgresql/statement.c dbd/postgresql/dbd_postgresql.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_sqlite3_connection.o: dbd/sqlite3/connection.c dbd/sqlite3/dbd_sqlite3.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_sqlite3_main.o: dbd/sqlite3/main.c dbd/sqlite3/dbd_sqlite3.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_sqlite3_statement.o: dbd/sqlite3/statement.c dbd/sqlite3/dbd_sqlite3.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_db2_connection.o: dbd/db2/connection.c dbd/db2/dbd_db2.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_db2_main.o: dbd/db2/main.c dbd/db2/dbd_db2.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_db2_statement.o: dbd/db2/statement.c dbd/db2/dbd_db2.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_oracle_connection.o: dbd/oracle/connection.c dbd/oracle/dbd_oracle.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_oracle_main.o: dbd/oracle/main.c dbd/oracle/dbd_oracle.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build/dbd_oracle_statement.o: dbd/oracle/statement.c dbd/oracle/dbd_oracle.h dbd/common.h $(CC) -c -o $@ $< $(CFLAGS) build: $(MKDIR) ${BUILDDIR} lua-dbi-0.5.hg5ba1dd988961/README000066400000000000000000000001201220150355400156300ustar00rootroot00000000000000Please visit http://code.google.com/p/luadbi/w/list for details on using LuaDBI lua-dbi-0.5.hg5ba1dd988961/dbd/000077500000000000000000000000001220150355400155105ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/common.c000066400000000000000000000043701220150355400171500ustar00rootroot00000000000000#include const char *strlower(char *in) { char *s = in; while(*s) { *s= (*s <= 'Z' && *s >= 'A') ? (*s - 'A') + 'a' : *s; s++; } return in; } /* * replace '?' placeholders with {native_prefix}\d+ placeholders * to be compatible with native API */ char *replace_placeholders(lua_State *L, char native_prefix, const char *sql) { size_t len = strlen(sql); int num_placeholders = 0; int extra_space = 0; int i; char *newsql; int newpos = 1; int ph_num = 1; int in_quote = 0; char format_str[4]; format_str[0] = native_prefix; format_str[1] = '%'; format_str[2] = 'u'; format_str[3] = '\0'; /* * dumb count of all '?' * this will match more placeholders than necessesary * but it's safer to allocate more placeholders at the * cost of a few bytes than risk a buffer overflow */ for (i = 1; i < len; i++) { if (sql[i] == '?') { num_placeholders++; } } /* * this is MAX_PLACEHOLDER_SIZE-1 because the '?' is * replaced with '{native_prefix}' */ extra_space = num_placeholders * (MAX_PLACEHOLDER_SIZE-1); /* * allocate a new string for the converted SQL statement */ newsql = malloc(sizeof(char) * (len+extra_space+1)); memset(newsql, 0, sizeof(char) * (len+extra_space+1)); /* * copy first char. In valid SQL this cannot be a placeholder */ newsql[0] = sql[0]; /* * only replace '?' not in a single quoted string */ for (i = 1; i < len; i++) { /* * don't change the quote flag if the ''' is preceded * by a '\' to account for escaping */ if (sql[i] == '\'' && sql[i-1] != '\\') { in_quote = !in_quote; } if (sql[i] == '?' && !in_quote) { size_t n; if (ph_num > MAX_PLACEHOLDERS) { luaL_error(L, "Sorry, you are using more than %d placeholders. Use %c{num} format instead", MAX_PLACEHOLDERS, native_prefix); } n = snprintf(&newsql[newpos], MAX_PLACEHOLDER_SIZE, format_str, ph_num++); newpos += n; } else { newsql[newpos] = sql[i]; newpos++; } } /* * terminate string on the last position */ newsql[newpos] = '\0'; /* fprintf(stderr, "[%s]\n", newsql); */ return newsql; } lua-dbi-0.5.hg5ba1dd988961/dbd/common.h000066400000000000000000000074321220150355400171570ustar00rootroot00000000000000#include #include #include #include #include #include #if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) #include #endif #ifdef _WIN32 #define LUA_EXPORT __declspec(dllexport) #else #define LUA_EXPORT #endif #ifdef _MSC_VER /* all MS compilers define this (version) */ #define snprintf _snprintf #endif /* * * Table construction helper functions * * LUA_PUSH_ATTRIB_* creates string indexed (hashmap) * LUA_PUSH_ARRAY_* creates integer indexed (array) * */ #define LUA_PUSH_ATTRIB_INT(n, v) \ lua_pushstring(L, n); \ lua_pushinteger(L, v); \ lua_rawset(L, -3); #define LUA_PUSH_ATTRIB_FLOAT(n, v) \ lua_pushstring(L, n); \ lua_pushnumber(L, v); \ lua_rawset(L, -3); #define LUA_PUSH_ATTRIB_STRING(n, v) \ lua_pushstring(L, n); \ lua_pushstring(L, v); \ lua_rawset(L, -3); #define LUA_PUSH_ATTRIB_BOOL(n, v) \ lua_pushstring(L, n); \ lua_pushboolean(L, v); \ lua_rawset(L, -3); #define LUA_PUSH_ATTRIB_NIL(n) \ lua_pushstring(L, n); \ lua_pushnil(L); \ lua_rawset(L, -3); #define LUA_PUSH_ARRAY_INT(n, v) \ lua_pushinteger(L, v); \ lua_rawseti(L, -2, n); \ n++; #define LUA_PUSH_ARRAY_FLOAT(n, v) \ lua_pushnumber(L, v); \ lua_rawseti(L, -2, n); \ n++; #define LUA_PUSH_ARRAY_STRING(n, v) \ lua_pushstring(L, v); \ lua_rawseti(L, -2, n); \ n++; #define LUA_PUSH_ARRAY_BOOL(n, v) \ lua_pushboolean(L, v); \ lua_rawseti(L, -2, n); \ n++; #define LUA_PUSH_ARRAY_NIL(n) \ lua_pushnil(L); \ lua_rawseti(L, -2, n); \ n++; /* * * Describes SQL to Lua API type conversions * */ typedef enum lua_push_type { LUA_PUSH_NIL = 0, LUA_PUSH_INTEGER, LUA_PUSH_NUMBER, LUA_PUSH_STRING, LUA_PUSH_BOOLEAN, LUA_PUSH_MAX } lua_push_type_t; /* * used for placeholder translations * from '?' to the .\d{4} */ #define MAX_PLACEHOLDERS 9999 #define MAX_PLACEHOLDER_SIZE (1+4) /* .\d{4} */ /* * * Common error strings * defined here for consistency in driver implementations * */ #define DBI_ERR_CONNECTION_FAILED "Failed to connect to database: %s" #define DBI_ERR_DB_UNAVAILABLE "Database not available" #define DBI_ERR_EXECUTE_INVALID "Execute called on a closed or invalid statement" #define DBI_ERR_EXECUTE_FAILED "Execute failed %s" #define DBI_ERR_FETCH_INVALID "Fetch called on a closed or invalid statement" #define DBI_ERR_FETCH_FAILED "Fetch failed %s" #define DBI_ERR_PARAM_MISCOUNT "Statement expected %d parameters but received %d" #define DBI_ERR_BINDING_PARAMS "Error binding statement parameters: %s" #define DBI_ERR_BINDING_EXEC "Error executing statement parameters: %s" #define DBI_ERR_FETCH_NO_EXECUTE "Fetch called before execute" #define DBI_ERR_BINDING_RESULTS "Error binding statement results: %s" #define DBI_ERR_UNKNOWN_PUSH "Unknown push type in result set" #define DBI_ERR_ALLOC_STATEMENT "Error allocating statement handle: %s" #define DBI_ERR_PREP_STATEMENT "Error preparing statement handle: %s" #define DBI_ERR_INVALID_PORT "Invalid port: %d" #define DBI_ERR_ALLOC_RESULT "Error allocating result set: %s" #define DBI_ERR_DESC_RESULT "Error describing result set: %s" #define DBI_ERR_BINDING_TYPE_ERR "Unknown or unsupported type `%s'" #define DBI_ERR_INVALID_STATEMENT "Invalid statement handle" #define DBI_ERR_NOT_IMPLEMENTED "Method %s.%s is not implemented" #define DBI_ERR_QUOTING_STR "Error quoting string: %s" /* * convert string to lower case */ const char *strlower(char *in); /* * replace '?' placeholders with .\d+ placeholders * to be compatible with the native driver API */ char *replace_placeholders(lua_State *L, char native_prefix, const char *sql); lua-dbi-0.5.hg5ba1dd988961/dbd/db2/000077500000000000000000000000001220150355400161575ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/db2/connection.c000066400000000000000000000146411220150355400204700ustar00rootroot00000000000000#include "dbd_db2.h" int dbd_db2_statement_create(lua_State *L, connection_t *conn, const char *sql_query); static int commit(connection_t *conn) { SQLRETURN rc = SQL_SUCCESS; rc = SQLEndTran(SQL_HANDLE_DBC, conn->db2, SQL_COMMIT); return rc != SQL_SUCCESS; } static int rollback(connection_t *conn) { SQLRETURN rc = SQL_SUCCESS; rc = SQLEndTran(SQL_HANDLE_DBC, conn->db2, SQL_ROLLBACK); return rc != SQL_SUCCESS; } /* * connection = DBD.DB2.New(dbname, user, password, host, port) */ static int connection_new(lua_State *L) { int n = lua_gettop(L); connection_t *conn = NULL; SQLRETURN rc = SQL_SUCCESS; const char *user = NULL; const char *password = NULL; const char *db = NULL; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; /* db, user, password */ switch(n) { case 5: case 4: case 3: if (lua_isnil(L, 3) == 0) password = luaL_checkstring(L, 3); case 2: if (lua_isnil(L, 2) == 0) user = luaL_checkstring(L, 2); case 1: /* * db is the only mandatory parameter */ db = luaL_checkstring(L, 1); } conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); /* allocate an environment handle */ rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &conn->env); if (rc != SQL_SUCCESS) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, "Cannot allocate environment handle"); return 2; } /* set attribute to enable application to run as ODBC 3.0 application */ rc = SQLSetEnvAttr(conn->env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0); if (rc != SQL_SUCCESS) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, "Cannot set ODBC version attribute"); return 2; } /* allocate a database connection handle */ rc = SQLAllocHandle(SQL_HANDLE_DBC, conn->env, &conn->db2); if (rc != SQL_SUCCESS) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, "Cannot allocate database handle"); return 2; } /* set AUTOCOMMIT off */ rc = SQLSetConnectAttr(conn->db2, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_NTS); if (rc != SQL_SUCCESS) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, "Cannot turn off autocommit"); return 2; } /* connect to the database */ rc = SQLConnect(conn->db2, (SQLCHAR *)db, SQL_NTS, (SQLCHAR *)user, SQL_NTS, (SQLCHAR *)password, SQL_NTS); if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_DBC, conn->db2, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, message); return 2; } luaL_getmetatable(L, DBD_DB2_CONNECTION); lua_setmetatable(L, -2); return 1; } /* * success = connection:autocommit(on) */ static int connection_autocommit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); int on = lua_toboolean(L, 2); int err = 0; if (conn->db2) { int onval = on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF; SQLRETURN rc = SQLSetConnectAttr(conn->db2, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)onval, SQL_NTS); err = rc != SQL_SUCCESS; } lua_pushboolean(L, !err); return 1; } /* * success = connection:close() */ static int connection_close(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); int disconnect = 0; SQLRETURN rc = SQL_SUCCESS; if (conn->db2) { rollback(conn); /* disconnect from the database */ rc = SQLDisconnect(conn->db2); /* free connection handle */ rc = SQLFreeHandle(SQL_HANDLE_DBC, conn->db2); conn->db2 = 0; } if (conn->env) { /* free environment handle */ rc = SQLFreeHandle(SQL_HANDLE_ENV, conn->env); } lua_pushboolean(L, disconnect); return 1; } /* * success = connection:commit() */ static int connection_commit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); int err = 1; if (conn->db2) { err = commit(conn); } lua_pushboolean(L, !err); return 1; } /* * ok = connection:ping() */ static int connection_ping(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); int ok = 0; if (conn->db2) { ok = 1; } lua_pushboolean(L, ok); return 1; } /* * statement = connection:prepare(sql_string) */ static int connection_prepare(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); if (conn->db2) { return dbd_db2_statement_create(L, conn, luaL_checkstring(L, 2)); } lua_pushnil(L); lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); return 2; } /* * quoted = connection:quote(str) */ static int connection_quote(lua_State *L) { luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_DB2_CONNECTION, "quote"); return 0; } /* * success = connection:rollback() */ static int connection_rollback(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); int err = 1; if (conn->db2) { err = rollback(conn); } lua_pushboolean(L, !err); return 1; } /* * __gc */ static int connection_gc(lua_State *L) { /* always close the connection */ connection_close(L); return 0; } /* * __tostring */ static int connection_tostring(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_DB2_CONNECTION); lua_pushfstring(L, "%s: %p", DBD_DB2_CONNECTION, conn); return 1; } int dbd_db2_connection(lua_State *L) { static const luaL_Reg connection_methods[] = { {"autocommit", connection_autocommit}, {"close", connection_close}, {"commit", connection_commit}, {"ping", connection_ping}, {"prepare", connection_prepare}, {"quote", connection_quote}, {"rollback", connection_rollback}, {NULL, NULL} }; static const luaL_Reg connection_class_methods[] = { {"New", connection_new}, {NULL, NULL} }; luaL_newmetatable(L, DBD_DB2_CONNECTION); luaL_register(L, 0, connection_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, connection_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_DB2_CONNECTION, connection_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/db2/dbd_db2.h000066400000000000000000000016521220150355400176140ustar00rootroot00000000000000#undef UNICODE #include #include #include #include #define DBD_DB2_CONNECTION "DBD.DB2.Connection" #define DBD_DB2_STATEMENT "DBD.DB2.Statement" /* * result set metadata */ typedef struct _resultset { SQLSMALLINT name_len; SQLSMALLINT type; SQLUINTEGER size; SQLSMALLINT scale; SQLCHAR name[32]; } resultset_t; /* * bind parameters */ typedef struct _bindparams { SQLCHAR *buffer; SQLINTEGER len; SQLINTEGER buffer_len; } bindparams_t; /* * connection object implentation */ typedef struct _connection { SQLHANDLE env; SQLHANDLE db2; } connection_t; /* * statement object implementation */ typedef struct _statement { resultset_t * resultset; bindparams_t * bind; unsigned char *buffer; SQLSMALLINT num_result_columns; /* variable for SQLNumResultCols */ SQLHANDLE stmt; SQLHANDLE db2; } statement_t; lua-dbi-0.5.hg5ba1dd988961/dbd/db2/main.c000066400000000000000000000003661220150355400172540ustar00rootroot00000000000000#include "dbd_db2.h" int dbd_db2_connection(lua_State *L); int dbd_db2_statement(lua_State *L); /* * library entry point */ LUA_EXPORT int luaopen_dbddb2(lua_State *L) { dbd_db2_connection(L); dbd_db2_statement(L); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/db2/statement.c000066400000000000000000000331661220150355400203400ustar00rootroot00000000000000#include "dbd_db2.h" #define BIND_BUFFER_SIZE 1024 static lua_push_type_t db2_to_lua_push(unsigned int db2_type, int len) { lua_push_type_t lua_type; if (len == SQL_NULL_DATA) return LUA_PUSH_NIL; switch(db2_type) { case SQL_SMALLINT: case SQL_INTEGER: lua_type = LUA_PUSH_INTEGER; break; case SQL_DECIMAL: lua_type = LUA_PUSH_NUMBER; break; default: lua_type = LUA_PUSH_STRING; } return lua_type; } /* * num_affected_rows = statement:affected() */ static int statement_affected(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); SQLRETURN rc = SQL_SUCCESS; SQLINTEGER affected; if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } rc = SQLRowCount(statement->stmt, &affected); lua_pushinteger(L, affected); return 1; } /* * success = statement:close() */ static int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); if (statement->stmt) { SQLFreeHandle(SQL_HANDLE_STMT, statement->stmt); if (statement->resultset) { free(statement->resultset); statement->resultset = NULL; } if (statement->bind) { int i; for (i = 0; i < statement->num_result_columns; i++) { free(statement->bind[i].buffer); } free(statement->bind); statement->bind = NULL; } statement->num_result_columns = 0; } return 0; } /* * column_names = statement:columns() */ static int statement_columns(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); int i; int d; SQLRETURN rc = SQL_SUCCESS; if (!statement->resultset || !statement->bind) { lua_pushnil(L); return 1; } d = 1; lua_newtable(L); for (i = 0; i < statement->num_result_columns; i++) { const char *name = strlower(statement->resultset[i].name); LUA_PUSH_ARRAY_STRING(d, name); } return 1; } /* * success = statement:execute(...) */ static int statement_execute(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); int n = lua_gettop(L); int p; int i; int errflag = 0; const char *errstr = NULL; SQLRETURN rc = SQL_SUCCESS; unsigned char *buffer = NULL; int offset = 0; resultset_t *resultset = NULL; bindparams_t *bind; /* variable to read the results */ SQLSMALLINT num_params; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; if (!statement->stmt) { lua_pushboolean(L, 0); lua_pushstring(L, DBI_ERR_EXECUTE_INVALID); return 2; } rc = SQLNumParams(statement->stmt, &num_params); if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, message); return 2; } if (num_params != n-1) { /* * SQLExecute does not handle this condition, * and the client library will fill unset params * with NULLs */ lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, num_params, n-1); return 2; } if (num_params > 0) { buffer = (unsigned char *)malloc(sizeof(double) * num_params); } for (p = 2; p <= n; p++) { int i = p - 1; int type = lua_type(L, p); char err[64]; const char *str = NULL; size_t len = 0; double *num; int *boolean; const static SQLLEN nullvalue = SQL_NULL_DATA; switch(type) { case LUA_TNIL: rc = SQLBindParameter(statement->stmt, i, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)0, 0, (SQLPOINTER)&nullvalue); errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; case LUA_TNUMBER: num = (double *)(buffer + offset); *num = lua_tonumber(L, p); offset += sizeof(double); rc = SQLBindParameter(statement->stmt, i, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DECIMAL, 10, 0, (SQLPOINTER)num, 0, NULL); errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; case LUA_TSTRING: str = lua_tolstring(L, p, &len); rc = SQLBindParameter(statement->stmt, i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLPOINTER)str, len, NULL); errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; case LUA_TBOOLEAN: boolean = (int *)(buffer + offset); *boolean = lua_toboolean(L, p); offset += sizeof(int); rc = SQLBindParameter(statement->stmt, i, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, (SQLPOINTER)boolean, len, NULL); errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; default: /* * Unknown/unsupported value type */ errflag = 1; snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); errstr = err; } if (errflag) break; } if (errflag) { if (buffer) free(buffer); lua_pushboolean(L, 0); if (errstr) { lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr); } else { SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, message); } return 2; } rc = SQLExecute(statement->stmt); if (rc != SQL_SUCCESS) { if (buffer) free(buffer); SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, message); return 2; } /* * identify the number of output columns */ rc = SQLNumResultCols(statement->stmt, &statement->num_result_columns); if (statement->num_result_columns > 0) { resultset = (resultset_t *)malloc(sizeof(resultset_t) * statement->num_result_columns); memset(resultset, 0, sizeof(resultset_t) * statement->num_result_columns); bind = (bindparams_t *)malloc(sizeof(bindparams_t) * statement->num_result_columns); memset(bind, 0, sizeof(bindparams_t) * statement->num_result_columns); for (i = 0; i < statement->num_result_columns; i++) { /* * return a set of attributes for a column */ rc = SQLDescribeCol(statement->stmt, (SQLSMALLINT)(i + 1), resultset[i].name, sizeof(resultset[i].name), &resultset[i].name_len, &resultset[i].type, &resultset[i].size, &resultset[i].scale, NULL); if (rc != SQL_SUCCESS) { if (buffer) free(buffer); SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_DESC_RESULT, message); return 2; } bind[i].buffer_len = resultset[i].size+1; /* *allocate memory to bind a column */ bind[i].buffer = (SQLCHAR *)malloc((int)bind[i].buffer_len); rc = SQLBindCol(statement->stmt, (SQLSMALLINT)(i + 1), SQL_C_CHAR, bind[i].buffer, bind[i].buffer_len, &bind[i].len); if (rc != SQL_SUCCESS) { if (buffer) free(buffer); SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_ALLOC_RESULT, message); return 2; } } statement->resultset = resultset; statement->bind = bind; } if (buffer) free(buffer); lua_pushboolean(L, 1); return 1; } /* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int i; int d; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; SQLRETURN rc = SQL_SUCCESS; if (!statement->resultset || !statement->bind) { lua_pushnil(L); return 1; } /* fetch each row, and display */ rc = SQLFetch(statement->stmt); if (rc == SQL_NO_DATA_FOUND) { SQLFreeStmt(statement->stmt, SQL_RESET_PARAMS); lua_pushnil(L); return 1; } if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); luaL_error(L, DBI_ERR_FETCH_FAILED, message); } d = 1; lua_newtable(L); for (i = 0; i < statement->num_result_columns; i++) { lua_push_type_t lua_push = db2_to_lua_push(statement->resultset[i].type, statement->bind[i].len); const char *name = strlower(statement->resultset[i].name); double val; char *value = (char *)statement->bind[i].buffer; switch (lua_push) { case LUA_PUSH_NIL: if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } break; case LUA_PUSH_INTEGER: if (named_columns) { LUA_PUSH_ATTRIB_INT(name, atoi(value)); } else { LUA_PUSH_ARRAY_INT(d, atoi(value)); } break; case LUA_PUSH_NUMBER: val = strtod(value, NULL); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } break; case LUA_PUSH_BOOLEAN: if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, atoi(value)); } else { LUA_PUSH_ARRAY_BOOL(d, atoi(value)); } break; case LUA_PUSH_STRING: if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, value); } else { LUA_PUSH_ARRAY_STRING(d, value); } break; default: luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } return 1; } static int next_iterator(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_DB2_STATEMENT); int named_columns = lua_toboolean(L, lua_upvalueindex(2)); return statement_fetch_impl(L, statement, named_columns); } /* * table = statement:fetch(named_indexes) */ static int statement_fetch(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); int named_columns = lua_toboolean(L, 2); return statement_fetch_impl(L, statement, named_columns); } /* * num_rows = statement:rowcount() */ static int statement_rowcount(lua_State *L) { luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_DB2_STATEMENT, "rowcount"); return 0; } /* * iterfunc = statement:rows(named_indexes) */ static int statement_rows(lua_State *L) { if (lua_gettop(L) == 1) { lua_pushvalue(L, 1); lua_pushboolean(L, 0); } else { lua_pushvalue(L, 1); lua_pushboolean(L, lua_toboolean(L, 2)); } lua_pushcclosure(L, next_iterator, 2); return 1; } /* * __gc */ static int statement_gc(lua_State *L) { /* always free the handle */ statement_close(L); return 0; } /* * __tostring */ static int statement_tostring(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); lua_pushfstring(L, "%s: %p", DBD_DB2_STATEMENT, statement); return 1; } int dbd_db2_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { SQLRETURN rc = SQL_SUCCESS; statement_t *statement = NULL; SQLHANDLE stmt; SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER sqlcode; SQLSMALLINT length; rc = SQLAllocHandle(SQL_HANDLE_STMT, conn->db2, &stmt); if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_DBC, conn->db2, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_ALLOC_STATEMENT, message); return 2; } /* * turn off deferred prepare * statements will be sent to the server at prepare time, * and therefore we can catch errors now rather * than at execute time */ rc = SQLSetStmtAttr(stmt,SQL_ATTR_DEFERRED_PREPARE,(SQLPOINTER)SQL_DEFERRED_PREPARE_OFF,0); rc = SQLPrepare(stmt, (SQLCHAR *)sql_query, SQL_NTS); if (rc != SQL_SUCCESS) { SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, message); return 2; } statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); statement->stmt = stmt; statement->db2 = conn->db2; statement->resultset = NULL; statement->bind = NULL; luaL_getmetatable(L, DBD_DB2_STATEMENT); lua_setmetatable(L, -2); return 1; } int dbd_db2_statement(lua_State *L) { static const luaL_Reg statement_methods[] = { {"affected", statement_affected}, {"close", statement_close}, {"columns", statement_columns}, {"execute", statement_execute}, {"fetch", statement_fetch}, {"rowcount", statement_rowcount}, {"rows", statement_rows}, {NULL, NULL} }; static const luaL_Reg statement_class_methods[] = { {NULL, NULL} }; luaL_newmetatable(L, DBD_DB2_STATEMENT); luaL_register(L, 0, statement_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, statement_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, statement_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_DB2_STATEMENT, statement_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/mysql/000077500000000000000000000000001220150355400166555ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/mysql/connection.c000066400000000000000000000122371220150355400211650ustar00rootroot00000000000000#include "dbd_mysql.h" int dbd_mysql_statement_create(lua_State *L, connection_t *conn, const char *sql_query); /* * connection,err = DBD.MySQl.New(dbname, user, password, host, port) */ static int connection_new(lua_State *L) { int n = lua_gettop(L); connection_t *conn = NULL; const char *host = NULL; const char *user = NULL; const char *password = NULL; const char *db = NULL; int port = 0; const char *unix_socket = NULL; /* TODO always NULL */ int client_flag = 0; /* TODO always 0, set flags from options table */ /* db, user, password, host, port */ switch (n) { case 5: if (lua_isnil(L, 5) == 0) port = luaL_checkint(L, 5); case 4: if (lua_isnil(L, 4) == 0) host = luaL_checkstring(L, 4); case 3: if (lua_isnil(L, 3) == 0) password = luaL_checkstring(L, 3); case 2: if (lua_isnil(L, 2) == 0) user = luaL_checkstring(L, 2); case 1: /* * db is the only mandatory parameter */ db = luaL_checkstring(L, 1); } conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); conn->mysql = mysql_init(NULL); if (!mysql_real_connect(conn->mysql, host, user, password, db, port, unix_socket, client_flag)) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, mysql_error(conn->mysql)); return 2; } /* * by default turn off autocommit */ mysql_autocommit(conn->mysql, 0); luaL_getmetatable(L, DBD_MYSQL_CONNECTION); lua_setmetatable(L, -2); return 1; } /* * success = connection:autocommit(on) */ static int connection_autocommit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); int on = lua_toboolean(L, 2); int err = 0; if (conn->mysql) { err = mysql_autocommit(conn->mysql, on); } lua_pushboolean(L, !err); return 1; } /* * success = connection:close() */ static int connection_close(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); int disconnect = 0; if (conn->mysql) { mysql_close(conn->mysql); disconnect = 1; conn->mysql = NULL; } lua_pushboolean(L, disconnect); return 1; } /* * success = connection:commit() */ static int connection_commit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); int err = 0; if (conn->mysql) { err = mysql_commit(conn->mysql); } lua_pushboolean(L, !err); return 1; } /* * ok = connection:ping() */ static int connection_ping(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); int err = 1; if (conn->mysql) { err = mysql_ping(conn->mysql); } lua_pushboolean(L, !err); return 1; } /* * statement,err = connection:prepare(sql_string) */ static int connection_prepare(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); if (conn->mysql) { return dbd_mysql_statement_create(L, conn, luaL_checkstring(L, 2)); } lua_pushnil(L); lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); return 2; } /* * quoted = connection:quote(str) */ static int connection_quote(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); size_t len; const char *from = luaL_checklstring(L, 2, &len); char *to = (char *)calloc(len*2+1, sizeof(char)); int quoted_len; if (!conn->mysql) { luaL_error(L, DBI_ERR_DB_UNAVAILABLE); } quoted_len = mysql_real_escape_string(conn->mysql, to, from, len); lua_pushlstring(L, to, quoted_len); free(to); return 1; } /* * success = connection:rollback() */ static int connection_rollback(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); int err = 0; if (conn->mysql) { err = mysql_rollback(conn->mysql); } lua_pushboolean(L, !err); return 1; } /* * __gc */ static int connection_gc(lua_State *L) { /* always close the connection */ connection_close(L); return 0; } /* * __tostring */ static int connection_tostring(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION); lua_pushfstring(L, "%s: %p", DBD_MYSQL_CONNECTION, conn); return 1; } int dbd_mysql_connection(lua_State *L) { static const luaL_Reg connection_methods[] = { {"autocommit", connection_autocommit}, {"close", connection_close}, {"commit", connection_commit}, {"ping", connection_ping}, {"prepare", connection_prepare}, {"quote", connection_quote}, {"rollback", connection_rollback}, {NULL, NULL} }; static const luaL_Reg connection_class_methods[] = { {"New", connection_new}, {NULL, NULL} }; luaL_newmetatable(L, DBD_MYSQL_CONNECTION); luaL_register(L, 0, connection_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, connection_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_MYSQL_CONNECTION, connection_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/mysql/dbd_mysql.h000066400000000000000000000010211220150355400207760ustar00rootroot00000000000000#ifdef _MSC_VER /* all MS compilers define this (version) */ #include #endif #include #include #define DBD_MYSQL_CONNECTION "DBD.MySQL.Connection" #define DBD_MYSQL_STATEMENT "DBD.MySQL.Statement" /* * connection object implementation */ typedef struct _connection { MYSQL *mysql; } connection_t; /* * statement object implementation */ typedef struct _statement { MYSQL *mysql; MYSQL_STMT *stmt; MYSQL_RES *metadata; /* result dataset metadata */ } statement_t; lua-dbi-0.5.hg5ba1dd988961/dbd/mysql/main.c000066400000000000000000000004011220150355400177400ustar00rootroot00000000000000#include "dbd_mysql.h" int dbd_mysql_connection(lua_State *L); int dbd_mysql_statement(lua_State *L); /* * libabry entry point */ LUA_EXPORT int luaopen_dbdmysql(lua_State *L) { dbd_mysql_connection(L); dbd_mysql_statement(L); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/mysql/statement.c000066400000000000000000000336251220150355400210360ustar00rootroot00000000000000#include "dbd_mysql.h" static lua_push_type_t mysql_to_lua_push(unsigned int mysql_type) { lua_push_type_t lua_type; switch(mysql_type) { case MYSQL_TYPE_NULL: lua_type = LUA_PUSH_NIL; break; case MYSQL_TYPE_TINY: case MYSQL_TYPE_YEAR: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: lua_type = LUA_PUSH_INTEGER; break; case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_LONGLONG: lua_type = LUA_PUSH_NUMBER; break; default: lua_type = LUA_PUSH_STRING; } return lua_type; } static size_t mysql_buffer_size(MYSQL_FIELD *field) { unsigned int mysql_type = field->type; size_t size = 0; switch (mysql_type) { case MYSQL_TYPE_TINY: size = 1; break; case MYSQL_TYPE_YEAR: case MYSQL_TYPE_SHORT: size = 2; break; case MYSQL_TYPE_INT24: size = 4; break; case MYSQL_TYPE_LONG: size = 4; break; case MYSQL_TYPE_LONGLONG: size = 8; break; case MYSQL_TYPE_FLOAT: size = 4; break; case MYSQL_TYPE_DOUBLE: size = 8; break; case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: size = sizeof(MYSQL_TIME); break; default: size = field->length; } return size; } /* * num_affected_rows = statement:affected() */ static int statement_affected(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } lua_pushinteger(L, mysql_stmt_affected_rows(statement->stmt)); return 1; } /* * success = statement:close() */ static int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); if (statement->metadata) { mysql_free_result(statement->metadata); statement->metadata = NULL; } if (statement->stmt) { mysql_stmt_close(statement->stmt); statement->stmt = NULL; } lua_pushboolean(L, 1); return 1; } /* * column_names = statement:columns() */ static int statement_columns(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); MYSQL_FIELD *fields; int i; int num_columns; int d = 1; if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); return 0; } fields = mysql_fetch_fields(statement->metadata); num_columns = mysql_num_fields(statement->metadata); lua_newtable(L); for (i = 0; i < num_columns; i++) { const char *name = fields[i].name; LUA_PUSH_ARRAY_STRING(d, name); } return 1; } /* * success,err = statement:execute(...) */ static int statement_execute(lua_State *L) { int n = lua_gettop(L); statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); int num_bind_params = n - 1; int expected_params; unsigned char *buffer = NULL; int offset = 0; MYSQL_BIND *bind = NULL; MYSQL_RES *metadata = NULL; char *error_message = NULL; char *errstr = NULL; int p; if (statement->metadata) { /* * free existing metadata from any previous executions */ mysql_free_result(statement->metadata); statement->metadata = NULL; } if (!statement->stmt) { lua_pushboolean(L, 0); lua_pushstring(L, DBI_ERR_EXECUTE_INVALID); return 2; } expected_params = mysql_stmt_param_count(statement->stmt); if (expected_params != num_bind_params) { /* * mysql_stmt_bind_param does not handle this condition, * and the client library will segfault if these do no match */ lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params); return 2; } if (num_bind_params > 0) { bind = malloc(sizeof(MYSQL_BIND) * num_bind_params); if (bind == NULL) { luaL_error(L, "Could not alloc bind params\n"); } buffer = (unsigned char *)malloc(num_bind_params * sizeof(double)); memset(bind, 0, sizeof(MYSQL_BIND) * num_bind_params); } for (p = 2; p <= n; p++) { int type = lua_type(L, p); int i = p - 2; const char *str = NULL; size_t *str_len = NULL; double *num = NULL; int *boolean = NULL; char err[64]; switch(type) { case LUA_TNIL: bind[i].buffer_type = MYSQL_TYPE_NULL; bind[i].is_null = (my_bool*)1; break; case LUA_TBOOLEAN: boolean = (int *)(buffer + offset); offset += sizeof(int); *boolean = lua_toboolean(L, p); bind[i].buffer_type = MYSQL_TYPE_LONG; bind[i].is_null = (my_bool*)0; bind[i].buffer = (char *)boolean; bind[i].length = 0; break; case LUA_TNUMBER: /* * num needs to be it's own * memory here */ num = (double *)(buffer + offset); offset += sizeof(double); *num = lua_tonumber(L, p); bind[i].buffer_type = MYSQL_TYPE_DOUBLE; bind[i].is_null = (my_bool*)0; bind[i].buffer = (char *)num; bind[i].length = 0; break; case LUA_TSTRING: str_len = (size_t *)(buffer + offset); offset += sizeof(size_t); str = lua_tolstring(L, p, str_len); bind[i].buffer_type = MYSQL_TYPE_STRING; bind[i].is_null = (my_bool*)0; bind[i].buffer = (char *)str; bind[i].length = str_len; break; default: snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); errstr = err; error_message = DBI_ERR_BINDING_PARAMS; goto cleanup; } } if (mysql_stmt_bind_param(statement->stmt, bind)) { error_message = DBI_ERR_BINDING_PARAMS; goto cleanup; } if (mysql_stmt_execute(statement->stmt)) { error_message = DBI_ERR_BINDING_EXEC; goto cleanup; } metadata = mysql_stmt_result_metadata(statement->stmt); if (metadata) { mysql_stmt_store_result(statement->stmt); } cleanup: if (bind) { free(bind); } if (buffer) { free(buffer); } if (error_message) { lua_pushboolean(L, 0); lua_pushfstring(L, error_message, errstr ? errstr : mysql_stmt_error(statement->stmt)); return 2; } statement->metadata = metadata; lua_pushboolean(L, 1); return 1; } static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int column_count, fetch_result_ok; MYSQL_BIND *bind = NULL; unsigned long *real_length = NULL; const char *error_message = NULL; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->metadata) { luaL_error(L, DBI_ERR_FETCH_NO_EXECUTE); return 0; } column_count = mysql_num_fields(statement->metadata); if (column_count > 0) { int i; MYSQL_FIELD *fields; real_length = calloc(column_count, sizeof(unsigned long)); bind = malloc(sizeof(MYSQL_BIND) * column_count); memset(bind, 0, sizeof(MYSQL_BIND) * column_count); fields = mysql_fetch_fields(statement->metadata); for (i = 0; i < column_count; i++) { unsigned int length = mysql_buffer_size(&fields[i]); if (length > sizeof(MYSQL_TIME)) { bind[i].buffer = NULL; bind[i].buffer_length = 0; } else { char *buffer = (char *)malloc(length); memset(buffer, 0, length); bind[i].buffer = buffer; bind[i].buffer_length = length; } bind[i].buffer_type = fields[i].type; bind[i].length = &real_length[i]; } if (mysql_stmt_bind_result(statement->stmt, bind)) { error_message = DBI_ERR_BINDING_RESULTS; goto cleanup; } fetch_result_ok = mysql_stmt_fetch(statement->stmt); if (fetch_result_ok == 0 || fetch_result_ok == MYSQL_DATA_TRUNCATED) { int d = 1; lua_newtable(L); for (i = 0; i < column_count; i++) { lua_push_type_t lua_push = mysql_to_lua_push(fields[i].type); const char *name = fields[i].name; if (bind[i].buffer == NULL) { char *buffer = (char *)calloc(real_length[i]+1, sizeof(char)); bind[i].buffer = buffer; bind[i].buffer_length = real_length[i]; mysql_stmt_fetch_column(statement->stmt, &bind[i], i, 0); } if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { if (fields[i].type == MYSQL_TYPE_YEAR || fields[i].type == MYSQL_TYPE_SHORT) { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, *(short *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, *(short *)(bind[i].buffer)); } } else if (fields[i].type == MYSQL_TYPE_TINY) { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, (int)*(char *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, (int)*(char *)(bind[i].buffer)); } } else { if (named_columns) { LUA_PUSH_ATTRIB_INT(name, *(int *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_INT(d, *(int *)(bind[i].buffer)); } } } else if (lua_push == LUA_PUSH_NUMBER) { if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer)); } } else if (lua_push == LUA_PUSH_STRING) { if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 20, "%d-%02d-%02d %02d:%02d:%02d", t->year, t->month, t->day, t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else if (fields[i].type == MYSQL_TYPE_TIME) { char str[9]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 9, "%02d:%02d:%02d", t->hour, t->minute, t->second); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else if (fields[i].type == MYSQL_TYPE_DATE) { char str[20]; struct st_mysql_time *t = bind[i].buffer; snprintf(str, 11, "%d-%02d-%02d", t->year, t->month, t->day); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, str); } else { LUA_PUSH_ARRAY_STRING(d, str); } } else { if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, bind[i].buffer); } else { LUA_PUSH_ARRAY_STRING(d, bind[i].buffer); } } } else if (lua_push == LUA_PUSH_BOOLEAN) { if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, *(int *)(bind[i].buffer)); } else { LUA_PUSH_ARRAY_BOOL(d, *(int *)(bind[i].buffer)); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { lua_pushnil(L); } } cleanup: free(real_length); if (bind) { int i; for (i = 0; i < column_count; i++) { free(bind[i].buffer); } free(bind); } if (error_message) { luaL_error(L, error_message, mysql_stmt_error(statement->stmt)); return 0; } return 1; } static int next_iterator(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_MYSQL_STATEMENT); int named_columns = lua_toboolean(L, lua_upvalueindex(2)); return statement_fetch_impl(L, statement, named_columns); } /* * table = statement:fetch(named_indexes) */ static int statement_fetch(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); int named_columns = lua_toboolean(L, 2); return statement_fetch_impl(L, statement, named_columns); } /* * num_rows = statement:rowcount() */ static int statement_rowcount(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } lua_pushinteger(L, mysql_stmt_num_rows(statement->stmt)); return 1; } /* * iterfunc = statement:rows(named_indexes) */ static int statement_rows(lua_State *L) { if (lua_gettop(L) == 1) { lua_pushvalue(L, 1); lua_pushboolean(L, 0); } else { lua_pushvalue(L, 1); lua_pushboolean(L, lua_toboolean(L, 2)); } lua_pushcclosure(L, next_iterator, 2); return 1; } /* * __gc */ static int statement_gc(lua_State *L) { /* always free the handle */ statement_close(L); return 0; } /* * __tostring */ static int statement_tostring(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT); lua_pushfstring(L, "%s: %p", DBD_MYSQL_STATEMENT, statement); return 1; } int dbd_mysql_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { unsigned long sql_len = strlen(sql_query); statement_t *statement = NULL; MYSQL_STMT *stmt = mysql_stmt_init(conn->mysql); if (!stmt) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_ALLOC_STATEMENT, mysql_error(conn->mysql)); return 2; } if (mysql_stmt_prepare(stmt, sql_query, sql_len)) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, mysql_stmt_error(stmt)); return 2; } statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); statement->mysql = conn->mysql; statement->stmt = stmt; statement->metadata = NULL; /* mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (my_bool*)0); */ luaL_getmetatable(L, DBD_MYSQL_STATEMENT); lua_setmetatable(L, -2); return 1; } int dbd_mysql_statement(lua_State *L) { static const luaL_Reg statement_methods[] = { {"affected", statement_affected}, {"close", statement_close}, {"columns", statement_columns}, {"execute", statement_execute}, {"fetch", statement_fetch}, {"rowcount", statement_rowcount}, {"rows", statement_rows}, {NULL, NULL} }; static const luaL_Reg statement_class_methods[] = { {NULL, NULL} }; luaL_newmetatable(L, DBD_MYSQL_STATEMENT); luaL_register(L, 0, statement_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, statement_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, statement_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_MYSQL_STATEMENT, statement_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/oracle/000077500000000000000000000000001220150355400167555ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/oracle/connection.c000066400000000000000000000133301220150355400212600ustar00rootroot00000000000000#include "dbd_oracle.h" int dbd_oracle_statement_create(lua_State *L, connection_t *conn, const char *sql_query); static int commit(connection_t *conn) { int rc = OCITransCommit(conn->svc, conn->err, OCI_DEFAULT); return rc; } static int rollback(connection_t *conn) { int rc = OCITransRollback(conn->svc, conn->err, OCI_DEFAULT); return rc; } /* * connection,err = DBD.Oracle.New(dbfile) */ static int connection_new(lua_State *L) { int n = lua_gettop(L); int rc = 0; const char *user = NULL; const char *password = NULL; const char *db = NULL; OCIEnv *env = NULL; OCIError *err = NULL; OCISvcCtx *svc = NULL; connection_t *conn = NULL; /* db, user, password */ switch(n) { case 5: case 4: case 3: if (lua_isnil(L, 3) == 0) password = luaL_checkstring(L, 3); case 2: if (lua_isnil(L, 2) == 0) user = luaL_checkstring(L, 2); case 1: /* * db is the only mandatory parameter */ db = luaL_checkstring(L, 1); } /* * initialise OCI */ OCIInitialize((ub4) OCI_DEFAULT, (dvoid *)0, (dvoid * (*)(dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0, (void (*)(dvoid *, dvoid *))0); /* * initialise environment */ OCIEnvInit((OCIEnv **)&env, OCI_DEFAULT, 0, (dvoid **)0); /* * server contexts */ OCIHandleAlloc((dvoid *)env, (dvoid **)&err, OCI_HTYPE_ERROR, 0, (dvoid **)0); OCIHandleAlloc((dvoid *)env, (dvoid **)&svc, OCI_HTYPE_SVCCTX, 0, (dvoid **)0); /* * connect to database server */ rc = OCILogon(env, err, &svc, user, strlen(user), password, strlen(password), db, strlen(db)); if (rc != 0) { char errbuf[100]; int errcode; OCIErrorGet((dvoid *)err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, errbuf); return 2; } conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); conn->oracle = env; conn->err = err; conn->svc = svc; conn->autocommit = 0; luaL_getmetatable(L, DBD_ORACLE_CONNECTION); lua_setmetatable(L, -2); return 1; } /* * success = connection:autocommit(on) */ static int connection_autocommit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); int on = lua_toboolean(L, 2); int err = 1; if (conn->oracle) { if (on) rollback(conn); conn->autocommit = on; err = 0; } lua_pushboolean(L, !err); return 1; } /* * success = connection:close() */ static int connection_close(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); int disconnect = 0; if (conn->oracle) { rollback(conn); OCILogoff(conn->svc, conn->err); if (conn->svc) OCIHandleFree((dvoid *)conn->svc, OCI_HTYPE_ENV); if (conn->err) OCIHandleFree((dvoid *)conn->err, OCI_HTYPE_ERROR); disconnect = 1; conn->oracle = NULL; } lua_pushboolean(L, disconnect); return 1; } /* * success = connection:commit() */ static int connection_commit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); int err = 1; if (conn->oracle) { err = commit(conn); } lua_pushboolean(L, !err); return 1; } /* * ok = connection:ping() */ static int connection_ping(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); int ok = 0; if (conn->oracle) { ok = 1; } lua_pushboolean(L, ok); return 1; } /* * statement,err = connection:prepare(sql_str) */ static int connection_prepare(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); if (conn->oracle) { return dbd_oracle_statement_create(L, conn, luaL_checkstring(L, 2)); } lua_pushnil(L); lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); return 2; } /* * quoted = connection:quote(str) */ static int connection_quote(lua_State *L) { luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_ORACLE_CONNECTION, "quote"); return 0; } /* * success = connection:rollback() */ static int connection_rollback(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); int err = 1; if (conn->oracle) { err = rollback(conn); } lua_pushboolean(L, !err); return 1; } /* * __gc */ static int connection_gc(lua_State *L) { /* always close the connection */ connection_close(L); return 0; } /* * __tostring */ static int connection_tostring(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_ORACLE_CONNECTION); lua_pushfstring(L, "%s: %p", DBD_ORACLE_CONNECTION, conn); return 1; } int dbd_oracle_connection(lua_State *L) { /* * instance methods */ static const luaL_Reg connection_methods[] = { {"autocommit", connection_autocommit}, {"close", connection_close}, {"commit", connection_commit}, {"ping", connection_ping}, {"prepare", connection_prepare}, {"quote", connection_quote}, {"rollback", connection_rollback}, {NULL, NULL} }; /* * class methods */ static const luaL_Reg connection_class_methods[] = { {"New", connection_new}, {NULL, NULL} }; luaL_newmetatable(L, DBD_ORACLE_CONNECTION); luaL_register(L, 0, connection_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, connection_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_ORACLE_CONNECTION, connection_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/oracle/dbd_oracle.h000066400000000000000000000013101220150355400211770ustar00rootroot00000000000000#include #include #define DBD_ORACLE_CONNECTION "DBD.Oracle.Connection" #define DBD_ORACLE_STATEMENT "DBD.Oracle.Statement" typedef struct _bindparams { OCIParam *param; text *name; ub4 name_len; ub2 data_type; ub2 max_len; char *data; OCIDefine *define; sb2 null; } bindparams_t; /* * connection object */ typedef struct _connection { OCIEnv *oracle; OCISvcCtx *svc; OCIError *err; OCIServer *srv; OCISession *auth; int autocommit; } connection_t; /* * statement object */ typedef struct _statement { OCIStmt *stmt; connection_t *conn; int num_columns; bindparams_t *bind; int metadata; } statement_t; lua-dbi-0.5.hg5ba1dd988961/dbd/oracle/main.c000066400000000000000000000004111220150355400200410ustar00rootroot00000000000000#include "dbd_oracle.h" int dbd_oracle_connection(lua_State *L); int dbd_oracle_statement(lua_State *L); /* * library entry point */ LUA_EXPORT int luaopen_dbdoracle(lua_State *L) { dbd_oracle_connection(L); dbd_oracle_statement(L); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/oracle/statement.c000066400000000000000000000320411220150355400211250ustar00rootroot00000000000000#include "dbd_oracle.h" /* * Converts SQLite types to Lua types */ static lua_push_type_t oracle_to_lua_push(unsigned int oracle_type, int null) { lua_push_type_t lua_type; if (null) return LUA_PUSH_NIL; switch(oracle_type) { case SQLT_NUM: case SQLT_FLT: lua_type = LUA_PUSH_NUMBER; break; case SQLT_INT: lua_type = LUA_PUSH_INTEGER; break; default: lua_type = LUA_PUSH_STRING; } return lua_type; } /* * Fetch metadata from the database */ static void statement_fetch_metadata(lua_State *L, statement_t *statement) { bindparams_t *bind; int i; char errbuf[100]; int errcode; int rc; if (statement->metadata) return; statement->bind = (bindparams_t *)malloc(sizeof(bindparams_t) * statement->num_columns); memset(statement->bind, 0, sizeof(bindparams_t) * statement->num_columns); bind = statement->bind; for (i = 0; i < statement->num_columns; i++) { rc = OCIParamGet(statement->stmt, OCI_HTYPE_STMT, statement->conn->err, (dvoid **)&bind[i].param, i+1); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, "param get %s", errbuf); } rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].name), (ub4 *)&(bind[i].name_len), OCI_ATTR_NAME, statement->conn->err); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, "name get %s", errbuf); } rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].data_type), (ub4 *)0, OCI_ATTR_DATA_TYPE, statement->conn->err); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, "datatype get %s", errbuf); } rc = OCIAttrGet(bind[i].param, OCI_DTYPE_PARAM, (dvoid *)&(bind[i].max_len), 0, OCI_ATTR_DATA_SIZE, statement->conn->err); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, "datasize get %s", errbuf); } bind[i].data = calloc(bind[i].max_len+1, sizeof(char)); rc = OCIDefineByPos(statement->stmt, &bind[i].define, statement->conn->err, (ub4)i+1, bind[i].data, bind[i].max_len, SQLT_STR, (dvoid *)&(bind[i].null), (ub2 *)0, (ub2 *)0, (ub4)OCI_DEFAULT); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, "define by pos %s", errbuf); } } statement->metadata = 1; } /* * num_affected_rows = statement:affected() */ static int statement_affected(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); int affected; int rc; if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } /* * get number of affected rows */ rc = OCIAttrGet( (dvoid *)statement->stmt, (ub4)OCI_HTYPE_STMT, (dvoid *)&affected, (ub4 *)0, (ub4)OCI_ATTR_ROW_COUNT, statement->conn->err ); lua_pushinteger(L, affected); return 1; } /* * success = statement:close() */ int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); int ok = 0; if (statement->stmt) { int rc; rc = OCIHandleFree((dvoid *)statement->stmt, OCI_HTYPE_STMT); /* Free handles */ statement->stmt = NULL; } if (statement->bind) { free(statement->bind); statement->bind = NULL; } lua_pushboolean(L, ok); return 1; } /* * column_names = statement:columns() */ static int statement_columns(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); int rc; bindparams_t *bind; char errbuf[100]; int errcode; int i; int d = 1; if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); return 0; } statement_fetch_metadata(L, statement); lua_newtable(L); for (i = 0; i < statement->num_columns; i++) { const char *name = strlower(statement->bind[i].name); LUA_PUSH_ARRAY_STRING(d, name); } return 1; } /* * success,err = statement:execute(...) */ int statement_execute(lua_State *L) { int n = lua_gettop(L); statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); int p; int errflag = 0; const char *errstr = NULL; int num_columns; int rc; char errbuf[100]; int errcode; ub2 type; if (!statement->stmt) { lua_pushboolean(L, 0); lua_pushstring(L, DBI_ERR_EXECUTE_INVALID); return 2; } for (p = 2; p <= n; p++) { int i = p - 1; int type = lua_type(L, p); char err[64]; const char *value; OCIBind *bnd = (OCIBind *)0; switch(type) { case LUA_TNIL: errflag = OCIBindByPos( statement->stmt, &bnd, statement->conn->err, i, NULL, 0, SQLT_CHR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT); break; case LUA_TNUMBER: case LUA_TSTRING: case LUA_TBOOLEAN: value = lua_tostring(L, p); errflag = OCIBindByPos( statement->stmt, &bnd, statement->conn->err, i, value, strlen(value), SQLT_CHR, (dvoid *)0, (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, (ub4)OCI_DEFAULT); break; default: /* * Unknown/unsupported value type */ errflag = 1; snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); errstr = err; } if (errflag) break; } if (errflag) { lua_pushboolean(L, 0); if (errstr) lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr); else { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errbuf); } return 2; } /* * statement type */ rc = OCIAttrGet( (dvoid *)statement->stmt, (ub4)OCI_HTYPE_STMT, (dvoid *)&type, (ub4 *)0, (ub4)OCI_ATTR_STMT_TYPE, statement->conn->err ); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); lua_pushboolean(L, 0); lua_pushfstring(L, "Error getting type: %s", errbuf); return 2; } /* * execute statement */ rc = OCIStmtExecute( statement->conn->svc, statement->stmt, statement->conn->err, type == OCI_STMT_SELECT ? 0 : 1, (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, statement->conn->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT ); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errbuf); return 2; } /* * get number of columns */ rc = OCIAttrGet( (dvoid *)statement->stmt, (ub4)OCI_HTYPE_STMT, (dvoid *)&num_columns, (ub4 *)0, (ub4)OCI_ATTR_PARAM_COUNT, statement->conn->err ); if (rc) { OCIErrorGet((dvoid *)statement->conn->err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR); lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errbuf); return 2; } statement->num_columns = num_columns; lua_pushboolean(L, 1); return 1; } /* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int rc; sword status; int i; bindparams_t *bind; char errbuf[100]; int errcode; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } statement_fetch_metadata(L, statement); bind = statement->bind; status = OCIStmtFetch(statement->stmt, statement->conn->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT); if (status == OCI_NO_DATA) { /* No more rows */ lua_pushnil(L); return 1; } else if (status != OCI_SUCCESS) { OCIErrorGet((dvoid *)statement->conn->err, (ub4)1, (text *)NULL, &errcode, errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR); luaL_error(L, DBI_ERR_FETCH_FAILED, errbuf); } if (statement->num_columns) { int i; int d = 1; lua_newtable(L); for (i = 0; i < statement->num_columns; i++) { lua_push_type_t lua_push = oracle_to_lua_push(bind[i].data_type, bind[i].null); const char *name = strlower(bind[i].name); const char *data = bind[i].data; if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { int val = atoi(data); if (named_columns) { LUA_PUSH_ATTRIB_INT(name, val); } else { LUA_PUSH_ARRAY_INT(d, val); } } else if (lua_push == LUA_PUSH_NUMBER) { double val = strtod(data, NULL); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } } else if (lua_push == LUA_PUSH_STRING) { if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, data); } else { LUA_PUSH_ARRAY_STRING(d, data); } } else if (lua_push == LUA_PUSH_BOOLEAN) { int val = atoi(data); if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, val); } else { LUA_PUSH_ARRAY_BOOL(d, val); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { /* * no columns returned by statement? */ lua_pushnil(L); } return 1; } static int next_iterator(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_ORACLE_STATEMENT); int named_columns = lua_toboolean(L, lua_upvalueindex(2)); return statement_fetch_impl(L, statement, named_columns); } /* * table = statement:fetch(named_indexes) */ static int statement_fetch(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); int named_columns = lua_toboolean(L, 2); return statement_fetch_impl(L, statement, named_columns); } /* * num_rows = statement:rowcount() */ static int statement_rowcount(lua_State *L) { luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_ORACLE_STATEMENT, "rowcount"); return 0; } /* * iterfunc = statement:rows(named_indexes) */ static int statement_rows(lua_State *L) { if (lua_gettop(L) == 1) { lua_pushvalue(L, 1); lua_pushboolean(L, 0); } else { lua_pushvalue(L, 1); lua_pushboolean(L, lua_toboolean(L, 2)); } lua_pushcclosure(L, next_iterator, 2); return 1; } /* * __gc */ static int statement_gc(lua_State *L) { /* always free the handle */ statement_close(L); return 0; } /* * __tostring */ static int statement_tostring(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_ORACLE_STATEMENT); lua_pushfstring(L, "%s: %p", DBD_ORACLE_STATEMENT, statement); return 1; } int dbd_oracle_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { int rc; statement_t *statement = NULL; OCIStmt *stmt; char *new_sql; /* * convert SQL string into a Oracle API compatible SQL statement */ new_sql = replace_placeholders(L, ':', sql_query); rc = OCIHandleAlloc((dvoid *)conn->oracle, (dvoid **)&stmt, OCI_HTYPE_STMT, 0, (dvoid **)0); rc = OCIStmtPrepare(stmt, conn->err, new_sql, strlen(new_sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); free(new_sql); statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); statement->conn = conn; statement->stmt = stmt; statement->num_columns = 0; statement->bind = NULL; statement->metadata = 0; luaL_getmetatable(L, DBD_ORACLE_STATEMENT); lua_setmetatable(L, -2); return 1; } int dbd_oracle_statement(lua_State *L) { static const luaL_Reg statement_methods[] = { {"affected", statement_affected}, {"close", statement_close}, {"columns", statement_columns}, {"execute", statement_execute}, {"fetch", statement_fetch}, {"rowcount", statement_rowcount}, {"rows", statement_rows}, {NULL, NULL} }; static const luaL_Reg statement_class_methods[] = { {NULL, NULL} }; luaL_newmetatable(L, DBD_ORACLE_STATEMENT); luaL_register(L, 0, statement_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, statement_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, statement_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_ORACLE_STATEMENT, statement_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/postgresql/000077500000000000000000000000001220150355400177135ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/postgresql/connection.c000066400000000000000000000150411220150355400222170ustar00rootroot00000000000000#include "dbd_postgresql.h" int dbd_postgresql_statement_create(lua_State *L, connection_t *conn, const char *sql_query); static int run(connection_t *conn, const char *command) { PGresult *result = PQexec(conn->postgresql, command); ExecStatusType status; if (!result) return 1; status = PQresultStatus(result); PQclear(result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) return 1; return 0; } static int commit(connection_t *conn) { return run(conn, "COMMIT"); } static int begin(connection_t *conn) { return run(conn, "BEGIN"); } static int rollback(connection_t *conn) { return run(conn, "ROLLBACK"); } /* * connection = DBD.PostgreSQL.New(dbname, user, password, host, port) */ static int connection_new(lua_State *L) { int n = lua_gettop(L); connection_t *conn = NULL; const char *host = NULL; const char *user = NULL; const char *password = NULL; const char *db = NULL; const char *port = NULL; const char *options = NULL; /* TODO always NULL */ const char *tty = NULL; /* TODO always NULL */ char portbuf[18]; /* db, user, password, host, port */ switch (n) { case 5: if (lua_isnil(L, 5) == 0) { int pport = luaL_checkint(L, 5); if (pport >= 1 && pport <= 65535) { snprintf(portbuf, sizeof(portbuf), "%d", pport); port = portbuf; } else { luaL_error(L, DBI_ERR_INVALID_PORT, pport); } } case 4: if (lua_isnil(L, 4) == 0) host = luaL_checkstring(L, 4); case 3: if (lua_isnil(L, 3) == 0) password = luaL_checkstring(L, 3); case 2: if (lua_isnil(L, 2) == 0) user = luaL_checkstring(L, 2); case 1: /* * db is the only mandatory parameter */ db = luaL_checkstring(L, 1); } conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); conn->postgresql = PQsetdbLogin(host, port, options, tty, db, user, password); conn->statement_id = 0; conn->autocommit = 0; begin(conn); if (PQstatus(conn->postgresql) != CONNECTION_OK) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, PQerrorMessage(conn->postgresql)); return 2; } luaL_getmetatable(L, DBD_POSTGRESQL_CONNECTION); lua_setmetatable(L, -2); return 1; } /* * success = connection:autocommit(on) */ static int connection_autocommit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); int on = lua_toboolean(L, 2); int err = 0; if (conn->postgresql) { if (on != conn->autocommit) { if (on) err = rollback(conn); else err = begin(conn); } conn->autocommit = on; } lua_pushboolean(L, !err); return 1; } /* * success = connection:close() */ static int connection_close(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); int disconnect = 0; if (conn->postgresql) { /* * if autocommit is turned off, we probably * want to rollback any outstanding transactions. */ if (!conn->autocommit) rollback(conn); PQfinish(conn->postgresql); disconnect = 1; conn->postgresql = NULL; } lua_pushboolean(L, disconnect); return 1; } /* * success = connection:commit() */ static int connection_commit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); int err = 0; if (conn->postgresql) { commit(conn); if (!conn->autocommit) err = begin(conn); else err = 1; } lua_pushboolean(L, !err); return 1; } /* * ok = connection:ping() */ static int connection_ping(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); int ok = 0; if (conn->postgresql) { ConnStatusType status = PQstatus(conn->postgresql); if (status == CONNECTION_OK) ok = 1; } lua_pushboolean(L, ok); return 1; } /* * statement = connection:prepare(sql_string) */ static int connection_prepare(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); if (conn->postgresql) { return dbd_postgresql_statement_create(L, conn, luaL_checkstring(L, 2)); } lua_pushnil(L); lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); return 2; } /* * quoted = connection:quote(str) */ static int connection_quote(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); size_t len; const char *from = luaL_checklstring(L, 2, &len); char *to = (char *)calloc(len*2+1, sizeof(char)); int err = 0; int quoted_len; if (!conn->postgresql) { luaL_error(L, DBI_ERR_DB_UNAVAILABLE); } quoted_len = PQescapeStringConn(conn->postgresql, to, from, len, &err); if (err) { free(to); luaL_error(L, DBI_ERR_QUOTING_STR, PQerrorMessage(conn->postgresql)); } lua_pushlstring(L, to, quoted_len); free(to); return 1; } /* * success = connection:rollback() */ static int connection_rollback(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); int err = 0; if (conn->postgresql) { rollback(conn); if (!conn->autocommit) err = begin(conn); else err = 1; } lua_pushboolean(L, !err); return 1; } /* * __gc */ static int connection_gc(lua_State *L) { /* always close the connection */ connection_close(L); return 0; } /* * __tostring */ static int connection_tostring(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_CONNECTION); lua_pushfstring(L, "%s: %p", DBD_POSTGRESQL_CONNECTION, conn); return 1; } int dbd_postgresql_connection(lua_State *L) { static const luaL_Reg connection_methods[] = { {"autocommit", connection_autocommit}, {"close", connection_close}, {"commit", connection_commit}, {"ping", connection_ping}, {"prepare", connection_prepare}, {"quote", connection_quote}, {"rollback", connection_rollback}, {NULL, NULL} }; static const luaL_Reg connection_class_methods[] = { {"New", connection_new}, {NULL, NULL} }; luaL_newmetatable(L, DBD_POSTGRESQL_CONNECTION); luaL_register(L, 0, connection_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, connection_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_POSTGRESQL_CONNECTION, connection_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/postgresql/dbd_postgresql.h000066400000000000000000000013041220150355400230760ustar00rootroot00000000000000#include #include #include /* * length of a prepared statement ID * dbd-postgresql-\d{17}\0 */ #define IDLEN 15+17+1 #define DBD_POSTGRESQL_CONNECTION "DBD.PostgreSQL.Connection" #define DBD_POSTGRESQL_STATEMENT "DBD.PostgreSQL.Statement" /* * connection object implentation */ typedef struct _connection { PGconn *postgresql; int autocommit; unsigned int statement_id; /* sequence for statement IDs */ } connection_t; /* * statement object implementation */ typedef struct _statement { PGconn *postgresql; PGresult *result; char name[IDLEN]; /* statement ID */ int tuple; /* number of rows returned */ } statement_t; lua-dbi-0.5.hg5ba1dd988961/dbd/postgresql/main.c000066400000000000000000000004401220150355400210010ustar00rootroot00000000000000#include "dbd_postgresql.h" int dbd_postgresql_connection(lua_State *L); int dbd_postgresql_statement(lua_State *L); /* * library entry point */ LUA_EXPORT int luaopen_dbdpostgresql(lua_State *L) { dbd_postgresql_connection(L); dbd_postgresql_statement(L); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/postgresql/statement.c000066400000000000000000000264741220150355400221000ustar00rootroot00000000000000#include "dbd_postgresql.h" #define BOOLOID 16 #define INT2OID 21 #define INT4OID 23 #define INT8OID 20 #define FLOAT4OID 700 #define FLOAT8OID 701 static lua_push_type_t postgresql_to_lua_push(unsigned int postgresql_type) { lua_push_type_t lua_type; switch(postgresql_type) { case INT2OID: case INT4OID: case INT8OID: lua_type = LUA_PUSH_INTEGER; break; case FLOAT4OID: case FLOAT8OID: lua_type = LUA_PUSH_NUMBER; break; case BOOLOID: lua_type = LUA_PUSH_BOOLEAN; break; default: lua_type = LUA_PUSH_STRING; } return lua_type; } static int deallocate(statement_t *statement) { char command[IDLEN+13]; PGresult *result; ExecStatusType status; snprintf(command, IDLEN+13, "DEALLOCATE \"%s\"", statement->name); result = PQexec(statement->postgresql, command); if (!result) return 1; status = PQresultStatus(result); PQclear(result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) return 1; return 0; } /* * num_affected_rows = statement:affected() */ static int statement_affected(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); if (!statement->result) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } lua_pushinteger(L, atoi(PQcmdTuples(statement->result))); return 1; } /* * success = statement:close() */ static int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); if (statement->result) { /* * Deallocate prepared statement on the * server side */ deallocate(statement); PQclear(statement->result); statement->result = NULL; } return 0; } /* * column_names = statement:columns() */ static int statement_columns(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); int i; int num_columns; int d = 1; if (!statement->result) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); return 0; } num_columns = PQnfields(statement->result); lua_newtable(L); for (i = 0; i < num_columns; i++) { const char *name = PQfname(statement->result, i); LUA_PUSH_ARRAY_STRING(d, name); } return 1; } /* * success = statement:execute(...) */ static int statement_execute(lua_State *L) { int n = lua_gettop(L); statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); int num_bind_params = n - 1; ExecStatusType status; int p; const char *errstr = NULL; const char **params; PGresult *result = NULL; statement->tuple = 0; params = malloc(num_bind_params * sizeof(params)); memset(params, 0, num_bind_params * sizeof(params)); /* * convert and copy parameters into a string array */ for (p = 2; p <= n; p++) { int i = p - 2; int type = lua_type(L, p); char err[64]; switch(type) { case LUA_TNIL: params[i] = NULL; break; case LUA_TBOOLEAN: /* * boolean values in postgresql can either be * t/f or 1/0. Pass integer values rather than * strings to maintain semantic compatibility * with other DBD drivers that pass booleans * as integers. */ params[i] = lua_toboolean(L, p) ? "1" : "0"; break; case LUA_TNUMBER: case LUA_TSTRING: params[i] = lua_tostring(L, p); break; default: snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); errstr = err; goto cleanup; } } result = PQexecPrepared( statement->postgresql, statement->name, num_bind_params, (const char **)params, NULL, NULL, 0 ); cleanup: free(params); if (errstr) { lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr); return 2; } if (!result) { lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_ALLOC_RESULT, PQerrorMessage(statement->postgresql)); return 2; } status = PQresultStatus(result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_BINDING_EXEC, PQresultErrorMessage(result)); return 2; } statement->result = result; lua_pushboolean(L, 1); return 1; } /* * can only be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int tuple = statement->tuple++; int i; int num_columns; int d = 1; if (!statement->result) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } if (PQresultStatus(statement->result) != PGRES_TUPLES_OK) { lua_pushnil(L); return 1; } if (tuple >= PQntuples(statement->result)) { lua_pushnil(L); /* no more results */ return 1; } num_columns = PQnfields(statement->result); lua_newtable(L); for (i = 0; i < num_columns; i++) { const char *name = PQfname(statement->result, i); if (PQgetisnull(statement->result, tuple, i)) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else { const char *value = PQgetvalue(statement->result, tuple, i); lua_push_type_t lua_push = postgresql_to_lua_push(PQftype(statement->result, i)); /* * data is returned as strings from PSQL * convert them here into Lua types */ if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { int val = atoi(value); if (named_columns) { LUA_PUSH_ATTRIB_INT(name, val); } else { LUA_PUSH_ARRAY_INT(d, val); } } else if (lua_push == LUA_PUSH_NUMBER) { double val = strtod(value, NULL); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } } else if (lua_push == LUA_PUSH_STRING) { if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, value); } else { LUA_PUSH_ARRAY_STRING(d, value); } } else if (lua_push == LUA_PUSH_BOOLEAN) { /* * booleans are returned as a string * either 't' or 'f' */ int val = value[0] == 't' ? 1 : 0; if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, val); } else { LUA_PUSH_ARRAY_BOOL(d, val); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } return 1; } static int next_iterator(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_POSTGRESQL_STATEMENT); int named_columns = lua_toboolean(L, lua_upvalueindex(2)); return statement_fetch_impl(L, statement, named_columns); } /* * table = statement:fetch(named_indexes) */ static int statement_fetch(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); int named_columns = lua_toboolean(L, 2); return statement_fetch_impl(L, statement, named_columns); } /* * num_rows = statement:rowcount() */ static int statement_rowcount(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); if (!statement->result) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } lua_pushinteger(L, PQntuples(statement->result)); return 1; } /* * iterfunc = statement:rows(named_indexes) */ static int statement_rows(lua_State *L) { if (lua_gettop(L) == 1) { lua_pushvalue(L, 1); lua_pushboolean(L, 0); } else { lua_pushvalue(L, 1); lua_pushboolean(L, lua_toboolean(L, 2)); } lua_pushcclosure(L, next_iterator, 2); return 1; } /* * __gc */ static int statement_gc(lua_State *L) { /* always free the handle */ statement_close(L); return 0; } /* * __tostring */ static int statement_tostring(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_POSTGRESQL_STATEMENT); lua_pushfstring(L, "%s: %p", DBD_POSTGRESQL_STATEMENT, statement); return 1; } int dbd_postgresql_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { statement_t *statement = NULL; ExecStatusType status; PGresult *result = NULL; char *new_sql; char name[IDLEN]; /* * convert SQL string into a PSQL API compatible SQL statement */ new_sql = replace_placeholders(L, '$', sql_query); snprintf(name, IDLEN, "dbd-postgresql-%017u", ++conn->statement_id); result = PQprepare(conn->postgresql, name, new_sql, 0, NULL); /* * free converted statement after use */ free(new_sql); if (!result) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_ALLOC_STATEMENT, PQerrorMessage(statement->postgresql)); return 2; } status = PQresultStatus(result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { const char *err_string = PQresultErrorMessage(result); PQclear(result); lua_pushnil(L); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, err_string); return 2; } PQclear(result); statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); statement->postgresql = conn->postgresql; statement->result = NULL; statement->tuple = 0; strncpy(statement->name, name, IDLEN-1); statement->name[IDLEN-1] = '\0'; luaL_getmetatable(L, DBD_POSTGRESQL_STATEMENT); lua_setmetatable(L, -2); return 1; } int dbd_postgresql_statement(lua_State *L) { static const luaL_Reg statement_methods[] = { {"affected", statement_affected}, {"close", statement_close}, {"columns", statement_columns}, {"execute", statement_execute}, {"fetch", statement_fetch}, {"rowcount", statement_rowcount}, {"rows", statement_rows}, {NULL, NULL} }; static const luaL_Reg statement_class_methods[] = { {NULL, NULL} }; luaL_newmetatable(L, DBD_POSTGRESQL_STATEMENT); luaL_register(L, 0, statement_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, statement_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, statement_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_POSTGRESQL_STATEMENT, statement_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/sqlite3/000077500000000000000000000000001220150355400170745ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/dbd/sqlite3/connection.c000066400000000000000000000121341220150355400214000ustar00rootroot00000000000000#include "dbd_sqlite3.h" int dbd_sqlite3_statement_create(lua_State *L, connection_t *conn, const char *sql_query); static int run(connection_t *conn, const char *command) { int res = sqlite3_exec(conn->sqlite, command, NULL, NULL, NULL); return res != SQLITE_OK; } static int commit(connection_t *conn) { return run(conn, "COMMIT TRANSACTION"); } static int begin(connection_t *conn) { int err = 0; if (sqlite3_get_autocommit(conn->sqlite)) { err = run(conn, "BEGIN TRANSACTION"); } else { err = 0; } return err; } static int rollback(connection_t *conn) { return run(conn, "ROLLBACK TRANSACTION"); } int try_begin_transaction(connection_t *conn) { if (conn->autocommit) { return 1; } return begin(conn) == 0; } /* * connection,err = DBD.SQLite3.New(dbfile) */ static int connection_new(lua_State *L) { int n = lua_gettop(L); const char *db = NULL; connection_t *conn = NULL; /* db */ switch(n) { default: /* * db is the only mandatory parameter */ db = luaL_checkstring(L, 1); } conn = (connection_t *)lua_newuserdata(L, sizeof(connection_t)); if (sqlite3_open(db, &conn->sqlite) != SQLITE_OK) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_CONNECTION_FAILED, sqlite3_errmsg(conn->sqlite)); return 2; } conn->autocommit = 0; luaL_getmetatable(L, DBD_SQLITE_CONNECTION); lua_setmetatable(L, -2); return 1; } /* * success = connection:autocommit(on) */ static int connection_autocommit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); int on = lua_toboolean(L, 2); int err = 1; if (conn->sqlite) { if (on) { err = rollback(conn); } conn->autocommit = on; } lua_pushboolean(L, !err); return 1; } /* * success = connection:close() */ static int connection_close(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); int disconnect = 0; if (conn->sqlite) { rollback(conn); sqlite3_close(conn->sqlite); disconnect = 1; conn->sqlite = NULL; } lua_pushboolean(L, disconnect); return 1; } /* * success = connection:commit() */ static int connection_commit(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); int err = 1; if (conn->sqlite) { err = commit(conn); } lua_pushboolean(L, !err); return 1; } /* * ok = connection:ping() */ static int connection_ping(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); int ok = 0; if (conn->sqlite) { ok = 1; } lua_pushboolean(L, ok); return 1; } /* * statement,err = connection:prepare(sql_str) */ static int connection_prepare(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); if (conn->sqlite) { return dbd_sqlite3_statement_create(L, conn, luaL_checkstring(L, 2)); } lua_pushnil(L); lua_pushstring(L, DBI_ERR_DB_UNAVAILABLE); return 2; } /* * quoted = connection:quote(str) */ static int connection_quote(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); size_t len; const char *from = luaL_checklstring(L, 2, &len); char *to; if (!conn->sqlite) { luaL_error(L, DBI_ERR_DB_UNAVAILABLE); } to = sqlite3_mprintf("%q", from); lua_pushstring(L, to); sqlite3_free(to); return 1; } /* * success = connection:rollback() */ static int connection_rollback(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); int err = 1; if (conn->sqlite) { err =rollback(conn); } lua_pushboolean(L, !err); return 1; } /* * __gc */ static int connection_gc(lua_State *L) { /* always close the connection */ connection_close(L); return 0; } /* * __tostring */ static int connection_tostring(lua_State *L) { connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_SQLITE_CONNECTION); lua_pushfstring(L, "%s: %p", DBD_SQLITE_CONNECTION, conn); return 1; } int dbd_sqlite3_connection(lua_State *L) { /* * instance methods */ static const luaL_Reg connection_methods[] = { {"autocommit", connection_autocommit}, {"close", connection_close}, {"commit", connection_commit}, {"ping", connection_ping}, {"prepare", connection_prepare}, {"quote", connection_quote}, {"rollback", connection_rollback}, {NULL, NULL} }; /* * class methods */ static const luaL_Reg connection_class_methods[] = { {"New", connection_new}, {NULL, NULL} }; luaL_newmetatable(L, DBD_SQLITE_CONNECTION); luaL_register(L, 0, connection_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, connection_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, connection_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_SQLITE_CONNECTION, connection_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/sqlite3/dbd_sqlite3.h000066400000000000000000000007051220150355400214440ustar00rootroot00000000000000#include #include #define DBD_SQLITE_CONNECTION "DBD.SQLite3.Connection" #define DBD_SQLITE_STATEMENT "DBD.SQLite3.Statement" /* * connection object */ typedef struct _connection { sqlite3 *sqlite; int autocommit; // int txn_in_progress; } connection_t; /* * statement object */ typedef struct _statement { connection_t *conn; sqlite3_stmt *stmt; int more_data; int affected; } statement_t; lua-dbi-0.5.hg5ba1dd988961/dbd/sqlite3/main.c000066400000000000000000000004171220150355400201660ustar00rootroot00000000000000#include "dbd_sqlite3.h" int dbd_sqlite3_connection(lua_State *L); int dbd_sqlite3_statement(lua_State *L); /* * library entry point */ LUA_EXPORT int luaopen_dbdsqlite3(lua_State *L) { dbd_sqlite3_connection(L); dbd_sqlite3_statement(L); return 1; } lua-dbi-0.5.hg5ba1dd988961/dbd/sqlite3/statement.c000066400000000000000000000240501220150355400212450ustar00rootroot00000000000000#include "dbd_sqlite3.h" extern int try_begin_transaction(connection_t *conn); extern int try_end_transaction(connection_t *conn); /* * Converts SQLite types to Lua types */ static lua_push_type_t sqlite_to_lua_push(unsigned int sqlite_type) { lua_push_type_t lua_type; switch(sqlite_type) { case SQLITE_NULL: lua_type = LUA_PUSH_NIL; break; case SQLITE_INTEGER: lua_type = LUA_PUSH_INTEGER; break; case SQLITE_FLOAT: lua_type = LUA_PUSH_NUMBER; break; default: lua_type = LUA_PUSH_STRING; } return lua_type; } /* * runs sqlite3_step on a statement handle */ static int step(statement_t *statement) { int res = sqlite3_step(statement->stmt); if (res == SQLITE_DONE) { statement->more_data = 0; return 1; } else if (res == SQLITE_ROW) { statement->more_data = 1; return 1; } return 0; } /* * num_affected_rows = statement:affected() */ static int statement_affected(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); } lua_pushinteger(L, statement->affected); return 1; } /* * success = statement:close() */ static int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); int ok = 0; if (statement->stmt) { if (sqlite3_finalize(statement->stmt) == SQLITE_OK) { ok = 1; } statement->stmt = NULL; } lua_pushboolean(L, ok); return 1; } /* * column_names = statement:columns() */ static int statement_columns(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); int i; int num_columns; int d = 1; if (!statement->stmt) { luaL_error(L, DBI_ERR_INVALID_STATEMENT); return 0; } num_columns = sqlite3_column_count(statement->stmt); lua_newtable(L); for (i = 0; i < num_columns; i++) { const char *name = sqlite3_column_name(statement->stmt, i); LUA_PUSH_ARRAY_STRING(d, name); } return 1; } /* * success,err = statement:execute(...) */ static int statement_execute(lua_State *L) { int n = lua_gettop(L); statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); int p; int errflag = 0; const char *errstr = NULL; int expected_params; int num_bind_params = n - 1; if (!statement->stmt) { lua_pushboolean(L, 0); lua_pushstring(L, DBI_ERR_EXECUTE_INVALID); return 2; } /* * reset the handle before binding params * this will be a NOP if the handle has not * been executed */ if (sqlite3_reset(statement->stmt) != SQLITE_OK) { lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite)); return 2; } sqlite3_clear_bindings(statement->stmt); expected_params = sqlite3_bind_parameter_count(statement->stmt); if (expected_params != num_bind_params) { /* * sqlite3_reset does not handle this condition, * and the client library will fill unset params * with NULLs */ lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_PARAM_MISCOUNT, expected_params, num_bind_params); return 2; } for (p = 2; p <= n; p++) { int i = p - 1; int type = lua_type(L, p); char err[64]; switch(type) { case LUA_TNIL: errflag = sqlite3_bind_null(statement->stmt, i) != SQLITE_OK; break; case LUA_TNUMBER: errflag = sqlite3_bind_double(statement->stmt, i, lua_tonumber(L, p)) != SQLITE_OK; break; case LUA_TSTRING: errflag = sqlite3_bind_text(statement->stmt, i, lua_tostring(L, p), -1, SQLITE_STATIC) != SQLITE_OK; break; case LUA_TBOOLEAN: errflag = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK; break; default: /* * Unknown/unsupported value type */ errflag = 1; snprintf(err, sizeof(err)-1, DBI_ERR_BINDING_TYPE_ERR, lua_typename(L, type)); errstr = err; } if (errflag) break; } if (errflag) { lua_pushboolean(L, 0); if (errstr) lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr); else lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->conn->sqlite)); return 2; } try_begin_transaction(statement->conn); if (!step(statement)) { lua_pushboolean(L, 0); lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite)); return 2; } statement->affected = sqlite3_changes(statement->conn->sqlite); lua_pushboolean(L, 1); return 1; } /* * must be called after an execute */ static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) { int num_columns; if (!statement->stmt) { luaL_error(L, DBI_ERR_FETCH_INVALID); return 0; } if (!statement->more_data) { /* * Result set is empty, or not result set returned */ lua_pushnil(L); return 1; } num_columns = sqlite3_column_count(statement->stmt); if (num_columns) { int i; int d = 1; lua_newtable(L); for (i = 0; i < num_columns; i++) { lua_push_type_t lua_push = sqlite_to_lua_push(sqlite3_column_type(statement->stmt, i)); const char *name = sqlite3_column_name(statement->stmt, i); if (lua_push == LUA_PUSH_NIL) { if (named_columns) { LUA_PUSH_ATTRIB_NIL(name); } else { LUA_PUSH_ARRAY_NIL(d); } } else if (lua_push == LUA_PUSH_INTEGER) { int val = sqlite3_column_int(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_INT(name, val); } else { LUA_PUSH_ARRAY_INT(d, val); } } else if (lua_push == LUA_PUSH_NUMBER) { double val = sqlite3_column_double(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_FLOAT(name, val); } else { LUA_PUSH_ARRAY_FLOAT(d, val); } } else if (lua_push == LUA_PUSH_STRING) { const char *val = (const char *)sqlite3_column_text(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_STRING(name, val); } else { LUA_PUSH_ARRAY_STRING(d, val); } } else if (lua_push == LUA_PUSH_BOOLEAN) { int val = sqlite3_column_int(statement->stmt, i); if (named_columns) { LUA_PUSH_ATTRIB_BOOL(name, val); } else { LUA_PUSH_ARRAY_BOOL(d, val); } } else { luaL_error(L, DBI_ERR_UNKNOWN_PUSH); } } } else { /* * no columns returned by statement? */ lua_pushnil(L); } if (step(statement) == 0) { if (sqlite3_reset(statement->stmt) != SQLITE_OK) { /* * reset needs to be called to retrieve the 'real' error message */ luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite)); } } return 1; } static int next_iterator(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, lua_upvalueindex(1), DBD_SQLITE_STATEMENT); int named_columns = lua_toboolean(L, lua_upvalueindex(2)); return statement_fetch_impl(L, statement, named_columns); } /* * table = statement:fetch(named_indexes) */ static int statement_fetch(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); int named_columns = lua_toboolean(L, 2); return statement_fetch_impl(L, statement, named_columns); } /* * iterfunc = statement:rows(named_indexes) */ static int statement_rows(lua_State *L) { if (lua_gettop(L) == 1) { lua_pushvalue(L, 1); lua_pushboolean(L, 0); } else { lua_pushvalue(L, 1); lua_pushboolean(L, lua_toboolean(L, 2)); } lua_pushcclosure(L, next_iterator, 2); return 1; } /* * num_rows = statement:rowcount() */ static int statement_rowcount(lua_State *L) { luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_SQLITE_STATEMENT, "rowcount"); return 0; } /* * __gc */ static int statement_gc(lua_State *L) { /* always free the handle */ statement_close(L); return 0; } /* * __tostring */ static int statement_tostring(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT); lua_pushfstring(L, "%s: %p", DBD_SQLITE_STATEMENT, statement); return 1; } int dbd_sqlite3_statement_create(lua_State *L, connection_t *conn, const char *sql_query) { statement_t *statement = NULL; statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t)); statement->conn = conn; statement->stmt = NULL; statement->more_data = 0; statement->affected = 0; if (sqlite3_prepare_v2(statement->conn->sqlite, sql_query, strlen(sql_query), &statement->stmt, NULL) != SQLITE_OK) { lua_pushnil(L); lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, sqlite3_errmsg(statement->conn->sqlite)); return 2; } luaL_getmetatable(L, DBD_SQLITE_STATEMENT); lua_setmetatable(L, -2); return 1; } int dbd_sqlite3_statement(lua_State *L) { static const luaL_Reg statement_methods[] = { {"affected", statement_affected}, {"close", statement_close}, {"columns", statement_columns}, {"execute", statement_execute}, {"fetch", statement_fetch}, {"rows", statement_rows}, {"rowcount", statement_rowcount}, {NULL, NULL} }; static const luaL_Reg statement_class_methods[] = { {NULL, NULL} }; luaL_newmetatable(L, DBD_SQLITE_STATEMENT); luaL_register(L, 0, statement_methods); lua_pushvalue(L,-1); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, statement_gc); lua_setfield(L, -2, "__gc"); lua_pushcfunction(L, statement_tostring); lua_setfield(L, -2, "__tostring"); luaL_register(L, DBD_SQLITE_STATEMENT, statement_class_methods); return 1; } lua-dbi-0.5.hg5ba1dd988961/vc++/000077500000000000000000000000001220150355400155155ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbddb2/000077500000000000000000000000001220150355400166365ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbddb2/dbddb2.vcproj000066400000000000000000000112171220150355400212060ustar00rootroot00000000000000 lua-dbi-0.5.hg5ba1dd988961/vc++/dbdmysql/000077500000000000000000000000001220150355400173345ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbdmysql/dbdmysql.vcproj000066400000000000000000000113371220150355400224050ustar00rootroot00000000000000 lua-dbi-0.5.hg5ba1dd988961/vc++/dbdoracle/000077500000000000000000000000001220150355400174345ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbdoracle/dbdoracle.vcproj000066400000000000000000000111221220150355400225750ustar00rootroot00000000000000 lua-dbi-0.5.hg5ba1dd988961/vc++/dbdpostgresql/000077500000000000000000000000001220150355400203725ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbdpostgresql/dbdpostgresql.vcproj000066400000000000000000000126251220150355400245020ustar00rootroot00000000000000 lua-dbi-0.5.hg5ba1dd988961/vc++/dbdsqlite3/000077500000000000000000000000001220150355400175535ustar00rootroot00000000000000lua-dbi-0.5.hg5ba1dd988961/vc++/dbdsqlite3/dbdsqlite3.vcproj000066400000000000000000000112351220150355400230400ustar00rootroot00000000000000 lua-dbi-0.5.hg5ba1dd988961/vc++/luadbi.sln000066400000000000000000000052351220150355400175000ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbdpostgresql", "dbdpostgresql\dbdpostgresql.vcproj", "{7DC4FC36-C3DC-475E-A6DA-CEB4BA237843}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbdmysql", "dbdmysql\dbdmysql.vcproj", "{C3A5B30E-0471-459E-AFF3-FF54F9F31599}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbdoracle", "dbdoracle\dbdoracle.vcproj", "{BD3DE628-23AE-416E-A983-8A0E8D4F0E15}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbddb2", "dbddb2\dbddb2.vcproj", "{9F935BC6-6766-4D60-8C48-9EF607883B7D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbdsqlite3", "dbdsqlite3\dbdsqlite3.vcproj", "{7B532158-C67A-490D-80EF-FF5552EE38B1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7DC4FC36-C3DC-475E-A6DA-CEB4BA237843}.Debug|Win32.ActiveCfg = Debug|Win32 {7DC4FC36-C3DC-475E-A6DA-CEB4BA237843}.Debug|Win32.Build.0 = Debug|Win32 {7DC4FC36-C3DC-475E-A6DA-CEB4BA237843}.Release|Win32.ActiveCfg = Release|Win32 {7DC4FC36-C3DC-475E-A6DA-CEB4BA237843}.Release|Win32.Build.0 = Release|Win32 {C3A5B30E-0471-459E-AFF3-FF54F9F31599}.Debug|Win32.ActiveCfg = Debug|Win32 {C3A5B30E-0471-459E-AFF3-FF54F9F31599}.Debug|Win32.Build.0 = Debug|Win32 {C3A5B30E-0471-459E-AFF3-FF54F9F31599}.Release|Win32.ActiveCfg = Release|Win32 {C3A5B30E-0471-459E-AFF3-FF54F9F31599}.Release|Win32.Build.0 = Release|Win32 {BD3DE628-23AE-416E-A983-8A0E8D4F0E15}.Debug|Win32.ActiveCfg = Debug|Win32 {BD3DE628-23AE-416E-A983-8A0E8D4F0E15}.Debug|Win32.Build.0 = Debug|Win32 {BD3DE628-23AE-416E-A983-8A0E8D4F0E15}.Release|Win32.ActiveCfg = Release|Win32 {BD3DE628-23AE-416E-A983-8A0E8D4F0E15}.Release|Win32.Build.0 = Release|Win32 {9F935BC6-6766-4D60-8C48-9EF607883B7D}.Debug|Win32.ActiveCfg = Debug|Win32 {9F935BC6-6766-4D60-8C48-9EF607883B7D}.Debug|Win32.Build.0 = Debug|Win32 {9F935BC6-6766-4D60-8C48-9EF607883B7D}.Release|Win32.ActiveCfg = Release|Win32 {9F935BC6-6766-4D60-8C48-9EF607883B7D}.Release|Win32.Build.0 = Release|Win32 {7B532158-C67A-490D-80EF-FF5552EE38B1}.Debug|Win32.ActiveCfg = Debug|Win32 {7B532158-C67A-490D-80EF-FF5552EE38B1}.Debug|Win32.Build.0 = Debug|Win32 {7B532158-C67A-490D-80EF-FF5552EE38B1}.Release|Win32.ActiveCfg = Release|Win32 {7B532158-C67A-490D-80EF-FF5552EE38B1}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal