@SuppressWarnings("unchecked") @Override public <T> ResultIterator<T> iterator(Select<T> query) { final ResultIterator<DataRow> rows = performIteratedQuery(query); QueryMetadata md = query.getMetaData(getEntityResolver()); if (md.isFetchingDataRows()) { return (ResultIterator<T>) rows; } else { // this is a bit optimized version of 'objectFromDataRow' with // resolver cached for reuse... still the rest is pretty suboptimal ClassDescriptor descriptor = md.getClassDescriptor(); final ObjectResolver resolver = new ObjectResolver(this, descriptor, true); return new ResultIterator<T>() { @Override public Iterator<T> iterator() { return new ResultIteratorIterator<T>(this); } @Override public List<T> allRows() { List<T> list = new ArrayList<>(); while (hasNextRow()) { list.add(nextRow()); } return list; } @Override public boolean hasNextRow() { return rows.hasNextRow(); } @Override public T nextRow() { DataRow row = rows.nextRow(); List<T> objects = (List<T>) resolver.synchronizedObjectsFromDataRows(Collections.singletonList(row)); return (T) objects.get(0); } @Override public void skipRow() { rows.skipRow(); } @Override public void close() { rows.close(); } }; } }
/** * Creates a new IncrementalFaultList using a given DataContext and query. * * @param dataContext DataContext used by IncrementalFaultList to fill itself with objects. * @param query Main query used to retrieve data. Must have "pageSize" property set to a value * greater than zero. * @param maxFetchSize maximum number of fetches in one query */ public IncrementalFaultList(DataContext dataContext, Query query, int maxFetchSize) { QueryMetadata metadata = query.getMetaData(dataContext.getEntityResolver()); if (metadata.getPageSize() <= 0) { throw new CayenneRuntimeException( "Not a paginated query; page size: " + metadata.getPageSize()); } this.dataContext = dataContext; this.pageSize = metadata.getPageSize(); this.rootEntity = metadata.getObjEntity(); if (rootEntity == null) { throw new CayenneRuntimeException( "Pagination is not supported for queries not rooted in an ObjEntity"); } // create an internal query, it is a partial replica of // the original query and will serve as a value holder for // various parameters this.internalQuery = new SelectQuery<Object>(rootEntity); this.internalQuery.setFetchingDataRows(metadata.isFetchingDataRows()); this.internalQuery.setPrefetchTree(metadata.getPrefetchTree()); this.helper = createHelper(metadata); this.idWidth = metadata.getDbEntity().getPrimaryKeys().size(); List<Object> elementsUnsynced = new ArrayList<>(); fillIn(query, elementsUnsynced); this.elements = Collections.synchronizedList(elementsUnsynced); this.maxFetchSize = maxFetchSize; }
/** @since 3.0 */ IncrementalListHelper createHelper(QueryMetadata metadata) { if (metadata.isFetchingDataRows()) { return new DataRowListHelper(); } else { return new PersistentListHelper(); } }