# HG changeset patch # User nrich@ii.net # Date 1292835672 0 # Node ID e490414a391d6bfa812561f70dc0034aea8a38cd # Parent 71c4b5dd82bb7f6e50c1ef0bcaf3663ef7bbb634 Fix DBD.SQLite3 transaction handling diff -r 71c4b5dd82bb -r e490414a391d dbd/sqlite3/connection.c --- a/dbd/sqlite3/connection.c Sun Jul 18 03:42:30 2010 +0000 +++ b/dbd/sqlite3/connection.c Mon Dec 20 09:01:12 2010 +0000 @@ -9,19 +9,36 @@ } static int commit(connection_t *conn) { - return run(conn, "COMMIT"); + conn->txn_in_progress = 0; + return run(conn, "COMMIT TRANSACTION"); } static int begin(connection_t *conn) { - return run(conn, "BEGIN"); + int err = 0; + + if (conn->txn_in_progress) { + err = 0; + } else { + conn->txn_in_progress = 1; + err = run(conn, "BEGIN TRANSACTION"); + } + + return err; } - static int rollback(connection_t *conn) { - return run(conn, "ROLLBACK"); + conn->txn_in_progress = 0; + 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 +67,7 @@ } conn->autocommit = 0; - begin(conn); + conn->txn_in_progress = 0; luaL_getmetatable(L, DBD_SQLITE_CONNECTION); lua_setmetatable(L, -2); @@ -67,10 +84,13 @@ int err = 1; if (conn->sqlite) { - if (on) + if (on) { err = rollback(conn); + } + /* else err = begin(conn); + */ conn->autocommit = on; } @@ -88,6 +108,7 @@ int disconnect = 0; if (conn->sqlite) { + rollback(conn); sqlite3_close(conn->sqlite); disconnect = 1; conn->sqlite = NULL; @@ -105,12 +126,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 +192,14 @@ int err = 1; if (conn->sqlite) { - rollback(conn); + err =rollback(conn); + /* if (!conn->autocommit) err = begin(conn); else err = 1; + */ } lua_pushboolean(L, !err); diff -r 71c4b5dd82bb -r e490414a391d dbd/sqlite3/dbd_sqlite3.h --- a/dbd/sqlite3/dbd_sqlite3.h Sun Jul 18 03:42:30 2010 +0000 +++ b/dbd/sqlite3/dbd_sqlite3.h Mon Dec 20 09:01:12 2010 +0000 @@ -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 -r 71c4b5dd82bb -r e490414a391d dbd/sqlite3/statement.c --- a/dbd/sqlite3/statement.c Sun Jul 18 03:42:30 2010 +0000 +++ b/dbd/sqlite3/statement.c Mon Dec 20 09:01:12 2010 +0000 @@ -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) { /* @@ -180,18 +185,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->conn->sqlite)); return 2; } - if (!step(statement)) { - lua_pushboolean(L, 0); - lua_pushfstring(L, DBI_ERR_EXECUTE_FAILED, sqlite3_errmsg(statement->sqlite)); - return 2; - } - - statement->affected = sqlite3_changes(statement->sqlite); + statement->affected = sqlite3_changes(statement->conn->sqlite); lua_pushboolean(L, 1); return 1; @@ -283,7 +290,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)); } } @@ -357,14 +364,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; }