Author: evgeny
Date: Thu Dec 10 10:09:39 2009
New Revision: 889168
URL: http://svn.apache.org/viewvc?rev=889168&view=rev
Log:
CAY-1323 Changer type mapping from oracle.sql.TIMESTAMP to JDBC Timestamp in
Result of query on Oracle.
* changed UtillDateType behavior
* add new use pattern of ExtendedTypes
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleTimestampType.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/TimestampType.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleUtilDateType.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DateTimeTypesTest.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/TimestampType.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/TimestampType.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/TimestampType.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/TimestampType.java
Thu Dec 10 10:09:39 2009
@@ -32,13 +32,13 @@
return Timestamp.class.getName();
}
- public Object materializeObject(ResultSet rs, int index, int type) throws
Exception {
+ public Timestamp materializeObject(ResultSet rs, int index, int type)
throws Exception {
return rs.getTimestamp(index);
}
- public Object materializeObject(CallableStatement rs, int index, int type)
+ public Timestamp materializeObject(CallableStatement cs, int index, int
type)
throws Exception {
- return rs.getTimestamp(index);
+ return cs.getTimestamp(index);
}
public void setJdbcObject(
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/UtilDateType.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/UtilDateType.java
Thu Dec 10 10:09:39 2009
@@ -25,7 +25,6 @@
import java.sql.Types;
import java.util.Date;
-import org.apache.cayenne.CayenneRuntimeException;
import org.apache.cayenne.dba.TypesMapping;
/**
@@ -56,7 +55,7 @@
+ TypesMapping.getSqlNameByType(type));
}
- public Object materializeObject(ResultSet rs, int index, int type) throws
Exception {
+ public Date materializeObject(ResultSet rs, int index, int type) throws
Exception {
Date val = null;
switch (type) {
@@ -70,28 +69,17 @@
val = rs.getTime(index);
break;
default:
- // here the driver can "surprise" us
- // check the type of returned value...
- Object object = rs.getObject(index);
-
- if (object != null && !(object instanceof Date)) {
- throw new CayenneRuntimeException(
- "Expected an instance of java.util.Date, instead
got "
- + object.getClass().getName()
- + ", column index: "
- + index);
- }
-
- val = (Date) object;
+ val = rs.getTimestamp(index);
break;
}
+ // return java.util.Date instead of subclass
return val == null ? null : new Date(val.getTime());
}
- public Object materializeObject(CallableStatement cs, int index, int type)
+ public Date materializeObject(CallableStatement cs, int index, int type)
throws Exception {
- Object val = null;
+ Date val = null;
switch (type) {
case Types.TIMESTAMP:
@@ -104,24 +92,12 @@
val = cs.getTime(index);
break;
default:
- val = cs.getObject(index);
- // check if value was properly converted by the driver
- if (val != null && !(val instanceof java.util.Date)) {
- String typeName = TypesMapping.getSqlNameByType(type);
- throw new ClassCastException(
- "Expected a java.util.Date or subclass, instead
fetched '"
- + val.getClass().getName()
- + "' for JDBC type "
- + typeName);
- }
+ val = cs.getTimestamp(index);
break;
}
- // all sql time/date classes are subclasses of java.util.Date,
- // so lets cast it to Date,
- // if it is not date, ClassCastException will be thrown,
- // which is what we want
- return val == null ? null : new java.util.Date(((java.util.Date)
val).getTime());
+ // return java.util.Date instead of subclass
+ return val == null ? null : new Date(val.getTime());
}
public void setJdbcObject(
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleAdapter.java
Thu Dec 10 10:09:39 2009
@@ -183,6 +183,9 @@
// override date handler with Oracle handler
map.registerType(new OracleUtilDateType());
+ // add Oracle specific oracle.sql.TIMESTAMP handler
+ map.registerType(new OracleTimestampType());
+
// At least on MacOS X, driver does not handle Short and Byte properly
map.registerType(new ShortType(true));
map.registerType(new ByteType(true));
Added:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleTimestampType.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleTimestampType.java?rev=889168&view=auto
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleTimestampType.java
(added)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleTimestampType.java
Thu Dec 10 10:09:39 2009
@@ -0,0 +1,35 @@
+/*****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ****************************************************************/
+package org.apache.cayenne.dba.oracle;
+
+import org.apache.cayenne.access.types.TimestampType;
+
+
+/**
+ * This is handler for Oracle specific type "oracle.sql.TIMESTAMP"
+ * Oracle official JDBC Driver is mapping SQL TIMESTAMP to this type
+ * Created to solve CAY-1323.
+ */
+public class OracleTimestampType extends TimestampType {
+
+ @Override
+ public String getClassName() {
+ return "oracle.sql.TIMESTAMP";
+ }
+}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleUtilDateType.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleUtilDateType.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleUtilDateType.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/oracle/OracleUtilDateType.java
Thu Dec 10 10:09:39 2009
@@ -32,26 +32,26 @@
public class OracleUtilDateType extends UtilDateType {
@Override
- public Object materializeObject(CallableStatement cs, int index, int type)
+ public Date materializeObject(CallableStatement cs, int index, int type)
throws Exception {
- Object date = super.materializeObject(cs, index, type);
+ Date date = super.materializeObject(cs, index, type);
if (date == null || type != Types.TIME) {
return date;
} else {
- return normalizeDate((Date) date);
+ return normalizeDate(date);
}
}
@Override
- public Object materializeObject(ResultSet rs, int index, int type)
+ public Date materializeObject(ResultSet rs, int index, int type)
throws Exception {
- Object date = super.materializeObject(rs, index, type);
+ Date date = super.materializeObject(rs, index, type);
if (date == null || type != Types.TIME) {
return date;
} else {
- return normalizeDate((Date) date);
+ return normalizeDate(date);
}
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/dba/sqlite/SQLiteDateType.java
Thu Dec 10 10:09:39 2009
@@ -50,7 +50,7 @@
}
@Override
- public Object materializeObject(ResultSet rs, int index, int type) throws
Exception {
+ public Date materializeObject(ResultSet rs, int index, int type) throws
Exception {
String string = rs.getString(index);
@@ -76,7 +76,7 @@
}
@Override
- public Object materializeObject(CallableStatement rs, int index, int type)
+ public Date materializeObject(CallableStatement rs, int index, int type)
throws Exception {
String string = rs.getString(index);
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DateTimeTypesTest.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DateTimeTypesTest.java?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DateTimeTypesTest.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DateTimeTypesTest.java
Thu Dec 10 10:09:39 2009
@@ -19,17 +19,20 @@
package org.apache.cayenne.access;
+import java.sql.Time;
+import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import org.apache.art.CalendarEntity;
import org.apache.art.DateTestEntity;
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.query.NamedQuery;
import org.apache.cayenne.query.SelectQuery;
import org.apache.cayenne.unit.CayenneCase;
/**
* Tests Date handling in Cayenne.
- *
*/
public class DateTimeTypesTest extends CayenneCase {
@@ -77,6 +80,7 @@
DateTestEntity testRead = (DateTestEntity)
context.performQuery(q).get(0);
assertNotNull(testRead.getDateColumn());
assertEquals(nowDate, testRead.getDateColumn());
+ assertEquals(Date.class, testRead.getDateColumn().getClass());
}
public void testTime() throws Exception {
@@ -92,6 +96,7 @@
SelectQuery q = new SelectQuery(DateTestEntity.class);
DateTestEntity testRead = (DateTestEntity)
context.performQuery(q).get(0);
assertNotNull(testRead.getTimeColumn());
+ assertEquals(Date.class, testRead.getTimeColumn().getClass());
// OpenBase fails to store seconds for the time
// FrontBase returns time with 1 hour offset (I guess "TIME WITH
TIMEZONE" may
@@ -121,4 +126,70 @@
assertNotNull(testRead.getTimestampColumn());
assertEquals(now, testRead.getTimestampColumn());
}
+
+ public void testSQLTemplateTimestamp() throws Exception {
+ DateTestEntity test = (DateTestEntity)
context.newObject("DateTestEntity");
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(2003, 1, 1, 1, 20, 30);
+
+ // most databases fail millisecond accuracy
+ // cal.set(Calendar.MILLISECOND, 55);
+
+ Date now = cal.getTime();
+ test.setTimestampColumn(now);
+ context.commitChanges();
+
+ NamedQuery q = new NamedQuery("SelectDateTest");
+ DataRow testRead = (DataRow) context.performQuery(q).get(0);
+ Object columnValue = testRead.get("TIMESTAMP_COLUMN");
+ assertNotNull(columnValue);
+ assertEquals(now, columnValue);
+ assertEquals(Timestamp.class, columnValue.getClass());
+ }
+
+ public void testSQLTemplateDate() throws Exception {
+ DateTestEntity test = (DateTestEntity)
context.newObject("DateTestEntity");
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(2003, 1, 1, 1, 20, 30);
+
+ // most databases fail millisecond accuracy
+ // cal.set(Calendar.MILLISECOND, 55);
+
+ java.sql.Date now = new java.sql.Date(cal.getTime().getTime());
+ test.setDateColumn(now);
+ context.commitChanges();
+
+ NamedQuery q = new NamedQuery("SelectDateTest");
+ DataRow testRead = (DataRow) context.performQuery(q).get(0);
+ Object columnValue = testRead.get("DATE_COLUMN");
+ assertNotNull(columnValue);
+ assertEquals(java.sql.Date.class, columnValue.getClass());
+ assertEquals(now.toString(), columnValue.toString());
+ }
+
+ public void testSQLTemplateTime() throws Exception {
+ DateTestEntity test = (DateTestEntity)
context.newObject("DateTestEntity");
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(2003, 1, 1, 1, 20, 30);
+
+ // most databases fail millisecond accuracy
+ // cal.set(Calendar.MILLISECOND, 55);
+
+ Time now = new Time(cal.getTime().getTime());
+ test.setTimeColumn(now);
+ context.commitChanges();
+
+ NamedQuery q = new NamedQuery("SelectDateTest");
+ DataRow testRead = (DataRow) context.performQuery(q).get(0);
+ Object columnValue = testRead.get("TIME_COLUMN");
+ assertNotNull(columnValue);
+ assertEquals(Time.class, columnValue.getClass());
+ assertEquals(now.toString(), columnValue.toString());
+ }
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml?rev=889168&r1=889167&r2=889168&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml
Thu Dec 10 10:09:39 2009
@@ -643,6 +643,10 @@
<property name="cayenne.SQLTemplate.columnNameCapitalization"
value="UPPER"/>
<sql><![CDATA[select * from ARTIST]]></sql>
</query>
+ <query name="SelectDateTest"
factory="org.apache.cayenne.map.SQLTemplateBuilder" root="data-map"
root-name="testmap">
+ <property name="cayenne.GenericSelectQuery.fetchingDataRows"
value="true"/>
+ <sql><![CDATA[SELECT * FROM DATE_TEST]]></sql>
+ </query>
<entity-listener class="org.apache.art.EntityListenerDataMap">
<post-add method-name="prePersistDataMap1"/>
<post-add method-name="prePersistDataMap2"/>