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
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 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.
|
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 |
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, inverseSorting, 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.
|
protected boolean |
canOptimize()
Indicate whether this object can be optimized.
|
void |
cleanup()
Clean up resources associated with this query when its scope ends.
|
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).
|
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.
|
void |
forceDynamicOperation()
Force this query to operate in dynamic retrieval mode, if it supports this mode.
|
java.lang.Object[] |
getArgs()
Get the query substitution arguments associated with this query, if any.
|
protected java.lang.Object |
getBreakValue()
Return an object which represents a property value which defines the
end of a sort band.
|
AbstractJoin |
getJoin()
Get the legacy natural join, if any, associated with this query.
|
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.
|
java.lang.String |
getOriginalWhere()
Get the original, HQL where clause associated with this query.
|
RecordBuffer[] |
getRecordBuffers()
Get an array of all record buffers managed by this query.
|
java.lang.Object[] |
getRow()
Assemble an array of primary key IDs or DMOs for the current record(s)
in the buffers underlying this query, from left-most to right-most (in
the sense of how the query joins the associated tables).
|
java.lang.String |
getSortPhrase()
Get the sort phrase associated with this query.
|
int |
getTableCount()
Get the number of tables joined by this query.
|
boolean |
hasWhereExpression()
Indicate whether this query has a client-side where clause expression associated with it.
|
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.
|
void |
load(java.lang.Object[] data,
LockType lockType,
boolean silentIfNullId)
Load one or more records into their associated buffers, given an array
of primary key ID values, or the actual DMOs themselves.
|
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).
|
AdaptiveComponent |
makeAdaptiveServerJoinComponent(java.util.List<AdaptiveComponent> joinList,
AdaptiveQuery query,
int iteration,
boolean outer,
CompoundComponent fallback)
Create an adaptive query component based on the information in this query (which is
presumed to be a single-table query), and given a list of adaptive query components which
represent outer, nested query loops, which will perform a server-side join to the
innermost, nested query component.
|
QueryComponent |
makePreselectServerJoinComponent(java.util.List<QueryComponent> joinList,
int iteration,
boolean outer)
Create a preselect query component based on the information in this query (which is
presumed to be a single-table query), and given a list of preselect query components which
represent outer, nested query loops, which will perform a server-side join to the
innermost, nested query component.
|
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.
|
void |
optimize()
Method which attempts to optimize this object's query components into one or more
server-side joins.
|
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.
|
void |
registerRecordChangeListeners(int scope)
Register all
RecordChangeListener s associated with this
query (if any), with the context-local ChangeBroker at the
indicated scope. |
protected void |
releaseAllBuffers()
Release all backing buffers of for all components.
|
void |
reset(boolean resolveArgs)
Reset the query by clearing its state to a known default.
|
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 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.
|
P2JQuery |
setExternalBuffers(DataModelObject... dmos)
Set one or more buffers which this query references externally.
|
void |
setFullRecords()
Force the query to retrieve full records, rather than primary keys only.
|
void |
setResults(Results results)
Set the given results object into this query.
|
void |
setScrolling()
Create a cursor for this query and ensure that any component queries
are scrollable, whether they already have been added, or are added in
the future.
|
void |
setStandalone(boolean standalone)
Change the standalone nature of this query.
|
void |
setUnknownRecord()
Set each buffer backing the query to unknown mode.
|
void |
stateChanged(RecordChangeEvent event)
Respond to a record change event.
|
void |
unique()
Retrieve a unique record (only valid for a single-table query).
|
void |
unique(LockType lockType)
Retrieve a unique record (only valid for a single-table query),
overriding the default lock type of the underlying query component.
|
_isOffEnd, backward, backward, currentRow, currentRowImpl, forward, forward, incrementMoves, isNativelyPreselect, isPreselect, isScrolling, reposition, reposition, repositionByID, repositionByID, resetScrolling, size, verifyScrolling
accumulate, addAccumulator, addAccumulator, addBuffer, addBuffer, addRepositionListener, afterReposition, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, changeForwardOnly, changeForwardOnly, deleteResultListEntry, exclude, forwardOnly, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, 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, isErrorIfNull, isFetchOnReposition, isLastOfBreakGroup, isNewBreakGroup, isOffEnd, isOpen, isRepositionNotificationActive, isSkipDeletedRecord, isStandalone, numBuffers, numResults, numResults, prepare, prepare, prepareFetch, prepareString, preprocessSubstitutionArguments, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, releaseBuffers, removeRepositionListener, setBuffers, setBuffers, setErrorIfNull, setFetchOnReposition, setParameterFilter, setSkipDeletedRecord, validateSubstitutionArguments
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addAccumulator, addAccumulator, addBuffer, addBuffer, addRepositionListener, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, changeForwardOnly, changeForwardOnly, deleteResultListEntry, exclude, forwardOnly, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, 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, hasAny, hasAny, hasAny, hasAny, hasOne, hasOne, hasOne, hasOne, include, indexInformation, indexInformation, isBrowsed, isFetchOnReposition, isOffEnd, isOpen, isSkipDeletedRecord, isStandalone, numBuffers, prepare, prepare, prepareString, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, removeRepositionListener, setBuffers, setBuffers, setErrorIfNull, setFetchOnReposition, setParameterFilter, setSkipDeletedRecord
private static final java.util.logging.Logger LOG
protected boolean currentRowDeleted
protected boolean foundFirst
protected boolean unregisterOnCleanup
private boolean preselect
private 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
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 setExternalBuffers(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.
setExternalBuffers
in interface P2JQuery
setExternalBuffers
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 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 void unique()
This method is required by the P2JQuery
interface, but it
is invalid for a compound query.
public void unique(LockType lockType)
This method is required by the P2JQuery
interface, but it
is invalid for a compound query.
public java.lang.Object[] peekFirst()
This implementation actually updates the underlying record buffer(s).
public java.lang.Object[] peekLast()
This implementation actually updates the underlying record buffer(s).
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 AdaptiveComponent makeAdaptiveServerJoinComponent(java.util.List<AdaptiveComponent> joinList, AdaptiveQuery query, int iteration, boolean outer, CompoundComponent fallback)
makeAdaptiveServerJoinComponent
in interface Joinable
joinList
- List of adaptive components representing nested query loops which will contain
the adaptive query component returned by this method. The last component in the
list represents the nested query loop immediately containing the returned query
component, with which the join will be made.query
- Adaptive query which will manage the server-side join of joinList
and
the returned query component.iteration
- Iteration type: FIRST, LAST, or NEXT.outer
- true
if the join should be a left outer join. This type of join is
not supported at the time of this writing, so this parameter should always be
false
. It is here to support a planned, future enhancement.fallback
- A compound query component to use in the event the multi-table adaptive query
switches from preselect to dynamic retrieval mode.public QueryComponent makePreselectServerJoinComponent(java.util.List<QueryComponent> joinList, int iteration, boolean outer)
makePreselectServerJoinComponent
in interface Joinable
joinList
- List of preselect components representing nested query loops which will contain
the preselect query component returned by this method. The last component in the
list represents the nested query loop immediately containing the returned query
component, with which the join will be made.iteration
- Iteration type: FIRST, LAST, or NEXT.outer
- true
if the join should be a left outer join. This type of join is
not supported at the time of this writing, so this parameter should always be
false
. It is here to support a planned, future enhancement.public void setFullRecords()
setFullRecords
in interface Joinable
public void setUnknownRecord()
setUnknownRecord
in interface Joinable
RecordBuffer.setUnknownMode()
public void reset(boolean resolveArgs)
public RecordBuffer[] getRecordBuffers()
getRecordBuffers
in interface Joinable
public void load(java.lang.Object[] data, LockType lockType, boolean silentIfNullId) throws MissingRecordException, PersistenceException
The contract of this method is that if an implementor cannot load the
expected value (e.g., the record has been deleted or is otherwise no
longer available), it must throw MissingRecordException
, after
setting the associated buffer into unknown mode
. Note that a record being locked by another session does
not constitute a "missing" record. Note also that this exception must
not be thrown until all the elements of data
have been
processed to the extent possible.
load
in interface Joinable
data
- Array of primary key IDs or DMOs, one per table involved in the
query.lockType
- Lock type which should override that of the query. Set to
null
to allow query to use its current lock type.silentIfNullId
- If true
, do not raise MissingRecordException
if some of the provided IDs are null
. null
IDs are valid for queries with OUTER join.MissingRecordException
- if any record cannot be loaded, because it is no longer
available (e.g., deleted, etc.).PersistenceException
- if there is an error loading data.getRow()
public void setResults(Results results)
setResults
in interface Joinable
results
- New result set for this query.public java.lang.Object[] getRow()
getRow
in interface Joinable
load(Object[], LockType, boolean)
public void registerRecordChangeListeners(int scope)
RecordChangeListener
s associated with this
query (if any), with the context-local ChangeBroker
at the
indicated scope.registerRecordChangeListeners
in interface Joinable
scope
- Scope at which listeners should be registered with the change
broker.public boolean hasWhereExpression()
hasWhereExpression
in interface Joinable
true
if there is a where expression; else false
.public java.lang.Object[] getArgs()
public java.lang.String getOriginalWhere()
getOriginalWhere
in interface Joinable
null
if there is none.public AbstractJoin getJoin()
public void forceDynamicOperation()
forceDynamicOperation
in interface Joinable
public java.lang.String getSortPhrase()
getSortPhrase
in interface Joinable
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 optimize()
This method has public access to enable it to be invoked from other packages within P2J, but it is not meant to invoked from application code.
optimize
in interface P2JQuery
optimize
in class AbstractQuery
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.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.java.lang.UnsupportedOperationException
- always.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 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.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