@@ -98,3 +98,97 @@ tableSpecification2 <- data.frame(
9898)
9999qns$addTableSpecification(tableSpecification2)
100100```
101+ # Using type checks and sql files
102+
103+ Optionally, you may wish to write sql only files and not require any R boilerplate.
104+ Query namespaces support this in two ways.
105+ Firstly, they allow you to add a file that is loaded as a method in the querynamespace class at runtime.
106+ Secondly, you can enforce type checking within these SQL files using the notation ` {TYPEC <TYPE>} ` or ` {TYPEC <TYPE>[]} `
107+ to allow vectors of length +1.
108+
109+ ## TYPEC annotation
110+ To add runtime checks to any sql statement within a query namespace add one of the following checks:
111+
112+ ``` {sql}
113+ {TYPEC INT @variable_name}
114+ {TYPEC INT[] @variable_name}
115+ {TYPEC BIGINT @variable_name}
116+ {TYPEC BIGINT[] @variable_name}
117+ {TYPEC CHAR @variable_name}
118+ {TYPEC CHAR[] @variable_name}
119+ {TYPEC NUMERIC @variable_name}
120+ {TYPEC NUMERIC[] @variable_name}
121+ {TYPEC INT @variable_name}
122+ {TYPEC INT[] @variable_name}
123+ ```
124+ In this situation, a value passed to an SQL query can never be ` NULL ` or ` NA ` and must be of the type specified.
125+
126+ For example:
127+
128+ ``` {r}
129+ qns$queryDb(
130+ "{TYPEC INT @id} SELECT * FROM @database_schema.@cohort_definition WHERE cohort_definition_id = @id",
131+ id = 5
132+ )
133+ ```
134+ In this case, if a non-integer value is passed into the SQL an error will be thrown prior to execution within the database.
135+
136+
137+ ## Adding sql files
138+
139+ For longer sql queries, using ` .sql ` files can be a more convenient way of managing these.
140+ To do this create a file that maps to the function name you wish to attach to the query namespace and add it as follows:
141+
142+ ``` {sql}
143+ -- CREATE the sql file
144+
145+ -- set the required types for input
146+ {TYPEC INT @ids[]}
147+ {TYPEC CHAR @database_schema}
148+ {TYPEC CHAR @cohort_definition}
149+
150+ SELECT * FROM @database_schema.@cohort_definition
151+ WHERE cohort_definition_id IN (@ids)
152+ ```
153+
154+ ``` {r eval=FALSE}
155+ # requires getResults.sql to exist
156+ qns$addQueryFile("getResults.sql")
157+ results <- qns$getResults(id = 12)
158+ results2 <- qns$getResults(id = c(5, 6, 7, 8))
159+ ```
160+ Optionally, we can attach this when creating the object
161+
162+ ``` {r eval=FALSE}
163+ qns2 <- createQueryNamespace(
164+ connectionDetails = connectionDetails,
165+ usePooledConnection = FALSE,
166+ tableSpecification = tableSpecification,
167+ tablePrefix = "rwe_study_99_",
168+ snakeCaseToCamelCase = TRUE,
169+ database_schema = "main",
170+ queryFiles = c("getResults.sql")
171+ )
172+ ```
173+ If you're creating a model within a package you may wish to expose a results model as follows:
174+
175+ ``` {r eval = FALSE}
176+ #' @expose
177+ myResultsMode <- function() {
178+ createQueryNamespace(
179+ connectionDetails = connectionDetails,
180+ usePooledConnection = FALSE,
181+ tableSpecification = tableSpecification,
182+ tablePrefix = "rwe_study_99_",
183+ snakeCaseToCamelCase = TRUE,
184+ database_schema = "main",
185+ queryFiles = list.files(system.file("sql", "resultsModel",
186+ package = utils::packageName()),
187+ "*.sql",
188+ full.names = TRUE)
189+ )
190+ }
191+
192+ ```
193+
194+ This would expose all of the ` .sql ` files in the ` inst/sql/resultsModel ` folder of your package as methods within the query namespace.
0 commit comments