aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/lua-dbi/APKBUILD32
-rw-r--r--main/lua-dbi/fix-table-maxn.patch26
-rw-r--r--main/lua-dbi/lua-dbi-0.5-sync-hg-47382fea7a9c.patch533
3 files changed, 38 insertions, 553 deletions
diff --git a/main/lua-dbi/APKBUILD b/main/lua-dbi/APKBUILD
index 342a98f253..3ced7c4c7e 100644
--- a/main/lua-dbi/APKBUILD
+++ b/main/lua-dbi/APKBUILD
@@ -2,17 +2,18 @@
# Maintainer: Leonardo Arena <rnalrd@alpinelinux.org>
pkgname=lua-dbi
_pkgname=luadbi
-pkgver=0.5
-pkgrel=7
+pkgver=0.6
+pkgrel=0
pkgdesc="A database interface library for Lua"
-url="http://code.google.com/p/luadbi"
+url="https://github.com/mwild1/luadbi"
arch="all"
license="GPL"
-makedepends="lua-dev mariadb-dev postgresql-dev sqlite-dev"
+makedepends="mariadb-dev postgresql-dev sqlite-dev"
_subpackages="$pkgname-mysql $pkgname-postgresql $pkgname-sqlite3"
-source="https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/luadbi/luadbi.$pkgver.tar.gz
- lua-dbi-0.5-sync-hg-47382fea7a9c.patch"
-builddir="$srcdir"
+source="https://github.com/mwild1/$_pkgname/archive/v$pkgver/$_pkgname.tar.gz
+ fix-table-maxn.patch"
+builddir="$srcdir/$_pkgname-$pkgver"
+options="!check" # provided tests require running DBs
_luaversions="5.1 5.2 5.3"
for _v in $_luaversions; do
@@ -22,7 +23,6 @@ for _v in $_luaversions; do
done
done
-
prepare() {
default_prepare
@@ -34,9 +34,7 @@ prepare() {
build() {
local lver; for lver in $_luaversions; do
msg "Building for Lua $lver..."
- cd "$builddir-$lver"
- echo LUA_IMPL=lua$lver >> .config
- make LUA_VERSION=$lver
+ make -C "$builddir-$lver" LUA_V=$lver
done
}
@@ -52,14 +50,8 @@ _subpackage() {
install_if="$pkgname=$pkgver-r$pkgrel lua$lver"
cd "$builddir-$lver"
-
- install -D -m755 DBI.lua "$subpkgdir"/usr/share/lua/$lver/DBI.lua
- install -D -m644 dbd$db.so "$subpkgdir"/usr/lib/lua/$lver/dbd$db.so
+ make LUA_V=$lver DESTDIR="$subpkgdir" install_${db/postgresql/psql}
}
-md5sums="ede2b003aadddc151aac87050c3d926e luadbi.0.5.tar.gz
-a1359b3a96a21a010310b505c667f8aa lua-dbi-0.5-sync-hg-47382fea7a9c.patch"
-sha256sums="49116458dd80052536bf5d7e2b2a1f5a0fa42a671ce77f1cb7355ef7faeb331e luadbi.0.5.tar.gz
-c6cd0587d789fa9af4687dac471e8b05aea63022224b0da482ec9dcfc7998dd2 lua-dbi-0.5-sync-hg-47382fea7a9c.patch"
-sha512sums="4ed641e113e90acc8a4f6b3b2d0f5d5044c0fbbef3b2fdfb84d15e17115e45c553a33b19bfb165e5af11a2adce501d66859963e3363d3ab1c6a39b0b2ae92e62 luadbi.0.5.tar.gz
-e4f5dc5a75204e7fc1221b4322f1044889a417c6bf7f01bfc7249756a3739931423c66282b560f223f4ea8ef7e1d8311fbe5dfa281d0102a835c436ace7470e4 lua-dbi-0.5-sync-hg-47382fea7a9c.patch"
+sha512sums="cac2390e95c5f41e3cf85694292ec7ed32b70ec3b6d0f52a67245d5bbd189beda11f1041c3f1ea7a11fe4d23aeb825d50332f21e938d654b72a96ebcc227c3eb luadbi.tar.gz
+3d2754b93abca4795ae7ce76c79d95601229e8dd9fdf7a1cceb95086c8f00e235f89bd44cd30aa5394b607c4abbe44010620250a3990b17a219c52bfe1b262f2 fix-table-maxn.patch"
diff --git a/main/lua-dbi/fix-table-maxn.patch b/main/lua-dbi/fix-table-maxn.patch
new file mode 100644
index 0000000000..a5036ab496
--- /dev/null
+++ b/main/lua-dbi/fix-table-maxn.patch
@@ -0,0 +1,26 @@
+From 23bac7124f27c7e36431932e77c68fca91c96c25 Mon Sep 17 00:00:00 2001
+From: sparked435 <aaron@zadzmo.org>
+Date: Thu, 24 Aug 2017 15:05:49 -0400
+Subject: [PATCH] Fix minor post-5.1 bug: table.maxn() has been removed. Should
+ only trigger if no drivers are available, an error condition anyway.
+
+Patch-Source: https://github.com/mwild1/luadbi/commit/23bac7124f27c7e36431932e77c68fca91c96c25
+---
+ DBI.lua | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/DBI.lua b/DBI.lua
+index 4dc77d2..e1f504a 100644
+--- a/DBI.lua
++++ b/DBI.lua
+@@ -28,8 +28,8 @@ local function available_drivers()
+ end
+
+ -- no drivers available
+- if table.maxn(available) < 1 then
+- available = {'(None)'}
++ if #available < 1 then
++ available = {'(None)'}
+ end
+
+ return available
diff --git a/main/lua-dbi/lua-dbi-0.5-sync-hg-47382fea7a9c.patch b/main/lua-dbi/lua-dbi-0.5-sync-hg-47382fea7a9c.patch
deleted file mode 100644
index 0483de0aea..0000000000
--- a/main/lua-dbi/lua-dbi-0.5-sync-hg-47382fea7a9c.patch
+++ /dev/null
@@ -1,533 +0,0 @@
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/common.c luadbi/dbd/common.c
---- lua-dbi-0.5/dbd/common.c 2009-06-13 04:50:59.000000000 -0400
-+++ luadbi/dbd/common.c 2015-01-15 13:38:28.163032130 -0500
-@@ -52,9 +52,12 @@
- /*
- * 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));
--
-+ newsql = calloc(len+extra_space+1, sizeof(char));
-+ if(!newsql) {
-+ lua_pushliteral(L, "out of memory");
-+ return lua_error(L);
-+ }
-+
- /*
- * copy first char. In valid SQL this cannot be a placeholder
- */
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/common.h luadbi/dbd/common.h
---- lua-dbi-0.5/dbd/common.h 2010-05-01 00:25:11.000000000 -0400
-+++ luadbi/dbd/common.h 2015-01-15 13:38:28.163032130 -0500
-@@ -39,6 +39,11 @@
- lua_pushnumber(L, v); \
- lua_rawset(L, -3);
-
-+#define LUA_PUSH_ATTRIB_STRING_BY_LENGTH(n, v, len) \
-+ lua_pushstring(L, n); \
-+ lua_pushlstring(L, v, len); \
-+ lua_rawset(L, -3);
-+
- #define LUA_PUSH_ATTRIB_STRING(n, v) \
- lua_pushstring(L, n); \
- lua_pushstring(L, v); \
-@@ -71,6 +76,11 @@
- lua_rawseti(L, -2, n); \
- n++;
-
-+#define LUA_PUSH_ARRAY_STRING_BY_LENGTH(n, v, len) \
-+ lua_pushlstring(L, v, len); \
-+ lua_rawseti(L, -2, n); \
-+ n++;
-+
- #define LUA_PUSH_ARRAY_BOOL(n, v) \
- lua_pushboolean(L, v); \
- lua_rawseti(L, -2, n); \
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/connection.c luadbi/dbd/mysql/connection.c
---- lua-dbi-0.5/dbd/mysql/connection.c 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/mysql/connection.c 2015-01-15 13:38:28.171032087 -0500
-@@ -16,7 +16,7 @@
- const char *db = NULL;
- int port = 0;
-
-- const char *unix_socket = NULL; /* TODO always NULL */
-+ const char *unix_socket = NULL;
- int client_flag = 0; /* TODO always 0, set flags from options table */
-
- /* db, user, password, host, port */
-@@ -27,6 +27,10 @@
- case 4:
- if (lua_isnil(L, 4) == 0)
- host = luaL_checkstring(L, 4);
-+ if (host[0] == '/') {
-+ unix_socket = host;
-+ host = NULL;
-+ };
- case 3:
- if (lua_isnil(L, 3) == 0)
- password = luaL_checkstring(L, 3);
-@@ -178,6 +182,16 @@
- }
-
- /*
-+ * last_id = statement:last_id()
-+ */
-+static int connection_lastid(lua_State *L) {
-+ connection_t *conn = (connection_t *)luaL_checkudata(L, 1, DBD_MYSQL_CONNECTION);
-+
-+ lua_pushinteger(L, mysql_insert_id( conn->mysql ));
-+ return 1;
-+}
-+
-+/*
- * __gc
- */
- static int connection_gc(lua_State *L) {
-@@ -207,6 +221,7 @@
- {"prepare", connection_prepare},
- {"quote", connection_quote},
- {"rollback", connection_rollback},
-+ {"last_id", connection_lastid},
- {NULL, NULL}
- };
-
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/dbd_mysql.h luadbi/dbd/mysql/dbd_mysql.h
---- lua-dbi-0.5/dbd/mysql/dbd_mysql.h 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/mysql/dbd_mysql.h 2015-01-15 13:38:28.172032081 -0500
-@@ -22,6 +22,10 @@
- typedef struct _statement {
- MYSQL *mysql;
- MYSQL_STMT *stmt;
-- MYSQL_RES *metadata; /* result dataset metadata */
-+ MYSQL_RES *metadata; /* result dataset metadata */
-+
-+ unsigned long *lengths; /* length of retrieved data
-+ we have to keep this from bind time to
-+ result retrival time */
- } statement_t;
-
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/mysql/statement.c luadbi/dbd/mysql/statement.c
---- lua-dbi-0.5/dbd/mysql/statement.c 2010-05-21 18:49:59.000000000 -0400
-+++ luadbi/dbd/mysql/statement.c 2015-01-15 13:38:28.173032076 -0500
-@@ -11,10 +11,12 @@
- case MYSQL_TYPE_TINY:
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_SHORT:
-- case MYSQL_TYPE_LONG:
-+ case MYSQL_TYPE_INT24:
-+ case MYSQL_TYPE_LONG:
- lua_type = LUA_PUSH_INTEGER;
- break;
-
-+ case MYSQL_TYPE_FLOAT:
- case MYSQL_TYPE_DOUBLE:
- case MYSQL_TYPE_LONGLONG:
- lua_type = LUA_PUSH_NUMBER;
-@@ -89,13 +91,18 @@
- statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_MYSQL_STATEMENT);
-
- if (statement->metadata) {
-- mysql_free_result(statement->metadata);
-- statement->metadata = NULL;
-+ mysql_free_result(statement->metadata);
-+ statement->metadata = NULL;
- }
-
-+ if (statement->lengths) {
-+ free(statement->lengths);
-+ statement->lengths = NULL;
-+ }
-+
- if (statement->stmt) {
-- mysql_stmt_close(statement->stmt);
-- statement->stmt = NULL;
-+ mysql_stmt_close(statement->stmt);
-+ statement->stmt = NULL;
- }
-
- lua_pushboolean(L, 1);
-@@ -286,7 +293,7 @@
- }
-
- static int statement_fetch_impl(lua_State *L, statement_t *statement, int named_columns) {
-- int column_count;
-+ int column_count, fetch_result_ok;
- MYSQL_BIND *bind = NULL;
- const char *error_message = NULL;
-
-@@ -306,6 +313,13 @@
- int i;
- MYSQL_FIELD *fields;
-
-+ if (statement->lengths) {
-+ free(statement->lengths);
-+ statement->lengths = NULL;
-+ }
-+
-+ statement->lengths = calloc(column_count, sizeof(unsigned long));
-+
- bind = malloc(sizeof(MYSQL_BIND) * column_count);
- memset(bind, 0, sizeof(MYSQL_BIND) * column_count);
-
-@@ -313,12 +327,19 @@
-
- for (i = 0; i < column_count; i++) {
- unsigned int length = mysql_buffer_size(&fields[i]);
-- char *buffer = (char *)malloc(length);
-- memset(buffer, 0, length);
-+ 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].buffer = buffer;
-- bind[i].buffer_length = length;
-+ bind[i].length = &(statement->lengths[i]);
- }
-
- if (mysql_stmt_bind_result(statement->stmt, bind)) {
-@@ -326,7 +347,8 @@
- goto cleanup;
- }
-
-- if (!mysql_stmt_fetch(statement->stmt)) {
-+ 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);
-@@ -334,6 +356,13 @@
- 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(statement->lengths[i]+1, sizeof(char));
-+ bind[i].buffer = buffer;
-+ bind[i].buffer_length = statement->lengths[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);
-@@ -361,11 +390,25 @@
- }
- }
- } 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));
-- }
-+ if (fields[i].type == MYSQL_TYPE_FLOAT) {
-+ if (named_columns) {
-+ LUA_PUSH_ATTRIB_FLOAT(name, *(float *)(bind[i].buffer));
-+ } else {
-+ LUA_PUSH_ARRAY_FLOAT(d, *(float *)(bind[i].buffer));
-+ }
-+ } else if (fields[i].type == MYSQL_TYPE_DOUBLE) {
-+ if (named_columns) {
-+ LUA_PUSH_ATTRIB_FLOAT(name, *(double *)(bind[i].buffer));
-+ } else {
-+ LUA_PUSH_ARRAY_FLOAT(d, *(double *)(bind[i].buffer));
-+ }
-+ } else {
-+ if (named_columns) {
-+ LUA_PUSH_ATTRIB_FLOAT(name, *(long long *)(bind[i].buffer));
-+ } else {
-+ LUA_PUSH_ARRAY_FLOAT(d, *(long long *)(bind[i].buffer));
-+ }
-+ }
- } else if (lua_push == LUA_PUSH_STRING) {
-
- if (fields[i].type == MYSQL_TYPE_TIMESTAMP || fields[i].type == MYSQL_TYPE_DATETIME) {
-@@ -404,9 +447,9 @@
-
- } else {
- if (named_columns) {
-- LUA_PUSH_ATTRIB_STRING(name, bind[i].buffer);
-+ LUA_PUSH_ATTRIB_STRING_BY_LENGTH(name, bind[i].buffer, *bind[i].length);
- } else {
-- LUA_PUSH_ARRAY_STRING(d, bind[i].buffer);
-+ LUA_PUSH_ARRAY_STRING_BY_LENGTH(d, bind[i].buffer, *bind[i].length);
- }
- }
- } else if (lua_push == LUA_PUSH_BOOLEAN) {
-@@ -425,6 +468,7 @@
- }
-
- cleanup:
-+
- if (bind) {
- int i;
-
-@@ -535,6 +579,7 @@
- statement->mysql = conn->mysql;
- statement->stmt = stmt;
- statement->metadata = NULL;
-+ statement->lengths = NULL;
-
- /*
- mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (my_bool*)0);
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/postgresql/connection.c luadbi/dbd/postgresql/connection.c
---- lua-dbi-0.5/dbd/postgresql/connection.c 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/postgresql/connection.c 2015-01-15 13:38:28.176032059 -0500
-@@ -109,10 +109,12 @@
- int err = 0;
-
- if (conn->postgresql) {
-- if (on)
-- err = rollback(conn);
-- else
-- err = begin(conn);
-+ if (on != conn->autocommit) {
-+ if (on)
-+ err = rollback(conn);
-+ else
-+ err = begin(conn);
-+ }
-
- conn->autocommit = on;
- }
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/postgresql/dbd_postgresql.h luadbi/dbd/postgresql/dbd_postgresql.h
---- lua-dbi-0.5/dbd/postgresql/dbd_postgresql.h 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/postgresql/dbd_postgresql.h 2015-01-15 13:38:28.176032059 -0500
-@@ -1,5 +1,4 @@
- #include <libpq-fe.h>
--#include <postgres_fe.h>
- #include <dbd/common.h>
-
- /*
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/connection.c luadbi/dbd/sqlite3/connection.c
---- lua-dbi-0.5/dbd/sqlite3/connection.c 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/sqlite3/connection.c 2015-01-15 13:38:28.178032048 -0500
-@@ -9,19 +9,33 @@
- }
-
- static int commit(connection_t *conn) {
-- return run(conn, "COMMIT");
-+ return run(conn, "COMMIT TRANSACTION");
- }
-
-
- static int begin(connection_t *conn) {
-- return run(conn, "BEGIN");
--}
-+ 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");
-+ 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)
-@@ -50,7 +64,6 @@
- }
-
- conn->autocommit = 0;
-- begin(conn);
-
- luaL_getmetatable(L, DBD_SQLITE_CONNECTION);
- lua_setmetatable(L, -2);
-@@ -67,10 +80,9 @@
- int err = 1;
-
- if (conn->sqlite) {
-- if (on)
-+ if (on) {
- err = rollback(conn);
-- else
-- err = begin(conn);
-+ }
-
- conn->autocommit = on;
- }
-@@ -88,6 +100,7 @@
- int disconnect = 0;
-
- if (conn->sqlite) {
-+ rollback(conn);
- sqlite3_close(conn->sqlite);
- disconnect = 1;
- conn->sqlite = NULL;
-@@ -105,12 +118,7 @@
- int err = 1;
-
- if (conn->sqlite) {
-- commit(conn);
--
-- if (!conn->autocommit)
-- err = begin(conn);
-- else
-- err = 1;
-+ err = commit(conn);
- }
-
- lua_pushboolean(L, !err);
-@@ -176,12 +184,7 @@
- int err = 1;
-
- if (conn->sqlite) {
-- rollback(conn);
--
-- if (!conn->autocommit)
-- err = begin(conn);
-- else
-- err = 1;
-+ err =rollback(conn);
- }
-
- lua_pushboolean(L, !err);
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/dbd_sqlite3.h luadbi/dbd/sqlite3/dbd_sqlite3.h
---- lua-dbi-0.5/dbd/sqlite3/dbd_sqlite3.h 2008-12-19 01:33:32.000000000 -0500
-+++ luadbi/dbd/sqlite3/dbd_sqlite3.h 2015-01-15 13:38:28.178032048 -0500
-@@ -10,14 +10,15 @@
- typedef struct _connection {
- sqlite3 *sqlite;
- int autocommit;
-+// int txn_in_progress;
- } connection_t;
-
- /*
- * statement object
- */
- typedef struct _statement {
-+ connection_t *conn;
- sqlite3_stmt *stmt;
-- sqlite3 *sqlite;
- int more_data;
- int affected;
- } statement_t;
-diff -urP '--exclude=.hg' lua-dbi-0.5/dbd/sqlite3/statement.c luadbi/dbd/sqlite3/statement.c
---- lua-dbi-0.5/dbd/sqlite3/statement.c 2010-05-01 00:25:12.000000000 -0400
-+++ luadbi/dbd/sqlite3/statement.c 2015-01-15 13:38:28.179032043 -0500
-@@ -1,5 +1,8 @@
- #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
- */
-@@ -128,10 +131,12 @@
- */
- if (sqlite3_reset(statement->stmt) != SQLITE_OK) {
- lua_pushboolean(L, 0);
-- lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->sqlite));
-+ 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) {
- /*
-@@ -156,10 +161,13 @@
- 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;
-+ case LUA_TSTRING: {
-+ size_t len = -1;
-+ const char *str = lua_tolstring(L, p, &len);
-+ errflag = sqlite3_bind_text(statement->stmt, i, str, len, SQLITE_STATIC) != SQLITE_OK;
- break;
-- case LUA_TBOOLEAN:
-+ }
-+ case LUA_TBOOLEAN:
- errflag = sqlite3_bind_int(statement->stmt, i, lua_toboolean(L, p)) != SQLITE_OK;
- break;
- default:
-@@ -180,18 +188,20 @@
- if (errstr)
- lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, errstr);
- else
-- lua_pushfstring(L, DBI_ERR_BINDING_PARAMS, sqlite3_errmsg(statement->sqlite));
-+ 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->sqlite));
-+ lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->conn->sqlite));
- return 2;
- }
-
-- statement->affected = sqlite3_changes(statement->sqlite);
-+ statement->affected = sqlite3_changes(statement->conn->sqlite);
-
- lua_pushboolean(L, 1);
- return 1;
-@@ -283,7 +293,7 @@
- /*
- * reset needs to be called to retrieve the 'real' error message
- */
-- luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->sqlite));
-+ luaL_error(L, DBI_ERR_FETCH_FAILED, sqlite3_errmsg(statement->conn->sqlite));
- }
- }
-
-@@ -327,9 +337,9 @@
- * num_rows = statement:rowcount()
- */
- static int statement_rowcount(lua_State *L) {
-- luaL_error(L, DBI_ERR_NOT_IMPLEMENTED, DBD_SQLITE_STATEMENT, "rowcount");
--
-- return 0;
-+ statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_SQLITE_STATEMENT);
-+ lua_pushinteger(L, sqlite3_data_count(statement->stmt));
-+ return 1;
- }
-
- /*
-@@ -357,14 +367,14 @@
- statement_t *statement = NULL;
-
- statement = (statement_t *)lua_newuserdata(L, sizeof(statement_t));
-- statement->sqlite = conn->sqlite;
-+ statement->conn = conn;
- statement->stmt = NULL;
- statement->more_data = 0;
- statement->affected = 0;
-
-- if (sqlite3_prepare_v2(statement->sqlite, sql_query, strlen(sql_query), &statement->stmt, NULL) != SQLITE_OK) {
-+ 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->sqlite));
-+ lua_pushfstring(L, DBI_ERR_PREP_STATEMENT, sqlite3_errmsg(statement->conn->sqlite));
- return 2;
- }
-