[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