11# ' @title Retrieves data from PJS
22# ' @description Retrieves and standardises PJS data. \code{retrieve_PJSdata} is
3+ # ' a wrapper for several \code{NVIpjsr}-functions and the intention of
4+ # ' \code{retrieve_PJSdata} is to shorten code and to ensure that a standard
5+ # ' procedure is followed when retrieving PJS data, see details. It can only
6+ # ' be used for retrieving case data from PJS where the columns "aar",
7+ # ' "ansvarlig_seksjon" and "innsendelsenr" are included in the columns. It
8+ # ' cannot be used for retrieving data from other tables available in
9+ # ' "journal_rapp".
10+ # '
11+ # ' @details \code{retrieve_PJSdata} is a wrapper for the following
12+ # ' \code{NVIdb}-functions and \code{NVIpjsr}-functions:
13+ # ' \itemize{
14+ # ' \item Constructs the select statement by a build_query-function (see details)
15+ # ' and selection parameters.
16+ # ' \item Creates an open ODBC-channel using
17+ # ' \ifelse{html}{\code{\link[NVIdb:login_PJS]{login_PJS}}}{\code{NVIdb::login_PJS}}.
18+ # ' \item Retrieves the data using the select statement constructed above.
19+ # ' \item Standardises the data using
20+ # ' \ifelse{html}{\code{\link{standardize_PJSdata}}}{\code{standardize_PJSdata}}.
21+ # ' \item Excludes unwanted cases using
22+ # ' \ifelse{html}{\code{\link{exclude_from_PJSdata}}}{\code{exclude_from_PJSdata}}.
23+ # ' }
24+ # '
25+ # ' For the function to run automatically without having to enter PJS user
26+ # ' credentials, it is dependent that PJS user credentials have been saved using
27+ # ' \code{set_credentials_PJS}.
28+ # ' Otherwise, the credentials must be input manually to establish an open
29+ # ' ODBC channel.
30+ # '
31+ # ' The select statement for PJS can be built giving the selection parameters and
32+ # ' input to one of the build_query-functions, i.e.
33+ # ' \ifelse{html}{\code{\link{build_query_hensikt}}}{\code{build_query_hensikt}},
34+ # ' \ifelse{html}{\code{\link{build_query_one_disease}}}{\code{build_query_one_disease}}
35+ # ' and
36+ # ' \ifelse{html}{\code{\link{build_query_outbreak}}}{\code{build_query_outbreak}}.
37+ # ' The selection parameters can be set by using
38+ # ' \ifelse{html}{\code{\link{set_disease_parameters}}}{\code{set_disease_parameters}}.
39+ # ' or by giving a list of similar format for input to
40+ # ' \code{selection_parameters}, see the build_query-functions for necessary
41+ # ' input.
42+ # '
43+ # ' \code{retrieve_PJSdata} gives the possibility of giving the select_statement
44+ # ' as a string instead of using the build_query-functions. If so, the
45+ # ' select_statement should be included in the selection parameters. This
46+ # ' should only by done for select statements that previously have been tested
47+ # ' and are known to have correct syntax. \code{retrieve_PJSdata} has no
48+ # ' possibility of checking the sql syntax before it is submitted to PJS and
49+ # ' untested select statements can take a lot of time or stop the function
50+ # ' without proper error messages. In the case that both a select_statement
51+ # ' and a function with the necessary selection_parameters are given,
52+ # ' the select_statement constructed by the function will be used.
53+ # '
54+ # ' The output is a named list where each entry is a data frame with PJS data. If
55+ # ' the select statement is named, the returned data frame will have that name.
56+ # ' If the select statement is unnamed, it will try to identify the first
57+ # ' table in the select statement and use this as name. If not possible, the
58+ # ' name will be of the format "PJSdata#" where # is the number of the select
59+ # ' statement.
60+
61+ # '
62+ # ' @param year [\code{numeric}]\cr
63+ # ' One year or a vector giving the first and last years that should be selected.
64+ # ' Defaults to \code{NULL}.
65+ # ' @param selection_parameters [\code{character(1)}]\cr
66+ # ' Either the path and file name for an R script that can be sourced and that
67+ # ' sets the selection parameters or a named list with the selection parameters
68+ # ' (i.e. of the same format as the output of
69+ # ' \ifelse{html}{\code{\link{set_disease_parameters}}}{\code{set_disease_parameters}}).
70+ # ' Defaults to \code{NULL}.
71+ # ' @param FUN \code{deprecated}\cr
72+ # ' \code{FUN} should instead be included as input to \code{selection_parameters}.
73+ # ' Defaults to \code{NULL}.
74+ # ' @param select_statement \code{deprecated}\cr
75+ # ' \code{select_statement} should instead be included as input to
76+ # ' \code{selection_parameters}. Defaults to \code{NULL}.
77+ # ' @param \dots Other arguments to be passed to the underlying functions:
78+ # ' \ifelse{html}{\code{\link[NVIdb:login_PJS]{login_PJS}}}{\code{NVIdb::login_PJS}}
79+ # ' and
80+ # ' \ifelse{html}{\code{\link{exclude_from_PJSdata}}}{\code{exclude_from_PJSdata}}.
81+ # '
82+ # ' @return A named list with PJS data.
83+ # '
84+ # ' @author Petter Hopp Petter.Hopp@@vetinst.no
85+ # ' @name retrieve_PJSdata-deprecated
86+ # ' @keywords internal
87+ NULL
88+ # '
89+ # ' @title Retrieves data from PJS
90+ # ' @description Retrieves and standardises PJS data. \code{retrieve_PJSdata} is
391# ' a wrapper for several \code{NVIdb} - and \code{NVIpjsr} - functions and the intention of
492# ' \code{retrieve_PJSdata} is to shorten code and to ensure that a standard
593# ' procedure is followed when retrieving PJS data, see details. It can only
50138# ' the select_statement constructed by the function will be used.
51139# '
52140# ' Be aware that there is a known problem for the R-package "odbc" when selecting
53- # ' long text variables like "anamnese". Such variables need to be put last in
54- # ' the select statement. The variable "anamnese" is included in the main views
55- # ' used for retrieving data from PJS. \code{retrieve_PJSdata} will rewrite
141+ # ' long text variables like "anamnese" and "merknad" (for sak). Such variables
142+ # ' need to be put last in the select statement. These variables are included
143+ # ' in the main views used for retrieving data from PJS. \code{retrieve_PJSdata} will rewrite
56144# ' select statements generated by the \code{build_query}-functions and sql
57145# ' statements starting with "SELECT * FROM 'tablename'", but will not rewrite
58146# ' the sql statement in other situations. If this happens, you must either
59- # ' rewrite the sql statement and put "anamnese" last in the select statement
60- # ' or use the R-package "RODBC" instead. If using "RODBC", you cannot use
61- # ' \code{retrieve_PJSdata }.
147+ # ' rewrite the sql statement and put these variables last in the select statement
148+ # ' or use the R-package "RODBC" instead by giving the argument
149+ # ' \code{dbinterface = "RODBC" }.
62150# '
63151# ' The output is a named list where each entry is a data frame with PJS data. If
64152# ' the select statement is named, the returned data frame will have that name.
77165# ' (i.e. of the same format as the output of
78166# ' \code{\link{set_disease_parameters}}).
79167# ' Defaults to \code{NULL}.
168+ # ' @param dbinterface [\code{character(1)}]\cr
169+ # ' The R-package that is used for interface towards the data base. Valid values
170+ # ' are c("odbc", "RODBC"). Defaults to \code{"odbc"}.
80171# ' @param \dots Other arguments to be passed to the underlying functions:
81172# ' \ifelse{html}{\code{\link[NVIdb:login]{NVIdb::login("PJS")}}}{\code{NVIdb::login("PJS")}}
82173# ' and \code{\link{exclude_from_PJSdata}}.
103194# ' PJSrawdata <- retrieve_PJSdata(year = 2024,
104195# ' selection_parameters = selection_parameters,
105196# ' abroad = "include")
197+ # '
198+ # ' # Read PJSdata using RODBC
199+ # ' PJSrawdata <- retrieve_PJSdata(year = 2024,
200+ # ' selection_parameters = selection_parameters,
201+ # ' dbinterface = "RODBC")
106202# ' }
107203# '
108204retrieve_PJSdata <- function (year = NULL ,
109205 selection_parameters = NULL ,
206+ dbinterface = " odbc" ,
110207 ... ) {
111208
112209 # CAPTURE DOTS ----
@@ -177,6 +274,8 @@ retrieve_PJSdata <- function(year = NULL,
177274 selection_parameters $ utbrudd2select ,
178275 selection_parameters $ select_statement , add = checks ))
179276 NVIcheckmate :: assert_non_null(list (unlist(selection_parameters $ FUN ), selection_parameters $ select_statement ), add = checks )
277+ checkmate :: assert_choice(dbinterface ,
278+ choices = c(" odbc" , " RODBC" ), add = checks )
180279
181280 # Report check-results
182281 checkmate :: reportAssertions(checks )
@@ -241,35 +340,53 @@ retrieve_PJSdata <- function(year = NULL,
241340 # OPEN ODBC CHANNEL ----
242341 # journal_rapp <- NVIdb::login(dbservice = "PJS", dbinterface = "odbc", ...)
243342 dots1 <- intersect(setdiff(names(formals(NVIdb :: login )), c(" dbservice" , " dbinterface" )), names(dots ))
244- journal_rapp <- do.call(NVIdb :: login , append(dots [dots1 ], list (dbservice = " PJS" , dbinterface = " odbc" )))
343+
344+ # if (dbinterface == "odbc") {
345+ journal_rapp <- do.call(NVIdb :: login , append(dots [dots1 ], list (dbservice = " PJS" , dbinterface = dbinterface )))
346+ # }
347+ # journal_rapp <- do.call(NVIdb::login, append(dots[dots1], list(dbservice = "PJS", dbinterface = "RODBC")))
245348
246349 PJSdata <- vector(" list" , length = length(select_statement ))
247350
248351 # PERFORM SELECTION AND STANDARDISATION FOR EACH SELECT STATEMENT ----
249352 for (i in c(1 : length(select_statement ))) {
250353
251- # MOVE anamnese LAST IN SELECTION STATEMENT ----
252- # Identify table in the first select clause in sql statement
253- db_table <- sub(" SELECT[[:space:]]*\\ *[[:space:]]*FROM[[:space:]]*([^[:space:]]*).*" ,
254- " \\ 1" ,
255- select_statement [[i ]], ignore.case = TRUE )
256- # List fields in the db_table
257- if (nchar(db_table ) > 0 && regexpr(" [[:space:],\\ *]" , db_table ) < 0 ) {
258- fields <- DBI :: dbListFields(conn = journal_rapp , name = db_table )
259- # Put anamnese last in select clause if exist in the db_table
260- if (" anamnese" %in% tolower(fields )) {
261- fields <- paste0(fields , collapse = " , " )
262- fields <- paste0(sub(" anamnese, " , " " , fields , ignore.case = TRUE ), " , anamnese" )
263- select_statement [[i ]] <- sub(paste0(" SELECT[[:space:]]*\\ *[[:space:]]*FROM[[:space:]]*" , db_table ),
264- paste(" SELECT" , fields , " FROM" , db_table ),
265- select_statement [[i ]],
266- ignore.case = TRUE )
354+ if (dbinterface == " odbc" ) {
355+ # MOVE anamnese LAST IN SELECTION STATEMENT ----
356+ # Identify table in the first select clause in sql statement
357+ db_table <- sub(" SELECT[[:space:]]*\\ *[[:space:]]*FROM[[:space:]]*([^[:space:]]*).*" ,
358+ " \\ 1" ,
359+ select_statement [[i ]], ignore.case = TRUE )
360+ # List fields in the db_table
361+ if (nchar(db_table ) > 0 && regexpr(" [[:space:],\\ *]" , db_table ) < 0 ) {
362+ fields <- DBI :: dbListFields(conn = journal_rapp , name = db_table )
363+ # Put anamnese last in select clause if exist in the db_table
364+ if (" anamnese" %in% tolower(fields ) | " merknad" %in% tolower(fields )) {
365+ fields <- paste0(fields , collapse = " , " )
366+ if (regexpr(" merknad" , fields , ignore.case = TRUE ) > 0 ) {
367+ fields <- paste0(sub(" merknad, " , " " , fields , ignore.case = TRUE ), " , merknad" )
368+ }
369+ if (regexpr(" anamnese" , fields , ignore.case = TRUE ) > 0 ) {
370+ fields <- paste0(sub(" anamnese, " , " " , fields , ignore.case = TRUE ), " , anamnese" )
371+ }
372+ select_statement [[i ]] <- sub(paste0(" SELECT[[:space:]]*\\ *[[:space:]]*FROM[[:space:]]*" , db_table ),
373+ paste(" SELECT" , fields , " FROM" , db_table ),
374+ select_statement [[i ]],
375+ ignore.case = TRUE )
376+ }
267377 }
378+
379+ # READ DATA FROM PJS ----
380+ PJSdata [[i ]] <- DBI :: dbGetQuery(con = journal_rapp ,
381+ statement = select_statement [[i ]])
382+ }
383+
384+ if (dbinterface == " RODBC" ) {
385+ PJSdata [[i ]] <- RODBC :: sqlQuery(journal_rapp ,
386+ query = select_statement [[i ]],
387+ as.is = TRUE )
268388 }
269389
270- # READ DATA FROM PJS ----
271- PJSdata [[i ]] <- DBI :: dbGetQuery(con = journal_rapp ,
272- statement = select_statement [[i ]])
273390 # STANDARDIZE DATA ----
274391 PJSdata [[i ]] <- standardize_PJSdata(PJSdata = PJSdata [[i ]], dbsource = dbsource [i ])
275392
@@ -280,7 +397,8 @@ retrieve_PJSdata <- function(year = NULL,
280397 }
281398
282399 # CLOSE ODBC CHANNEL ----
283- DBI :: dbDisconnect(journal_rapp )
400+ if (dbinterface == " odbc" ) {DBI :: dbDisconnect(journal_rapp )}
401+ if (dbinterface == " RODBC" ) {RODBC :: odbcClose(journal_rapp )}
284402
285403 # RETURN RESULT ----
286404 # Give name to each entry in the list of PJSdata
0 commit comments