Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: ResultModelManager
Title: Result Model Manager
Version: 0.6.0
Version: 0.6.0.9999
Authors@R:
person("Jamie", "Gilbert", , "gilbert@ohdsi.org", role = c("aut", "cre"))
Description: Database data model management utilities for R packages in the Observational Health Data Sciences and
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ forces errors if an input is not of an array of type int. `{TYPEC INT @cohort_id
length 1. NA/NULL is automatically prevented whenever there is a type check.
Default SQL render behaviour is not altered.

2. Query Namespaces now support adding sql files as automatically mapped functions

# ResultModelManager 0.6.0

Changes:
Expand Down
59 changes: 58 additions & 1 deletion R/QueryNamespace.R
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
#'
QueryNamespace <- R6::R6Class(
classname = "QueryNamespace",
lock_objects = FALSE,
private = list(
replacementVars = NULL,
tableSpecifications = list(),
Expand All @@ -133,9 +134,15 @@ QueryNamespace <- R6::R6Class(
#' @param connectionHandler ConnectionHandler instance @seealso[ConnectionHandler]
#' @param tableSpecification tableSpecification data.frame
#' @param tablePrefix constant string to prefix all tables with
#' @param queryFiles vector of file paths to sql files that can be automatically loaded and translated as additional methods for this module
#' @param executeFiles vector of file paths to sql files that can be automatically loaded and translated as additional methods for this module. Queries will executed and not return a result
#' @param snakeCaseToCamelCaseFileNames - if true the method name will turn snake case file names in queryFiles in to camel case (e.g. my_query.sql becomes qns$myQuery)
#' @param ... additional replacement variables e.g. database_schema, vocabulary_schema etc
initialize = function(connectionHandler = NULL, tableSpecification = NULL, tablePrefix = "", ...) {
initialize = function(connectionHandler = NULL, tableSpecification = NULL, tablePrefix = "", queryFiles = NULL, executeFiles = NULL, snakeCaseToCamelCaseFileNames = FALSE, ...) {
checkmate::assertString(tablePrefix)
checkmate::assertCharacter(queryFiles, null.ok = TRUE)
checkmate::assertCharacter(executeFiles, null.ok = TRUE)

self$tablePrefix <- tablePrefix
private$replacementVars <- fastmap::fastmap()
if (!is.null(connectionHandler)) {
Expand All @@ -153,9 +160,59 @@ QueryNamespace <- R6::R6Class(
}
}

lapply(queryFiles, self$addQueryFile, snakeCaseToCamelCaseFileNames = snakeCaseToCamelCaseFileNames)
lapply(executeFiles, self$addQueryFile, snakeCaseToCamelCaseFileNames = snakeCaseToCamelCaseFileNames, execFunction = TRUE)

self
},

#' Add query file
#' @description
#' Add an sql file query as a method to this namespace.
#' This allows you to run the query with any settings that are encapsulated within this object.
#' Package maintainers should take note that these functions will not be exposed and will include no validation
#' checks on user input. Use with care.
#' @param filepath path to sql file - this will determine the name of the function
#' @param execFunction default false - instead of returning a result, execute a query or set of queries
#' @param snakeCaseToCamelCaseFileNames - if true the method name will turn snake case names in to camel case (e.g. my_query.sql becomes qns$myQuery)
addQueryFile = function(filepath, snakeCaseToCamelCaseFileNames = FALSE, execFunction = FALSE) {
checkmate::assertFileExists(filepath)
# Ensure file has .sql extension
if (tolower(tools::file_ext(filepath)) != "sql") {
stop("File must have a .sql extension")
}

# Derive function name from file name
baseName <- basename(filepath)
functionName <- sub("\\.sql$", "", baseName)
if (snakeCaseToCamelCaseFileNames) {
# Convert snake_case to camelCase
functionName <- SqlRender::snakeCaseToCamelCase(functionName)
}

if (functionName %in% names(self)) {
stop(paste("Cannot add existing name", functionName, "to object"))
}

# Define the callback function that runs the query
callback <- function(...) {
sql <- SqlRender::readSql(filepath)
# Render SQL with replacement variables and any additional arguments
renderedSql <- self$render(sql, ...)
# Query the database and return results
if (execFunction){
return(self$executeSql(sql))
}

return(self$queryDb(renderedSql))
}

# Dynamically add the function as a method to this instance
self[[functionName]] <- callback

invisible(NULL)
},

#' Set Connection Handler
#' @description set connection handler object for object
#' @param connectionHandler ConnectionHandler instance
Expand Down
2 changes: 1 addition & 1 deletion docs/404.html

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

2 changes: 1 addition & 1 deletion docs/LICENSE-text.html

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

2 changes: 1 addition & 1 deletion docs/articles/CreatingMigrations.html

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

4 changes: 2 additions & 2 deletions docs/articles/ExampleProject.html

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

2 changes: 1 addition & 1 deletion docs/articles/PackageDesign.html

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

2 changes: 1 addition & 1 deletion docs/articles/UploadFunctionality.html

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

2 changes: 1 addition & 1 deletion docs/articles/UsingAnExportManager.html

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

2 changes: 1 addition & 1 deletion docs/articles/UsingConnectionHandlers.html

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

2 changes: 1 addition & 1 deletion docs/articles/UsingPythonUploads.html

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

4 changes: 2 additions & 2 deletions docs/articles/UsingQueryNamespaces.html

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

2 changes: 1 addition & 1 deletion docs/articles/index.html

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

2 changes: 1 addition & 1 deletion docs/authors.html

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

3 changes: 1 addition & 2 deletions docs/index.html

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

8 changes: 6 additions & 2 deletions docs/news/index.html

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

2 changes: 1 addition & 1 deletion docs/pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ articles:
UsingConnectionHandlers: UsingConnectionHandlers.html
UsingPythonUploads: UsingPythonUploads.html
UsingQueryNamespaces: UsingQueryNamespaces.html
last_built: 2025-09-18T14:52Z
last_built: 2025-09-18T17:33Z
urls:
reference: https://ohdsi.github.io/ResultModelManager/reference
article: https://ohdsi.github.io/ResultModelManager/articles
Loading
Loading