diff --git a/R/DBI-custom.R b/R/DBI-custom.R index 8ae936b..aacf90a 100644 --- a/R/DBI-custom.R +++ b/R/DBI-custom.R @@ -17,6 +17,7 @@ #' bound to a connection. Instead use [poolWithTransaction()]. #' #' * [DBI::dbDisconnect()] can't work because pool handles disconnection. +#' Use [poolClose()] instead. #' #' * [DBI::dbGetInfo()] returns information about the pool, not the database #' connection. diff --git a/R/DBI-wrap.R b/R/DBI-wrap.R index 9f859d5..31e7e93 100644 --- a/R/DBI-wrap.R +++ b/R/DBI-wrap.R @@ -4,9 +4,9 @@ #' These pool method for DBI generics methods check out a connection #' (with [poolCheckout()]), re-call the generic, then return the connection #' to the pool (with [poolReturn()]). +#' See [DBI-custom] for DBI methods that do not work with pool objects. #' #' @name DBI-wrap -#' @keywords internal #' @examples #' mtcars1 <- mtcars[ c(1:16), ] # first half of the mtcars dataset #' mtcars2 <- mtcars[-c(1:16), ] # second half of the mtcars dataset @@ -77,113 +77,142 @@ DBI_wrap <- function(fun_name) { } #' @export +#' @inheritParams DBI::dbDataType #' @rdname DBI-wrap setMethod("dbDataType", "Pool", DBI_wrap("dbDataType")) #' @export +#' @inheritParams DBI::dbGetQuery #' @rdname DBI-wrap setMethod("dbGetQuery", "Pool", DBI_wrap("dbGetQuery")) #' @export +#' @inheritParams DBI::dbExecute #' @rdname DBI-wrap setMethod("dbExecute", "Pool", DBI_wrap("dbExecute")) #' @export +#' @inheritParams DBI::dbListFields #' @rdname DBI-wrap setMethod("dbListFields", "Pool", DBI_wrap("dbListFields")) #' @export +#' @inheritParams DBI::dbListTables #' @rdname DBI-wrap setMethod("dbListTables", "Pool", DBI_wrap("dbListTables")) #' @export +#' @inheritParams DBI::dbListObjects #' @rdname DBI-wrap setMethod("dbListObjects", "Pool", DBI_wrap("dbListObjects")) #' @export +#' @inheritParams DBI::dbReadTable #' @rdname DBI-wrap setMethod("dbReadTable", "Pool", DBI_wrap("dbReadTable")) #' @export +#' @inheritParams DBI::dbWriteTable #' @rdname DBI-wrap setMethod("dbWriteTable", "Pool", DBI_wrap("dbWriteTable")) #' @export +#' @inheritParams DBI::dbCreateTable #' @rdname DBI-wrap setMethod("dbCreateTable", "Pool", DBI_wrap("dbCreateTable")) #' @export +#' @inheritParams DBI::dbAppendTable #' @rdname DBI-wrap setMethod("dbAppendTable", "Pool", DBI_wrap("dbAppendTable")) #' @export +#' @inheritParams DBI::dbExistsTable #' @rdname DBI-wrap setMethod("dbExistsTable", "Pool", DBI_wrap("dbExistsTable")) #' @export +#' @inheritParams DBI::dbRemoveTable #' @rdname DBI-wrap setMethod("dbRemoveTable", "Pool", DBI_wrap("dbRemoveTable")) #' @export +#' @inheritParams DBI::dbIsReadOnly #' @rdname DBI-wrap setMethod("dbIsReadOnly", "Pool", DBI_wrap("dbIsReadOnly")) #' @export +#' @inheritParams DBI::sqlData #' @rdname DBI-wrap setMethod("sqlData", "Pool", DBI_wrap("sqlData")) #' @export +#' @inheritParams DBI::sqlCreateTable #' @rdname DBI-wrap setMethod("sqlCreateTable", "Pool", DBI_wrap("sqlCreateTable")) #' @export +#' @inheritParams DBI::sqlAppendTable #' @rdname DBI-wrap setMethod("sqlAppendTable", "Pool", DBI_wrap("sqlAppendTable")) #' @export +#' @inheritParams DBI::sqlInterpolate +#' @param .dots A list of named arguments to interpolate. #' @rdname DBI-wrap setMethod("sqlInterpolate", "Pool", DBI_wrap("sqlInterpolate")) #' @export +#' @inheritParams DBI::sqlParseVariables #' @rdname DBI-wrap setMethod("sqlParseVariables", "Pool", DBI_wrap("sqlParseVariables")) #' @export +#' @inheritParams DBI::dbQuoteIdentifier #' @rdname DBI-wrap setMethod("dbQuoteIdentifier", "Pool", DBI_wrap("dbQuoteIdentifier")) #' @export +#' @inheritParams DBI::dbUnquoteIdentifier #' @rdname DBI-wrap setMethod("dbUnquoteIdentifier", "Pool", DBI_wrap("dbUnquoteIdentifier")) #' @export +#' @inheritParams DBI::dbQuoteLiteral #' @rdname DBI-wrap setMethod("dbQuoteLiteral", "Pool", DBI_wrap("dbQuoteLiteral")) #' @export +#' @inheritParams DBI::dbQuoteString #' @rdname DBI-wrap setMethod("dbQuoteString", "Pool", DBI_wrap("dbQuoteString")) #' @export +#' @inheritParams DBI::dbAppendTableArrow #' @rdname DBI-wrap setMethod("dbAppendTableArrow", "Pool", DBI_wrap("dbAppendTableArrow")) #' @export +#' @inheritParams DBI::dbCreateTableArrow #' @rdname DBI-wrap setMethod("dbCreateTableArrow", "Pool", DBI_wrap("dbCreateTableArrow")) #' @export +#' @inheritParams DBI::dbGetQueryArrow #' @rdname DBI-wrap setMethod("dbGetQueryArrow", "Pool", DBI_wrap("dbGetQueryArrow")) #' @export +#' @inheritParams DBI::dbReadTableArrow #' @rdname DBI-wrap setMethod("dbReadTableArrow", "Pool", DBI_wrap("dbReadTableArrow")) #' @export +#' @inheritParams DBI::dbSendQueryArrow #' @rdname DBI-wrap setMethod("dbSendQueryArrow", "Pool", DBI_wrap("dbSendQueryArrow")) #' @export +#' @inheritParams DBI::dbWriteTableArrow #' @rdname DBI-wrap setMethod("dbWriteTableArrow", "Pool", DBI_wrap("dbWriteTableArrow")) diff --git a/R/DBI.R b/R/DBI.R index 543bdc6..9020f4b 100644 --- a/R/DBI.R +++ b/R/DBI.R @@ -3,6 +3,18 @@ #' `dbPool()` is a drop-in replacement for [DBI::dbConnect()] that #' provides a shared pool of connections that can automatically reconnect #' to the database if needed. +#' See [DBI-wrap] for methods to use with pool objects, +#' and [DBI-custom] for unsupported methods and the "pool" way of using them. +#' +#' A new connection is created transparently +#' +#' - if the pool is empty +#' - if the currently checked out connection is invalid +#' (checked at most once every `validationInterval` seconds) +#' - if the pool is not full and the connections are all in use +#' +#' Use [poolClose()] to close the pool and all connections in it. +#' See [poolCraete()] for details on the internal workings of the pool. #' #' @param drv A [DBI Driver][DBI::DBIDriver-class], e.g. `RSQLite::SQLite()`, #' `RPostgres::Postgres()`, `odbc::odbc()` etc. diff --git a/R/pool-methods.R b/R/pool-methods.R index 94ebc6c..2f091ef 100644 --- a/R/pool-methods.R +++ b/R/pool-methods.R @@ -82,7 +82,8 @@ setMethod("poolClose", "Pool", function(pool) { #' When pooling DBI database connections, you normally would not use #' `poolCheckout()`. Instead, for single-shot queries, treat the pool object #' itself as the DBI connection object and it will perform checkout/return for -#' you. And for transactions, use [poolWithTransaction()]. +#' you. And for transactions, use [poolWithTransaction()]. See [dbPool()] for +#' an example. #' #' @param pool The pool to get the object from. #' @export diff --git a/_pkgdown.yml b/_pkgdown.yml index a0d60b8..1e1793a 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -20,6 +20,7 @@ reference: - title: Database functions contents: - dbPool - - 'DBI-custom' + - 'DBI-wrap' - poolWithTransaction - tbl.Pool + - 'DBI-custom' diff --git a/man/DBI-custom.Rd b/man/DBI-custom.Rd index 43c386f..b314d55 100644 --- a/man/DBI-custom.Rd +++ b/man/DBI-custom.Rd @@ -51,6 +51,7 @@ Instead use \code{\link[DBI:dbGetQuery]{DBI::dbGetQuery()}}, \code{\link[DBI:dbE \code{\link[DBI:dbWithTransaction]{DBI::dbWithTransaction()}} can't work with pool because transactions are bound to a connection. Instead use \code{\link[=poolWithTransaction]{poolWithTransaction()}}. \item \code{\link[DBI:dbDisconnect]{DBI::dbDisconnect()}} can't work because pool handles disconnection. +Use \code{\link[=poolClose]{poolClose()}} instead. \item \code{\link[DBI:dbGetInfo]{DBI::dbGetInfo()}} returns information about the pool, not the database connection. \item \code{\link[DBI:dbIsValid]{DBI::dbIsValid()}} returns whether or not the entire pool is valid (i.e. diff --git a/man/DBI-wrap.Rd b/man/DBI-wrap.Rd index 2f0d166..1c5608f 100644 --- a/man/DBI-wrap.Rd +++ b/man/DBI-wrap.Rd @@ -88,10 +88,77 @@ \S4method{dbWriteTableArrow}{Pool}(conn, name, value, ...) } +\arguments{ +\item{dbObj}{A object inheriting from \linkS4class{DBIDriver} +or \linkS4class{DBIConnection}} + +\item{obj}{An R object whose SQL type we want to determine.} + +\item{...}{Other arguments passed on to methods.} + +\item{conn}{A \linkS4class{DBIConnection} object, as returned by +\code{\link[DBI:dbConnect]{dbConnect()}}.} + +\item{statement}{a character string containing SQL.} + +\item{name}{The table name, passed on to \code{\link[DBI:dbQuoteIdentifier]{dbQuoteIdentifier()}}. Options are: +\itemize{ +\item a character string with the unquoted DBMS table name, +e.g. \code{"table_name"}, +\item a call to \code{\link[DBI:Id]{Id()}} with components to the fully qualified table name, +e.g. \code{Id(schema = "my_schema", table = "table_name")} +\item a call to \code{\link[DBI:SQL]{SQL()}} with the quoted and fully qualified table name +given verbatim, e.g. \code{SQL('"my_schema"."table_name"')} +}} + +\item{prefix}{A fully qualified path in the database's namespace, or \code{NULL}. +This argument will be processed with \code{\link[DBI:dbUnquoteIdentifier]{dbUnquoteIdentifier()}}. +If given the method will return all objects accessible through this prefix.} + +\item{value}{A \link{data.frame} (or coercible to data.frame).} + +\item{fields}{Either a character vector or a data frame. + +A named character vector: Names are column names, values are types. +Names are escaped with \code{\link[DBI:dbQuoteIdentifier]{dbQuoteIdentifier()}}. +Field types are unescaped. + +A data frame: field types are generated using +\code{\link[DBI:dbDataType]{dbDataType()}}.} + +\item{row.names}{Must be \code{NULL}.} + +\item{temporary}{If \code{TRUE}, will generate a temporary table.} + +\item{con}{A database connection.} + +\item{table}{The table name, passed on to \code{\link[DBI:dbQuoteIdentifier]{dbQuoteIdentifier()}}. Options are: +\itemize{ +\item a character string with the unquoted DBMS table name, +e.g. \code{"table_name"}, +\item a call to \code{\link[DBI:Id]{Id()}} with components to the fully qualified table name, +e.g. \code{Id(schema = "my_schema", table = "table_name")} +\item a call to \code{\link[DBI:SQL]{SQL()}} with the quoted and fully qualified table name +given verbatim, e.g. \code{SQL('"my_schema"."table_name"')} +}} + +\item{values}{A data frame. Factors will be converted to character vectors. +Character vectors will be escaped with \code{\link[DBI:dbQuoteString]{dbQuoteString()}}.} + +\item{sql}{A SQL string containing variables to interpolate. +Variables must start with a question mark and can be any valid R +identifier, i.e. it must start with a letter or \code{.}, and be followed +by a letter, digit, \code{.} or \verb{_}.} + +\item{.dots}{A list of named arguments to interpolate.} + +\item{x}{A character vector, \link[DBI]{SQL} or \link[DBI]{Id} object to quote as identifier.} +} \description{ These pool method for DBI generics methods check out a connection (with \code{\link[=poolCheckout]{poolCheckout()}}), re-call the generic, then return the connection to the pool (with \code{\link[=poolReturn]{poolReturn()}}). +See \link{DBI-custom} for DBI methods that do not work with pool objects. } \examples{ mtcars1 <- mtcars[ c(1:16), ] # first half of the mtcars dataset @@ -137,4 +204,3 @@ dbListTables(pool) poolClose(pool) } -\keyword{internal} diff --git a/man/dbPool.Rd b/man/dbPool.Rd index 7828ad7..aeb8b39 100644 --- a/man/dbPool.Rd +++ b/man/dbPool.Rd @@ -47,6 +47,19 @@ options, but these don't work for all databases.} \code{dbPool()} is a drop-in replacement for \code{\link[DBI:dbConnect]{DBI::dbConnect()}} that provides a shared pool of connections that can automatically reconnect to the database if needed. +See \link{DBI-wrap} for methods to use with pool objects, +and \link{DBI-custom} for unsupported methods and the "pool" way of using them. +} +\details{ +A new connection is created transparently + +- if the pool is empty +- if the currently checked out connection is invalid + (checked at most once every `validationInterval` seconds) +- if the pool is not full and the connections are all in use + +Use [poolClose()] to close the pool and all connections in it. +See [poolCraete()] for details on the internal workings of the pool. } \examples{ # You use a dbPool in the same way as a standard DBI connection diff --git a/man/poolCheckout.Rd b/man/poolCheckout.Rd index e936101..ee4c7f2 100644 --- a/man/poolCheckout.Rd +++ b/man/poolCheckout.Rd @@ -43,7 +43,8 @@ possible. When pooling DBI database connections, you normally would not use \code{poolCheckout()}. Instead, for single-shot queries, treat the pool object itself as the DBI connection object and it will perform checkout/return for -you. And for transactions, use \code{\link[=poolWithTransaction]{poolWithTransaction()}}. +you. And for transactions, use \code{\link[=poolWithTransaction]{poolWithTransaction()}}. See \code{\link[=dbPool]{dbPool()}} for +an example. } \examples{ pool <- dbPool(RSQLite::SQLite())