[R-sig-DB] dbDriver("name")
Paul Gilbert
pg||bert902 @end|ng |rom gm@||@com
Tue Oct 22 20:09:15 CEST 2013
On 13-10-22 09:30 AM, Hadley Wickham wrote:
>>> Thanks for the suggestion, however, I remain a bit confused. The function
>>> find_driver() seems like a direct replacement for dbConnect(), using a
>>> string to identify the database driver. You would be supporting what is a
>>> bad idea, and just changing the name of the function, which is a make work
>>> project for everyone.
>>
>> So unless we want to invent a completely new way of registering
>> drivers, it seems like patching dbDriver to use this strategy will be
>> effective. However, I think we should equally encourage people to use
>> the driver object directly, instead of the string. That doesn't help
>> you, but it does help people only concerned with connecting to one
>> database.
>
> Here's a first stab at it. I think it should work for the majority of
> existing packages, regardless of whether they're loaded or not:
I'm not sure if it is a good idea or not to find drivers that are not
loaded or attached. This may cause more problems than it adds
simplifications? Would you load or attach the packages in which the
drivers are found? You and others probably understand the implications
better than I do.
Possibly one of my comments initiated the findDriver() effort, so let me
give the context in which I have been doing something a bit similar. I
look through a list of loaded/attached packages for a particular
database, with a function called like this:
con <- TSfinddb(dbname="ets",
driverOrder=c("MySQL", "SQLite", "PostgreSQL"))
which attempts a dbConnect for each driver string, looking for the
database "ets". But I just look though attached or loaded packages and
the database may not exist even if the package is loaded, so I need to
wrap the dbConnect calls in try().
(There is some risk that this is a distraction relative to more
important things that need to be done on DBI. Please don't spend a lot
of time on findDriver motivated only by my remarks.)
Paul
>
> setMethod("dbDriver", "character",
> definition = function(drvName, ...) {
> findDriver(drvName)(...)
> }
> )
>
> findDriver <- function(drvName) {
> # If it exists in the global environment, use that
> d <- get2(drvName, globalenv())
> if (!is.null(d)) return(d)
>
> # Otherwise, see if the appropriately named package is available
> if (has_namespace(drvName)) {
> d <- get2(drvName, asNamespace(drvName))
> if (!is.null(d)) return(d)
> }
>
> pkgName <- paste0("R", drvName)
> # First, see if package with name R + drvName is available
> if (has_namespace(pkgName)) {
> d <- get2(drvName, asNamespace(pkgName))
> if (!is.null(d)) return(d)
> }
>
> # Can't find it:
> stop("Couldn't find driver ", drvName, ". Looked in:\n",
> "* global namespace\n",
> "* in package called ", drvName, "\n",
> "* in package called ", pkgName,
> call. = FALSE)
> }
>
> get2 <- function(x, env) {
> if (!exists(x, envir = env)) return(NULL)
> get(x, envir = env)
> }
>
> has_namespace <- function(x) {
> suppressMessages(requireNamespace(x, quietly = TRUE))
> }
>
> Hadley
>
More information about the R-sig-DB
mailing list