/**
* Build a FetchOptions instance using the provided params.
* @return A FetchOptions instance built using the provided params, or {@code null} if neither param is set.
*/
FetchOptions buildFetchOptions(long fromInclNo, long toExclNo) {
FetchOptions opts = null;
Integer offset = null;
if (fromInclNo != 0 && fromInclNo != Long.MAX_VALUE) {
// datastore api expects an int because we cap you at 1000 anyway.
offset = (int) Math.min(Integer.MAX_VALUE, fromInclNo);
opts = withOffset(offset);
}
if (toExclNo != Long.MAX_VALUE) {
// datastore api expects an int because we cap you at 1000 anyway.
int intExclNo = (int) Math.min(Integer.MAX_VALUE, toExclNo);
if (opts == null) {
// When fromInclNo isn't specified, intExclNo (the index of the last
// result to return) and limit are the same.
opts = withLimit(intExclNo);
} else {
// When we have values for both fromInclNo and toExclNo
// we can't take toExclNo as the limit for the query because
// toExclNo is the index of the last result, not the max
// results to return. In this scenario the limit is the
// index of the last result minus the offset. For example, if
// fromInclNo is 10 and toExclNo is 25, the limit for the query
// is 15 because we want 15 results starting after the first 10.
// We know that offset won't be null because opts is not null.
opts.limit(intExclNo - offset);
}
}
// users can provide the cursor as a Cursor or its String representation.
// If we have a cursor, add it to the fetch options
Cursor cursor = null;
Object obj = query.getExtension(CursorHelper.QUERY_CURSOR_PROPERTY_NAME);
if (obj != null) {
if (obj instanceof Cursor) {
cursor = (Cursor) obj;
}
else {
cursor = Cursor.fromWebSafeString((String) obj);
}
}
if (cursor != null) {
if (opts == null) {
opts = withStartCursor(cursor);
} else {
opts.startCursor(cursor);
}
}
// Use the fetch size of the fetch plan to determine chunk size.
FetchPlan fetchPlan = query.getFetchPlan();
Integer fetchSize = fetchPlan.getFetchSize();
if (fetchSize != FetchPlan.FETCH_SIZE_OPTIMAL) {
if (fetchSize == FetchPlan.FETCH_SIZE_GREEDY) {
fetchSize = Integer.MAX_VALUE;
}
} else {
fetchSize = null;
}
if (fetchSize != null) {
if (opts == null) {
opts = withChunkSize(fetchSize);
} else {
opts.chunkSize(fetchSize);
}
}
return opts;
}