Return-Path: Delivered-To: apmail-cayenne-commits-archive@www.apache.org Received: (qmail 37656 invoked from network); 6 Mar 2008 13:14:25 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Mar 2008 13:14:25 -0000 Received: (qmail 57658 invoked by uid 500); 6 Mar 2008 13:14:21 -0000 Delivered-To: apmail-cayenne-commits-archive@cayenne.apache.org Received: (qmail 57636 invoked by uid 500); 6 Mar 2008 13:14:21 -0000 Mailing-List: contact commits-help@cayenne.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cayenne.apache.org Delivered-To: mailing list commits@cayenne.apache.org Received: (qmail 57219 invoked by uid 99); 6 Mar 2008 13:14:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Mar 2008 05:14:20 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 06 Mar 2008 13:13:39 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C10A31A9832; Thu, 6 Mar 2008 05:13:57 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@cayenne.apache.org From: aadamchik@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080306131357.C10A31A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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( + (DataContext) actingContext, + query) + : new IncrementalFaultList((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 true 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 quals = new ArrayList(pageSize); List ids = new ArrayList(pageSize); for (int i = fromIndex; i < toIndex; i++) { - Object obj = elements.get(i); - if (isUnresolved(obj)) { - ids.add(obj); - - Map map = (Map) 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 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 map = (Map) 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 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 extends IncrementalFaultList { + + protected DbAttribute pk; + + SimpleIdIncrementalFaultList(DataContext dataContext, Query query) { + super(dataContext, query); + + Collection 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.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.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 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 idSnapshot = persistent.getObjectId().getIdSnapshot(); + + return idSnapshot.size() == 1 + && objectInTheList.equals(idSnapshot.get(pk.getName())); + } + } + + class SingleIdDataRowListHelper extends IncrementalFaultList.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> it = row.entrySet().iterator(); + Iterator> it = row.entrySet().iterator(); while (it.hasNext()) { - Map.Entry entry = it.next(); + Map.Entry 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 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 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(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( + 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);