CAY-2814 Select query iterator() and batchIterator() methods return incorrect results
- cleanup code for QueryResponse
diff --git a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
index deafacf..e55d21c 100644
--- a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
+++ b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
@@ -62,7 +62,7 @@
QueryResponse result = channel.onQuery(null, query);
@SuppressWarnings("unchecked")
- List<DataRow> rows = result.firstList();
+ List<DataRow> rows = (List<DataRow>)result.firstList();
if (rows.isEmpty()) {
LOGGER.warn("No DB snapshot for object to be deleted, no changes will be recorded. ID: " + id);
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
index 4c4c282..c8fb01b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
@@ -66,27 +66,35 @@
/**
* Returns whether current iteration result is a list or an update count.
*/
- boolean isList();
+ default boolean isList() {
+ return false;
+ }
/**
* Returns whether current response is an iterator
*
* @since 5.0
*/
- boolean isIterator();
+ default boolean isIterator() {
+ return false;
+ }
/**
* Returns a List under the current iterator position. Use {@link #isList()} to check
* the result type before calling this method.
*/
- List<?> currentList();
+ default List<?> currentList() {
+ return null;
+ }
/**
* Returns a current iterator.
*
* @since 5.0
*/
- ResultIterator<?> currentIterator();
+ default ResultIterator<?> currentIterator() {
+ return null;
+ }
/**
* Returns an update count under the current iterator position. Returned value is an
@@ -94,7 +102,9 @@
* an int[1]. Use {@link #isList()} to check the result type before calling this
* method.
*/
- int[] currentUpdateCount();
+ default int[] currentUpdateCount() {
+ return null;
+ }
/**
* Rewinds response iterator to the next result, returning true if it is available.
@@ -111,8 +121,9 @@
* null if the query has no lists. Note that this method resets current iterator to an
* undefined state.
*/
- @SuppressWarnings("rawtypes")
- List firstList();
+ default List<?> firstList() {
+ return null;
+ }
/**
* A utility method for quickly retrieving the Iterator in the response. Returns
@@ -120,12 +131,15 @@
*
* @since 5.0
*/
- @SuppressWarnings("rawtypes")
- ResultIterator firstIterator();
+ default ResultIterator<?> firstIterator() {
+ return null;
+ }
/**
* A utility method for quickly retrieving the first update count from the response.
* Note that this method resets current iterator to an undefined state.
*/
- int[] firstUpdateCount();
+ default int[] firstUpdateCount() {
+ return null;
+ }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
index 0182333..d1b42c1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
@@ -28,12 +28,12 @@
/**
* A simple serializable implementation of QueryResponse.
- *
+ *
* @since 1.2
*/
public class GenericResponse implements QueryResponse, Serializable {
- protected List results;
+ protected List<Object> results;
protected transient int currentIndex;
@@ -41,37 +41,39 @@
* Creates an empty BaseResponse.
*/
public GenericResponse() {
- results = new ArrayList();
+ results = new ArrayList<>();
}
/**
* Creates a BaseResponse with a single result list.
*/
- public GenericResponse(List list) {
- results = new ArrayList(1);
+ public GenericResponse(List<?> list) {
+ results = new ArrayList<>(1);
addResultList(list);
}
/**
* Creates a response that it a shallow copy of another response.
*/
+ @SuppressWarnings("unused")
public GenericResponse(QueryResponse response) {
-
- results = new ArrayList(response.size());
+ results = new ArrayList<>(response.size());
response.reset();
while (response.next()) {
if (response.isList()) {
addResultList(response.currentList());
- }
- else {
+ } else if (response.isIterator()) {
+ addResultIterator(response.currentIterator());
+ } else {
addBatchUpdateCount(response.currentUpdateCount());
}
}
}
- public List firstList() {
- for (reset(); next();) {
+ @Override
+ public List<?> firstList() {
+ for (reset(); next(); ) {
if (isList()) {
return currentList();
}
@@ -81,12 +83,19 @@
}
@Override
- public ResultIterator firstIterator() {
+ public ResultIterator<?> firstIterator() {
+ for (reset(); next(); ) {
+ if (isIterator()) {
+ return currentIterator();
+ }
+ }
+
return null;
}
+ @Override
public int[] firstUpdateCount() {
- for (reset(); next();) {
+ for (reset(); next(); ) {
if (!isList()) {
return currentUpdateCount();
}
@@ -95,37 +104,43 @@
return null;
}
- public List currentList() {
- return (List) results.get(currentIndex - 1);
+ @Override
+ public List<?> currentList() {
+ return (List<?>) results.get(currentIndex - 1);
}
@Override
- public ResultIterator currentIterator() {
- return null;
+ public ResultIterator<?> currentIterator() {
+ return (ResultIterator<?>) results.get(currentIndex - 1);
}
+ @Override
public int[] currentUpdateCount() {
return (int[]) results.get(currentIndex - 1);
}
+ @Override
public boolean isList() {
return results.get(currentIndex - 1) instanceof List;
}
@Override
public boolean isIterator() {
- return false;
+ return results.get(currentIndex - 1) instanceof ResultIterator;
}
+ @Override
public boolean next() {
return ++currentIndex <= results.size();
}
+ @Override
public void reset() {
// use a zero-based index, not -1, as this will simplify serialization handling
currentIndex = 0;
}
+ @Override
public int size() {
return results.size();
}
@@ -138,20 +153,25 @@
}
public void addBatchUpdateCount(int[] resultCount) {
-
if (resultCount != null) {
results.add(resultCount);
}
}
public void addUpdateCount(int resultCount) {
- results.add(new int[] {
- resultCount
- });
+ results.add(new int[]{resultCount});
}
- public void addResultList(List list) {
- this.results.add(list);
+ public void addResultList(List<?> list) {
+ results.add(list);
+ }
+
+ /**
+ * @param iterator to add as a result
+ * @since 5.0
+ */
+ public void addResultIterator(ResultIterator<?> iterator) {
+ results.add(iterator);
}
/**
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
index 961af91..72e9913 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
@@ -21,20 +21,19 @@
import org.apache.cayenne.ResultIterator;
-import java.util.List;
-
/**
* Implementation of QueryResponse for iterated query.
*
* @since 5.0
*/
public class IteratedQueryResponse extends GenericResponse {
- private ResultIterator iterator;
- public IteratedQueryResponse(ResultIterator iterator) {
+ private ResultIterator<?> iterator;
+
+ public IteratedQueryResponse(ResultIterator<?> iterator) {
this.iterator = iterator;
}
- public void setIterator(ResultIterator iterator) {
+ public void setIterator(ResultIterator<?> iterator) {
this.iterator = iterator;
}
@@ -44,47 +43,23 @@
}
@Override
- public boolean isList() {
- return false;
- }
-
- @Override
public boolean isIterator() {
return true;
}
@Override
- public List<?> currentList() {
- return null;
- }
-
- @Override
- public ResultIterator currentIterator() {
+ public ResultIterator<?> currentIterator() {
return iterator;
}
@Override
- public int[] currentUpdateCount() {
- return new int[0];
- }
-
- @Override
public boolean next() {
return false;
}
@Override
- public List firstList() {
- return null;
- }
-
- @Override
public ResultIterator<?> firstIterator() {
return iterator;
}
- @Override
- public int[] firstUpdateCount() {
- return new int[0];
- }
}
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
index 30f8783..13f2f7a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
@@ -25,7 +25,6 @@
import java.util.List;
import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.ResultIterator;
/**
* A QueryResponse optimized to hold a single object or data row list.
@@ -34,7 +33,7 @@
*/
public class ListResponse implements QueryResponse, Serializable {
- protected List objectList;
+ protected List<?> objectList;
protected transient int currentIndex;
@@ -42,14 +41,14 @@
* Creates an empty response.
*/
public ListResponse() {
- this.objectList = new ArrayList(1);
+ this.objectList = new ArrayList<>(1);
}
public ListResponse(Object object) {
this.objectList = Collections.singletonList(object);
}
- public ListResponse(List objectList) {
+ public ListResponse(List<?> objectList) {
this.objectList = objectList;
}
@@ -65,12 +64,7 @@
return true;
}
- @Override
- public boolean isIterator() {
- return false;
- }
-
- public List currentList() {
+ public List<?> currentList() {
if (currentIndex != 1) {
throw new IndexOutOfBoundsException("Past iteration end: " + currentIndex);
}
@@ -78,11 +72,6 @@
return objectList;
}
- @Override
- public ResultIterator<?> currentIterator() {
- return null;
- }
-
public int[] currentUpdateCount() {
throw new IllegalStateException("Current object is not an update count");
}
@@ -96,16 +85,8 @@
currentIndex = 0;
}
- public List firstList() {
+ public List<?> firstList() {
return objectList;
}
- @Override
- public ResultIterator firstIterator() {
- return null;
- }
-
- public int[] firstUpdateCount() {
- return new int[0];
- }
}