cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r634260 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/access/ main/java/org/apache/cayenne/access/jdbc/ main/java/org/apache/cayenne/access/util/ test/java/org/apache/cayenne/access/ test/re...
Date Thu, 06 Mar 2008 13:13:50 GMT
Author: aadamchik
Date: Thu Mar  6 05:13:41 2008
New Revision: 634260

URL: http://svn.apache.org/viewvc?rev=634260&view=rev
Log:
CAY-999 Scaling paginated list
(optimized single id lists)

Added:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/SimpleIdIncrementalFaultList.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListDataRowsTest.java
      - copied, changed from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListDataRowsTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListPrefetchTest.java
      - copied, changed from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListPrefetchTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
      - copied, changed from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.SimpleIdIncrementalFaultListDataRowsTest.xml
      - copied unchanged from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.IncrementalFaultListDataRowsTest.xml
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.SimpleIdIncrementalFaultListTest.xml
      - copied unchanged from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.IncrementalFaultListTest.xml
Removed:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListDataRowsTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListPrefetchTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.IncrementalFaultListDataRowsTest.xml
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/dml/access.IncrementalFaultListTest.xml
Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ResultIterator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/TransactionResultIteratorDecorator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/DistinctResultIterator.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataContextQueryAction.java
Thu Mar  6 05:13:41 2008
@@ -21,12 +21,14 @@
 
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.PersistenceState;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.cache.QueryCache;
+import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.query.ObjectIdQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.RefreshQuery;
@@ -86,9 +88,16 @@
     @Override
     protected boolean interceptPaginatedQuery() {
         if (metadata.getPageSize() > 0) {
-            response = new ListResponse(new IncrementalFaultList(
-                    (DataContext) actingContext,
-                    query));
+
+            DbEntity dbEntity = metadata.getDbEntity();
+            List<?> paginatedList = dbEntity != null
+                    && dbEntity.getPrimaryKeys().size() == 1
+                    ? new SimpleIdIncrementalFaultList<Object>(
+                            (DataContext) actingContext,
+                            query)
+                    : new IncrementalFaultList<Object>((DataContext) actingContext,
query);
+
+            response = new ListResponse(paginatedList);
             return DONE;
         }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/IncrementalFaultList.java
Thu Mar  6 05:13:41 2008
@@ -133,12 +133,7 @@
         this.internalQuery.setResolvingInherited(metadata.isResolvingInherited());
         this.internalQuery.setPrefetchTree(metadata.getPrefetchTree());
 
-        if (metadata.isFetchingDataRows()) {
-            helper = new DataRowListHelper();
-        }
-        else {
-            helper = new PersistentListHelper();
-        }
+        this.helper = createHelper(metadata);
 
         boolean resolvesFirstPage = true;
 
@@ -170,6 +165,18 @@
     }
 
     /**
+     * @since 3.0
+     */
+    IncrementalListHelper createHelper(QueryMetadata metadata) {
+        if (metadata.isFetchingDataRows()) {
+            return new DataRowListHelper();
+        }
+        else {
+            return new PersistentListHelper();
+        }
+    }
+
+    /**
      * @since 1.2
      */
     SelectQuery getInternalQuery() {
@@ -227,7 +234,7 @@
                 // continue reading ids
                 DbEntity entity = rootEntity.getDbEntity();
                 while (it.hasNextRow()) {
-                    elementsList.add(it.nextObjectId(entity));
+                    elementsList.add(it.nextId(entity));
                 }
 
                 QueryLogger.logSelectCount(elementsList.size(), System
@@ -268,27 +275,6 @@
     }
 
     /**
-     * @param object
-     * @return <code>true</code> if the object corresponds to an unresolved state
and
-     *         doesn require a fetch before being returned to the user.
-     */
-    private boolean isUnresolved(Object object) {
-        if (object instanceof Persistent) {
-            return false;
-        }
-
-        if (internalQuery.isFetchingDataRows()) {
-            // both unresolved and resolved objects are represented
-            // as Maps, so no instanceof check is possible.
-            Map<?, ?> map = (Map<?, ?>) object;
-            int size = map.size();
-            return size < rowWidth;
-        }
-
-        return true;
-    }
-
-    /**
      * Checks that an object is of the same type as the rest of objects (DataObject or
      * DataRows depending on the query type).
      */
@@ -337,16 +323,10 @@
             List<Expression> quals = new ArrayList<Expression>(pageSize);
             List<Object> ids = new ArrayList<Object>(pageSize);
             for (int i = fromIndex; i < toIndex; i++) {
-                Object obj = elements.get(i);
-                if (isUnresolved(obj)) {
-                    ids.add(obj);
-
-                    Map<String, ?> map = (Map<String, ?>) obj;
-                    if (map.isEmpty()) {
-                        throw new CayenneRuntimeException("Empty id map at index " + i);
-                    }
-
-                    quals.add(ExpressionFactory.matchAllDbExp(map, Expression.EQUAL_TO));
+                Object object = elements.get(i);
+                if (helper.incorrectObjectType(object)) {
+                    quals.add(buildIdQualifier(object));
+                    ids.add(object);
                 }
             }
 
@@ -376,49 +356,7 @@
             }
 
             // sanity check - database data may have changed
-            if (objects.size() < ids.size()) {
-                // find missing ids
-                StringBuilder buf = new StringBuilder();
-                buf.append("Some ObjectIds are missing from the database. ");
-                buf.append("Expected ").append(ids.size()).append(", fetched ").append(
-                        objects.size());
-
-                Iterator<Object> idsIt = ids.iterator();
-                boolean first = true;
-                while (idsIt.hasNext()) {
-                    boolean found = false;
-                    Object id = idsIt.next();
-                    Iterator oIt = objects.iterator();
-                    while (oIt.hasNext()) {
-                        if (((Persistent) oIt.next())
-                                .getObjectId()
-                                .getIdSnapshot()
-                                .equals(id)) {
-                            found = true;
-                            break;
-                        }
-                    }
-
-                    if (!found) {
-                        if (first) {
-                            first = false;
-                        }
-                        else {
-                            buf.append(", ");
-                        }
-
-                        buf.append(id.toString());
-                    }
-                }
-
-                throw new CayenneRuntimeException(buf.toString());
-            }
-            else if (objects.size() > ids.size()) {
-                throw new CayenneRuntimeException("Expected "
-                        + ids.size()
-                        + " objects, retrieved "
-                        + objects.size());
-            }
+            checkPageResultConsistency(objects, ids);
 
             // replace ids in the list with objects
             Iterator it = objects.iterator();
@@ -431,6 +369,67 @@
     }
 
     /**
+     * Returns a qualifier expression for an unresolved id object.
+     * 
+     * @since 3.0
+     */
+    Expression buildIdQualifier(Object id) {
+
+        Map<String, ?> map = (Map<String, ?>) id;
+        if (map.isEmpty()) {
+            throw new CayenneRuntimeException("Empty id map");
+        }
+
+        return ExpressionFactory.matchAllDbExp(map, Expression.EQUAL_TO);
+    }
+
+    /**
+     * @since 3.0
+     */
+    void checkPageResultConsistency(List<?> objects, List<?> ids) {
+
+        if (objects.size() < ids.size()) {
+            // find missing ids
+            StringBuilder buffer = new StringBuilder();
+            buffer.append("Some ObjectIds are missing from the database. ");
+            buffer.append("Expected ").append(ids.size()).append(", fetched ").append(
+                    objects.size());
+
+            boolean first = true;
+            for (Object id : ids) {
+                boolean found = false;
+
+                for (Object object : objects) {
+
+                    if (helper.replacesObject(object, id)) {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) {
+                    if (first) {
+                        first = false;
+                    }
+                    else {
+                        buffer.append(", ");
+                    }
+
+                    buffer.append(id.toString());
+                }
+            }
+
+            throw new CayenneRuntimeException(buffer.toString());
+        }
+        else if (objects.size() > ids.size()) {
+            throw new CayenneRuntimeException("Expected "
+                    + ids.size()
+                    + " objects, retrieved "
+                    + objects.size());
+        }
+    }
+
+    /**
      * Returns zero-based index of the virtual "page" for a given array element index.
      */
     public int pageIndex(int elementIndex) {
@@ -603,7 +602,7 @@
         synchronized (elements) {
             Object o = elements.get(index);
 
-            if (isUnresolved(o)) {
+            if (helper.incorrectObjectType(o)) {
                 // read this page
                 int pageStart = pageIndex(index) * pageSize;
                 resolveInterval(pageStart, pageStart + pageSize);

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ResultIterator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ResultIterator.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ResultIterator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ResultIterator.java
Thu Mar  6 05:13:41 2008
@@ -62,6 +62,16 @@
     Map<String, Object> nextObjectId(DbEntity entity) throws CayenneException;
 
     /**
+     * Reads and returns an id column or columns for the DbEntity. If an entity has a
+     * single column id, the return value is an Object matching the column type (e.g.
+     * java.lang.Long). If an entity has a compound PK, the return value is a DataRow
+     * (i.e. equivalent to {@link #nextObjectId(DbEntity)}).
+     * 
+     * @since 3.0
+     */
+    Object nextId(DbEntity entity) throws CayenneException;
+
+    /**
      * Skips current data row instead of reading it.
      */
     void skipDataRow() throws CayenneException;

Added: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/SimpleIdIncrementalFaultList.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/SimpleIdIncrementalFaultList.java?rev=634260&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/SimpleIdIncrementalFaultList.java
(added)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/SimpleIdIncrementalFaultList.java
Thu Mar  6 05:13:41 2008
@@ -0,0 +1,139 @@
+/*****************************************************************
+ *   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.access;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.cayenne.Persistent;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.query.Query;
+import org.apache.cayenne.query.QueryMetadata;
+
+/**
+ * A paginated list that implements a strategy for retrieval of entities with a single PK
+ * column. It is much more memory-efficient compared to the superclass.
+ * 
+ * @since 3.0
+ * @author Andrus Adamchik
+ */
+class SimpleIdIncrementalFaultList<E> extends IncrementalFaultList<E> {
+
+    protected DbAttribute pk;
+
+    SimpleIdIncrementalFaultList(DataContext dataContext, Query query) {
+        super(dataContext, query);
+
+        Collection<DbAttribute> pks = rootEntity.getDbEntity().getPrimaryKeys();
+        if (pks.size() != 1) {
+            throw new IllegalArgumentException(
+                    "Expected a single column primary key, instead got "
+                            + pks.size()
+                            + ". ObjEntity: "
+                            + rootEntity.getName());
+        }
+
+        pk = pks.iterator().next();
+    }
+
+    @Override
+    IncrementalFaultList<E>.IncrementalListHelper createHelper(QueryMetadata metadata)
{
+        if (metadata.isFetchingDataRows()) {
+            return new SingleIdDataRowListHelper();
+        }
+        else {
+            return new SingleIdPersistentListHelper();
+        }
+    }
+
+    @Override
+    protected Expression buildIdQualifier(Object id) {
+        return ExpressionFactory.matchDbExp(pk.getName(), id);
+    }
+
+    class SingleIdPersistentListHelper extends
+            IncrementalFaultList<E>.PersistentListHelper {
+
+        @Override
+        boolean objectsAreEqual(Object object, Object objectInTheList) {
+
+            if (objectInTheList instanceof Persistent) {
+                // due to object uniquing this should be sufficient
+                return object == objectInTheList;
+            }
+            else {
+                Persistent persistent = (Persistent) object;
+                Map<String, Object> idSnapshot = persistent.getObjectId().getIdSnapshot();
+
+                return idSnapshot.size() == 1
+                        && objectInTheList.equals(idSnapshot.get(pk.getName()));
+            }
+        }
+
+        @Override
+        boolean replacesObject(Object object, Object objectInTheList) {
+            if (objectInTheList instanceof Persistent) {
+                return false;
+            }
+
+            Persistent persistent = (Persistent) object;
+            Map<String, Object> idSnapshot = persistent.getObjectId().getIdSnapshot();
+
+            return idSnapshot.size() == 1
+                    && objectInTheList.equals(idSnapshot.get(pk.getName()));
+        }
+    }
+
+    class SingleIdDataRowListHelper extends IncrementalFaultList<E>.DataRowListHelper
{
+
+        @Override
+        boolean objectsAreEqual(Object object, Object objectInTheList) {
+
+            if (objectInTheList instanceof Map) {
+                return super.objectsAreEqual(object, objectInTheList);
+            }
+
+            if (object == null && objectInTheList == null) {
+                return true;
+            }
+
+            if (object != null && objectInTheList != null) {
+
+                Map<?, ?> map = (Map<?, ?>) object;
+
+                return objectInTheList.equals(map.get(pk.getName()));
+            }
+
+            return false;
+        }
+
+        @Override
+        boolean replacesObject(Object object, Object objectInTheList) {
+
+            if (objectInTheList instanceof Map) {
+                return false;
+            }
+
+            Map<?, ?> map = (Map<?, ?>) object;
+            return objectInTheList.equals(map.get(pk.getName()));
+        }
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/TransactionResultIteratorDecorator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/TransactionResultIteratorDecorator.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/TransactionResultIteratorDecorator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/TransactionResultIteratorDecorator.java
Thu Mar  6 05:13:41 2008
@@ -99,6 +99,13 @@
     public Map nextObjectId(DbEntity entity) throws CayenneException {
         return result.nextObjectId(entity);
     }
+    
+    /**
+     * @since 3.0
+     */
+    public Object nextId(DbEntity entity) throws CayenneException {
+        return result.nextId(entity);
+    }
 
     public void skipDataRow() throws CayenneException {
         result.skipDataRow();

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/jdbc/JDBCResultIterator.java
Thu Mar  6 05:13:41 2008
@@ -177,6 +177,29 @@
         return row;
     }
 
+    /**
+     * @since 3.0
+     */
+    public Object nextId(DbEntity entity) throws CayenneException {
+        if (!hasNextRow()) {
+            throw new CayenneException(
+                    "An attempt to read uninitialized row or past the end of the iterator.");
+        }
+
+        // index id
+        if (rootEntity != entity || pkIndices == null) {
+            this.rootEntity = entity;
+            indexPK();
+        }
+
+        Object id = readId();
+
+        // rewind
+        checkNextRow();
+
+        return id;
+    }
+
     public void skipDataRow() throws CayenneException {
         if (!hasNextRow()) {
             throw new CayenneException(
@@ -304,6 +327,41 @@
         }
         catch (Exception otherex) {
             throw new CayenneException("Exception materializing column.", Util
+                    .unwindException(otherex));
+        }
+    }
+
+    protected Object readId() throws CayenneException {
+
+        int len = pkIndices.length;
+
+        if (len != 1) {
+            return readIdRow();
+        }
+
+        ExtendedType[] converters = rowDescriptor.getConverters();
+
+        try {
+
+            // dereference column index
+            int index = pkIndices[0];
+
+            // note: jdbc column indexes start from 1, not 0 as in arrays
+            Object val = converters[index].materializeObject(
+                    resultSet,
+                    index + 1,
+                    types[index]);
+
+            // note that postProcessor overrides are not applied. ID mapping must be the
+            // same across inheritance hierarchy, so overrides do not make sense.
+            return val;
+        }
+        catch (CayenneException cex) {
+            // rethrow unmodified
+            throw cex;
+        }
+        catch (Exception otherex) {
+            throw new CayenneException("Exception materializing id column.", Util
                     .unwindException(otherex));
         }
     }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/DistinctResultIterator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/DistinctResultIterator.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/DistinctResultIterator.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/util/DistinctResultIterator.java
Thu Mar  6 05:13:41 2008
@@ -20,6 +20,7 @@
 package org.apache.cayenne.access.util;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -136,9 +137,9 @@
 
         // if we were previously reading full rows, we need to strip extra keys...
         if (!readingIds) {
-            Iterator<Map.Entry<String,Object>> it = row.entrySet().iterator();
+            Iterator<Map.Entry<String, Object>> it = row.entrySet().iterator();
             while (it.hasNext()) {
-                Map.Entry<String,Object> entry = it.next();
+                Map.Entry<String, Object> entry = it.next();
                 String name = entry.getKey();
                 DbAttribute attribute = (DbAttribute) entity.getAttribute(name);
                 if (attribute == null || !attribute.isPrimaryKey()) {
@@ -149,6 +150,29 @@
 
         checkNextId(entity);
         return row;
+    }
+
+    /**
+     * @since 3.0
+     */
+    public Object nextId(DbEntity entity) throws CayenneException {
+        Collection<DbAttribute> pk = entity.getPrimaryKeys();
+        if (pk.size() != 1) {
+            return nextObjectId(entity);
+        }
+
+        if (!hasNextRow()) {
+            throw new CayenneException(
+                    "An attempt to read uninitialized row or past the end of the iterator.");
+        }
+
+        Map<String, Object> row = nextDataRow;
+
+        checkNextId(entity);
+
+        // TODO: andrus 3/6/2008: not very efficient ... a better algorithm would've
+        // relied on wrapped iterator 'nextId' method.
+        return row.get(pk.iterator().next().getName());
     }
 
     public void skipDataRow() throws CayenneException {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java?rev=634260&r1=634259&r2=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextTest.java
Thu Mar  6 05:13:41 2008
@@ -314,8 +314,8 @@
         assertNotNull(objects);
         assertTrue(objects instanceof IncrementalFaultList);
 
-        assertTrue(((IncrementalFaultList) objects).elements.get(0) instanceof Map);
-        assertTrue(((IncrementalFaultList) objects).elements.get(7) instanceof Map);
+        assertTrue(((IncrementalFaultList<?>) objects).elements.get(0) instanceof Long);
+        assertTrue(((IncrementalFaultList<?>) objects).elements.get(7) instanceof Long);
         
         assertTrue(objects.get(0) instanceof Artist);
     }

Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListDataRowsTest.java
(from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListDataRowsTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListDataRowsTest.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListDataRowsTest.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListDataRowsTest.java&r1=632777&r2=634260&rev=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListDataRowsTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListDataRowsTest.java
Thu Mar  6 05:13:41 2008
@@ -36,8 +36,9 @@
  * 
  * @author Andrus Adamchik
  */
-public class IncrementalFaultListDataRowsTest extends CayenneCase {
-    protected IncrementalFaultList list;
+public class SimpleIdIncrementalFaultListDataRowsTest extends CayenneCase {
+
+    protected SimpleIdIncrementalFaultList list;
     protected Query query;
 
     @Override
@@ -53,7 +54,7 @@
         q.addOrdering("db:ARTIST_ID", Ordering.ASC);
 
         query = q;
-        list = new IncrementalFaultList(super.createDataContext(), query);
+        list = new SimpleIdIncrementalFaultList(super.createDataContext(), query);
     }
 
     public void testGet1() throws Exception {
@@ -61,8 +62,7 @@
         assertTrue(list.elements.get(0) instanceof Map);
         assertEquals(list.rowWidth, ((Map) list.elements.get(0)).size());
 
-        assertTrue(list.elements.get(19) instanceof Map);
-        assertEquals(1, ((Map) list.elements.get(19)).size());
+        assertTrue(list.elements.get(19) instanceof Long);
 
         Object a = list.get(19);
 
@@ -149,13 +149,14 @@
             Object obj = it.next();
             assertNotNull(obj);
             assertTrue(
-                "Unexpected object class: " + obj.getClass().getName(),
-                obj instanceof Map);
+                    "Unexpected object class: " + obj.getClass().getName(),
+                    obj instanceof Map);
             assertEquals(list.rowWidth, ((Map) obj).size());
 
             // iterator must be resolved page by page
-            int expectedResolved =
-                list.pageIndex(counter) * list.getPageSize() + list.getPageSize();
+            int expectedResolved = list.pageIndex(counter)
+                    * list.getPageSize()
+                    + list.getPageSize();
             if (expectedResolved > list.size()) {
                 expectedResolved = list.size();
             }
@@ -163,9 +164,7 @@
             assertEquals(list.size() - expectedResolved, list.getUnfetchedObjects());
 
             if (list.getUnfetchedObjects() >= list.getPageSize()) {
-                // must be map that only contains object id columns
-                assertTrue(list.elements.get(list.size() - 1) instanceof Map);
-                assertEquals(1, ((Map) list.elements.get(list.size() - 1)).size());
+                assertTrue(list.elements.get(list.size() - 1) instanceof Long);
             }
 
             counter++;

Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListPrefetchTest.java
(from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListPrefetchTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListPrefetchTest.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListPrefetchTest.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListPrefetchTest.java&r1=632777&r2=634260&rev=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListPrefetchTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListPrefetchTest.java
Thu Mar  6 05:13:41 2008
@@ -33,12 +33,21 @@
 /**
  * @author Andrus Adamchik
  */
-public class IncrementalFaultListPrefetchTest extends DataContextCase {
+public class SimpleIdIncrementalFaultListPrefetchTest extends DataContextCase {
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         createTestData("testPaintings");
+    }
+    
+    public void testListType() {
+        Expression e = ExpressionFactory.likeExp("artistName", "artist1%");
+        SelectQuery q = new SelectQuery("Artist", e);
+        q.setPageSize(4);
+
+        List<?> result = context.performQuery(q);
+        assertTrue(result instanceof SimpleIdIncrementalFaultList);
     }
 
     /**

Copied: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
(from r632777, cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java?p2=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java&p1=cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java&r1=632777&r2=634260&rev=634260&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/IncrementalFaultListTest.java
(original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/SimpleIdIncrementalFaultListTest.java
Thu Mar  6 05:13:41 2008
@@ -36,9 +36,9 @@
 /**
  * @author Andrus Adamchik
  */
-public class IncrementalFaultListTest extends CayenneCase {
+public class SimpleIdIncrementalFaultListTest extends CayenneCase {
 
-    protected IncrementalFaultList list;
+    protected SimpleIdIncrementalFaultList<?> list;
     protected Query query;
 
     protected void prepareList(int pageSize) throws Exception {
@@ -53,7 +53,7 @@
         q.setPageSize(pageSize);
         q.addOrdering("db:ARTIST_ID", Ordering.ASC);
         query = q;
-        list = new IncrementalFaultList(super.createDataContext(), query);
+        list = new SimpleIdIncrementalFaultList<Object>(createDataContext(), query);
     }
 
     public void testSize() throws Exception {
@@ -109,7 +109,9 @@
         q.setPageSize(6);
         q.addOrdering("db:ARTIST_ID", Ordering.DESC);
 
-        IncrementalFaultList list = new IncrementalFaultList(context, q);
+        SimpleIdIncrementalFaultList<?> list = new SimpleIdIncrementalFaultList<Object>(
+                context,
+                q);
 
         assertSame(newArtist, list.get(DataContextTest.artistCount));
     }
@@ -179,8 +181,8 @@
 
     public void testPagesRead1() throws Exception {
         prepareList(6);
-        assertTrue(list.elements.get(0) instanceof Map);
-        assertTrue(list.elements.get(8) instanceof Map);
+        assertTrue(list.elements.get(0) instanceof Long);
+        assertTrue(list.elements.get(8) instanceof Long);
 
         list.resolveInterval(5, 10);
         assertTrue(list.elements.get(7) instanceof Artist);
@@ -191,8 +193,8 @@
 
     public void testGet1() throws Exception {
         prepareList(6);
-        assertTrue(list.elements.get(0) instanceof Map);
-        assertTrue(list.elements.get(8) instanceof Map);
+        assertTrue(list.elements.get(0) instanceof Long);
+        assertTrue(list.elements.get(8) instanceof Long);
 
         Object a = list.get(8);
 
@@ -204,8 +206,8 @@
     public void testGet2() throws Exception {
         prepareList(6);
         ((SelectQuery) query).setFetchingDataRows(true);
-        assertTrue(list.elements.get(0) instanceof Map);
-        assertTrue(list.elements.get(8) instanceof Map);
+        assertTrue(list.elements.get(0) instanceof Long);
+        assertTrue(list.elements.get(8) instanceof Long);
 
         Object a0 = list.get(0);
 



Mime
View raw message