Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow execution of queries without prepared statements #29

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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