Fix DBD.SQLite3 transaction handling

Mon, 20 Dec 2010 09:01:12 +0000

author
nrich@ii.net
date
Mon, 20 Dec 2010 09:01:12 +0000
changeset 41
e490414a391d
parent 40
71c4b5dd82bb
child 42
93335fa1f1d0

Fix DBD.SQLite3 transaction handling

dbd/sqlite3/connection.c file | annotate | diff | comparison | revisions
dbd/sqlite3/dbd_sqlite3.h file | annotate | diff | comparison | revisions
dbd/sqlite3/statement.c file | annotate | diff | comparison | revisions
--- 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);
--- 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;
--- 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;
     } 
 

mercurial