From cac40267fc91b8643895efe20e3b021cff5f9c26 Mon Sep 17 00:00:00 2001 From: Hongjiang Zhang Date: Thu, 21 May 2020 15:49:49 +0800 Subject: [PATCH 01/12] print decimal as long if scale is zero optimize numeric and decimal displaying add unit test case for print simple decimal close the cursor --- jaydebeapi/__init__.py | 21 +++++++++++++++++++-- test/data/create_simple_decimal.sql | 5 +++++ test/data/insert_simple_decimal.sql | 1 + test/test_integration.py | 13 +++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/data/create_simple_decimal.sql create mode 100644 test/data/insert_simple_decimal.sql diff --git a/jaydebeapi/__init__.py b/jaydebeapi/__init__.py index 7af7d59..484a1d1 100644 --- a/jaydebeapi/__init__.py +++ b/jaydebeapi/__init__.py @@ -663,12 +663,29 @@ def _java_to_py(java_method): return getattr(java_val, java_method)() return to_py +def _java_to_py_bigdecimal(java_method): + def to_py(rs, col): + java_val = rs.getObject(col) + if java_val is None: + return + if hasattr(java_val, 'scale'): + scale = getattr(java_val, 'scale')() + if scale == 0: + return getattr(java_val, 'longValue')() + else: + return getattr(java_val, java_method)() + else: + return getattr(java_val, java_method)() + return to_py + _to_double = _java_to_py('doubleValue') _to_int = _java_to_py('intValue') _to_boolean = _java_to_py('booleanValue') +_to_decimal = _java_to_py_bigdecimal('doubleValue') + def _init_types(types_map): global _jdbc_name_to_const _jdbc_name_to_const = types_map @@ -698,8 +715,8 @@ _DEFAULT_CONVERTERS = { 'TIME': _to_time, 'DATE': _to_date, 'BINARY': _to_binary, - 'DECIMAL': _to_double, - 'NUMERIC': _to_double, + 'DECIMAL': _to_decimal, + 'NUMERIC': _to_decimal, 'DOUBLE': _to_double, 'FLOAT': _to_double, 'TINYINT': _to_int, diff --git a/test/data/create_simple_decimal.sql b/test/data/create_simple_decimal.sql new file mode 100644 index 0000000..7f47130 --- /dev/null +++ b/test/data/create_simple_decimal.sql @@ -0,0 +1,5 @@ +create table customer ( +"CUST_ID" INTEGER not null, +"USER_ID" DECIMAL(18,0) not null, +primary key ("CUST_ID") +); diff --git a/test/data/insert_simple_decimal.sql b/test/data/insert_simple_decimal.sql new file mode 100644 index 0000000..c3cd478 --- /dev/null +++ b/test/data/insert_simple_decimal.sql @@ -0,0 +1 @@ +insert into CUSTOMER (CUST_ID, USER_ID) values (1, 12345); diff --git a/test/test_integration.py b/test/test_integration.py index c317ce5..ccb3193 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -70,6 +70,7 @@ class IntegrationTestBase(object): def tearDown(self): cursor = self.conn.cursor() cursor.execute("drop table ACCOUNT"); + cursor.execute("drop table CUSTOMER"); self.conn.close() def test_execute_and_fetch_no_data(self): @@ -207,11 +208,21 @@ class IntegrationTestBase(object): cursor.execute("select * from ACCOUNT") self.assertEqual(cursor.rowcount, -1) + def test_simple_decimal_print(self): + cursor = self.conn.cursor() + cursor.execute("select * from CUSTOMER") + result = cursor.fetchall() + cursor.close() + exp = [(1, 12345)] + self.assertEqual(result, exp) + class SqliteTestBase(IntegrationTestBase): def setUpSql(self): self.sql_file(os.path.join(_THIS_DIR, 'data', 'create.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql')) + self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_simple_decimal.sql')) + self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert_simple_decimal.sql')) def test_execute_type_blob(self): cursor = self.conn.cursor() @@ -275,6 +286,8 @@ class HsqldbTest(IntegrationTestBase, unittest.TestCase): def setUpSql(self): self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_hsqldb.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql')) + self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_simple_decimal.sql')) + self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert_simple_decimal.sql')) class PropertiesDriverArgsPassingTest(unittest.TestCase): From abea135fb8bc1c825d76baf3bca6c5ed85c00abc Mon Sep 17 00:00:00 2001 From: Hongjiang Zhang Date: Sun, 31 May 2020 06:13:21 +0800 Subject: [PATCH 02/12] merge baztian's commit --- test/test_integration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index ccb3193..f39f018 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -213,8 +213,8 @@ class IntegrationTestBase(object): cursor.execute("select * from CUSTOMER") result = cursor.fetchall() cursor.close() - exp = [(1, 12345)] - self.assertEqual(result, exp) + exp = "[(1, 12345)]" + self.assertEqual(str(result), exp) class SqliteTestBase(IntegrationTestBase): From b921a6d48063c8880f00adcd3b13d0cd175bda90 Mon Sep 17 00:00:00 2001 From: Hongjiang Zhang Date: Mon, 1 Jun 2020 11:40:54 +0800 Subject: [PATCH 03/12] assert each element instead of compare string value Long value sometimes has 'L' postfix which breaks string compare --- test/test_integration.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/test_integration.py b/test/test_integration.py index f39f018..7def4a6 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -213,8 +213,11 @@ class IntegrationTestBase(object): cursor.execute("select * from CUSTOMER") result = cursor.fetchall() cursor.close() - exp = "[(1, 12345)]" - self.assertEqual(str(result), exp) + # exp = "[(1, 12345)]" + self.assertEqual(1, len(result)) + self.assertEqual(2, len(result[0])) + self.assertEqual(result[0][0], 1) + self.assertEqual(result[0][1], 12345) class SqliteTestBase(IntegrationTestBase): From b662b14e0156593acadba431445c37eb9a359b08 Mon Sep 17 00:00:00 2001 From: Hongjiang Zhang Date: Tue, 2 Jun 2020 07:46:36 +0800 Subject: [PATCH 04/12] add mock testcase --- .../jaydebeapi/mockdriver/MockConnection.java | 18 ++++++++++++++++++ test/test_mock.py | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java index 6c959fd..bf7f5f3 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -1,6 +1,7 @@ package org.jaydebeapi.mockdriver; import java.lang.reflect.Field; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -59,6 +60,23 @@ public abstract class MockConnection implements Connection { Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); } + public final void mockSimpleDecimalResult(int value) throws SQLException { + PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); + Mockito.when(mockPreparedStatement.execute()).thenReturn(true); + mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for simple decimal)"); + Mockito.when(mockPreparedStatement.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); + + BigDecimal bd = new BigDecimal(Integer.toString(value)); + Mockito.when(mockResultSet.getObject(1)).thenReturn(bd); + Mockito.when(mockResultSet.getBigDecimal(1)).thenReturn(bd); + Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); + Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); + } + public final void mockDateResult(int year, int month, int day) throws SQLException { PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); Mockito.when(mockPreparedStatement.execute()).thenReturn(true); diff --git a/test/test_mock.py b/test/test_mock.py index 2d44952..d6fe171 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -57,6 +57,13 @@ class MockTest(unittest.TestCase): result = cursor.fetchone() self.assertEquals(result[0], "1899-12-31") + def test_simple_decimal(self): + self.conn.jconn.mockSimpleDecimalResult(12345) + cursor = self.conn.cursor() + cursor.execute("dummy stmt") + result = cursor.fetchone() + self.assertEquals(result[0], 12345) + def test_sql_exception_on_execute(self): self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected") cursor = self.conn.cursor() From beb116875b67d010e18e013b8f8fec7e30e285d1 Mon Sep 17 00:00:00 2001 From: baztian Date: Tue, 2 Jun 2020 14:43:00 +0200 Subject: [PATCH 05/12] Make test actually fail on for unfixed behaviour --- test/test_mock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_mock.py b/test/test_mock.py index d6fe171..5175c69 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -62,7 +62,7 @@ class MockTest(unittest.TestCase): cursor = self.conn.cursor() cursor.execute("dummy stmt") result = cursor.fetchone() - self.assertEquals(result[0], 12345) + self.assertEquals(str(result[0]), "12345") def test_sql_exception_on_execute(self): self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected") From fc90daddc3041e936230112b0ab1f1b2a93050d0 Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 20:49:43 +0200 Subject: [PATCH 06/12] Simplified mock code --- .../main/java/org/jaydebeapi/mockdriver/MockConnection.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java index bf7f5f3..86baa83 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -70,9 +70,8 @@ public abstract class MockConnection implements Connection { Mockito.when(mockResultSet.getMetaData()).thenReturn(mockMetaData); Mockito.when(mockMetaData.getColumnCount()).thenReturn(1); - BigDecimal bd = new BigDecimal(Integer.toString(value)); + BigDecimal bd = BigDecimal.valueOf(value); Mockito.when(mockResultSet.getObject(1)).thenReturn(bd); - Mockito.when(mockResultSet.getBigDecimal(1)).thenReturn(bd); Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); } From 5f3da6b096fd67d39b054b0b48011b7883da7bc4 Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 21:15:21 +0200 Subject: [PATCH 07/12] Add test for scaled decimal --- .../org/jaydebeapi/mockdriver/MockConnection.java | 6 +++--- test/test_mock.py | 11 +++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java index 86baa83..54893a5 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -60,17 +60,17 @@ public abstract class MockConnection implements Connection { Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); } - public final void mockSimpleDecimalResult(int value) throws SQLException { + public final void mockBigDecimalResult(long value, int scale) throws SQLException { PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); Mockito.when(mockPreparedStatement.execute()).thenReturn(true); - mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for simple decimal)"); + mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for BigDecimal)"); Mockito.when(mockPreparedStatement.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); - BigDecimal bd = BigDecimal.valueOf(value); + BigDecimal bd = BigDecimal.valueOf(value, scale); Mockito.when(mockResultSet.getObject(1)).thenReturn(bd); Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); diff --git a/test/test_mock.py b/test/test_mock.py index 5175c69..8631713 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -57,13 +57,20 @@ class MockTest(unittest.TestCase): result = cursor.fetchone() self.assertEquals(result[0], "1899-12-31") - def test_simple_decimal(self): - self.conn.jconn.mockSimpleDecimalResult(12345) + def test_decimal_scale_zero(self): + self.conn.jconn.mockBigDecimalResult(12345, 0) cursor = self.conn.cursor() cursor.execute("dummy stmt") result = cursor.fetchone() self.assertEquals(str(result[0]), "12345") + def test_decimal_places(self): + self.conn.jconn.mockBigDecimalResult(12345, 2) + cursor = self.conn.cursor() + cursor.execute("dummy stmt") + result = cursor.fetchone() + self.assertEquals(str(result[0]), "123.45") + def test_sql_exception_on_execute(self): self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected") cursor = self.conn.cursor() From 3a4edca97b3650bcff5d206592bd7e52e60fc07c Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 21:27:46 +0200 Subject: [PATCH 08/12] Also test non BigDecimal decimal types --- .../jaydebeapi/mockdriver/MockConnection.java | 20 +++++++++++++++++-- test/test_mock.py | 11 ++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java index 54893a5..8f9c0fd 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -70,8 +70,24 @@ public abstract class MockConnection implements Connection { Mockito.when(mockResultSet.getMetaData()).thenReturn(mockMetaData); Mockito.when(mockMetaData.getColumnCount()).thenReturn(1); - BigDecimal bd = BigDecimal.valueOf(value, scale); - Mockito.when(mockResultSet.getObject(1)).thenReturn(bd); + BigDecimal columnValue = BigDecimal.valueOf(value, scale); + Mockito.when(mockResultSet.getObject(1)).thenReturn(columnValue); + Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); + Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); + } + + public final void mockFloatDecimalResult(float value) throws SQLException { + PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); + Mockito.when(mockPreparedStatement.execute()).thenReturn(true); + mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for other)"); + Mockito.when(mockPreparedStatement.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); + + Float columnValue = Float.valueOf(value); + Mockito.when(mockResultSet.getObject(1)).thenReturn(value); Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); } diff --git a/test/test_mock.py b/test/test_mock.py index 8631713..766561c 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -65,11 +65,18 @@ class MockTest(unittest.TestCase): self.assertEquals(str(result[0]), "12345") def test_decimal_places(self): - self.conn.jconn.mockBigDecimalResult(12345, 2) + self.conn.jconn.mockBigDecimalResult(12345, 1) cursor = self.conn.cursor() cursor.execute("dummy stmt") result = cursor.fetchone() - self.assertEquals(str(result[0]), "123.45") + self.assertEquals(str(result[0]), "1234.5") + + def test_float_decimal(self): + self.conn.jconn.mockFloatDecimalResult(1234.5) + cursor = self.conn.cursor() + cursor.execute("dummy stmt") + result = cursor.fetchone() + self.assertEquals(str(result[0]), "1234.5") def test_sql_exception_on_execute(self): self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected") From 6e53d9f707b1122b0104416e808fc91e87f554e8 Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 21:32:35 +0200 Subject: [PATCH 09/12] Remove unnecessary integration test --- test/data/create_simple_decimal.sql | 5 ----- test/data/insert_simple_decimal.sql | 1 - test/test_integration.py | 16 ---------------- 3 files changed, 22 deletions(-) delete mode 100644 test/data/create_simple_decimal.sql delete mode 100644 test/data/insert_simple_decimal.sql diff --git a/test/data/create_simple_decimal.sql b/test/data/create_simple_decimal.sql deleted file mode 100644 index 7f47130..0000000 --- a/test/data/create_simple_decimal.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table customer ( -"CUST_ID" INTEGER not null, -"USER_ID" DECIMAL(18,0) not null, -primary key ("CUST_ID") -); diff --git a/test/data/insert_simple_decimal.sql b/test/data/insert_simple_decimal.sql deleted file mode 100644 index c3cd478..0000000 --- a/test/data/insert_simple_decimal.sql +++ /dev/null @@ -1 +0,0 @@ -insert into CUSTOMER (CUST_ID, USER_ID) values (1, 12345); diff --git a/test/test_integration.py b/test/test_integration.py index 7def4a6..c317ce5 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -70,7 +70,6 @@ class IntegrationTestBase(object): def tearDown(self): cursor = self.conn.cursor() cursor.execute("drop table ACCOUNT"); - cursor.execute("drop table CUSTOMER"); self.conn.close() def test_execute_and_fetch_no_data(self): @@ -208,24 +207,11 @@ class IntegrationTestBase(object): cursor.execute("select * from ACCOUNT") self.assertEqual(cursor.rowcount, -1) - def test_simple_decimal_print(self): - cursor = self.conn.cursor() - cursor.execute("select * from CUSTOMER") - result = cursor.fetchall() - cursor.close() - # exp = "[(1, 12345)]" - self.assertEqual(1, len(result)) - self.assertEqual(2, len(result[0])) - self.assertEqual(result[0][0], 1) - self.assertEqual(result[0][1], 12345) - class SqliteTestBase(IntegrationTestBase): def setUpSql(self): self.sql_file(os.path.join(_THIS_DIR, 'data', 'create.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql')) - self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_simple_decimal.sql')) - self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert_simple_decimal.sql')) def test_execute_type_blob(self): cursor = self.conn.cursor() @@ -289,8 +275,6 @@ class HsqldbTest(IntegrationTestBase, unittest.TestCase): def setUpSql(self): self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_hsqldb.sql')) self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert.sql')) - self.sql_file(os.path.join(_THIS_DIR, 'data', 'create_simple_decimal.sql')) - self.sql_file(os.path.join(_THIS_DIR, 'data', 'insert_simple_decimal.sql')) class PropertiesDriverArgsPassingTest(unittest.TestCase): From d8b96c510e518fb337e111669321c8ed5ad91eed Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 21:36:03 +0200 Subject: [PATCH 10/12] Add changelog entry --- README.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index bba9372..c72e0e3 100644 --- a/README.rst +++ b/README.rst @@ -160,10 +160,14 @@ Changelog ========= - Next version - unreleased + + - Return (big) decimal types as long value if scale is zero (thanks + to @ministat) + - 1.2.1 - 2020-05-27 - Increased thread safety. Should resolve some of the - `No suitable driver found` errors. (thanks to @thealmightygrant) + `No suitable driver found` errors (thanks to @thealmightygrant) - 1.2.0 - 2020-05-22 From 78791871b0d75893c9da06adaa4c00ef7c0c84a8 Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 21:48:04 +0200 Subject: [PATCH 11/12] Change float test to double to resolve issues with Jython --- .../main/java/org/jaydebeapi/mockdriver/MockConnection.java | 4 ++-- test/test_mock.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java index 8f9c0fd..7d8b3c2 100644 --- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java +++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java @@ -76,7 +76,7 @@ public abstract class MockConnection implements Connection { Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); } - public final void mockFloatDecimalResult(float value) throws SQLException { + public final void mockDoubleDecimalResult(double value) throws SQLException { PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class); Mockito.when(mockPreparedStatement.execute()).thenReturn(true); mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for other)"); @@ -86,7 +86,7 @@ public abstract class MockConnection implements Connection { Mockito.when(mockResultSet.getMetaData()).thenReturn(mockMetaData); Mockito.when(mockMetaData.getColumnCount()).thenReturn(1); - Float columnValue = Float.valueOf(value); + Double columnValue = Double.valueOf(value); Mockito.when(mockResultSet.getObject(1)).thenReturn(value); Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DECIMAL); Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement); diff --git a/test/test_mock.py b/test/test_mock.py index 766561c..61f15de 100644 --- a/test/test_mock.py +++ b/test/test_mock.py @@ -71,8 +71,8 @@ class MockTest(unittest.TestCase): result = cursor.fetchone() self.assertEquals(str(result[0]), "1234.5") - def test_float_decimal(self): - self.conn.jconn.mockFloatDecimalResult(1234.5) + def test_double_decimal(self): + self.conn.jconn.mockDoubleDecimalResult(1234.5) cursor = self.conn.cursor() cursor.execute("dummy stmt") result = cursor.fetchone() From 694197128a6610d0da46b1653126cedc56c02f83 Mon Sep 17 00:00:00 2001 From: baztian Date: Wed, 3 Jun 2020 22:17:55 +0200 Subject: [PATCH 12/12] Fix decimal type conversion for Jython --- README.rst | 1 + jaydebeapi/__init__.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index c72e0e3..2132b34 100644 --- a/README.rst +++ b/README.rst @@ -163,6 +163,7 @@ Changelog - Return (big) decimal types as long value if scale is zero (thanks to @ministat) + - Fix `DECIMAL` and `NUMERIC` type conversion for Jython - 1.2.1 - 2020-05-27 diff --git a/jaydebeapi/__init__.py b/jaydebeapi/__init__.py index 484a1d1..b66c444 100644 --- a/jaydebeapi/__init__.py +++ b/jaydebeapi/__init__.py @@ -663,19 +663,19 @@ def _java_to_py(java_method): return getattr(java_val, java_method)() return to_py -def _java_to_py_bigdecimal(java_method): +def _java_to_py_bigdecimal(): def to_py(rs, col): java_val = rs.getObject(col) if java_val is None: return if hasattr(java_val, 'scale'): - scale = getattr(java_val, 'scale')() + scale = java_val.scale() if scale == 0: - return getattr(java_val, 'longValue')() + return java_val.longValue() else: - return getattr(java_val, java_method)() + return java_val.doubleValue() else: - return getattr(java_val, java_method)() + return float(java_val) return to_py _to_double = _java_to_py('doubleValue') @@ -684,7 +684,7 @@ _to_int = _java_to_py('intValue') _to_boolean = _java_to_py('booleanValue') -_to_decimal = _java_to_py_bigdecimal('doubleValue') +_to_decimal = _java_to_py_bigdecimal() def _init_types(types_map): global _jdbc_name_to_const