From a1f8d3c3b4621570065d968b4b734bae3f0eaf79 Mon Sep 17 00:00:00 2001 From: tdawber Date: Thu, 19 Jan 2017 14:58:59 +1100 Subject: [PATCH 1/2] allow execution of queries without prepared statements --- jaydebeapi/__init__.py | 25 +++++++++++++------ .../jaydebeapi/mockdriver/MockConnection.java | 8 ++++++ test/test_integration.py | 10 ++++++++ test/test_mock.py | 9 +++++++ 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/jaydebeapi/__init__.py b/jaydebeapi/__init__.py index d33014a..f0380d7 100644 --- a/jaydebeapi/__init__.py +++ b/jaydebeapi/__init__.py @@ -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() 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 8818975..d849137 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", 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): diff --git a/test/test_mock.py b/test/test_mock.py index 6dcb702..80ae5cd 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_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() From 935beae68ecdc954295ce62d5ec86d4009e15cf9 Mon Sep 17 00:00:00 2001 From: tdawber Date: Thu, 19 Jan 2017 15:35:13 +1100 Subject: [PATCH 2/2] Disable pysqlite test --- test/test_integration.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_integration.py b/test/test_integration.py index d849137..2bd89e7 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -249,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):