You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2006/05/08 02:31:40 UTC
svn commit: r404884 - in
/incubator/cayenne/main/trunk/cayenne/cayenne-java/src:
cayenne/java/org/objectstyle/cayenne/access/jdbc/
cayenne/java/org/objectstyle/cayenne/access/trans/
tests/java/org/objectstyle/cayenne/unit/jira/
Author: aadamchik
Date: Sun May 7 17:31:39 2006
New Revision: 404884
URL: http://svn.apache.org/viewcvs?rev=404884&view=rev
Log:
CAY-207. Had to introuce a new public method in SelectTranslator, but I guess this
does not really compromize our API freeze...
Added:
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/DataRowPostProcessor.java
Modified:
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/JDBCResultIterator.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/SelectAction.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/trans/SelectTranslator.java
incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/objectstyle/cayenne/unit/jira/CAY_207Tst.java
Added: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/DataRowPostProcessor.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/DataRowPostProcessor.java?rev=404884&view=auto
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/DataRowPostProcessor.java (added)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/DataRowPostProcessor.java Sun May 7 17:31:39 2006
@@ -0,0 +1,199 @@
+/* ====================================================================
+ *
+ * The ObjectStyle Group Software License, version 1.1
+ * ObjectStyle Group - http://objectstyle.org/
+ *
+ * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
+ * of the software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any,
+ * must include the following acknowlegement:
+ * "This product includes software developed by independent contributors
+ * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
+ * or promote products derived from this software without prior written
+ * permission. For written permission, email
+ * "andrus at objectstyle dot org".
+ *
+ * 5. Products derived from this software may not be called "ObjectStyle"
+ * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
+ * names without prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals and hosted on ObjectStyle Group web site. For more
+ * information on the ObjectStyle Group, please see
+ * <http://objectstyle.org/>.
+ */
+package org.objectstyle.cayenne.access.jdbc;
+
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.objectstyle.cayenne.DataRow;
+import org.objectstyle.cayenne.access.trans.SelectTranslator;
+import org.objectstyle.cayenne.access.types.ExtendedType;
+import org.objectstyle.cayenne.dba.TypesMapping;
+import org.objectstyle.cayenne.map.Entity;
+import org.objectstyle.cayenne.map.EntityInheritanceTree;
+import org.objectstyle.cayenne.map.ObjAttribute;
+import org.objectstyle.cayenne.map.ObjEntity;
+
+/**
+ * Deals with DataRow type conversion in inheritance situations.
+ *
+ * @since 1.2
+ * @author Andrus Adamchik
+ */
+class DataRowPostProcessor {
+
+ private EntityInheritanceTree inheritanceTree;
+ private Map columnOverrides;
+
+ // factory method
+ static DataRowPostProcessor createPostProcessor(SelectTranslator translator) {
+ Map attributeOverrides = translator.getAttributeOverrides();
+
+ if (attributeOverrides.isEmpty()) {
+ return null;
+ }
+
+ EntityInheritanceTree inheritanceTree = translator.getRootInheritanceTree();
+ if (inheritanceTree == null || inheritanceTree.getChildrenCount() == 0) {
+ return null;
+ }
+
+ ColumnDescriptor[] columns = translator.getResultColumns();
+
+ Map columnOverrides = new HashMap(2);
+
+ Iterator it = attributeOverrides.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+
+ ObjAttribute attribute = (ObjAttribute) entry.getKey();
+ Entity entity = attribute.getEntity();
+
+ String key = null;
+ int jdbcType = TypesMapping.NOT_DEFINED;
+ int index = -1;
+ for (int i = 0; i < columns.length; i++) {
+ if (columns[i] == entry.getValue()) {
+
+ // if attribute type is the same as column, there is no conflict
+ if (!attribute.getType().equals(columns[i].getJavaClass())) {
+ // note that JDBC index is "1" based
+ index = i + 1;
+ jdbcType = columns[i].getJdbcType();
+ key = columns[i].getLabel();
+ }
+
+ break;
+ }
+ }
+
+ if (index < 1) {
+ continue;
+ }
+
+ ExtendedType converter = translator
+ .getAdapter()
+ .getExtendedTypes()
+ .getRegisteredType(attribute.getJavaClass());
+
+ Collection overrides = null;
+
+ if (columnOverrides == null) {
+ columnOverrides = new HashMap(2);
+ }
+ else {
+ overrides = (Collection) columnOverrides.get(entity.getName());
+ }
+
+ if (overrides == null) {
+ overrides = new ArrayList(3);
+ columnOverrides.put(entity.getName(), overrides);
+ }
+
+ overrides.add(new ColumnOverride(index, key, converter, jdbcType));
+ }
+
+ return columnOverrides != null ? new DataRowPostProcessor(
+ inheritanceTree,
+ columnOverrides) : null;
+ }
+
+ private DataRowPostProcessor(EntityInheritanceTree inheritanceTree, Map columnOverides) {
+
+ this.inheritanceTree = inheritanceTree;
+ this.columnOverrides = columnOverides;
+ }
+
+ void postprocessRow(ResultSet resultSet, DataRow row) throws Exception {
+
+ ObjEntity entity = inheritanceTree.entityMatchingRow(row);
+ if (entity != null) {
+ Collection overrides = (Collection) columnOverrides.get(entity.getName());
+
+ if (overrides != null) {
+ Iterator it = overrides.iterator();
+ while (it.hasNext()) {
+ ColumnOverride override = (ColumnOverride) it.next();
+
+ Object newValue = override.converter.materializeObject(
+ resultSet,
+ override.index,
+ override.jdbcType);
+ row.put(override.key, newValue);
+ }
+ }
+ }
+ }
+
+ static final class ColumnOverride {
+
+ int index;
+ int jdbcType;
+ String key;
+ ExtendedType converter;
+
+ ColumnOverride(int index, String key, ExtendedType converter, int jdbcType) {
+ this.index = index;
+ this.key = key;
+ this.converter = converter;
+ this.jdbcType = jdbcType;
+ }
+ }
+}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/JDBCResultIterator.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/JDBCResultIterator.java?rev=404884&r1=404883&r2=404884&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/JDBCResultIterator.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/JDBCResultIterator.java Sun May 7 17:31:39 2006
@@ -79,7 +79,7 @@
* A ResultIterator over the underlying JDBC ResultSet.
*
* @since 1.2
- * @author Andrei Adamchik
+ * @author Andrus Adamchik
*/
// Replaces DefaultResultIterator
public class JDBCResultIterator implements ResultIterator {
@@ -91,6 +91,8 @@
protected RowDescriptor rowDescriptor;
+ DataRowPostProcessor postProcessor;
+
// last indexed PK
protected DbEntity rootEntity;
protected int[] pkIndices;
@@ -294,7 +296,7 @@
*/
protected Map readDataRow() throws CayenneException {
try {
- Map dataRow = new DataRow(mapCapacity);
+ DataRow dataRow = new DataRow(mapCapacity);
ExtendedType[] converters = rowDescriptor.getConverters();
ColumnDescriptor[] columns = rowDescriptor.getColumns();
int resultWidth = rowDescriptor.getWidth();
@@ -306,6 +308,10 @@
.getJdbcType());
dataRow.put(columns[i].getLabel(), val);
}
+
+ if(postProcessor != null) {
+ postProcessor.postprocessRow(resultSet, dataRow);
+ }
return dataRow;
}
@@ -401,5 +407,9 @@
public RowDescriptor getRowDescriptor() {
return rowDescriptor;
+ }
+
+ void setPostProcessor(DataRowPostProcessor postProcessor) {
+ this.postProcessor = postProcessor;
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/SelectAction.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/SelectAction.java?rev=404884&r1=404883&r2=404884&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/SelectAction.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/jdbc/SelectAction.java Sun May 7 17:31:39 2006
@@ -117,6 +117,9 @@
descriptor,
query.getFetchLimit());
+ workerIterator.setPostProcessor(DataRowPostProcessor
+ .createPostProcessor(translator));
+
ResultIterator it = workerIterator;
// wrap result iterator if distinct has to be suppressed
@@ -128,7 +131,7 @@
QueryMetadata md = query.getMetaData(getEntityResolver());
final PrefetchTreeNode rootPrefetch = md.getPrefetchTree();
-
+
if (rootPrefetch != null) {
rootPrefetch.traverse(new PrefetchProcessor() {
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/trans/SelectTranslator.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/trans/SelectTranslator.java?rev=404884&r1=404883&r2=404884&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/trans/SelectTranslator.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/access/trans/SelectTranslator.java Sun May 7 17:31:39 2006
@@ -113,6 +113,7 @@
List resultColumns;
List groupByList;
+ Map attributeOverrides;
int aliasCounter;
@@ -320,6 +321,17 @@
}
/**
+ * Returns a map of ColumnDescriptors keyed by ObjAttribute for columns that may need
+ * to be reprocessed manually due to incompatible mappings along the inheritance
+ * hierarchy.
+ *
+ * @since 1.2
+ */
+ public Map getAttributeOverrides() {
+ return attributeOverrides != null ? attributeOverrides : Collections.EMPTY_MAP;
+ }
+
+ /**
* Returns true if SelectTranslator determined that a query requiring DISTINCT can't
* be run with DISTINCT keyword for internal reasons. If this method returns true,
* DataNode may need to do in-memory distinct filtering.
@@ -407,7 +419,21 @@
"ObjAttribute has no DbAttribute: " + oa.getName());
}
- appendColumn(columns, oa, dbAttr, attributes, null);
+ if (!appendColumn(columns, oa, dbAttr, attributes, null)) {
+
+ for (int i = 0; i < columns.size(); i++) {
+ ColumnDescriptor column = (ColumnDescriptor) columns.get(i);
+ if (dbAttr.getName().equals(column.getName())) {
+
+ if (attributeOverrides == null) {
+ attributeOverrides = new HashMap();
+ }
+
+ attributeOverrides.put(oa, column);
+ break;
+ }
+ }
+ }
}
}
}
@@ -500,7 +526,8 @@
// note that we my select a source attribute, but label it as
// target for simplified snapshot processing
- appendColumn(columns, null, attribute, attributes, labelPrefix + '.'
+ appendColumn(columns, null, attribute, attributes, labelPrefix
+ + '.'
+ j.getTargetName());
}
}
@@ -632,7 +659,7 @@
return columns;
}
- private void appendColumn(
+ private boolean appendColumn(
List columns,
ObjAttribute objAttribute,
DbAttribute attribute,
@@ -651,6 +678,10 @@
}
columns.add(column);
+ return true;
+ }
+ else {
+ return false;
}
}
Modified: incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/objectstyle/cayenne/unit/jira/CAY_207Tst.java
URL: http://svn.apache.org/viewcvs/incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/objectstyle/cayenne/unit/jira/CAY_207Tst.java?rev=404884&r1=404883&r2=404884&view=diff
==============================================================================
--- incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/objectstyle/cayenne/unit/jira/CAY_207Tst.java (original)
+++ incubator/cayenne/main/trunk/cayenne/cayenne-java/src/tests/java/org/objectstyle/cayenne/unit/jira/CAY_207Tst.java Sun May 7 17:31:39 2006
@@ -98,11 +98,10 @@
Object p1 = o1.readProperty("clientContactType");
assertNotNull(p1);
- // ***** The next assertion fails - uncomment to test
- //assertTrue(
- // "Invalid property class: " + p1.getClass().getName(),
- // p1 instanceof CAY_207String1);
-
+
+ assertTrue(
+ "Invalid property class: " + p1.getClass().getName(),
+ p1 instanceof CAY_207String1);
}
finally {
cleanup(context);
@@ -121,12 +120,9 @@
Object p2 = o2.readProperty("clientContactType");
assertNotNull(p2);
-
- // ***** The next assertion fails - uncomment to test
- // assertTrue(
- // "Invalid property class: " + p2.getClass().getName(),
- // p2 instanceof CAY_207String2);
-
+ assertTrue(
+ "Invalid property class: " + p2.getClass().getName(),
+ p2 instanceof CAY_207String2);
}
finally {
cleanup(context);