From 6d63212aa5894013a879f1954a375689887180cf Mon Sep 17 00:00:00 2001 From: jgilber2 Date: Fri, 9 Jan 2026 08:52:34 -0800 Subject: [PATCH 1/4] Added named field of query options called with withr:: --- R/ConnectionHandler.R | 33 ++++++++++++++++++++++++--------- man/ConnectionHandler.Rd | 16 +++++++++++++--- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/R/ConnectionHandler.R b/R/ConnectionHandler.R index e9051de..68a0b4d 100644 --- a/R/ConnectionHandler.R +++ b/R/ConnectionHandler.R @@ -35,12 +35,23 @@ #' @export #' @field connectionDetails DatabaseConnector connectionDetails object #' @field con DatabaseConnector connection object -#' @field isActive Is connection active or not#' +#' @field isActive Is connection active or not' #' @field snakeCaseToCamelCase (Optional) Boolean. return the results columns in camel case (default) +#' @field queryOptions (Optional) Active field. Named list of options that are wrapped when queries are translated. For example `list(sqlRenderTempSchema = 'my_scratch_space')`. Will override default global behaviour without altering global option state ConnectionHandler <- R6::R6Class( classname = "ConnectionHandler", private = list( - .dbms = "" + .dbms = "", + .queryOptions = list() + ), + active = list( + queryOptions = function (val) { + if (missing(val)) + return(private$.queryOptions) + # must be a named list - strictly + checkmate::assertList(val, names = "strict") + private$.queryOptions <- val + } ), public = list( connectionDetails = NULL, @@ -51,7 +62,8 @@ ConnectionHandler <- R6::R6Class( #' @param connectionDetails DatabaseConnector::connectionDetails class #' @param loadConnection Boolean option to load connection right away #' @param snakeCaseToCamelCase (Optional) Boolean. return the results columns in camel case (default) - initialize = function(connectionDetails, loadConnection = TRUE, snakeCaseToCamelCase = TRUE) { + #' @param queryOptions (Optional) named list of options that are wrapped when queries are translated. For example `list(sqlRenderTempSchema = 'my_scratch_space')`. Will override default global behaviour without altering global option state + initialize = function(connectionDetails, loadConnection = TRUE, snakeCaseToCamelCase = TRUE, queryOptions = list()) { checkmate::assertClass(connectionDetails, "ConnectionDetails") self$connectionDetails <- connectionDetails self$snakeCaseToCamelCase <- snakeCaseToCamelCase @@ -59,6 +71,7 @@ ConnectionHandler <- R6::R6Class( self$initConnection() } private$.dbms <- connectionDetails$dbms + self$queryOptions <- queryOptions }, #' get dbms @@ -91,11 +104,13 @@ ConnectionHandler <- R6::R6Class( mustTranslate <- FALSE } - sql <- SqlRender::render(sql = sql, ...) - # Only translate if translate is needed. - if (mustTranslate) { - sql <- SqlRender::translate(sql, targetDialect = self$dbms()) - } + withr::with_options(private$.queryOptions, { + sql <- SqlRender::render(sql = sql, ...) + # Only translate if translate is needed. + if (mustTranslate) { + sql <- SqlRender::translate(sql, targetDialect = self$dbms()) + } + }) return(sql) }, @@ -152,7 +167,7 @@ ConnectionHandler <- R6::R6Class( #' Closes connection (if active) finalize = function() { if (interactive()) { - rlang::inform("Due to changes in the R6 package, this method is deprecated and will be removed in a future version. Please use closeConnection instead") + rlang::inform("Due to changes in the R6 package, the ConnectionHandler$finalize method is deprecated and will be removed in a future version. Please use $closeConnection instead") } if (self$isActive & self$dbIsValid()) { self$closeConnection() diff --git a/man/ConnectionHandler.Rd b/man/ConnectionHandler.Rd index 0cd92ec..7f636b5 100644 --- a/man/ConnectionHandler.Rd +++ b/man/ConnectionHandler.Rd @@ -24,12 +24,19 @@ Allows a connection to cleanly be opened and closed and stored within class/obje \item{\code{con}}{DatabaseConnector connection object} -\item{\code{isActive}}{Is connection active or not#'} +\item{\code{isActive}}{Is connection active or not'} \item{\code{snakeCaseToCamelCase}}{(Optional) Boolean. return the results columns in camel case (default)} } \if{html}{\out{}} } +\section{Active bindings}{ +\if{html}{\out{
}} +\describe{ +\item{\code{queryOptions}}{(Optional) Active field. Named list of options that are wrapped when queries are translated. For example \code{list(sqlRenderTempSchema = 'my_scratch_space')}. Will override default global behaviour without altering global option state} +} +\if{html}{\out{
}} +} \section{Methods}{ \subsection{Public methods}{ \itemize{ @@ -57,7 +64,8 @@ Allows a connection to cleanly be opened and closed and stored within class/obje \if{html}{\out{
}}\preformatted{ConnectionHandler$new( connectionDetails, loadConnection = TRUE, - snakeCaseToCamelCase = TRUE + snakeCaseToCamelCase = TRUE, + queryOptions = list() )}\if{html}{\out{
}} } @@ -68,7 +76,9 @@ Allows a connection to cleanly be opened and closed and stored within class/obje \item{\code{loadConnection}}{Boolean option to load connection right away} -\item{\code{snakeCaseToCamelCase}}{(Optional) Boolean. return the results columns in camel case (default) +\item{\code{snakeCaseToCamelCase}}{(Optional) Boolean. return the results columns in camel case (default)} + +\item{\code{queryOptions}}{(Optional) named list of options that are wrapped when queries are translated. For example \code{list(sqlRenderTempSchema = 'my_scratch_space')}. Will override default global behaviour without altering global option state get dbms} } \if{html}{\out{}} From e22d0b2b1f3fd986c553189c2a14d573b5df9af6 Mon Sep 17 00:00:00 2001 From: jgilber2 Date: Fri, 9 Jan 2026 08:55:38 -0800 Subject: [PATCH 2/4] Added to pooled connection handler constructor --- R/PooledConnectionHandler.R | 6 +++++- man/PooledConnectionHandler.Rd | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/R/PooledConnectionHandler.R b/R/PooledConnectionHandler.R index cfe8afa..300c0c6 100644 --- a/R/PooledConnectionHandler.R +++ b/R/PooledConnectionHandler.R @@ -95,11 +95,13 @@ PooledConnectionHandler <- R6::R6Class( #' @param snakeCaseToCamelCase (Optional) Boolean. return the results columns in camel case (default) #' @param dbConnectArgs Optional arguments to call pool::dbPool overrides default usage of connectionDetails #' @param forceJdbcConnection Force JDBC connection (requires using DatabaseConnector ConnectionDetails) + #' @param queryOptions (Optional) named list of options that are wrapped when queries are translated. For example `list(sqlRenderTempSchema = 'my_scratch_space')`. Will override default global behaviour without altering global option state initialize = function(connectionDetails = NULL, snakeCaseToCamelCase = TRUE, loadConnection = TRUE, dbConnectArgs = NULL, - forceJdbcConnection = TRUE) { + forceJdbcConnection = TRUE, + queryOptions = list()) { checkmate::assertList(dbConnectArgs, null.ok = TRUE) checkmate::assertClass(connectionDetails, "ConnectionDetails", null.ok = TRUE) @@ -125,6 +127,8 @@ PooledConnectionHandler <- R6::R6Class( if (loadConnection) { self$initConnection() } + + self$queryOptions <- queryOptions }, #' initialize pooled db connection diff --git a/man/PooledConnectionHandler.Rd b/man/PooledConnectionHandler.Rd index 0a6d783..9d85bc7 100644 --- a/man/PooledConnectionHandler.Rd +++ b/man/PooledConnectionHandler.Rd @@ -51,7 +51,8 @@ Note that a side effect of using this is that each call to this increments the . snakeCaseToCamelCase = TRUE, loadConnection = TRUE, dbConnectArgs = NULL, - forceJdbcConnection = TRUE + forceJdbcConnection = TRUE, + queryOptions = list() )}\if{html}{\out{}} } @@ -66,7 +67,9 @@ Note that a side effect of using this is that each call to this increments the . \item{\code{dbConnectArgs}}{Optional arguments to call pool::dbPool overrides default usage of connectionDetails} -\item{\code{forceJdbcConnection}}{Force JDBC connection (requires using DatabaseConnector ConnectionDetails) +\item{\code{forceJdbcConnection}}{Force JDBC connection (requires using DatabaseConnector ConnectionDetails)} + +\item{\code{queryOptions}}{(Optional) named list of options that are wrapped when queries are translated. For example \code{list(sqlRenderTempSchema = 'my_scratch_space')}. Will override default global behaviour without altering global option state initialize pooled db connection} } \if{html}{\out{}} From 579810d9cf869f15b9bbf414726ccffff36f56d9 Mon Sep 17 00:00:00 2001 From: jgilber2 Date: Fri, 9 Jan 2026 08:58:26 -0800 Subject: [PATCH 3/4] Added to QueryNamespace factory --- R/QueryNamespace.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/R/QueryNamespace.R b/R/QueryNamespace.R index 989d945..ab06fb0 100644 --- a/R/QueryNamespace.R +++ b/R/QueryNamespace.R @@ -308,6 +308,7 @@ QueryNamespace <- R6::R6Class( #' @param connectionHandler ResultModelManager ConnectionHandler or PooledConnectionHandler instance #' @param tableSpecification Table specfication data.frame #' @param snakeCaseToCamelCase convert snakecase results to camelCase field names (TRUE by default) +#' @param queryOptions (Optional) Active field. Named list of options that are wrapped when queries are translated. For example `list(sqlRenderTempSchema = 'my_scratch_space')`. Will override default global behaviour without altering global option state #' @param ... Elipsis - use for any additional string keys to replace createQueryNamespace <- function(connectionDetails = NULL, connectionHandler = NULL, @@ -316,6 +317,7 @@ createQueryNamespace <- function(connectionDetails = NULL, resultModelSpecificationPath = NULL, tablePrefix = "", snakeCaseToCamelCase = TRUE, + queryOptions = list(), ...) { checkmate::assertClass(connectionDetails, "ConnectionDetails", null.ok = TRUE) checkmate::assertClass(connectionHandler, "ConnectionHandler", null.ok = TRUE) @@ -352,7 +354,7 @@ createQueryNamespace <- function(connectionDetails = NULL, } } connectionHandler$snakeCaseToCamelCase <- snakeCaseToCamelCase - + connectionHandler$queryOptions <- queryOptions qns <- QueryNamespace$new(connectionHandler, tableSpecification = tableSpecification, tablePrefix = tablePrefix, From 7d49eb7fe66a7b579edacf732ef093108683117a Mon Sep 17 00:00:00 2001 From: jgilber2 Date: Fri, 9 Jan 2026 09:07:53 -0800 Subject: [PATCH 4/4] Don't override queryOptions in queryNamespaces unless not null --- R/QueryNamespace.R | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/R/QueryNamespace.R b/R/QueryNamespace.R index ab06fb0..6b3df8c 100644 --- a/R/QueryNamespace.R +++ b/R/QueryNamespace.R @@ -317,7 +317,7 @@ createQueryNamespace <- function(connectionDetails = NULL, resultModelSpecificationPath = NULL, tablePrefix = "", snakeCaseToCamelCase = TRUE, - queryOptions = list(), + queryOptions = NULL, ...) { checkmate::assertClass(connectionDetails, "ConnectionDetails", null.ok = TRUE) checkmate::assertClass(connectionHandler, "ConnectionHandler", null.ok = TRUE) @@ -354,7 +354,11 @@ createQueryNamespace <- function(connectionDetails = NULL, } } connectionHandler$snakeCaseToCamelCase <- snakeCaseToCamelCase - connectionHandler$queryOptions <- queryOptions + + if (!is.null(queryOptions)) { + connectionHandler$queryOptions <- queryOptions + } + qns <- QueryNamespace$new(connectionHandler, tableSpecification = tableSpecification, tablePrefix = tablePrefix,