public class CompoundQuery extends DynamicQuery implements QueryConstants, RecordChangeListener
addComponent
method variants. This query type can
combine both PreselectQuery
s and RandomAccessQuery
s as its
components. However, preselected tables must always be to the left of
(i.e., outward from) non-preselected tables in the query. That is, a
PreselectQuery
object can never be added, once a
RandomAccessQuery
object has been added to a compound query.
Inner and left outer joins are supported. However, inner joins must
always occur to the left (i.e., outward from) outer joins. If, at the
time a component query specified as an inner join is added, there are
previously added outer-join components which in their where
clause use one or more buffers as the inner-join component's
where
clause, these outer-join components will automatically
be converted to an inner join, to satisfy the condition that all inner
joins are on the left of the outer-join components.
This query retrieves result records in two modes: iterating and random
access. Iterating mode is active when using the iterate()
method
to advance the query to the next, composite row of records in the result
set. Random access mode is active when using any of the other retrieval
methods (first
, last
, next
,
previous
, current
). The difference between the
modes is that iterating mode always terminates with a
QueryOffEndException
when no further record retrieval is
possible; random access mode does not. Random access mode thus allows
client code to advance off the end of the result set and continue
processing.
CompoundQuery
abstracts the use of multiple query
implementations to achieve a dynamic, multi-table query. It delegates the
record retrieval work to the underlying queries, but manages the overall
navigation of the results. Delegate queries must implement the Joinable
interface. Each "row" in the "result set" is a logical
construct, the virtual composite of multiple record buffers. Advancing to
a new row (be it forwards, backwards, first, last) means advancing the
most specific query possible to the next matching record in its
predetermined progression. Once the most specific query can no longer
advance, the next most specific query is advanced, the most specific query
is reset to its starting state, and we try to find a joining match for the
most specific query again, given that its outer query has a new value with
which to join. This continues until the most specific possible query has
advanced, or we have moved to our least specific query component, and no
further match is possible. At this point, the query is "off-end". For
iterating mode, this is the end of query execution and an end condition is
raised. In random access mode, further navigation is possible.
Substitution Parameters
Query substitution parameters require different modes of resolution,
depending upon the type of parameter and the nature of the query. A query
may be set at construction to resolve all of its parameters once, up front
or iteratively, each time an iterative loop construct is entered. The
former corresponds with Progress' OPEN QUERY style queries; the latter
corresponds with all other iterative record retrieval constructs in
Progress (e.g., FOR EACH, DO PRESELECT, REPEAT PRESELECT, REPEAT FOR).
The number of times a parameter is resolved and the timing of such resolution becomes important if an iterative record retrieval construct modifies the values of such parameters during record retrieval. This may occur, for example, if the body of an outer FOR loop modifies the value of a variable used in the where clause of an inner FOR loop. While less of an issue for preselect type queries, these can still be affected if the where clause of a nested query component invokes a client-side function, which may in turn modify state on which the query or related logic depends.
The following conversion rules apply:
------------------------------------------------------------------------ Progress Construct CompoundQuery Modes resolveOnce preselect ------------------------------------------------------------------------ OPEN QUERY FOR true (forced to false) false OPEN QUERY PRESELECT true (ignored?) true FOR {EACH | FIRST | LAST} false false DO PRESELECT false true REPEAT PRESELECT false true ------------------------------------------------------------------------
Modifier and Type | Class and Description |
---|---|
private class |
CompoundQuery.Optimizer
Inner class which attempts to optimize the enclosing, compound query's individual query
components into server-side joins.
|
private class |
CompoundQuery.SnapshotParameterFilter
Filter that handles parameters passed to the component's subquery which handles the target
buffer.
|
P2JQuery.Parameter, P2JQuery.QueryOpenedListener, P2JQuery.QueryOpenListener
Modifier and Type | Field and Description |
---|---|
private int |
activeIndex
Index of component query currently being iterated
|
private java.util.Map<RecordBuffer,java.lang.Integer> |
buffersMap
Map of all buffers participating in this query to their 0-based index positions
|
private Finalizable |
cleaner
Cleaner executed when this query's block is exit.
|
private java.util.List<CompoundComponent> |
components
Query components currently in use by the compound query
|
private int[] |
counters
Current index position in each component query loop
|
protected boolean |
currentRowDeleted
Determines if the current row was deleted by DELETE-RESULT-LIST-ENTRY.
|
private static boolean |
deferOptimization
Defer optimization until after first composite row has been retrieved (experimental)
|
protected boolean |
foundFirst
Determines if we have fetched a result row.
|
private static java.util.logging.Logger |
log
Logger
|
private java.util.List<CompoundComponent> |
originalComponents
Query components originally added to the compound query
|
private boolean |
postponeAccumulation
Postpone accumulation on retrieve.
|
private boolean |
preselect
Force preselection of all results?
|
private boolean |
preselected
Have results been preselected?
|
private boolean |
regCleaner
Has query been registered for resource cleanup?
|
private boolean |
resolveOnce
Resolve arguments once, up front, or on every loop cycle?
|
private int |
tableCount
Total number of tables involved in this compound query
|
protected boolean |
unregisterOnCleanup
Determines if this will be unregistered from ChangeBroker on cleanup.
|
private boolean[] |
useSnapshot
Specifies if snapshot values (values at the time when the record was loaded) should be used
as HQL sub-query parameters for specific component instead of the actual values.
|
cursor
closed, dynamicPredicate, indexedReposition, inverseSorting, outer, parameterFilter
CURRENT, FIRST, LAST, NEXT, NONE, PREVIOUS, RETRIEVE_MODES, UNIQUE
Constructor and Description |
---|
CompoundQuery()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
addComponent(Joinable query)
Add a joinable query to the compound query.
|
void |
addComponent(Joinable query,
int iteration)
Add a joinable query to the compound query, and specify the nature of
the iteration which will be performed (first, last, next, etc.) on that
component, when the compound query is iterated.
|
void |
addComponent(Joinable query,
int iteration,
boolean outer)
Add a joinable query to the compound query, and specify the nature of
the iteration which will be performed (first, last, next, etc.) on that
component, when the compound query is iterated.
|
(package private) void |
addCompoundComponent(CompoundComponent component)
Add a component query to this compound query and adjust the table count accordingly.
|
boolean |
addDynamicFilter(FieldReference fr,
BaseDataType val,
java.lang.String format)
Adds a new constraint term to the where predicate of this query, effectively filtering out
any rows whose referenced field does not match the requested value.
|
P2JQuery |
addExternalBuffers(DataModelObject... dmos)
Add one or more buffers to the list of those which this query references externally.
|
protected void |
afterReposition(boolean permitFetch,
boolean error)
This method is an extension to the AbstractQuery normal behavior.
|
protected boolean |
canOptimize()
Indicate whether this object can be optimized.
|
void |
cleanup()
Clean up resources associated with this query when its scope ends.
|
void |
clearDynamicFilters()
Clears any dynamically filters added at runtime.
|
void |
close()
Explicitly close the prepared query.
|
void |
close(boolean inResource)
Explicitly close the prepared query.
|
private java.lang.Object[] |
collectRowData(int navigation)
Assemble an array of primary key IDs or DMOs for the current records in
the buffers underlying this query, from left-most to right-most (in the
sense of how the query joins the associated tables).
|
logical |
createResultListEntry()
Creates an entry in the result list for the current row.
|
void |
current()
Retrieve the current virtual, composite row of results for the compound
query.
|
void |
current(LockType lockType)
Retrieve the current virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
logical |
deleteResultListEntry(boolean allowBetweenRows)
Deletes the current row of a query's result list.
|
void |
first()
Retrieve the first virtual, composite row of results for the compound
query.
|
void |
first(boolean iterating)
Retrieve the first virtual, composite row of results for the compound
query.
|
void |
first(boolean iterating,
LockType lockType)
Retrieve the first virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
void |
first(LockType lockType)
Retrieve the first virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
protected java.lang.Object |
getBreakValue()
Return an object which represents a property value which defines the
end of a sort band.
|
private java.util.List<CompoundComponent> |
getComponents()
Retrieve the list of query components.
|
OffEnd |
getOffEnd()
Report the off-end status of this query, which is essentially the
off-end status of its outermost component query.
|
java.util.List<QueryOffEndListener> |
getOffEndListeners()
Get all the off-end listeners associated with this query.
|
(package private) java.util.List<CompoundComponent> |
getOriginalComponents()
Retrieve the list of original query components (unoptimized).
|
private RecordBuffer[] |
getRecordBuffersInternal()
Get an array of all record buffers managed by this query.
|
int |
getTableCount()
Get the number of tables joined by this query.
|
character |
indexInformation(NumberType n)
Conversion of INDEX-INFORMATION attribute (KW_IDX_INFO).
|
CompoundQuery |
initialize(boolean resolveOnce,
boolean preselect)
Initialization logic.
|
private void |
initializeComponentQuery(Joinable query)
Initialize state of a component query.
|
protected void |
initReferenceRowSupport(int blockDepth)
Init structures required to use reference row: create the map of all buffers, register
parameter filters for sub-queries and register this query as a record change listener.
|
protected boolean |
isPresorted()
Determines if the query is presorted, i.e.
|
void |
iterate()
Advance the compound query, triggering one or more of the underlying
queries to retrieve a new record.
|
void |
last()
Retrieve the last virtual, composite row of results for the compound
query.
|
void |
last(boolean iterating)
Retrieve the last virtual, composite row of results for the compound
query.
|
void |
last(boolean iterating,
LockType lockType)
Retrieve the last virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
void |
last(LockType lockType)
Retrieve the last virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
protected boolean |
loadByValues(java.lang.Object[] data,
LockType lockType,
boolean iterating)
Load a virtual, composite record by loading each record buffer managed
by this query with a DMO, given its primary key ID in the specified
ids array. |
protected void |
loadRowAtCursor()
Synchronize the query with the cursor by causing the query to load the
current row's results (if any) into its backing buffer(s).
|
private void |
maybeOptimize()
Method which attempts to optimize this object's query components into one or more
server-side joins.
|
void |
next()
Retrieve the next virtual, composite row of results for the compound
query.
|
void |
next(boolean iterating)
Retrieve the next virtual, composite row of results for the compound
query.
|
void |
next(boolean iterating,
LockType lockType)
Retrieve the next virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
void |
next(LockType lockType)
Retrieve the next virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
void |
notifyRepositionListeners(boolean closed,
boolean error,
int targetRepositionRow)
Notify all registered listeners that query is repositioned or closed.
|
void |
open()
Open the query once all query components have been added.
|
java.lang.Object[] |
peekFirst()
Fetch the array of primary key IDs associated with the first result in
this query's result list.
|
java.lang.Object[] |
peekLast()
Fetch the array of primary key IDs associated with the last result in
this query's result list.
|
java.lang.Object[] |
peekNext()
Fetch the array of primary key IDs associated with the next result in this query's result
list.
|
java.lang.Object[] |
peekPrevious()
Fetch the array of primary key IDs associated with the previous result
in this query's result list.
|
protected void |
postponeAccumulation()
Switch on postponed accumulation on next retrieve.
|
protected void |
preselectResults()
Preselect all results by creating a common cursor and
SimpleResults for each
component. |
protected void |
presort()
If the query is a presort query, then presort the results stored in the cursor.
|
void |
previous()
Retrieve the previous virtual, composite row of results for the compound
query.
|
void |
previous(boolean iterating)
Retrieve the previous virtual, composite row of results for the compound
query.
|
void |
previous(boolean iterating,
LockType lockType)
Retrieve the previous virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
void |
previous(LockType lockType)
Retrieve the previous virtual, composite row of results for the compound
query, overriding the lock type to apply to each underlying query.
|
private java.lang.Object[] |
processComponent(int navigation,
CompoundComponent component,
int count,
LockType lockType,
boolean peek)
Advance a single query component, according to the overall query
navigation direction, and that component's natural iteration type.
|
java.util.Iterator<RecordBuffer> |
recordBuffers()
Report the record buffers for whose changes this object is interested
in listening.
|
protected void |
registerCleaner()
Register a
Finalizable with the transaction manager for
resource cleanup when this query's scope ends. |
private int |
registerRecordChangeListeners()
Register the query within each component as a record change listener.
|
protected void |
releaseAllBuffers()
Release all backing buffers of for all components.
|
void |
releaseBuffers()
Releases buffers from all components.
|
protected void |
restoreAccumulation()
Switch on postponed accumulation on next retrieve.
|
protected java.lang.Object[] |
retrieve(int navigation,
LockType lockType,
boolean iterating)
Retrieve a virtual, composite row of results for the compound query.
|
protected java.lang.Object[] |
retrieve(int navigation,
LockType lockType,
boolean iterating,
boolean peek)
Retrieve a virtual, composite row of results for the compound query.
|
private java.lang.Object[] |
retrieveImpl(int navigation,
LockType lockType,
boolean iterating,
boolean peek)
Retrieve a virtual, composite row of results for the compound query.
|
void |
setBrowsed(boolean browsed)
Indicate to this query that whether it is associated with a browse widget or not.
|
private void |
setComponentsBrowsed()
Iterate the component queries of this object and set their browsed flags to match that of
this object.
|
void |
setScrolling()
Create a cursor for this query and ensure that any component queries are scrollable, whether they
already have been added, or will be added in the future.
|
void |
setSkipDeletedRecord(logical on)
Setter for SKIP-DELETED-RECORD query attribute.
|
void |
setStandalone(boolean standalone)
Change the standalone nature of this query.
|
void |
stateChanged(RecordChangeEvent event)
Respond to a record change event.
|
_isOffEnd, backward, backward, currentRow, currentRowImpl, forward, forward, incrementMoves, isNativelyPreselect, isPreselect, isScrolling, reposition, reposition, repositionByID, repositionByID, repositionByID, reset, resetScrolling, size, verifyScrolling
_isSkipDeletedRecord, accumulate, addAccumulator, addAccumulator, addBuffer, addBuffer, addQueryOpenListener, addRepositionListener, afterReposition, afterReposition, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, buffersMatch, changeForwardOnly, changeForwardOnly, deleteResultListEntry, exclude, forwardOnly, getCache, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getDefaultLock, getExternalBuffers, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getLast, getLast, getLast, getLast, getLast, getLast, getLast, getLast, getNext, getNext, getNext, getNext, getNext, getNext, getNext, getNext, getNumResults, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getReferencedBuffers, hasAccumulators, hasAny, hasAny, hasAny, hasAny, hasOne, hasOne, hasOne, hasOne, include, indexInformation, indexInformation, isBrowsed, isDynamicPredicate, isErrorIfNull, isFatalError, isFetchOnReposition, isFillingBrowseRows, isIndexedReposition, isLastOfBreakGroup, isNewBreakGroup, isOffEnd, isOmitAlias, isOpen, isRepositionNotificationActive, isSkipDeletedRecord, isStandalone, notifyQueryOpenListeners, numBuffers, numResults, numResults, prepare, prepare, prepareFetch, prepareString, preprocessSubstitutionArguments, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, removeRepositionListener, setBuffers, setBuffers, setCache, setCache, setDynamicPredicate, setErrorIfNull, setFatalError, setFetchOnReposition, setFillingBrowseRows, setIndexedReposition, setOmitAlias, setOuter, setParameterFilter, translateSort, translateSort, translateWhere
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addAccumulator, addAccumulator, addQueryOpenListener, addRepositionListener, changeForwardOnly, changeForwardOnly, deleteResultListEntry, exclude, forwardOnly, getBasicLogging, getCache, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getFirst, getJoin, getLast, getLast, getLast, getLast, getLast, getLast, getLast, getLast, getNext, getNext, getNext, getNext, getNext, getNext, getNext, getNext, getNumResults, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getPrevious, getRecordBuffers, hasAny, hasAny, hasAny, hasAny, hasOne, hasOne, hasOne, hasOne, include, indexInformation, indexInformation, isBrowsed, isDynamicPredicate, isFetchOnReposition, isFillingBrowseRows, isFindByRowid, isFirstOfGroup, isFirstOfGroup, isIndexedReposition, isLastOfGroup, isLastOfGroup, isOffEnd, isSkipDeletedRecord, isStandalone, notifyQueryOpenListeners, prepare, prepare, prepareString, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, queryRepositionByID, removeRepositionListener, resetQuery, setBasicLogging, setBasicLogging, setCache, setCache, setDynamicPredicate, setErrorIfNull, setFetchOnReposition, setFillingBrowseRows, setIndexedReposition, setParameterFilter, unique, unique
addBuffer, addBuffer, addBuffer, addBuffer, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, numBuffers, setBuffers, setBuffers, setBuffers
private static final java.util.logging.Logger log
private static final boolean deferOptimization
protected boolean currentRowDeleted
protected boolean foundFirst
protected boolean unregisterOnCleanup
private boolean preselect
private final java.util.List<CompoundComponent> originalComponents
private boolean resolveOnce
private java.util.List<CompoundComponent> components
private boolean preselected
private int[] counters
private boolean[] useSnapshot
components.size() - 1
and excludes the first (outermost) component
because it cannot have HQL which includes fields of an outer component.private int activeIndex
private int tableCount
private boolean postponeAccumulation
private java.util.Map<RecordBuffer,java.lang.Integer> buffersMap
private boolean regCleaner
private final Finalizable cleaner
public CompoundQuery()
initialize()
is
called.public CompoundQuery initialize(boolean resolveOnce, boolean preselect)
This code is intentionally separated from the constructor. The purpose of this separation is to allow construction to occur in the prior scope while initialization can still occur within a method or lambda that is inside the next block's scope.
preselect
- true
to force preselection of all results; false
otherwise.public void setScrolling()
setScrolling
in interface P2JQuery
setScrolling
in class DynamicQuery
public int getTableCount()
getTableCount
in interface P2JQuery
public java.util.List<QueryOffEndListener> getOffEndListeners()
getOffEndListeners
in interface P2JQuery
public void addComponent(Joinable query)
NEXT
iteration type.query
- Query which will perform the fundamental work for this
component when the compound query is iterated.java.lang.IllegalStateException
- if this method is invoked during an iteration cycle.iterate()
public void addComponent(Joinable query, int iteration)
query
- Query which will perform the fundamental work for this
component when the compound query is iterated.iteration
- A constant
indicating the type of work
to be performed upon an iteration of the compound query. This
parameter determines whether the underlying query will be asked
to perform a first, last, next, previous, or unique record
retrieval.java.lang.IllegalStateException
- if this method is invoked during an iteration cycle.iterate()
public void addComponent(Joinable query, int iteration, boolean outer)
outer
.query
- Query which will perform the fundamental work for this
component when the compound query is iterated.iteration
- A constant
indicating the type of work
to be performed upon an iteration of the compound query. This
parameter determines whether the underlying query will be asked
to perform a first, last, next, previous, or unique record
retrieval.outer
- true
if this component should be joined to the
previously added component via a left outer join;
false
if an inner join is required.
If, at the time a component query specified as an inner join is added, there are
previously added outer-join components which in their where
clause
use one or more buffers as the inner-join component's where
clause,
these outer-join components will automatically be converted to an inner join,
to satisfy the condition that all inner joins are on the left of the outer-join
components.
java.lang.IllegalStateException
- if this method is invoked during an iteration cycle.iterate()
public P2JQuery addExternalBuffers(DataModelObject... dmos)
This method overrides the default implementation to set external buffers on the most recently added component of this compound query. It therefore must be called immediately after the target component is added and before the query is opened, optimized, or executed.
addExternalBuffers
in interface P2JQuery
addExternalBuffers
in class AbstractQuery
dmos
- One or more external buffers to add to the most recently added query component.java.lang.IllegalStateException
- if called before a component has been added or after query has been optimized.public void setSkipDeletedRecord(logical on)
setSkipDeletedRecord
in interface P2JQuery
setSkipDeletedRecord
in class AbstractQuery
on
- New value for the attribute.public void setBrowsed(boolean browsed)
setBrowsed
in interface P2JQuery
setBrowsed
in class AbstractQuery
browsed
- true
to indicate the query has an associated browse widget, else false
.public void open()
open
in interface P2JQuery
open
in class DynamicQuery
public void iterate()
QueryOffEndException
- if no more records can be retrieved by the underlying queries.ErrorConditionException
- if an underlying query triggers an error.public void first()
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
first
in interface P2JQuery
ErrorConditionException
- if an underlying query triggers an error.public void first(boolean iterating)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void first(LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
first
in interface P2JQuery
lockType
- Lock type which should override that of any underlying query.ErrorConditionException
- if an underlying query triggers an error.public void first(boolean iterating, LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.lockType
- Lock type which should override that of any underlying query.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void last()
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
last
in interface P2JQuery
ErrorConditionException
- if an underlying query triggers an error.public void last(boolean iterating)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void last(LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
last
in interface P2JQuery
lockType
- Lock type which should override that of any underlying query.ErrorConditionException
- if an underlying query triggers an error.public void last(boolean iterating, LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.lockType
- Lock type which should override that of any underlying query.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void next()
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
next
in interface P2JQuery
ErrorConditionException
- if an underlying query triggers an error.public void next(boolean iterating)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void next(LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
next
in interface P2JQuery
lockType
- Lock type which should override that of any underlying query.ErrorConditionException
- if an underlying query triggers an error.public void next(boolean iterating, LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.lockType
- Lock type which should override that of any underlying query.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void previous()
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
previous
in interface P2JQuery
ErrorConditionException
- if an underlying query triggers an error.public void previous(boolean iterating)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void previous(LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
previous
in interface P2JQuery
lockType
- Lock type which should override that of any underlying query.ErrorConditionException
- if an underlying query triggers an error.public void previous(boolean iterating, LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.lockType
- Lock type which should override that of any underlying query.QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an underlying query triggers an error.public void current()
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
current
in interface P2JQuery
ErrorConditionException
- if an underlying query triggers an error.public void current(LockType lockType)
This is a combination of records retrieved by each component query. If the compound query involves outer joins, some of the underlying buffers may be empty when this method returns.
current
in interface P2JQuery
lockType
- Lock type which should override that of any underlying query.ErrorConditionException
- if an underlying query triggers an error.public java.lang.Object[] peekFirst()
This implementation actually updates the underlying record buffer(s).
null
if there is no such result.public java.lang.Object[] peekLast()
This implementation actually updates the underlying record buffer(s).
null
if there is no such result.public java.lang.Object[] peekNext()
This implementation actually updates the underlying record buffer(s). The difference between
this function and next()
function is that this function calls
Scrollable.peekNext()
on sub-queries in order to get the next record from underlying
results, while next()
returns the next record after the current row.
peekNext
in interface Scrollable
null
if there is no such result.public java.lang.Object[] peekPrevious()
This implementation actually updates the underlying record buffer(s). The difference between
this function and previous()
function is that this function calls
Scrollable.peekPrevious()
on sub-queries in order to get the next record from
underlying results, while previous()
returns the next record after the current row.
peekPrevious
in interface Scrollable
null
if there is no such result.public void notifyRepositionListeners(boolean closed, boolean error, int targetRepositionRow)
notifyRepositionListeners
in interface P2JQuery
notifyRepositionListeners
in class AbstractQuery
closed
- A true
value will inform all listeners that the
query was explicitly closed.error
- true
if an error happened during reposition.targetRepositionRow
- Row used as the target for reposition. If it was deleted, reposition with fetching
may end up on a different row.public java.util.Iterator<RecordBuffer> recordBuffers()
ChangeBroker
to receive notifications of any change to DMOs whose
interface types match those returned by the RecordBuffer.getDMOInterface()
methods of the returned buffers.recordBuffers
in interface RecordChangeListener
public void stateChanged(RecordChangeEvent event) throws PersistenceException
stateChanged
in interface RecordChangeListener
event
- Event which describes the DMO state change.PersistenceException
- if any error occurs while processing the state change event.public void setStandalone(boolean standalone)
setStandalone
in interface P2JQuery
setStandalone
in class AbstractQuery
standalone
- true
to set query as standalone;
false
to set query as contained.public void close()
close
in interface P2JQuery
close
in class AbstractQuery
public void close(boolean inResource)
public void cleanup()
cleanup
in interface P2JQuery
cleanup
in class AbstractQuery
public OffEnd getOffEnd()
public character indexInformation(NumberType n)
indexInformation
in interface IndexInformation
indexInformation
in interface P2JQuery
indexInformation
in class AbstractQuery
n
- An integer expression that evaluates to the level of join for which you want index
information.public logical deleteResultListEntry(boolean allowBetweenRows)
deleteResultListEntry
in interface P2JQuery
deleteResultListEntry
in class AbstractQuery
allowBetweenRows
- If true
then the cursor can be positioned between rows (the next
row will be deleted). false
for conventional DELETE-RESULT-LIST-ENTRY()
mode where the cursor should be positioned on a row (otherwise false
is
returned).true
on success.public logical createResultListEntry()
createResultListEntry
in interface P2JQuery
createResultListEntry
in class AbstractQuery
true
on success.protected void registerCleaner()
Finalizable
with the transaction manager for
resource cleanup when this query's scope ends.protected void afterReposition(boolean permitFetch, boolean error)
afterReposition
in class AbstractQuery
permitFetch
- true
to permit immediate record fetch;
false
to override fetchOnReposition
flag and explicitly disallow immediate record fetch.error
- true
if error happened during reposition.protected void initReferenceRowSupport(int blockDepth)
blockDepth
- Depth of the block at which this query is registered as record change listener.
0
for global scope.protected java.lang.Object getBreakValue()
order by
clause.
If the break value for this query currently is non-null
,
this indicates that the most recently retrieved record has crossed a
sort band boundary, and that a new band has begun. This value
will only be non-null
at the point at which such a record
is found, and will be null
for all other records.
Note: break values are only tracked for invocations of
next
and previous
. Other retrievals will
result in break value being null
.
getBreakValue
in class DynamicQuery
null
always; when a compound query is the backing query for
a dynamic results object, it should never return a non-null value,
because it cannot shift into a preselect mode.protected java.lang.Object[] retrieve(int navigation, LockType lockType, boolean iterating)
Preselect Mode
CompoundQuery
generally operates as a dynamic query,
though it can be used to generate a fixed list of preselected results.
When in this mode, the first time this method is executed, a results
list is generated. This is done by retrieving each virtual, composite
row which meets the overall query's criteria, and caching the primary
keys of these records in the underlying cursor. Each underlying query
is assigned the correct subset of these IDs, such that subsequent
retrieval requests can safely use the cursor to retrieve the correct
records. As a result, in preselect mode, this method is only ever
invoked once per query.
navigation
- Type of advancement applied to the compound query; i.e., how
the virtual composite result set is navigated as a whole:
forward (next), backward (previous), jump to first or last, or
reload current records in all buffers.lockType
- Overriding lock type to apply to each underlying buffer.iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.null
if no more results were available (and we
were not iterating).QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an error occurred retrieving the record for an underlying
query.protected java.lang.Object[] retrieve(int navigation, LockType lockType, boolean iterating, boolean peek)
Preselect Mode
CompoundQuery
generally operates as a dynamic query,
though it can be used to generate a fixed list of preselected results.
When in this mode, the first time this method is executed, a results
list is generated. This is done by retrieving each virtual, composite
row which meets the overall query's criteria, and caching the primary
keys of these records in the underlying cursor. Each underlying query
is assigned the correct subset of these IDs, such that subsequent
retrieval requests can safely use the cursor to retrieve the correct
records. As a result, in preselect mode, this method is only ever
invoked once per query.
navigation
- Type of advancement applied to the compound query; i.e., how
the virtual composite result set is navigated as a whole:
forward (next), backward (previous), jump to first or last, or
reload current records in all buffers.lockType
- Overriding lock type to apply to each underlying buffer.iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.peek
- true
if sub-queries should be interrogated using
Scrollable.peekNext()
/Scrollable.peekPrevious()
rather than P2JQuery.next()
/P2JQuery.previous()
.
The difference is that in the first case sub-queries return the
next/previous record from underlying results, while in the second
case they return the next/previous record after the current row.null
if no more results were available (and we
were not iterating).QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an error occurred retrieving the record for an underlying
query.protected boolean isPresorted()
true
if the query is presorted.protected void presort()
protected void preselectResults()
SimpleResults
for each
component.protected void loadRowAtCursor()
loadRowAtCursor
in class AbstractQuery
protected boolean loadByValues(java.lang.Object[] data, LockType lockType, boolean iterating)
ids
array. The IDs are arranged to coincide with the
tables underlying the query, from left-most to right-most (in the sense
of how they are joined by the query).data
- Array of primary key IDs or DMOs, one per table involved in the
querylockType
- Lock type which should override that of any underlying query.
Set to null
to allow underlying query to use its
existing lock type.iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.true
if ids
was not
null
; else false
.collectRowData(int)
protected boolean canOptimize()
true
by default. Subclasses should override this behavior as needed.private int registerRecordChangeListeners()
private void maybeOptimize()
This method must only be invoked after the first query result is fetched via the un-optimized query, to ensure we correctly preserve the pre-query state of the involved record buffers, in the event the compound query runs off end immediately.
private RecordBuffer[] getRecordBuffersInternal()
private void setComponentsBrowsed()
private java.lang.Object[] collectRowData(int navigation)
This snapshot is only generated for scrolling queries.
navigation
- Type of advancement applied to the compound query; i.e., how
the virtual composite result set is navigated as a whole:
forward (next), backward (previous), jump to first or last, or
reload current records in all buffers.loadByValues(java.lang.Object[], com.goldencode.p2j.persist.lock.LockType, boolean)
private java.lang.Object[] retrieveImpl(int navigation, LockType lockType, boolean iterating, boolean peek)
navigation
- Type of advancement applied to the compound query; i.e., how
the virtual composite result set is navigated as a whole:
forward (next), backward (previous), jump to first or last, or
reload current records in all buffers.lockType
- Overriding lock type to apply to each underlying buffer.iterating
- true
if this method is being invoked within the
context of an iterating loop, which can only be exited by
raising an end condition; false
if end condition
should not be raised, even if no further advancement of the
composite result is possible.peek
- true
if sub-queries should be interrogated using
Scrollable.peekNext()
/Scrollable.peekPrevious()
rather than P2JQuery.next()
/P2JQuery.previous()
.
The difference is that in the first case sub-queries return the
next/previous record from underlying results, while in the second
case they return the next/previous record after the current row.null
if no more results were available (and we
were not iterating).QueryOffEndException
- if no more results were available in iterating mode.ErrorConditionException
- if an error occurred retrieving the record for an underlying
query.protected void postponeAccumulation()
protected void restoreAccumulation()
protected void releaseAllBuffers()
void addCompoundComponent(CompoundComponent component)
component
- Query component to be added.java.util.List<CompoundComponent> getOriginalComponents()
private java.util.List<CompoundComponent> getComponents()
private void initializeComponentQuery(Joinable query)
query
- Component query to be initialized.private java.lang.Object[] processComponent(int navigation, CompoundComponent component, int count, LockType lockType, boolean peek)
navigation
- Type of advancement applied to the compound query; i.e., how
the virtual composite result set is navigated as a whole:
forward (next), backward (previous), jump to first or last, or
reload current records in all buffers.component
- Query component being asked to retrieve a record.count
- Index of this query component's result within the current join.lockType
- Lock type to apply to the retrieved record for this query
componentpeek
- true
if sub-queries should be interrogated using
Scrollable.peekNext()
/Scrollable.peekPrevious()
rather than P2JQuery.next()
/P2JQuery.previous()
.
The difference is that in the first case sub-queries return the
next/previous record from underlying results, while in the second
case they return the next/previous record after the current row.
Peeking works only for NEXT and PREV iteration types.peek
is true
: an array of
the primary key IDs for the query component, if a result was
successfully retrieved; null
if no more results
were available.
If peek
is false
: always returns
null
.
QueryOffEndException
- if query component is being asked to retrieve a FIRST, LAST,
or UNIQUE record, and it has already done so in the current
iteration pass (prevents looping infinitely on these
constructs).QueryConstants.RETRIEVE_MODES
public void releaseBuffers()
releaseBuffers
in interface P2JQuery
releaseBuffers
in class AbstractQuery
public boolean addDynamicFilter(FieldReference fr, BaseDataType val, java.lang.String format)
new-where := (fr = val) AND (old-query)
.
Note: The constraints are exclusive meaning that if constraints will be added for same field of same buffer, the query will return an empty result because the field cannot be at the same time equals to two different values.
Use clearDynamicFilters()
to clean all dynamically added criteria and restore the
sorting order of the query to its original form.
addDynamicFilter
in interface P2JQuery
fr
- A reference to field used as filtering criterion. Only the rows that matches the
specified value for this field will be selected. Must not be null
.val
- The filtering value for this constraint. Can be null
or unknown
, in
which case the SQL null
value will be assumed. In this case the predicate
will look like:
new-where := (fr IS NULL) AND (old-query)
format
- The format to be used when comparing values. The reason for this parameter is that
for some datatype (ex: decimal
) the on-screen value can be different from
the database (because of rounding).true
if the filtering constraint was successfully added. If the field
reference is not related to the buffer(s) of this query, false
is returned.public void clearDynamicFilters()
clearDynamicFilters
in interface P2JQuery