Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions jaydebeapiarrow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,12 @@ def _handle_sql_exception_jpype():

reraise(exc_type, exc_info[1], exc_info[2])

def _jdbc_connect_jpype(jclassname, url, driver_args, jars, libs):
def _jdbc_connect_jpype(jclassname, url, driver_args, jars, libs, jvm_args=None):
import jpype
if not _is_jvm_started():
args = []
if jvm_args:
args.extend(jvm_args)
class_path = []
if jars:
class_path.extend(jars)
Expand Down Expand Up @@ -379,7 +382,7 @@ def TimestampFromTicks(ticks):
return Timestamp(*time.localtime(ticks)[:6])

# DB-API 2.0 Module Interface connect constructor
def connect(jclassname, url, driver_args=None, jars=None, libs=None):
def connect(jclassname, url, driver_args=None, jars=None, libs=None, jvm_args=None):
"""Open a connection to a database using a JDBC driver and return
a Connection instance.

Expand All @@ -395,6 +398,11 @@ def connect(jclassname, url, driver_args=None, jars=None, libs=None):
jars: Jar filename or sequence of filenames for the JDBC driver
libs: Dll/so filenames or sequence of dlls/sos used as shared
library by the JDBC driver
jvm_args: Sequence of additional JVM arguments (e.g.
['-Duser.timezone=America/Toronto',
'-Dfile.encoding=UTF-8']). Only used on the first
connect() call when the JVM is started. Ignored on
subsequent calls since the JVM cannot be restarted.
"""
if isinstance(driver_args, str):
driver_args = [ driver_args ]
Expand All @@ -410,7 +418,7 @@ def connect(jclassname, url, driver_args=None, jars=None, libs=None):
libs = [ libs ]
else:
libs = []
jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs)
jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs, jvm_args)
return Connection(jconn, jclassname)

# DB-API 2.0 Connection Object
Expand Down
28 changes: 28 additions & 0 deletions test/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2007,3 +2007,31 @@ def test_hsqldb_jar_path_with_spaces(self):
)
self.assertTrue(result.stdout.strip().startswith('OK'),
f'Connection failed: {result.stdout}\n{result.stderr}')


class JvmArgsTest(unittest.TestCase):
"""Test that jvm_args parameter passes custom JVM arguments on first connect."""

_TEST_PROP = 'jaydebeapiarrow.test.jvmargs'

def setUp(self):
import jpype
if jpype.isJVMStarted():
self.skipTest("JVM already started; jvm_args only takes effect on first connect")

def test_jvm_args_sets_system_property(self):
"""jvm_args should set JVM system properties during startup."""
import jpype
import glob
mock_jars = glob.glob(os.path.join(_THIS_DIR, 'mock-jars', 'mockdriver*.jar'))
c = jaydebeapiarrow.connect(
'org.jaydebeapi.mockdriver.MockDriver',
'jdbc:jaydebeapi://dummyurl',
jars=mock_jars,
jvm_args=[f'-D{self._TEST_PROP}=hello_from_jvm_args']
)
try:
prop_value = jpype.java.lang.System.getProperty(self._TEST_PROP)
self.assertEqual(prop_value, 'hello_from_jvm_args')
finally:
c.close()
15 changes: 14 additions & 1 deletion test/test_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,6 @@ def test_rollback_called_when_autocommit_disabled(self):
self.conn.jconn.mockAutoCommit(False)
self.conn.rollback()


def test_lastrowid_exists_and_is_none(self):
"""PEP-249: lastrowid attribute must exist on cursor (fixes #84)."""
with self.conn.cursor() as cursor:
Expand All @@ -1273,6 +1272,20 @@ def test_lastrowid_none_after_executemany(self):
"""lastrowid should be None after executemany (mock driver limitation: skip)."""
self.skipTest("Mock driver executeBatch returns None; covered by integration test")

# --- JVM args parameter test (issue #90) ---

def test_connect_accepts_jvm_args(self):
"""connect() should accept jvm_args parameter without error."""
import jpype
# The JVM is already started by setUp, so jvm_args won't take effect,
# but the parameter should be accepted without raising TypeError.
conn = jaydebeapiarrow.connect(
'org.jaydebeapi.mockdriver.MockDriver',
'jdbc:jaydebeapi://dummyurl',
jvm_args=['-Duser.timezone=UTC']
)
conn.close()


class JarPathSpacesTest(unittest.TestCase):
"""Tests for JAR file paths containing spaces (issue #86).
Expand Down
Loading