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
25 changes: 18 additions & 7 deletions jaydebeapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,18 +488,29 @@ def _set_stmt_parms(self, prep_stmt, parameters):
# print (i, parameters[i], type(parameters[i]))
prep_stmt.setObject(i + 1, parameters[i])

def execute(self, operation, parameters=None):
def execute(self, operation, parameters=None, use_prepared_statements=True):
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 use_prepared_statements:
self._prep = self._connection.jconn.prepareStatement(operation)
self._set_stmt_parms(self._prep, parameters)

try:
is_rs = self._prep.execute()
except:
_handle_sql_exception()
else:
self._prep = self._connection.jconn.createStatement()

try:
is_rs = self._prep.execute(operation)
except:
_handle_sql_exception()

if is_rs:
self._rs = self._prep.getResultSet()
self._meta = self._rs.getMetaData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,23 +26,30 @@ 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);
Mockito.when(mockMetaData.getColumnCount()).thenReturn(1);
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() {
Expand Down
13 changes: 13 additions & 0 deletions test/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# <http://www.gnu.org/licenses/>.

import jaydebeapi
from jaydebeapi import OperationalError

import os
import sys
Expand Down Expand Up @@ -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", use_prepared_statements=False)
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):
Expand Down Expand Up @@ -239,6 +249,9 @@ def connect(self):
def test_execute_type_time(self):
"""Time type not supported by PySqlite"""

def test_sql_exception_on_execute(self):
"""Additional named parameters not supported by PySqlite"""

class SqliteXerialTest(SqliteTestBase, unittest.TestCase):

def connect(self):
Expand Down
9 changes: 9 additions & 0 deletions test/test_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_no_prepared_execute(self):
self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected")
cursor = self.conn.cursor()
try:
cursor.execute("dummy stmt", use_prepared_statements=False)
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()
Expand Down