Allow for db properties to be passed to connect method. Alternative solution opposed to #17 to fix #16

master
baztian 2017-01-09 20:36:25 +01:00
parent 9d71d122c6
commit 2640445de0
3 changed files with 69 additions and 25 deletions

View File

@ -72,22 +72,25 @@ the ``connect`` method. This gives you a DB-API_ conform connection to
the database. the database.
The first argument to ``connect`` is the name of the Java driver The first argument to ``connect`` is the name of the Java driver
class. Then you can supply a single argument or a sequence of class. The second argument is a string with the JDBC connection
arguments that are internally passed to the Java URL. Third you can optionally supply a sequence consisting of user and
``DriverManager.getConnection`` method. Usually this is the JDBC password or alternatively a dictionary containing arguments that are
connection URL. See the Javadoc of ``DriverManager`` class for internally passed as properties to the Java
details. ``DriverManager.getConnection`` method. See the Javadoc of
``DriverManager`` class for details.
The next parameter to ``connect`` is optional and specifies the The next parameter to ``connect`` is optional as well and specifies
jar-Files of the driver if your classpath isn't set up sufficiently the jar-Files of the driver if your classpath isn't set up
yet. The classpath set in ``CLASSPATH`` environment variable will be sufficiently yet. The classpath set in ``CLASSPATH`` environment
honored. See the documentation of your Java runtime environment. variable will be honored. See the documentation of your Java runtime
environment.
Here is an example: Here is an example:
>>> import jaydebeapi >>> import jaydebeapi
>>> conn = jaydebeapi.connect('org.hsqldb.jdbcDriver', >>> conn = jaydebeapi.connect('org.hsqldb.jdbcDriver',
... ['jdbc:hsqldb:mem:.', 'SA', ''], ... 'jdbc:hsqldb:mem:.',
... ['SA', ''],
... '/path/to/hsqldb.jar',) ... '/path/to/hsqldb.jar',)
>>> curs = conn.cursor() >>> curs = conn.cursor()
>>> curs.execute('create table CUSTOMER' >>> curs.execute('create table CUSTOMER'
@ -144,6 +147,11 @@ Changelog
========= =========
- Next version - unreleased - Next version - unreleased
- Allow for db properties to be passed to the connect
method. *Probably incompatible to code based on previous
versions.* See documentation of the connect method.
- 0.2.0 - 2015-04-26 - 0.2.0 - 2015-04-26
- Python 3 support (requires JPype1 >= 0.6.0). - Python 3 support (requires JPype1 >= 0.6.0).

View File

@ -83,7 +83,7 @@ def _handle_sql_exception_jython():
exc_type = InterfaceError exc_type = InterfaceError
reraise(exc_type, exc_info[1], exc_info[2]) reraise(exc_type, exc_info[1], exc_info[2])
def _jdbc_connect_jython(jclassname, jars, libs, *args): def _jdbc_connect_jython(jclassname, url, driver_args, jars, libs):
if _jdbc_name_to_const is None: if _jdbc_name_to_const is None:
from java.sql import Types from java.sql import Types
types = Types types = Types
@ -114,7 +114,15 @@ def _jdbc_connect_jython(jclassname, jars, libs, *args):
_jython_set_classpath(jars) _jython_set_classpath(jars)
Class.forName(jclassname).newInstance() Class.forName(jclassname).newInstance()
from java.sql import DriverManager from java.sql import DriverManager
return DriverManager.getConnection(*args) if isinstance(driver_args, dict):
from java.util import Properties
info = Properties()
for k, v in driver_args.iteritems():
info.setProperty(k, v)
dargs = [ info ]
else:
dargs = driver_args
return DriverManager.getConnection(url, *dargs)
def _jython_set_classpath(jars): def _jython_set_classpath(jars):
''' '''
@ -147,7 +155,7 @@ def _handle_sql_exception_jpype():
exc_type = InterfaceError exc_type = InterfaceError
reraise(exc_type, exc_info[1], exc_info[2]) reraise(exc_type, exc_info[1], exc_info[2])
def _jdbc_connect_jpype(jclassname, jars, libs, *driver_args): def _jdbc_connect_jpype(jclassname, url, driver_args, jars, libs):
import jpype import jpype
if not jpype.isJVMStarted(): if not jpype.isJVMStarted():
args = [] args = []
@ -180,7 +188,15 @@ def _jdbc_connect_jpype(jclassname, jars, libs, *driver_args):
return jpype.JArray(jpype.JByte, 1)(data) return jpype.JArray(jpype.JByte, 1)(data)
# register driver for DriverManager # register driver for DriverManager
jpype.JClass(jclassname) jpype.JClass(jclassname)
return jpype.java.sql.DriverManager.getConnection(*driver_args) if isinstance(driver_args, dict):
Properties = jpype.java.util.Properties
info = Properties()
for k, v in driver_args.iteritems():
info.setProperty(k, v)
dargs = [ info ]
else:
dargs = driver_args
return jpype.java.sql.DriverManager.getConnection(url, *dargs)
def _get_classpath(): def _get_classpath():
"""Extract CLASSPATH from system environment as JPype doesn't seem """Extract CLASSPATH from system environment as JPype doesn't seem
@ -330,15 +346,18 @@ def TimestampFromTicks(ticks):
return apply(Timestamp, time.localtime(ticks)[:6]) return apply(Timestamp, time.localtime(ticks)[:6])
# DB-API 2.0 Module Interface connect constructor # DB-API 2.0 Module Interface connect constructor
def connect(jclassname, driver_args, jars=None, libs=None): def connect(jclassname, url, driver_args=None, jars=None, libs=None):
"""Open a connection to a database using a JDBC driver and return """Open a connection to a database using a JDBC driver and return
a Connection instance. a Connection instance.
jclassname: Full qualified Java class name of the JDBC driver. jclassname: Full qualified Java class name of the JDBC driver.
driver_args: Argument or sequence of arguments to be passed to the url: Database url as required by the JDBC driver.
Java DriverManager.getConnection method. Usually the driver_args: Dictionary or sequence of arguments to be passed to
database URL. See the Java DriverManager.getConnection method. Usually
http://docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html sequence of username and password for the db. Alternatively
a dictionary of connection arguments (where `user` and
`password` would probably be included). See
http://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html
for more details for more details
jars: Jar filename or sequence of filenames for the JDBC driver jars: Jar filename or sequence of filenames for the JDBC driver
libs: Dll/so filenames or sequence of dlls/sos used as shared libs: Dll/so filenames or sequence of dlls/sos used as shared
@ -346,6 +365,8 @@ def connect(jclassname, driver_args, jars=None, libs=None):
""" """
if isinstance(driver_args, string_type): if isinstance(driver_args, string_type):
driver_args = [ driver_args ] driver_args = [ driver_args ]
if not driver_args:
driver_args = []
if jars: if jars:
if isinstance(jars, string_type): if isinstance(jars, string_type):
jars = [ jars ] jars = [ jars ]
@ -356,7 +377,7 @@ def connect(jclassname, driver_args, jars=None, libs=None):
libs = [ libs ] libs = [ libs ]
else: else:
libs = [] libs = []
jconn = _jdbc_connect(jclassname, jars, libs, *driver_args) jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs)
return Connection(jconn, _converters) return Connection(jconn, _converters)
# DB-API 2.0 Connection Object # DB-API 2.0 Connection Object

View File

@ -244,7 +244,7 @@ class SqliteXerialTest(SqliteTestBase, unittest.TestCase):
def connect(self): def connect(self):
#http://bitbucket.org/xerial/sqlite-jdbc #http://bitbucket.org/xerial/sqlite-jdbc
# sqlite-jdbc-3.7.2.jar # sqlite-jdbc-3.7.2.jar
driver, driver_args = 'org.sqlite.JDBC', 'jdbc:sqlite::memory:' driver, url = 'org.sqlite.JDBC', 'jdbc:sqlite::memory:'
# db2jcc # db2jcc
# driver, driver_args = 'com.ibm.db2.jcc.DB2Driver', \ # driver, driver_args = 'com.ibm.db2.jcc.DB2Driver', \
# ['jdbc:db2://4.100.73.81:50000/db2t', 'user', 'passwd'] # ['jdbc:db2://4.100.73.81:50000/db2t', 'user', 'passwd']
@ -256,7 +256,7 @@ class SqliteXerialTest(SqliteTestBase, unittest.TestCase):
# driver, driver_args = 'oracle.jdbc.OracleDriver', \ # driver, driver_args = 'oracle.jdbc.OracleDriver', \
# ['jdbc:oracle:thin:@//hh-cluster-scan:1521/HH_TPP', # ['jdbc:oracle:thin:@//hh-cluster-scan:1521/HH_TPP',
# 'user', 'passwd'] # 'user', 'passwd']
return jaydebeapi, jaydebeapi.connect(driver, driver_args) return jaydebeapi, jaydebeapi.connect(driver, url)
@unittest.skipUnless(is_jython(), "don't know how to support blob") @unittest.skipUnless(is_jython(), "don't know how to support blob")
def test_execute_type_blob(self): def test_execute_type_blob(self):
@ -267,10 +267,25 @@ class HsqldbTest(IntegrationTestBase, unittest.TestCase):
def connect(self): def connect(self):
# http://hsqldb.org/ # http://hsqldb.org/
# hsqldb.jar # hsqldb.jar
driver, driver_args = 'org.hsqldb.jdbcDriver', ['jdbc:hsqldb:mem:.', driver, url, driver_args = ( 'org.hsqldb.jdbcDriver',
'SA', ''] 'jdbc:hsqldb:mem:.',
return jaydebeapi, jaydebeapi.connect(driver, driver_args) ['SA', ''] )
return jaydebeapi, jaydebeapi.connect(driver, url, driver_args)
def setUpSql(self): def setUpSql(self):
self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_hsqldb.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_hsqldb.sql'))
self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql'))
class PropertiesDriverArgsPassingTest(unittest.TestCase):
def test_connect_with_sequence(self):
driver, url, driver_args = ( 'org.hsqldb.jdbcDriver',
'jdbc:hsqldb:mem:.',
['SA', ''] )
jaydebeapi.connect(driver, url, driver_args)
def test_connect_with_properties(self):
driver, url, driver_args = ( 'org.hsqldb.jdbcDriver',
'jdbc:hsqldb:mem:.',
{'user': 'SA', 'password': '' } )
jaydebeapi.connect(driver, url, driver_args)