Skip to content

Commit d939010

Browse files
authored
Merge pull request #58 from OHDSI/develop
Release 0.5.9
2 parents ad706b4 + 1c35bd7 commit d939010

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+794
-533
lines changed

.Rbuildignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ compare_versions
3434
^Meta$
3535
LICENSE
3636
.git
37-
..Rcheck
37+
..Rcheck
38+
errorReportSql.txt

DESCRIPTION

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
Package: ResultModelManager
22
Title: Result Model Manager
3-
Version: 0.5.8
3+
Version: 0.5.9
44
Authors@R:
55
person("Jamie", "Gilbert", , "[email protected]", role = c("aut", "cre"))
6-
Description: Database data model management utilities for OHDSI packages.
6+
Description: Database data model management utilities for R packages in the Observational Health Data Sciences and
7+
Informatics program <https://ohdsi.org>. 'ResultModelManager' provides utility functions to allow package
8+
maintainers to migrate existing SQL database models, export and import results in consistent patterns.
9+
URL: https://github.com/OHDSI/ResultModelManager
10+
BugReports: https://github.com/OHDSI/ResultModelManager/issues
711
License: Apache License (== 2.0)
812
Encoding: UTF-8
913
VignetteBuilder: knitr
1014
Roxygen: list(markdown = TRUE)
11-
RoxygenNote: 7.2.3
15+
RoxygenNote: 7.3.2
1216
Depends:
1317
R (>= 4.1.0),
1418
R6,
@@ -25,13 +29,13 @@ Imports:
2529
dbplyr,
2630
rlang,
2731
lubridate,
28-
fastmap
32+
fastmap,
33+
withr
2934
Suggests:
3035
testthat (>= 3.0.0),
3136
RSQLite,
3237
duckdb,
3338
RPostgres,
34-
withr,
3539
knitr,
3640
rmarkdown,
3741
keyring,

NAMESPACE

+2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ importFrom(ParallelLogger,logError)
2222
importFrom(ParallelLogger,logInfo)
2323
importFrom(SqlRender,render)
2424
importFrom(SqlRender,translate)
25+
importFrom(dbplyr,in_schema)
2526
importFrom(dplyr,"%>%")
2627
importFrom(fastmap,fastmap)
2728
importFrom(pool,dbPool)
2829
importFrom(pool,poolClose)
2930
importFrom(readr,read_csv)
3031
importFrom(rlang,.data)
32+
importFrom(withr,defer)

NEWS.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# ResultModelManager 0.5.9
2+
3+
Changes:
4+
5+
1. Changes made to make package CRAN compliant
6+
7+
2. `PooledConnectionHandler` now uses withr::defer to automatically returned pooled connections returned with
8+
`getConnection`
9+
110
# ResultModelManager 0.5.8
211

312
Bug fixes:

R/ConnectionHandler.R

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#' @import R6
2929
#' @importFrom DBI dbIsValid
3030
#' @importFrom SqlRender render translate
31+
#' @importFrom dbplyr in_schema
3132
#'
3233
#' @export ConnectionHandler
3334
ConnectionHandler <- R6::R6Class(
@@ -186,8 +187,7 @@ ConnectionHandler <- R6::R6Class(
186187
if (self$dbms() %in% c("postgresql", "redshift")) {
187188
DatabaseConnector::dbExecute(self$getConnection(), "ABORT;")
188189
}
189-
print(sql)
190-
stop(error)
190+
stop(paste0(sql, "\n\n", error))
191191
}
192192
)
193193

@@ -209,8 +209,7 @@ ConnectionHandler <- R6::R6Class(
209209
if (self$dbms() %in% c("postgresql", "redshift")) {
210210
self$executeFunction("ABORT;")
211211
}
212-
print(sql)
213-
stop(error)
212+
stop(paste0(sql, "\n\n", error))
214213
}
215214
)
216215

R/DataModel.R

+6-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ checkAndFixColumnNames <-
3939

4040
# Set all fields to requried if optional isn't specified
4141
if (!"optional" %in% colnames(tableSpecs)) {
42-
tableSpecs$otpional <- "no"
42+
tableSpecs$optional <- "no"
4343
}
4444

4545
optionalNames <- tableSpecs %>%
@@ -494,7 +494,7 @@ uploadTable <- function(tableName,
494494
#' Upload results to the database server.
495495
#'
496496
#' @description
497-
#' Requires the results data model tables have been created using following the specifications, @seealso \code{\link{generateSqlSchema}} function.
497+
#' Requires the results data model tables have been created using following the specifications, generateSqlSchema function.
498498
#'
499499
#' Results files should be in the snake_case format for table headers and not camelCase
500500
#'
@@ -809,19 +809,20 @@ loadResultsDataModelSpecifications <- function(filePath) {
809809
#' Another assumption of this function is that we're only attempting to
810810
#' recast to a character data type and not try to handle different type
811811
#' conversions.
812+
#' @noRd
812813
formatChunk <- function(pkValuesInDb, chunk) {
813814
for (columnName in names(pkValuesInDb)) {
814-
if (class(pkValuesInDb[[columnName]]) == "integer") {
815+
if (inherits(pkValuesInDb[[columnName]], "integer")) {
815816
pkValuesInDb[[columnName]] <- as.numeric(pkValuesInDb[[columnName]])
816817
}
817818

818-
if (class(chunk[[columnName]]) == "integer") {
819+
if (inherits(chunk[[columnName]], "integer")) {
819820
chunk[[columnName]] <- as.numeric(chunk[[columnName]])
820821
}
821822

822823

823824
if (class(pkValuesInDb[[columnName]]) != class(chunk[[columnName]])) {
824-
if (class(pkValuesInDb[[columnName]]) == "character") {
825+
if (inherits(pkValuesInDb[[columnName]], "character")) {
825826
chunk <- chunk |> dplyr::mutate_at(columnName, as.character)
826827
} else {
827828
errorMsg <- paste0(

R/PooledConnectionHandler.R

+24-10
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616

1717

1818
requiredPackage <- function(packageName) {
19-
packages <- utils::installed.packages()
20-
packages <- as.data.frame(packages)
21-
if (!packageName %in% packages$Package) {
22-
utils::install.packages(packageName)
19+
packageLoc <- tryCatch(
20+
find.package(packageName),
21+
errorr = function(...) {
22+
return(NULL)
23+
}
24+
)
25+
26+
if (is.null(packageLoc)) {
27+
stop(paste("Package", packageName, "is required please use install.packages to install"))
2328
}
2429
}
2530

@@ -82,6 +87,7 @@ requiredPackage <- function(packageName) {
8287
#'
8388
#' @importFrom pool dbPool poolClose
8489
#' @importFrom DBI dbIsValid
90+
#' @importFrom withr defer
8591
#'
8692
#' @export PooledConnectionHandler
8793
PooledConnectionHandler <- R6::R6Class(
@@ -138,11 +144,21 @@ PooledConnectionHandler <- R6::R6Class(
138144
self$isActive <- TRUE
139145
},
140146

147+
#' Get Connection
148+
#' @description
149+
#' Returns a connection from the pool
150+
#' When the desired frame exits, the connection will be returned to the pool
151+
#' @param .deferedFrame defaults to the parent frame of the calling block.
152+
getConnection = function(.deferedFrame = parent.frame(n = 2)) {
153+
conn <- pool::poolCheckout(super$getConnection())
154+
withr::defer(pool::poolReturn(conn), envir = .deferedFrame)
155+
return(conn)
156+
},
157+
141158
#' get dbms
142159
#' @description Get the dbms type of the connection
143160
dbms = function() {
144-
conn <- pool::poolCheckout(self$getConnection())
145-
on.exit(pool::poolReturn(conn))
161+
conn <- self$getConnection()
146162
DatabaseConnector::dbms(conn)
147163
},
148164

@@ -163,8 +179,7 @@ PooledConnectionHandler <- R6::R6Class(
163179
#' @param sql sql query string
164180
#' @param snakeCaseToCamelCase (Optional) Boolean. return the results columns in camel case (default)
165181
queryFunction = function(sql, snakeCaseToCamelCase = self$snakeCaseToCamelCase) {
166-
conn <- pool::poolCheckout(self$getConnection())
167-
on.exit(pool::poolReturn(conn))
182+
conn <- self$getConnection()
168183
data <- DatabaseConnector::dbGetQuery(conn, sql, translate = FALSE)
169184
if (snakeCaseToCamelCase) {
170185
colnames(data) <- SqlRender::snakeCaseToCamelCase(colnames(data))
@@ -179,8 +194,7 @@ PooledConnectionHandler <- R6::R6Class(
179194
#' Overrides ConnectionHandler Call. Does not translate or render sql.
180195
#' @param sql sql query string
181196
executeFunction = function(sql) {
182-
conn <- pool::poolCheckout(self$getConnection())
183-
on.exit(pool::poolReturn(conn))
197+
conn <- self$getConnection()
184198
DatabaseConnector::dbExecute(conn, sql, translate = FALSE)
185199
}
186200
)

R/QueryNamespace.R

+28-8
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,36 @@
2020
#' Given a results specification and ConnectionHandler instance - this class allow queries to be namespaced within
2121
#' any tables specified within a list of pre-determined tables. This allows the encapsulation of queries, using specific
2222
#' table names in a consistent manner that is striaghtforward to maintain over time.
23-
#'
23+
#' @importFrom fastmap fastmap
2424
#' @examples
25-
#' \dontrun{
25+
#'
2626
#' library(ResultModelManager)
27-
#' connectionHandler <- ConnectionHandler$new(connectionDetails = )
2827
#'
28+
#' # Create some junk test data
29+
#' connectionDetails <-
30+
#' DatabaseConnector::createConnectionDetails(
31+
#' server = "test_db.sqlite",
32+
#' dbms = "sqlite"
33+
#' )
34+
#'
35+
#' conn <- DatabaseConnector::connect(connectionDetails)
36+
#' DatabaseConnector::insertTable(
37+
#' connection = conn,
38+
#' tableName = "cd_cohort",
39+
#' data = data.frame(
40+
#' cohort_id = c(1, 2, 3),
41+
#' cohort_name = c("cohort one", "cohort two", "cohort three"),
42+
#' json = "{}",
43+
#' sql = "SELECT 1"
44+
#' )
45+
#' )
46+
#' DatabaseConnector::disconnect(conn)
47+
#'
48+
#' connectionHandler <- ConnectionHandler$new(connectionDetails = connectionDetails)
2949
#' tableSpecification <- data.frame(
3050
#' tableName = "cohort",
3151
#' columnName = c(
32-
#' "cohort_definition_id",
52+
#' "cohort_id",
3353
#' "cohort_name",
3454
#' "json",
3555
#' "sql"
@@ -39,7 +59,7 @@
3959
#' )
4060
#'
4161
#' cohortNamespace <- QueryNamespace$new(
42-
#' connnectionHandler = connnectionHandler,
62+
#' connectionHandler = connectionHandler,
4363
#' tableSpecification = tableSpecification,
4464
#' result_schema = "main",
4565
#' tablePrefix = "cd_"
@@ -48,9 +68,9 @@
4868
#' # Returns : "SELECT * FROM main.cd_cohort WHERE cohort_id = @cohort_id"
4969
#' print(cohortNamespace$render(sql))
5070
#' # Returns query result
51-
#' result <- cohortNamespace$querySql(sql, cohort_id = 1)
52-
#' }
53-
#' @importFrom fastmap fastmap
71+
#' result <- cohortNamespace$queryDb(sql, cohort_id = 1)
72+
#' # cleanup test data
73+
#' unlink("test_db.sqlite")
5474
QueryNamespace <- R6::R6Class(
5575
classname = "QueryNamespace",
5676
private = list(

R/SchemaGenerator.R

+2-4
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,16 @@
2828
#' Schema generator
2929
#' @description
3030
#' Take a csv schema definition and create a basic sql script with it.
31-
#'
31+
#' returns string containing the sql for the table
3232
#' @param csvFilepath Path to schema file. Csv file must have the columns:
33-
#' "table_name", "column_name", "data_type", "is_required", "primary_key"
33+
#' "table_name", "column_name", "data_type", "primary_key"
3434
#' @param schemaDefinition A schemaDefintiion data.frame` with the columns:
3535
#' tableName, columnName, dataType, isRequired, primaryKey
3636
#' @param sqlOutputPath File to write sql to.
3737
#' @param overwrite Boolean - overwrite existing file?
3838
#' @export
3939
#'
4040
#' @importFrom readr read_csv
41-
#' @return
42-
#' string containing the sql for the table
4341
generateSqlSchema <- function(csvFilepath = NULL,
4442
schemaDefinition = NULL,
4543
sqlOutputPath = NULL,

README.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
ResultModelManager
22
==================
33
[![Build Status](https://github.com/OHDSI/ResultModelManager/workflows/R-CMD-check/badge.svg)](https://github.com/OHDSI/ResultModelManager/actions?query=workflow%3AR-CMD-check)
4-
[![codecov.io](https://app.codecov.io/github/OHDSI/ResultModelManager/coverage.svg?branch=main)](https://codecov.io/github/OHDSI/ResultModelManager?branch=main)
4+
[![codecov.io](https://codecov.io/github/OHDSI/ResultModelManager/coverage.svg?branch=main)](https://app.codecov.io/github/OHDSI/ResultModelManager?branch=main)
55

66
ResultModelManager (RMM) [HADES](https://ohdsi.github.io/Hades/).
77

88
Introduction
99
============
10-
RMM is an R package designed to handle common ohdsi results data management functions by providing a common API for data model migrations and definitions
10+
RMM is a database data model management utilities for R packages in the [Observational Health Data Sciences and Informatics program](https://ohdsi.org). RMM provides utility functions to
11+
allow package maintainers to migrate existing SQL database models, export and import results in consistent patterns.
1112

1213

1314
System Requirements
@@ -26,6 +27,17 @@ Installation
2627
remotes::install_github("OHDSI/ResultModelManager")
2728
```
2829

30+
Usage
31+
=====
32+
33+
See articles:
34+
- [Creating migrations](https://ohdsi.github.io/ResultModelManager/articles/CreatingMigrations.html)
35+
- [Example Project](https://ohdsi.github.io/ResultModelManager/articles/ExampleProject.html)
36+
- [Upload functionality](https://ohdsi.github.io/ResultModelManager/articles/UploadFunctionality.html)
37+
- [Connection handler](https://ohdsi.github.io/ResultModelManager/articles/UsingConnectionHandlers.html)
38+
- [Using query namespaces](https://ohdsi.github.io/ResultModelManager/articles/UsingQueryNamespaces.html)
39+
40+
2941
Support
3042
=======
3143
* Developer questions/comments/feedback: <a href="http://forums.ohdsi.org/c/developers">OHDSI Forum</a>

0 commit comments

Comments
 (0)