Skip to content

Commit

Permalink
Merge pull request #340 from r-dbi/f-13-savepoint
Browse files Browse the repository at this point in the history
- `dbBegin()`, `dbCommit()` and `dbRollback()` gain `name` argument to support savepoints. An unnamed transaction must be started beforehand (#13).
  • Loading branch information
krlmlr committed Sep 25, 2021
2 parents 7835589 + 5d02df2 commit a856f45
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 23 deletions.
50 changes: 34 additions & 16 deletions R/transactions.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,53 @@
NULL

#' @export
#' @param name If provided, uses the `SAVEPOINT` SQL syntax
#' to establish, remove (commit) or undo a ßsavepoint.
#' @rdname postgres-transactions
setMethod("dbBegin", "PqConnection", function(conn, ...) {
if (connection_is_transacting(conn@ptr)) {
stop("Nested transactions not supported.", call. = FALSE)
setMethod("dbBegin", "PqConnection", function(conn, ..., name = NULL) {
if (is.null(name)) {
if (connection_is_transacting(conn@ptr)) {
stop("Nested transactions not supported.", call. = FALSE)
}
dbExecute(conn, "BEGIN")
connection_set_transacting(conn@ptr, TRUE)
} else {
if (!connection_is_transacting(conn@ptr)) {
stop("Savepoints require an active transaction.", call. = FALSE)
}
dbExecute(conn, paste0("SAVEPOINT ", dbQuoteIdentifier(conn, name)))
}

dbExecute(conn, "BEGIN")
connection_set_transacting(conn@ptr, TRUE)
invisible(TRUE)
})

#' @export
#' @rdname postgres-transactions
setMethod("dbCommit", "PqConnection", function(conn, ...) {
if (!connection_is_transacting(conn@ptr)) {
stop("Call dbBegin() to start a transaction.", call. = FALSE)
setMethod("dbCommit", "PqConnection", function(conn, ..., name = NULL) {
if (is.null(name)) {
if (!connection_is_transacting(conn@ptr)) {
stop("Call dbBegin() to start a transaction.", call. = FALSE)
}
dbExecute(conn, "COMMIT")
connection_set_transacting(conn@ptr, FALSE)
} else {
dbExecute(conn, paste0("RELEASE SAVEPOINT ", dbQuoteIdentifier(conn, name)))
}
dbExecute(conn, "COMMIT")
connection_set_transacting(conn@ptr, FALSE)
invisible(TRUE)
})

#' @export
#' @rdname postgres-transactions
setMethod("dbRollback", "PqConnection", function(conn, ...) {
if (!connection_is_transacting(conn@ptr)) {
stop("Call dbBegin() to start a transaction.", call. = FALSE)
setMethod("dbRollback", "PqConnection", function(conn, ..., name = NULL) {
if (is.null(name)) {
if (!connection_is_transacting(conn@ptr)) {
stop("Call dbBegin() to start a transaction.", call. = FALSE)
}
dbExecute(conn, "ROLLBACK")
connection_set_transacting(conn@ptr, FALSE)
} else {
name_quoted <- dbQuoteIdentifier(conn, name)
dbExecute(conn, paste0("ROLLBACK TO ", name_quoted))
dbExecute(conn, paste0("RELEASE SAVEPOINT ", name_quoted))
}
dbExecute(conn, "ROLLBACK")
connection_set_transacting(conn@ptr, FALSE)
invisible(TRUE)
})
4 changes: 4 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ stopc <- function(...) {
warningc <- function(...) {
warning(..., call. = FALSE, domain = NA)
}

try_silent <- function(code) {
tryCatch(code, error = function(e) invisible())
}
9 changes: 6 additions & 3 deletions man/postgres-transactions.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a856f45

Please sign in to comment.