diff --git a/jaydebeapi/__init__.py b/jaydebeapi/__init__.py
index 51c2b84..8c244fe 100644
--- a/jaydebeapi/__init__.py
+++ b/jaydebeapi/__init__.py
@@ -7,12 +7,12 @@
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
-#
+#
# JayDeBeApi is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
-#
+#
# You should have received a copy of the GNU Lesser General Public
# License along with JayDeBeApi. If not, see
# .
@@ -83,7 +83,7 @@ def _handle_sql_exception_jython():
exc_type = InterfaceError
reraise(exc_type, exc_info[1], exc_info[2])
-def _jdbc_connect_jython(jclassname, jars, libs, *args):
+def _jdbc_connect_jython(jclassname, jars, libs, props, *args):
if _jdbc_name_to_const is None:
from java.sql import Types
types = Types
@@ -146,8 +146,8 @@ def _handle_sql_exception_jpype():
else:
exc_type = InterfaceError
reraise(exc_type, exc_info[1], exc_info[2])
-
-def _jdbc_connect_jpype(jclassname, jars, libs, *driver_args):
+
+def _jdbc_connect_jpype(jclassname, jars, libs, props, *driver_args):
import jpype
if not jpype.isJVMStarted():
args = []
@@ -180,6 +180,13 @@ def _java_array_byte(data):
return jpype.JArray(jpype.JByte, 1)(data)
# register driver for DriverManager
jpype.JClass(jclassname)
+
+ if props is not None:
+ jprops = jpype.java.util.Properties()
+ for k, v in props.iteritems():
+ jprops.put(k, v)
+ return jpype.java.sql.DriverManager.getConnection(driver_args[0], jprops)
+
return jpype.java.sql.DriverManager.getConnection(*driver_args)
def _get_classpath():
@@ -330,7 +337,7 @@ def TimestampFromTicks(ticks):
return apply(Timestamp, time.localtime(ticks)[:6])
# DB-API 2.0 Module Interface connect constructor
-def connect(jclassname, driver_args, jars=None, libs=None):
+def connect(jclassname, driver_args, jars=None, libs=None, props=None):
"""Open a connection to a database using a JDBC driver and return
a Connection instance.
@@ -356,7 +363,7 @@ def connect(jclassname, driver_args, jars=None, libs=None):
libs = [ libs ]
else:
libs = []
- jconn = _jdbc_connect(jclassname, jars, libs, *driver_args)
+ jconn = _jdbc_connect(jclassname, jars, libs, props, *driver_args)
return Connection(jconn, _converters)
# DB-API 2.0 Connection Object
@@ -470,15 +477,25 @@ def _set_stmt_parms(self, prep_stmt, parameters):
def execute(self, operation, parameters=None):
if self._connection._closed:
raise Error()
- if not parameters:
- parameters = ()
+
self._close_last()
- self._prep = self._connection.jconn.prepareStatement(operation)
- self._set_stmt_parms(self._prep, parameters)
- try:
- is_rs = self._prep.execute()
- except:
- _handle_sql_exception()
+
+ if parameters == None:
+ self._prep = self._connection.jconn.createStatement()
+
+ try:
+ is_rs = self._prep.execute(operation)
+ except:
+ _handle_sql_exception()
+ else:
+ self._prep = self._connection.jconn.prepareStatement(operation)
+ self._set_stmt_parms(self._prep, parameters)
+
+ try:
+ is_rs = self._prep.execute()
+ except:
+ _handle_sql_exception()
+
if is_rs:
self._rs = self._prep.getResultSet()
self._meta = self._rs.getMetaData()
diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
index 8ed0703..ae11d01 100644
--- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
+++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
@@ -2,6 +2,7 @@
import java.lang.reflect.Field;
import java.sql.Connection;
+import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
@@ -25,16 +26,22 @@ public final void mockExceptionOnRollback(String className, String exceptionMess
public final void mockExceptionOnExecute(String className, String exceptionMessage) throws SQLException {
PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
+ Statement mockStatement = Mockito.mock(Statement.class);
Throwable exception = createException(className, exceptionMessage);
Mockito.when(mockPreparedStatement.execute()).thenThrow(exception);
+ Mockito.when(mockStatement.execute(Mockito.anyString())).thenThrow(exception);
Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
+ Mockito.when(this.createStatement()).thenReturn(mockStatement);
}
public final void mockType(String sqlTypesName) throws SQLException {
PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
+ Statement mockStatement = Mockito.mock(Statement.class);
Mockito.when(mockPreparedStatement.execute()).thenReturn(true);
+ Mockito.when(mockStatement.execute(Mockito.anyString())).thenReturn(true);
mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for type " + sqlTypesName + ")");
Mockito.when(mockPreparedStatement.getResultSet()).thenReturn(mockResultSet);
+ Mockito.when(mockStatement.getResultSet()).thenReturn(mockResultSet);
Mockito.when(mockResultSet.next()).thenReturn(true);
ResultSetMetaData mockMetaData = Mockito.mock(ResultSetMetaData.class);
Mockito.when(mockResultSet.getMetaData()).thenReturn(mockMetaData);
@@ -42,6 +49,7 @@ public final void mockType(String sqlTypesName) throws SQLException {
int sqlTypeCode = extractTypeCodeForName(sqlTypesName);
Mockito.when(mockMetaData.getColumnType(1)).thenReturn(sqlTypeCode);
Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
+ Mockito.when(this.createStatement()).thenReturn(mockStatement);
}
public final ResultSet verifyResultSet() {
diff --git a/test/test_integration.py b/test/test_integration.py
index 42b6117..a1b2389 100644
--- a/test/test_integration.py
+++ b/test/test_integration.py
@@ -18,6 +18,7 @@
# .
import jaydebeapi
+from jaydebeapi import OperationalError
import os
import sys
@@ -207,6 +208,15 @@ def test_execute_different_rowcounts(self):
cursor.execute("select * from ACCOUNT")
self.assertEqual(cursor.rowcount, -1)
+ def test_sql_exception_on_execute(self):
+ cursor = self.conn.cursor()
+ try:
+ cursor.execute("dummy stmt")
+ except jaydebeapi.DatabaseError as e:
+ self.assertEquals(str(e).split(" ")[0], "java.sql.SQLException:")
+ except self.conn.OperationalError as e:
+ self.assertEquals("syntax" in str(e), True)
+
class SqliteTestBase(IntegrationTestBase):
def setUpSql(self):
diff --git a/test/test_mock.py b/test/test_mock.py
index 6dcb702..ffeb979 100644
--- a/test/test_mock.py
+++ b/test/test_mock.py
@@ -59,6 +59,15 @@ def test_sql_exception_on_execute(self):
except jaydebeapi.DatabaseError as e:
self.assertEquals(str(e), "java.sql.SQLException: expected")
+ def test_sql_exception_on_parameter_execute(self):
+ self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected")
+ cursor = self.conn.cursor()
+ try:
+ cursor.execute("dummy stmt", (18,))
+ fail("expected exception")
+ except jaydebeapi.DatabaseError as e:
+ self.assertEquals(str(e), "java.sql.SQLException: expected")
+
def test_runtime_exception_on_execute(self):
self.conn.jconn.mockExceptionOnExecute("java.lang.RuntimeException", "expected")
cursor = self.conn.cursor()