blob: b44f7bdba697045e3e01d6ccf698a27175bd9e59 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.queries;
import java.util.*;
import org.eclipse.persistence.internal.queries.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent;
import org.eclipse.persistence.exceptions.*;
/**
* <p><b>Purpose</b>:
* Abstract class for all Cursor-related policy objects
*/
public abstract class CursorPolicy extends ContainerPolicy {
protected int pageSize;
protected ReadQuery query;
/**
* INTERNAL:
* default constructor
*/
protected CursorPolicy() {
super();
setPageSize(10);
}
/**
* INTERNAL:
*/
protected CursorPolicy(ReadQuery query, int pageSize) {
super();
setQuery(query);
setPageSize(pageSize);
}
/**
* INTERNAL:
*/
@Override
public ContainerPolicy clone(ReadQuery query) {
CursorPolicy clone = (CursorPolicy)super.clone(query);
clone.setQuery(query);
return clone;
}
/**
* INTERNAL:
* Creates a CollectionChangeEvent for the container
*/
@Override
public CollectionChangeEvent createChangeEvent(Object collectionOwner, String propertyName, Object collectionChanged, Object elementChanged, int changeType, Integer index, boolean isChangeApplied){
throw ValidationException.operationNotSupported("createChangeEvent");
}
/**
* INTERNAL:
* Execute the cursored select and build the stream.
*/
@Override
public abstract Object execute();
/**
* Return the number of elements to be read into a cursored stream
* when more elements are needed from the database.
*/
public int getPageSize() {
return pageSize;
}
/**
* INTERNAL:
* Return the query.
*/
public ReadQuery getQuery() {
return query;
}
/**
* INTERNAL:
* Return whether the iterator has more objects.
*
* @param iterator java.lang.Object
* @return boolean true if iterator has more objects
*/
@Override
public boolean hasNext(Object iterator) {
return ((Enumeration)iterator).hasMoreElements();
}
@Override
public boolean isCursorPolicy() {
return true;
}
/**
* INTERNAL:
* Return an iterator for the given container.
* This iterator can then be used as a parameter to #hasNext()
* and #next().
*
* @see ContainerPolicy#hasNext(java.lang.Object)
* @see ContainerPolicy#next(java.lang.Object)
*/
@Override
public Object iteratorFor(Object container) {
return container;
}
/**
* INTERNAL:
* Return the next object on the queue. The iterator is the one
* returned from #iteratorFor().
*
* @see ContainerPolicy#iteratorFor(java.lang.Object)
*/
@Override
protected Object next(Object iterator) {
return ((Enumeration)iterator).nextElement();
}
/**
* INTERNAL:
* This can be used by collection such as cursored stream to gain control over execution.
*/
@Override
public boolean overridesRead() {
return true;
}
/**
* INTERNAL:
* Prepare and validate.
*/
@Override
public void prepare(DatabaseQuery query, AbstractSession session) throws QueryException {
super.prepare(query, session);
setQuery((ReadQuery)query);
ClassDescriptor descriptor = query.getDescriptor();
// ReadAllQuery has a descriptor, DataReadQuery does not.
if (descriptor != null) {
// Interface queries cannot use cursors.
if (descriptor.isDescriptorForInterface()) {
throw QueryException.noCursorSupport(query);
}
// Ensure inheritance queries outer join subclasses.
if (query.isObjectLevelReadQuery() && descriptor.hasInheritance()) {
((ObjectLevelReadQuery) query).setShouldOuterJoinSubclasses(true);
}
}
query.getQueryMechanism().prepareCursorSelectAllRows();
}
/**
* INTERNAL:
* Execute the cursored select and build the stream.
*/
@Override
public abstract Object remoteExecute();
/**
* Set the number of elements to be read into a cursored stream
* when more elements are needed from the database.
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
* INTERNAL:
* Set the query.
*/
public void setQuery(ReadQuery query) {
this.query = query;
}
/**
* INTERNAL:
* Return the size of container.
*/
@Override
public int sizeFor(Object container) {
return ((Cursor)container).size();
}
@Override
protected Object toStringInfo() {
return "page size = " + getPageSize();
}
}