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 2008/03/06 14:13:50 UTC
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...
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);