diff --git a/jaydebeapiarrow/__init__.py b/jaydebeapiarrow/__init__.py index 9b1f8053..c8a80ccf 100644 --- a/jaydebeapiarrow/__init__.py +++ b/jaydebeapiarrow/__init__.py @@ -396,6 +396,14 @@ def connect(jclassname, url, driver_args=None, jars=None, libs=None): libs: Dll/so filenames or sequence of dlls/sos used as shared library by the JDBC driver """ + if not isinstance(url, str): + raise ProgrammingError( + "The 'url' parameter must be a JDBC connection string, " + "not %s. If you meant to pass connection credentials, " + "use the 'driver_args' parameter. " + "Usage: connect(jclassname, url, driver_args=None, jars=None, libs=None)" + % type(url).__name__ + ) if isinstance(driver_args, str): driver_args = [ driver_args ] if not driver_args: diff --git a/test/test_integration.py b/test/test_integration.py index c9242f0d..5f101a35 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -2007,3 +2007,12 @@ def test_hsqldb_jar_path_with_spaces(self): ) self.assertTrue(result.stdout.strip().startswith('OK'), f'Connection failed: {result.stdout}\n{result.stderr}') + + def test_connect_url_must_be_string(self): + """Passing a list as url should raise ProgrammingError (issue #95).""" + with self.assertRaises(jaydebeapiarrow.ProgrammingError) as ctx: + jaydebeapiarrow.connect( + 'org.hsqldb.jdbcDriver', + ['jdbc:hsqldb:mem:.', 'SA', ''] + ) + self.assertIn('url', str(ctx.exception).lower()) diff --git a/test/test_mock.py b/test/test_mock.py index c45843d4..ad965c6d 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -1327,3 +1327,25 @@ def test_jar_path_with_special_chars(self): shutil.copy2(mock_jar, dest) stdout, stderr = self._run_connect_in_subprocess(dest) self.assertEqual(stdout, 'OK', f'Connection failed: {stderr}') + + +class ConnectValidationTest(unittest.TestCase): + """Tests for connect() argument validation (issue #95).""" + + def test_url_must_be_string_not_list(self): + """Passing a list as url should raise ProgrammingError.""" + with self.assertRaises(jaydebeapiarrow.ProgrammingError) as ctx: + jaydebeapiarrow.connect( + 'org.jaydebeapi.mockdriver.MockDriver', + ['jdbc:jaydebeapi://dummyurl', 'user', 'pass'] + ) + self.assertIn('url', str(ctx.exception).lower()) + + def test_url_must_be_string_not_dict(self): + """Passing a dict as url should raise ProgrammingError.""" + with self.assertRaises(jaydebeapiarrow.ProgrammingError) as ctx: + jaydebeapiarrow.connect( + 'org.jaydebeapi.mockdriver.MockDriver', + {'user': 'sa', 'password': ''} + ) + self.assertIn('url', str(ctx.exception).lower())