Skip to content

Commit

Permalink
Fall back to using the driver's class if connect via DriverManager fails
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.rforge.net/RJDBC/trunk@11 4a7c0e7c-d491-4dbe-a893-edef5ccece86
  • Loading branch information
s-u committed Mar 6, 2007
1 parent 8808727 commit c6a0907
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.1-5 (under development)
* instantiate driver's class and use a call to 'connect' as a
fall-back if the DriverManager fails to find a proper driver.

0.1-4 2007-03-05
* added SQL error information to most JDBC errors

Expand Down
16 changes: 14 additions & 2 deletions R/class.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
##=== JDBCDriver

setClass("JDBCDriver", representation("DBIDriver", identifier.quote="character"))
setClass("JDBCDriver", representation("DBIDriver", identifier.quote="character", jdrv="jobjRef"))

JDBC <- function(driverClass='', classPath='', identifier.quote=NA) {
.jinit(classPath)
if (nchar(driverClass) && is.jnull(.jfindClass(as.character(driverClass)[1])))
stop("Cannot find JDBC driver class ",driverClass)
new("JDBCDriver", identifier.quote=as.character(identifier.quote))
jdrv <- .jnew(driverClass, check=FALSE)
.jcheck(TRUE)
if (is.jnull(jdrv)) jdrv <- .jnull()
new("JDBCDriver", identifier.quote=as.character(identifier.quote), jdrv=jdrv)
}

.verify.JDBC.result <- function (result, ...) {
Expand All @@ -32,6 +35,15 @@ setMethod("dbUnloadDriver", "JDBCDriver", def=function(drv, ...) NULL)

setMethod("dbConnect", "JDBCDriver", def=function(drv, url, user='', password='', ...) {
jc <- .jcall("java/sql/DriverManager","Ljava/sql/Connection;","getConnection", as.character(url)[1], as.character(user)[1], as.character(password)[1], check=FALSE)
if (is.jnull(jc) || !is.jnull(drv@jdrv)) {

This comment has been minimized.

Copy link
@amarek96

amarek96 Dec 4, 2013

This line should be as follows...
if (is.jnull(jc) && !is.jnull(drv@jdrv)) {

# ok one reason for this to fail is its interaction with rJava's
# class loader. In that case we try to load the driver directly.
oex <- .jgetEx(TRUE)
p <- .jnew("java/util/Properties")
if (length(user)==1 && nchar(user)) .jcall(p,"Ljava/lang/Object;","setProperty","user",user)
if (length(password)==1 && nchar(password)) .jcall(p,"Ljava/lang/Object;","setProperty","password",password)
jc <- .jcall(drv@jdrv, "Ljava/sql/Connection;", "connect", as.character(url)[1], p)
}
.verify.JDBC.result(jc, "Unable to connect JDBC to ",url)
new("JDBCConnection", jc=jc, identifier.quote=drv@identifier.quote)},
valueClass="JDBCConnection")
Expand Down

1 comment on commit c6a0907

@amarek96
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method "dbConnect" creates two connections, one of which is orphaned. The method first invokes java.sql.DriverManager.getConnection(), which creates the first connection. The following if-statement checks if jc is null OR drv@jdrv is not null. Instead of OR it should be AND, i.e. if (is.jnull(jc) && !is.jnull(drv@jdrv)).

The OR incorrectly lets dbConnect enter the if-statement if drv is not null and thus create a second (duplicate) connection with java.sql.Driver.connect(). For example:

drv = JDBC("com.teradata.jdbc.TeraDriver","c:\terajdbc\terajdbc4.jar;c:\terajdbc\tdgssconfig.jar")
con = dbConnect(drv,"jdbc:teradata://system","user","password")
dbDisconnect(con)

The dbDisconnect will only close one of the two connections created by dbConnect.

Please sign in to comment.