diff --git a/README.rst b/README.rst
index 28e9eb8..13ab23c 100644
--- a/README.rst
+++ b/README.rst
@@ -159,6 +159,9 @@ Changelog
=========
- Next version - unreleased
+
+ - Don't fail on dates before 1900 on Python < 3.
+
- 1.1.0 - 2017-03-19
- Support BIT and TINYINT type mappings (thanks @Mokubyow for
diff --git a/jaydebeapi/__init__.py b/jaydebeapi/__init__.py
index bb77016..4e1c597 100644
--- a/jaydebeapi/__init__.py
+++ b/jaydebeapi/__init__.py
@@ -595,8 +595,12 @@ def _to_date(rs, col):
java_val = rs.getDate(col)
if not java_val:
return
- d = datetime.datetime.strptime(str(java_val)[:10], "%Y-%m-%d")
- return d.strftime("%Y-%m-%d")
+ # The following code requires Python 3.3+ on dates before year 1900.
+ # d = datetime.datetime.strptime(str(java_val)[:10], "%Y-%m-%d")
+ # return d.strftime("%Y-%m-%d")
+ # Workaround / simpler soltution (see
+ # https://github.com/baztian/jaydebeapi/issues/18):
+ return str(java_val)[:10]
def _to_binary(rs, col):
java_val = rs.getObject(col)
diff --git a/mockdriver/pom.xml b/mockdriver/pom.xml
index 8a78498..e261790 100644
--- a/mockdriver/pom.xml
+++ b/mockdriver/pom.xml
@@ -7,6 +7,11 @@
1.0-SNAPSHOT
jar
+
+ 1.7
+ 1.7
+
+
org.mockito
diff --git a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
index 8ed0703..6c959fd 100644
--- a/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
+++ b/mockdriver/src/main/java/org/jaydebeapi/mockdriver/MockConnection.java
@@ -2,73 +2,98 @@ package org.jaydebeapi.mockdriver;
import java.lang.reflect.Field;
import java.sql.Connection;
+import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
+import java.util.Calendar;
import org.mockito.Mockito;
public abstract class MockConnection implements Connection {
- ResultSet mockResultSet;
+ ResultSet mockResultSet;
- public final void mockExceptionOnCommit(String className, String exceptionMessage) throws SQLException {
- Throwable exception = createException(className, exceptionMessage);
- Mockito.doThrow(exception).when(this).commit();
+ private static Throwable createException(String className, String exceptionMessage) {
+ try {
+ return (Throwable) Class.forName(className).getConstructor(String.class)
+ .newInstance(exceptionMessage);
+ } catch (Exception e) {
+ throw new RuntimeException("Couldn't initialize class " + className + ".", e);
}
+ }
- public final void mockExceptionOnRollback(String className, String exceptionMessage) throws SQLException {
- Throwable exception = createException(className, exceptionMessage);
- Mockito.doThrow(exception).when(this).rollback();
+ private static int extractTypeCodeForName(String sqlTypesName) {
+ try {
+ Field field = Types.class.getField(sqlTypesName);
+ return field.getInt(null);
+ } catch (NoSuchFieldException e) {
+ throw new IllegalArgumentException("Type " + sqlTypesName + " not found in Types class.", e);
+ } catch (SecurityException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
}
+ }
- public final void mockExceptionOnExecute(String className, String exceptionMessage) throws SQLException {
- PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
- Throwable exception = createException(className, exceptionMessage);
- Mockito.when(mockPreparedStatement.execute()).thenThrow(exception);
- Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
- }
+ public final void mockExceptionOnCommit(String className, String exceptionMessage)
+ throws SQLException {
+ Throwable exception = createException(className, exceptionMessage);
+ Mockito.doThrow(exception).when(this).commit();
+ }
- public final void mockType(String sqlTypesName) throws SQLException {
- PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
- Mockito.when(mockPreparedStatement.execute()).thenReturn(true);
- mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for type " + sqlTypesName + ")");
- 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);
- int sqlTypeCode = extractTypeCodeForName(sqlTypesName);
- Mockito.when(mockMetaData.getColumnType(1)).thenReturn(sqlTypeCode);
- Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
- }
+ public final void mockExceptionOnRollback(String className, String exceptionMessage)
+ throws SQLException {
+ Throwable exception = createException(className, exceptionMessage);
+ Mockito.doThrow(exception).when(this).rollback();
+ }
- public final ResultSet verifyResultSet() {
- return Mockito.verify(mockResultSet);
- }
+ public final void mockExceptionOnExecute(String className, String exceptionMessage)
+ throws SQLException {
+ PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
+ Throwable exception = createException(className, exceptionMessage);
+ Mockito.when(mockPreparedStatement.execute()).thenThrow(exception);
+ Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
+ }
- private static Throwable createException(String className, String exceptionMessage) {
- try {
- return (Throwable) Class.forName(className).getConstructor(String.class).newInstance(exceptionMessage);
- } catch (Exception e) {
- throw new RuntimeException("Couldn't initialize class " + className + ".", e);
- }
- }
+ public final void mockDateResult(int year, int month, int day) throws SQLException {
+ PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
+ Mockito.when(mockPreparedStatement.execute()).thenReturn(true);
+ mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for date)");
+ 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);
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.MONTH, month - 1);
+ cal.set(Calendar.DAY_OF_MONTH, day);
+ Date ancientDate = new Date(cal.getTime().getTime());
+ Mockito.when(mockResultSet.getDate(1)).thenReturn(ancientDate);
+ Mockito.when(mockMetaData.getColumnType(1)).thenReturn(Types.DATE);
+ Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
+ }
- private static int extractTypeCodeForName(String sqlTypesName) {
- try {
- Field field = Types.class.getField(sqlTypesName);
- return field.getInt(null);
- } catch (NoSuchFieldException e) {
- throw new IllegalArgumentException("Type " + sqlTypesName + " not found in Types class.", e);
- } catch (SecurityException e) {
- throw new RuntimeException(e);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
+ public final void mockType(String sqlTypesName) throws SQLException {
+ PreparedStatement mockPreparedStatement = Mockito.mock(PreparedStatement.class);
+ Mockito.when(mockPreparedStatement.execute()).thenReturn(true);
+ mockResultSet = Mockito.mock(ResultSet.class, "ResultSet(for type " + sqlTypesName + ")");
+ 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);
+ int sqlTypeCode = extractTypeCodeForName(sqlTypesName);
+ Mockito.when(mockMetaData.getColumnType(1)).thenReturn(sqlTypeCode);
+ Mockito.when(this.prepareStatement(Mockito.anyString())).thenReturn(mockPreparedStatement);
+ }
+ public final ResultSet verifyResultSet() {
+ return Mockito.verify(mockResultSet);
+ }
}
diff --git a/test/test_mock.py b/test/test_mock.py
index 6dcb702..09443a1 100644
--- a/test/test_mock.py
+++ b/test/test_mock.py
@@ -50,6 +50,13 @@ class MockTest(unittest.TestCase):
'getObject'))
verify_get(1)
+ def test_ancient_date_mapped(self):
+ self.conn.jconn.mockDateResult(1899, 12, 31)
+ cursor = self.conn.cursor()
+ cursor.execute("dummy stmt")
+ result = cursor.fetchone()
+ self.assertEquals(result[0], "1899-12-31")
+
def test_sql_exception_on_execute(self):
self.conn.jconn.mockExceptionOnExecute("java.sql.SQLException", "expected")
cursor = self.conn.cursor()