-
Notifications
You must be signed in to change notification settings - Fork 32
/
DBI-pool.R
67 lines (61 loc) · 1.9 KB
/
DBI-pool.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#' @include DBI.R
NULL
## This method used to attempt to clean up for you if it
## detected open results sets. However, different database
## drivers implement different DBI methods and this quickly
## became unwieldy. From now on, pool will not reset a
## connection's state back to a clean slate (which is not
## something to worry about unless users are explicitly
## checking out connections -- only necessary for pretty
## complicated transactions).
#' @export
#' @rdname object
setMethod("onPassivate", "DBIConnection", function(object) {
invisible()
})
#' @export
#' @rdname object
setMethod("onDestroy", "DBIConnection", function(object) {
DBI::dbDisconnect(object)
})
#' @export
#' @rdname object
setMethod("onValidate", "DBIConnection", function(object) {
pool <- attr(object, "..metadata", exact = TRUE)$pool
query <- pool$state$validateQuery
if (!is.null(query)) {
error <- try({
dbGetQuery(object, query)
return()
}, silent = TRUE)
} else {
## options mostly gathered from here:
## http://stackoverflow.com/a/3670000/6174455
options <- c(
"SELECT 1",
"SELECT 1 FROM DUAL",
"SELECT 1 FROM INFORMATION_SCHEMA.SYSTEM_USERS",
"SELECT * FROM INFORMATION_SCHEMA.TABLES",
"VALUES 1",
"SELECT 1 FROM SYSIBM.SYSDUMMY1",
"select count(*) from systables"
)
## Iterates through the possible validation queries:
## the first one that succeeds get stored in the `state`
## of pool (a public variable) and we return.
## If none succeed, validation is not possible and we
## throw an error.
for (opt in options) {
error <- try({
dbGetQuery(object, opt)
pool$state$validateQuery <- opt
return()
}, silent = TRUE)
}
}
cond <- attr(error, "condition", exact = TRUE)
stop(simpleError(
paste("Validation not successful --", conditionMessage(cond)),
conditionCall(cond)
))
})