From ac29ca1782ba71a95d8e5cb026e4e89201ef2761 Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Mon, 6 Jun 2016 04:36:18 +0100 Subject: [PATCH 1/6] dbWithTransaction --- NAMESPACE | 5 -- R/DBConnection.R | 126 --------------------------------------- man/dbBreak.Rd | 17 ------ man/dbDisconnect.Rd | 4 +- man/dbExecute.Rd | 46 -------------- man/dbExistsTable.Rd | 1 - man/dbGetChunkedQuery.Rd | 82 ------------------------- man/dbGetException.Rd | 10 ++-- man/dbGetQuery.Rd | 3 +- man/dbListFields.Rd | 3 +- man/dbListResults.Rd | 3 +- man/dbListTables.Rd | 3 +- man/dbReadTable.Rd | 3 +- man/dbRemoveTable.Rd | 3 +- man/dbSendQuery.Rd | 3 +- 15 files changed, 12 insertions(+), 300 deletions(-) delete mode 100644 man/dbBreak.Rd delete mode 100644 man/dbExecute.Rd delete mode 100644 man/dbGetChunkedQuery.Rd diff --git a/NAMESPACE b/NAMESPACE index fc3d18114..f9d7425ac 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,7 +6,6 @@ export(SQL) export(SQLKeywords) export(dbBegin) export(dbBind) -export(dbBreak) export(dbCallProc) export(dbClearResult) export(dbColumnInfo) @@ -15,10 +14,8 @@ export(dbConnect) export(dbDataType) export(dbDisconnect) export(dbDriver) -export(dbExecute) export(dbExistsTable) export(dbFetch) -export(dbGetChunkedQuery) export(dbGetDBIVersion) export(dbGetException) export(dbGetInfo) @@ -65,8 +62,6 @@ exportClasses(DBIObject) exportClasses(DBIResult) exportClasses(SQL) exportMethods(dbDataType) -exportMethods(dbExecute) -exportMethods(dbGetChunkedQuery) exportMethods(dbGetQuery) exportMethods(dbQuoteIdentifier) exportMethods(dbWithTransaction) diff --git a/R/DBConnection.R b/R/DBConnection.R index 2add3fc39..4718c6424 100644 --- a/R/DBConnection.R +++ b/R/DBConnection.R @@ -106,132 +106,6 @@ setGeneric("dbSendQuery", valueClass = "DBIResult" ) -#' Execute an SQL statement that does not produce a result set. -#' -#' This function should be used when you want to execute a non- -#' \code{SELECT} query on table (ex: \code{UPDATE}, \code{DELETE}, -#' \code{INSERT INTO}, \code{DROP TABLE}, ...). It will execute -#' the query and return the number of rows affected by the operation. -#' (If the return value is 0 or -1, you're using it wrong.) -#' -#' @inheritParams dbDisconnect -#' @param statement a character vector of length 1 containing SQL. -#' @return The number of rows affected by the \code{statement} -#' @aliases dbExecute,DBIConnection,character-method -#' @family connection methods -#' @export -#' @examples -#' con <- dbConnect(RSQLite::SQLite(), ":memory:") -#' dbWriteTable(con, "cars", head(cars, 3)) -#' dbReadTable(con, "cars") # there's 3 rows! -#' dbExecute(con, "INSERT INTO cars (speed, dist) -#' VALUES (1, 1), (2, 2), (3, 3);") -#' dbReadTable(con, "cars") # there's now 6 rows! -#' dbDisconnect(con) -setGeneric("dbExecute", - def = function(conn, statement, ...) standardGeneric("dbExecute") -) - -#' @export -setMethod("dbExecute", signature("DBIConnection", "character"), - function(conn, statement, ...) { - rs <- dbSendQuery(conn, statement, ...) - on.exit(dbClearResult(rs)) - dbGetRowsAffected(rs) - } -) - -#' Sentinel value to indicate the early termination of -#' \code{\link{dbGetChunkedQuery}} -#' @export -dbBreak <- structure(list(), class = "dbi_break_sentinel") - -dbFetchChunked <- function(rs, n, callback) { - while (TRUE) { - chunk <- dbFetch(rs, n = n) - if (nrow(chunk) == 0) { - return(chunk) - } - result <- callback(chunk) - if (identical(result, dbBreak)) { - return(chunk) - } - } -} - -#' Fetch data in chunks and access it with a callback -#' -#' This function allows you to fetch data in chunks of \code{n} -#' rows at a time and acess that chunk using a callback. This is -#' meant as a safer and more efficient alternative to -#' \code{\link{dbSendQuery}}. On one hand, it does not keep the -#' result set open, so you don't have to worry about -#' \code{\link{dbClearResult}}. On the other hand, you never need -#' to have all of the data on your machine at once (each chunk -#' comes and goes), but you can still produce global results. -#' -#' For most use cases, you will want to actually loop through all -#' of the data. But there are some cases for which this is not true -#' (for example, if you just want to locate a particular row). In -#' these situations, you can stop the function from continuing to -#' execute once your terminating condition is met. To do so, use: -#' \code{if (terminatingCondition) return(dbBreak)}. \code{dbBreak} -#' is a sentinel value that \code{DBI} recognizes and knows how -#' to interpret correctly. -#' -#' @param conn A \code{\linkS4class{DBIConnection}} object, as produced by -#' \code{\link{dbConnect}}. -#' @param statement A character vector of length 1 containing SQL. -#' @param n The number of rows to fetch in each chunk. -#' @param callback A callback function whose only argument must be -#' the (partial) result set returned by the \code{statement} (dataframe). -#' @param ... Other parameters passed on to methods. -#' -#' @return The last chunk of data fetched. -#' -#' @aliases dbGetChunkedQuery,DBIConnection,character-method -#' @family connection methods -#' @export -#' @examples -#' con <- dbConnect(RSQLite::SQLite(), ":memory:") -#' dbWriteTable(con, "cars", cars) -#' -#' ## Want to loop through all chunks to produce a global result -#' distSum <- 0 -#' rowCount <- 0 -#' -#' dbGetChunkedQuery(con, "SELECT dist FROM cars", 10, function(df) { -#' distSum <<- distSum + sum(df$dist) -#' rowCount <<- rowCount + nrow(df) -#' }) -#' -#' (distAvg <- distSum / rowCount) -#' -#' ## Want to stop once we find the row we're looking for -#' rowCount <- 0 -#' -#' dbGetChunkedQuery(con, "SELECT * FROM cars", 1, function(df) { -#' rowCount <<- rowCount + nrow(df) -#' if (df$speed == 19 && df$dist == 46) { -#' print(paste("Your row is number", rowCount)) -#' return(dbBreak) -#' } -#' }) -#' -#' dbDisconnect(con) -setGeneric("dbGetChunkedQuery", function(conn, statement, n, callback, ...) { - standardGeneric("dbGetChunkedQuery") -}) - -#' @export -setMethod("dbGetChunkedQuery", signature("DBIConnection", "character"), - function(conn, statement, n, callback, ...) { - rs <- dbSendQuery(conn, statement, ...) - on.exit(dbClearResult(rs)) - dbFetchChunked(rs, n, callback) - } -) - #' Send query, retrieve results and then clear result set. #' #' \code{dbGetQuery} comes with a default implementation that calls diff --git a/man/dbBreak.Rd b/man/dbBreak.Rd deleted file mode 100644 index 1fdc1ed89..000000000 --- a/man/dbBreak.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/DBConnection.R -\docType{data} -\name{dbBreak} -\alias{dbBreak} -\title{Sentinel value to indicate the early termination of -\code{\link{dbGetChunkedQuery}}} -\format{An object of class \code{dbi_break_sentinel} of length 0.} -\usage{ -dbBreak -} -\description{ -Sentinel value to indicate the early termination of -\code{\link{dbGetChunkedQuery}} -} -\keyword{datasets} - diff --git a/man/dbDisconnect.Rd b/man/dbDisconnect.Rd index a97160bc8..dc2ee0237 100644 --- a/man/dbDisconnect.Rd +++ b/man/dbDisconnect.Rd @@ -26,9 +26,7 @@ dbDisconnect(con) } } \seealso{ -Other connection methods: \code{\link{dbExecute}}, - \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, +Other connection methods: \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, diff --git a/man/dbExecute.Rd b/man/dbExecute.Rd deleted file mode 100644 index 5aec3fa41..000000000 --- a/man/dbExecute.Rd +++ /dev/null @@ -1,46 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/DBConnection.R -\name{dbExecute} -\alias{dbExecute} -\alias{dbExecute,DBIConnection,character-method} -\title{Execute an SQL statement that does not produce a result set.} -\usage{ -dbExecute(conn, statement, ...) -} -\arguments{ -\item{conn}{A \code{\linkS4class{DBIConnection}} object, as produced by -\code{\link{dbConnect}}.} - -\item{statement}{a character vector of length 1 containing SQL.} - -\item{...}{Other parameters passed on to methods.} -} -\value{ -The number of rows affected by the \code{statement} -} -\description{ -This function should be used when you want to execute a non- -\code{SELECT} query on table (ex: \code{UPDATE}, \code{DELETE}, -\code{INSERT INTO}, \code{DROP TABLE}, ...). It will execute -the query and return the number of rows affected by the operation. -(If the return value is 0 or -1, you're using it wrong.) -} -\examples{ -con <- dbConnect(RSQLite::SQLite(), ":memory:") -dbWriteTable(con, "cars", head(cars, 3)) -dbReadTable(con, "cars") # there's 3 rows! -dbExecute(con, "INSERT INTO cars (speed, dist) - VALUES (1, 1), (2, 2), (3, 3);") -dbReadTable(con, "cars") # there's now 6 rows! -dbDisconnect(con) -} -\seealso{ -Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, - \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, - \code{\link{dbListFields}}, \code{\link{dbListResults}}, - \code{\link{dbListTables}}, \code{\link{dbReadTable}}, - \code{\link{dbRemoveTable}}, \code{\link{dbSendQuery}} -} - diff --git a/man/dbExistsTable.Rd b/man/dbExistsTable.Rd index 76de092a4..957b26fa1 100644 --- a/man/dbExistsTable.Rd +++ b/man/dbExistsTable.Rd @@ -22,7 +22,6 @@ Does a table exist? } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbGetChunkedQuery}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, diff --git a/man/dbGetChunkedQuery.Rd b/man/dbGetChunkedQuery.Rd deleted file mode 100644 index bea7dde8d..000000000 --- a/man/dbGetChunkedQuery.Rd +++ /dev/null @@ -1,82 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/DBConnection.R -\name{dbGetChunkedQuery} -\alias{dbGetChunkedQuery} -\alias{dbGetChunkedQuery,DBIConnection,character-method} -\title{Fetch data in chunks and access it with a callback} -\usage{ -dbGetChunkedQuery(conn, statement, n, callback, ...) -} -\arguments{ -\item{conn}{A \code{\linkS4class{DBIConnection}} object, as produced by -\code{\link{dbConnect}}.} - -\item{statement}{A character vector of length 1 containing SQL.} - -\item{n}{The number of rows to fetch in each chunk.} - -\item{callback}{A callback function whose only argument must be -the (partial) result set returned by the \code{statement} (dataframe).} - -\item{...}{Other parameters passed on to methods.} -} -\value{ -The last chunk of data fetched. -} -\description{ -This function allows you to fetch data in chunks of \code{n} -rows at a time and acess that chunk using a callback. This is -meant as a safer and more efficient alternative to -\code{\link{dbSendQuery}}. On one hand, it does not keep the -result set open, so you don't have to worry about -\code{\link{dbClearResult}}. On the other hand, you never need -to have all of the data on your machine at once (each chunk -comes and goes), but you can still produce global results. -} -\details{ -For most use cases, you will want to actually loop through all -of the data. But there are some cases for which this is not true -(for example, if you just want to locate a particular row). In -these situations, you can stop the function from continuing to -execute once your terminating condition is met. To do so, use: -\code{if (terminatingCondition) return(dbBreak)}. \code{dbBreak} -is a sentinel value that \code{DBI} recognizes and knows how -to interpret correctly. -} -\examples{ -con <- dbConnect(RSQLite::SQLite(), ":memory:") -dbWriteTable(con, "cars", cars) - -## Want to loop through all chunks to produce a global result -distSum <- 0 -rowCount <- 0 - -dbGetChunkedQuery(con, "SELECT dist FROM cars", 10, function(df) { - distSum <<- distSum + sum(df$dist) - rowCount <<- rowCount + nrow(df) -}) - -(distAvg <- distSum / rowCount) - -## Want to stop once we find the row we're looking for -rowCount <- 0 - -dbGetChunkedQuery(con, "SELECT * FROM cars", 1, function(df) { - rowCount <<- rowCount + nrow(df) - if (df$speed == 19 && df$dist == 46) { - print(paste("Your row is number", rowCount)) - return(dbBreak) - } -}) - -dbDisconnect(con) -} -\seealso{ -Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, - \code{\link{dbListFields}}, \code{\link{dbListResults}}, - \code{\link{dbListTables}}, \code{\link{dbReadTable}}, - \code{\link{dbRemoveTable}}, \code{\link{dbSendQuery}} -} - diff --git a/man/dbGetException.Rd b/man/dbGetException.Rd index b25997580..ade423cc9 100644 --- a/man/dbGetException.Rd +++ b/man/dbGetException.Rd @@ -22,11 +22,9 @@ Get DBMS exceptions. } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, - \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, - \code{\link{dbListResults}}, \code{\link{dbListTables}}, - \code{\link{dbReadTable}}, \code{\link{dbRemoveTable}}, - \code{\link{dbSendQuery}} + \code{\link{dbExistsTable}}, \code{\link{dbGetQuery}}, + \code{\link{dbListFields}}, \code{\link{dbListResults}}, + \code{\link{dbListTables}}, \code{\link{dbReadTable}}, + \code{\link{dbRemoveTable}}, \code{\link{dbSendQuery}} } diff --git a/man/dbGetQuery.Rd b/man/dbGetQuery.Rd index 1c17100de..ad3aeb678 100644 --- a/man/dbGetQuery.Rd +++ b/man/dbGetQuery.Rd @@ -41,8 +41,7 @@ dbDisconnect(con) } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, \code{\link{dbRemoveTable}}, diff --git a/man/dbListFields.Rd b/man/dbListFields.Rd index 91fdd86ce..85048f0a7 100644 --- a/man/dbListFields.Rd +++ b/man/dbListFields.Rd @@ -24,8 +24,7 @@ List field names of a remote table. \code{\link{dbColumnInfo}} to get the type of the fields. Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, \code{\link{dbRemoveTable}}, diff --git a/man/dbListResults.Rd b/man/dbListResults.Rd index 181f29118..1cfb2c446 100644 --- a/man/dbListResults.Rd +++ b/man/dbListResults.Rd @@ -21,8 +21,7 @@ List of \linkS4class{DBIResult} objects currently active on the connection. } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, \code{\link{dbRemoveTable}}, diff --git a/man/dbListTables.Rd b/man/dbListTables.Rd index 7d898b229..3bbec5f81 100644 --- a/man/dbListTables.Rd +++ b/man/dbListTables.Rd @@ -21,8 +21,7 @@ This should, where possible, include temporary tables. } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbReadTable}}, \code{\link{dbRemoveTable}}, diff --git a/man/dbReadTable.Rd b/man/dbReadTable.Rd index f4265a355..e0603000d 100644 --- a/man/dbReadTable.Rd +++ b/man/dbReadTable.Rd @@ -44,8 +44,7 @@ dbDisconnect(con) } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbRemoveTable}}, diff --git a/man/dbRemoveTable.Rd b/man/dbRemoveTable.Rd index a39d77154..7db450c5a 100644 --- a/man/dbRemoveTable.Rd +++ b/man/dbRemoveTable.Rd @@ -22,8 +22,7 @@ Executes the sql \code{DROP TABLE name}. } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, diff --git a/man/dbSendQuery.Rd b/man/dbSendQuery.Rd index 5e7f179bb..32e5b5296 100644 --- a/man/dbSendQuery.Rd +++ b/man/dbSendQuery.Rd @@ -53,8 +53,7 @@ dbDisconnect(con) } \seealso{ Other connection methods: \code{\link{dbDisconnect}}, - \code{\link{dbExecute}}, \code{\link{dbExistsTable}}, - \code{\link{dbGetChunkedQuery}}, + \code{\link{dbExistsTable}}, \code{\link{dbGetException}}, \code{\link{dbGetQuery}}, \code{\link{dbListFields}}, \code{\link{dbListResults}}, \code{\link{dbListTables}}, \code{\link{dbReadTable}}, From 8d4fdd946f0930c0a701b2726dadd9115382afeb Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Mon, 6 Jun 2016 04:38:00 +0100 Subject: [PATCH 2/6] removed NEWS update --- NEWS.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index b33360f69..6ae347bb8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,9 +1,3 @@ -# DBI 0.4-2 - -* Added `dbExecute` function. -* Added `dbGetChunkedQuery` function. -* Added `dbWithTransaction` function. - # DBI 0.4-1 (2016-05-07) - The default `show()` implementations silently ignore all errors. Some DBI drivers (e.g., RPostgreSQL) might fail to implement `dbIsValid()` or the other methods used. From 93d6c3da3e0610d60407c1e5e4dec3c6d01f5ec0 Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Mon, 6 Jun 2016 17:25:09 +0100 Subject: [PATCH 3/6] improved error messages --- R/transactions.R | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/R/transactions.R b/R/transactions.R index 98d049088..143e47424 100644 --- a/R/transactions.R +++ b/R/transactions.R @@ -96,17 +96,20 @@ setGeneric("dbWithTransaction", #' @export setMethod("dbWithTransaction", "DBIConnection", function(conn, code) { ## check if each operation is successful - success <- dbBegin(conn) - if (!success) stop("`dbBegin` was not successful") + if (!dbBegin(conn)) { + stop("Failed to begin transaction", call. = FALSE) + } tryCatch({ res <- force(code) - success <- dbCommit(conn) - if (!success) stop("`dbCommit` was not successful") + if (!dbCommit(conn)) { + stop("Failed to commit transaction", call. = FALSE) + } res }, error = function(e) { - success <- dbRollback(conn) - if (!success) stop("`dbRollback` was not successful") + if (!dbRollback(conn)) { + stop("Failed to rollback transaction", call. = FALSE) + } stop(e) } ) From c8a8b6487689a4913d08248e7b3d6aa4c7282d4a Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Mon, 13 Jun 2016 14:42:12 +0100 Subject: [PATCH 4/6] included error in rollback fail --- R/transactions.R | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/R/transactions.R b/R/transactions.R index 143e47424..dfc48c690 100644 --- a/R/transactions.R +++ b/R/transactions.R @@ -108,9 +108,11 @@ setMethod("dbWithTransaction", "DBIConnection", function(conn, code) { }, error = function(e) { if (!dbRollback(conn)) { - stop("Failed to rollback transaction", call. = FALSE) + stop(paste("Failed to rollback transaction", + "Tried to roll back because an error", + "occurred:", conditionMessage(e)), + call. = FALSE) } stop(e) - } - ) + }) }) From e4818dead0b0d2e5ccfe651f5504fafe3cf3d8c6 Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Mon, 13 Jun 2016 15:34:17 +0100 Subject: [PATCH 5/6] better error handling --- R/transactions.R | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/R/transactions.R b/R/transactions.R index dfc48c690..9ef6a9bcc 100644 --- a/R/transactions.R +++ b/R/transactions.R @@ -96,19 +96,22 @@ setGeneric("dbWithTransaction", #' @export setMethod("dbWithTransaction", "DBIConnection", function(conn, code) { ## check if each operation is successful - if (!dbBegin(conn)) { + call <- dbBegin(conn) + if (identical(call, FALSE)) { stop("Failed to begin transaction", call. = FALSE) } tryCatch({ res <- force(code) - if (!dbCommit(conn)) { + call <- dbCommit(conn) + if (identical(call, FALSE)) { stop("Failed to commit transaction", call. = FALSE) } res }, error = function(e) { - if (!dbRollback(conn)) { - stop(paste("Failed to rollback transaction", + call <- dbRollback(conn) + if (identical(call, FALSE)) { + stop(paste("Failed to rollback transaction.", "Tried to roll back because an error", "occurred:", conditionMessage(e)), call. = FALSE) From 872452480340abc9ca1fbc20c64332eda63923d1 Mon Sep 17 00:00:00 2001 From: Barbara Borges Ribeiro Date: Tue, 14 Jun 2016 15:27:46 +0100 Subject: [PATCH 6/6] re-added NEWS items --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index 6ae347bb8..b142ad81a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# DBI 0.4-2 (2016-06-08) + +- Remove redundant declaration of transaction methods (#110, @bborgesr). +- New `dbExecute()`, forwards to `dbSendQuery()` by default (#109, @bborgesr). + # DBI 0.4-1 (2016-05-07) - The default `show()` implementations silently ignore all errors. Some DBI drivers (e.g., RPostgreSQL) might fail to implement `dbIsValid()` or the other methods used.