Skip to content

Commit

Permalink
Merge pull request #464 from bpvgoncalves/fix_brk_rev_dep
Browse files Browse the repository at this point in the history
  • Loading branch information
krlmlr authored Oct 30, 2023
2 parents 11b6980 + 36072e0 commit af98957
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 68 deletions.
8 changes: 0 additions & 8 deletions R/cpp11.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ connection_in_transaction <- function(con_) {
.Call(`_RSQLite_connection_in_transaction`, con_)
}

connection_add_transaction <- function(con_) {
invisible(.Call(`_RSQLite_connection_add_transaction`, con_))
}

connection_rem_transaction <- function(con_) {
invisible(.Call(`_RSQLite_connection_rem_transaction`, con_))
}

connection_copy_database <- function(from, to) {
invisible(.Call(`_RSQLite_connection_copy_database`, from, to))
}
Expand Down
1 change: 0 additions & 1 deletion R/dbBegin_SQLiteConnection.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ dbBegin_SQLiteConnection <- function(conn, .name = NULL, ..., name = NULL) {
} else {
dbExecute(conn, paste0("SAVEPOINT ", dbQuoteIdentifier(conn, name)))
}
connection_add_transaction(conn@ptr)
invisible(TRUE)
}
#' @rdname sqlite-transaction
Expand Down
1 change: 0 additions & 1 deletion R/dbCommit_SQLiteConnection.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ dbCommit_SQLiteConnection <- function(conn, .name = NULL, ..., name = NULL) {
} else {
dbExecute(conn, paste0("RELEASE SAVEPOINT ", dbQuoteIdentifier(conn, name)))
}
connection_rem_transaction(conn@ptr)
invisible(TRUE)
}
#' @rdname sqlite-transaction
Expand Down
1 change: 0 additions & 1 deletion R/dbRollback_SQLiteConnection.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ dbRollback_SQLiteConnection <- function(conn, .name = NULL, ..., name = NULL) {
dbExecute(conn, paste0("ROLLBACK TO ", name_quoted))
dbExecute(conn, paste0("RELEASE SAVEPOINT ", name_quoted))
}
connection_rem_transaction(conn@ptr)
invisible(TRUE)
}
#' @rdname sqlite-transaction
Expand Down
19 changes: 4 additions & 15 deletions src/DbConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
DbConnection::DbConnection(const std::string& path, const bool allow_ext, const int flags, const std::string& vfs, bool with_alt_types)
: pConn_(NULL),
with_alt_types_(with_alt_types),
busy_callback_(NULL),
transaction_(0) {
busy_callback_(NULL) {

// Get the underlying database connection
int rc = sqlite3_open_v2(path.c_str(), &pConn_, flags, vfs.empty() ? NULL : vfs.c_str());
Expand Down Expand Up @@ -114,21 +113,11 @@ int DbConnection::busy_callback_helper(void *data, int num)
}

bool DbConnection::in_transaction() const {
if (transaction_ > 0) {
int status = sqlite3_get_autocommit(pConn_);

if (status == 0) {
return true;
} else {
return false;
}
}

void DbConnection::add_transaction() {
transaction_ += 1;
}

void DbConnection::rem_transaction() {
if (transaction_ > 0) {
transaction_ -= 1;
} else {
cpp11::stop("Cannot remove non-existent transactions");
}
}
3 changes: 0 additions & 3 deletions src/DbConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,13 @@ class DbConnection : boost::noncopyable {
void set_busy_handler(SEXP r_callback);

bool in_transaction() const;
void add_transaction();
void rem_transaction();

private:
sqlite3* pConn_;
const bool with_alt_types_;
SEXP busy_callback_;
void release_callback_data();
static int busy_callback_helper(void *data, int num);
int transaction_;
};

#endif // __RSQLITE_SQLITE_CONNECTION__
11 changes: 0 additions & 11 deletions src/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,6 @@ bool connection_in_transaction(cpp11::external_pointer<DbConnectionPtr> con_){
DbConnectionPtr* con = con_.get();
return (con->get()->in_transaction() != 0);
}
[[cpp11::register]]
void connection_add_transaction(cpp11::external_pointer<DbConnectionPtr> con_){
DbConnectionPtr* con = con_.get();
con->get()->add_transaction();
}
[[cpp11::register]]
void connection_rem_transaction(cpp11::external_pointer<DbConnectionPtr> con_){
DbConnectionPtr* con = con_.get();
con->get()->rem_transaction();
}


// Quoting

Expand Down
18 changes: 0 additions & 18 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,6 @@ extern "C" SEXP _RSQLite_connection_in_transaction(SEXP con_) {
END_CPP11
}
// connection.cpp
void connection_add_transaction(cpp11::external_pointer<DbConnectionPtr> con_);
extern "C" SEXP _RSQLite_connection_add_transaction(SEXP con_) {
BEGIN_CPP11
connection_add_transaction(cpp11::as_cpp<cpp11::decay_t<cpp11::external_pointer<DbConnectionPtr>>>(con_));
return R_NilValue;
END_CPP11
}
// connection.cpp
void connection_rem_transaction(cpp11::external_pointer<DbConnectionPtr> con_);
extern "C" SEXP _RSQLite_connection_rem_transaction(SEXP con_) {
BEGIN_CPP11
connection_rem_transaction(cpp11::as_cpp<cpp11::decay_t<cpp11::external_pointer<DbConnectionPtr>>>(con_));
return R_NilValue;
END_CPP11
}
// connection.cpp
void connection_copy_database(const cpp11::external_pointer<DbConnectionPtr>& from, const cpp11::external_pointer<DbConnectionPtr>& to);
extern "C" SEXP _RSQLite_connection_copy_database(SEXP from, SEXP to) {
BEGIN_CPP11
Expand Down Expand Up @@ -171,13 +155,11 @@ extern "C" SEXP _RSQLite_init_logging(SEXP log_level) {

extern "C" {
static const R_CallMethodDef CallEntries[] = {
{"_RSQLite_connection_add_transaction", (DL_FUNC) &_RSQLite_connection_add_transaction, 1},
{"_RSQLite_connection_connect", (DL_FUNC) &_RSQLite_connection_connect, 5},
{"_RSQLite_connection_copy_database", (DL_FUNC) &_RSQLite_connection_copy_database, 2},
{"_RSQLite_connection_import_file", (DL_FUNC) &_RSQLite_connection_import_file, 6},
{"_RSQLite_connection_in_transaction", (DL_FUNC) &_RSQLite_connection_in_transaction, 1},
{"_RSQLite_connection_release", (DL_FUNC) &_RSQLite_connection_release, 1},
{"_RSQLite_connection_rem_transaction", (DL_FUNC) &_RSQLite_connection_rem_transaction, 1},
{"_RSQLite_connection_valid", (DL_FUNC) &_RSQLite_connection_valid, 1},
{"_RSQLite_extension_load", (DL_FUNC) &_RSQLite_extension_load, 3},
{"_RSQLite_init_logging", (DL_FUNC) &_RSQLite_init_logging, 1},
Expand Down
136 changes: 126 additions & 10 deletions tests/testthat/test-transactions.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ test_that("commit unnamed transactions", {

expect_false(sqliteIsTransacting(con))
dbBegin(con)
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())
dbCommit(con)
Expand All @@ -56,8 +56,8 @@ test_that("rollback unnamed transactions", {

expect_false(sqliteIsTransacting(con))
dbBegin(con)
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())
dbRollback(con)
Expand Down Expand Up @@ -85,6 +85,7 @@ test_that("no nested unnamed transactions (commit after error)", {
dbBegin(con)
expect_true(sqliteIsTransacting(con))
expect_error(dbBegin(con))
expect_true(sqliteIsTransacting(con))
dbCommit(con)
expect_false(sqliteIsTransacting(con))

Expand All @@ -109,6 +110,7 @@ test_that("no nested unnamed transactions (rollback after error)", {
dbBegin(con)
expect_true(sqliteIsTransacting(con))
expect_error(dbBegin(con))
expect_true(sqliteIsTransacting(con))
dbRollback(con)
expect_false(sqliteIsTransacting(con))

Expand All @@ -131,8 +133,8 @@ test_that("commit named transactions", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())
dbCommit(con, name = "tx")
Expand All @@ -159,8 +161,8 @@ test_that("rollback named transactions", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())

Expand Down Expand Up @@ -188,8 +190,8 @@ test_that("nested named transactions (commit - commit)", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())

Expand Down Expand Up @@ -231,8 +233,8 @@ test_that("nested named transactions (commit - rollback)", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())

Expand Down Expand Up @@ -274,8 +276,8 @@ test_that("nested named transactions (rollback - commit)", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())

Expand Down Expand Up @@ -317,8 +319,8 @@ test_that("nested named transactions (rollback - rollback)", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "tx")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())

Expand Down Expand Up @@ -360,8 +362,8 @@ test_that("named transactions with keywords", {

expect_false(sqliteIsTransacting(con))
dbBegin(con, name = "SELECT")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), character())
dbCommit(con, name = "SELECT")
Expand All @@ -370,12 +372,126 @@ test_that("named transactions with keywords", {
expect_equal(dbListTables(con2), "a")

dbBegin(con, name = "WHERE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "b", data.frame(b = 1))
expect_true(sqliteIsTransacting(con))
expect_equal(dbListTables(con), c("a", "b"))
expect_equal(dbListTables(con2), "a")
dbRollback(con, name = "WHERE")
expect_false(sqliteIsTransacting(con))
expect_equal(dbListTables(con), "a")
expect_equal(dbListTables(con2), "a")
})

test_that("transactions managed without dbBegin+dbCommit", {
db_file <- tempfile("transactions", fileext = ".sqlite")
con <- dbConnect(SQLite(), db_file)
on.exit(dbDisconnect(con))

expect_false(sqliteIsTransacting(con))
dbExecute(con, "BEGIN")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "END")
expect_false(sqliteIsTransacting(con))

dbExecute(con, "BEGIN")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "b", data.frame(b = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "COMMIT")
expect_false(sqliteIsTransacting(con))

expect_false(sqliteIsTransacting(con))
dbExecute(con, "BEGIN IMMEDIATE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "c", data.frame(c = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "END")
expect_false(sqliteIsTransacting(con))

dbExecute(con, "BEGIN IMMEDIATE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "d", data.frame(d = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "COMMIT")
expect_false(sqliteIsTransacting(con))
})

test_that("transactions managed without dbBegin+dbRollback", {
db_file <- tempfile("transactions", fileext = ".sqlite")
con <- dbConnect(SQLite(), db_file)
on.exit(dbDisconnect(con))

expect_false(sqliteIsTransacting(con))
dbExecute(con, "BEGIN")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "ROLLBACK")
expect_false(sqliteIsTransacting(con))

dbExecute(con, "BEGIN IMMEDIATE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "b", data.frame(b = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "ROLLBACK")
expect_false(sqliteIsTransacting(con))
})

test_that("mixed management of transactions", {
db_file <- tempfile("transactions", fileext = ".sqlite")
con <- dbConnect(SQLite(), db_file)
on.exit(dbDisconnect(con))

expect_false(sqliteIsTransacting(con))
dbExecute(con, "BEGIN")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "a", data.frame(a = 1))
expect_true(sqliteIsTransacting(con))
dbCommit(con)
expect_false(sqliteIsTransacting(con))

dbExecute(con, "BEGIN IMMEDIATE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "b", data.frame(b = 1))
expect_true(sqliteIsTransacting(con))
dbCommit(con)
expect_false(sqliteIsTransacting(con))

expect_false(sqliteIsTransacting(con))
dbExecute(con, "BEGIN")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "c", data.frame(c = 1))
expect_true(sqliteIsTransacting(con))
dbRollback(con)
expect_false(sqliteIsTransacting(con))

dbExecute(con, "BEGIN IMMEDIATE")
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "d", data.frame(d = 1))
expect_true(sqliteIsTransacting(con))
dbRollback(con)
expect_false(sqliteIsTransacting(con))

dbBegin(con)
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "e", data.frame(e = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "COMMIT")
expect_false(sqliteIsTransacting(con))

dbBegin(con)
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "f", data.frame(f = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "END")
expect_false(sqliteIsTransacting(con))

dbBegin(con)
expect_true(sqliteIsTransacting(con))
dbWriteTable(con, "g", data.frame(g = 1))
expect_true(sqliteIsTransacting(con))
dbExecute(con, "ROLLBACK")
expect_false(sqliteIsTransacting(con))
})

0 comments on commit af98957

Please sign in to comment.