public class AdaptiveQuery extends PreselectQuery implements RecordChangeListener, VirtualResultsListener
AdaptiveQuery
balances the high performance of a preselect
query implementation with the flexibility of a dynamic query
implementation.
The design point behind this implementation is that in many if not most cases, a preselect query plan is the highest performing strategy. It leverages the strength of the database server to do the heavy lifting of set-oriented data record retrieval. In most use cases, this is the most appropriate retrieval strategy. However, to emulate Progress' semantic, it is necessary to reflect table updates in a query which has already begun iterating through its result set. This dynamic approach is much slower in the P2J architecture, since it requires at minimum one, and sometimes many more round trips to the server for each record retrieved. Therefore it is desirable to avoid dynamic retrieval mode whenever possible.
The one performance weakness of the preselect approach is the case where
client code does not need the full result set acquired by the query. To
deal with this, AdaptiveQuery
uses an instance of ProgressiveResults
to fetch progressively larger brackets of result set
data while in preselect mode. Thus, early results are returned quickly,
and if more results are needed, they are fetched in increasingly larger
batches. This amortizes the access cost most effectively for both ends of
the spectrum: use cases which require only one or a handful of results
never incur the cost of larger fetches and use cases which require many
results acquire them with far fewer calls than in dynamic mode.
AdaptiveQuery
takes an optimistic approach by operating in
preselect mode immediately and for as long as possible. It registers as a
ChangeBroker
listener. If during its preselect mode operation it
receives notification of a DMO state change which would invalidate its
current result set, it automatically switches over to dynamic retrieval
mode. It will remain in dynamic mode for as long as necessary, but will
switch back into preselect mode at the earliest opportunity.
Once switching from preselect to dynamic mode, the query will operate in
this mode until the underlying DynamicResults
object detects
that it is possible to switch back to preselect mode. This occurs when
the DynamicQuery
underlying the DynamicResults
object crosses a sort band boundary. A sort band is the
grouping defined by the coarsest sort criterion of the query. A boundary
is crossed when the DMO property defining the sort band changes from one
retrieved record to the next. The value of this property in the last
record before the boundary is crossed is termed the break value.
When the break value for the underlying dynamic query is non-null, this is
an indication that the sort band boundary has been crossed. At this point,
it is possible to construct a new preselect mode query which uses all the
original query criteria, plus the break value, to ensure the query results
pick up where the dynamically retrieved result set ended.
TODO: Make invalidation check more robust; currently it is too conservative.
TODO: Make revalidation failsafe more sophisticated; currently it locks into dynamic mode
after MAX_REVALIDATIONS
revalidations.
TODO: Make global invalidation setting configurable from the directory.
Modifier and Type | Class and Description |
---|---|
private class |
AdaptiveQuery.DynamicResults
An implementation of the
Results interface which uses a single
table or multi-table DynamicQuery as a delegate. |
private class |
AdaptiveQuery.ResultsSource
A
ResultsProvider implementation which is invoked when
transitioning between preselect and dynamic modes (both directions). |
P2JQuery.Parameter, P2JQuery.QueryOpenedListener, P2JQuery.QueryOpenListener
SessionListener.Event, SessionListener.Scope
Modifier and Type | Field and Description |
---|---|
private ResultsAdapter |
adapter
Results adapter which can connect to different low-level delegates
|
private java.lang.Object |
breakValue
Property value which indicates a new sort band in dynamic mode
|
private boolean |
cacheOnReval
Preselected results should all be cached on next revalidation
|
protected Cursor |
cursor
Represents cache of the dynamic scrolling query.
|
protected boolean |
errorCondition
Reflects whether an error was detected while getting results
|
private static boolean |
forceGlobalInvalidation
Force invalidation checks across all sessions
|
protected boolean |
foundFirst
Determines if we have fetched a result row.
|
private boolean |
globalInvalidation
Implement invalidation checks across all sessions
|
private Results |
highLevelResults
High level results object for parent query
|
private java.util.Map<java.lang.String,java.util.Set<java.lang.String>> |
invalidationProperties
Properties whose changes trigger invalidation, keyed by DMO entity
|
private AdaptiveComponent |
invalidComponent
Query component which triggered invalidation
|
private static java.util.logging.Logger |
LOG
Logger
|
private static int |
MAX_REVALIDATIONS
Maximum number of times query can switch from dynamic to preselect mode
|
private boolean |
resultsCached
Are results cached due to a previously committed transaction?
|
private int |
revalCount
Number of times this query has transitioned back to preselect mode
|
private boolean |
unregisterOnCleanup
Determines if this will be unregistered from ChangeBroker on cleanup.
|
betweenRows, components, currentRowDeleted, offEnd, sort
closed, dynamicPredicate, indexedReposition, inverseSorting, outer, parameterFilter
CURRENT, FIRST, LAST, NEXT, NONE, PREVIOUS, RETRIEVE_MODES, UNIQUE
Constructor and Description |
---|
AdaptiveQuery()
Default constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
DataModelObject inverse)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
DataModelObject inverse,
LockType lockType)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
DataModelObject inverse,
java.lang.Object[] args)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
DataModelObject inverse,
java.lang.Object[] args,
LockType lockType)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
DataModelObject inverse,
java.lang.Object[] args,
LockType lockType,
int iteration,
boolean outer)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
LockType lockType)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
java.lang.Object[] args)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
java.lang.Object[] args,
LockType lockType)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
java.lang.Object[] args,
LockType lockType,
int iteration,
boolean outer)
Add a component to the query.
|
void |
addComponent(DataModelObject dmo,
java.lang.String where,
java.lang.String sort,
java.lang.String indexInfo,
DataModelObject inverse,
java.lang.Object[] args,
LockType lockType,
int iteration,
boolean outer)
Add a component to the query.
|
(package private) void |
addDynamicSortCriterion(FieldReference fr,
boolean asc)
Adds a new sorting criterion as the strongest criterion for sorting the result of this
query.
|
protected java.util.List<SortCriterion> |
assembleOrderByClause()
Assemble the
order by clause for an FQL query by combining the sort criteria from each query
component sequentially. |
protected HQLExpression |
assembleWhereClause(java.util.List<SortCriterion> sortCriteria)
Assemble the restriction (i.e., where) clause for an FQL query.
|
boolean |
backward(int rows)
Move the current cursor position backward by the specified number of
rows.
|
void |
cleanup()
Clean up query resources when this query's scope ends.
|
(package private) void |
clearDynamicSortCriteria()
Clears any dynamically sort criteria added at runtime.
|
void |
close(boolean inResource)
Explicitly close the prepared query.
|
protected DynamicQuery |
createCompoundQuery(AdaptiveComponent invalidComp)
Create a multi-table, compound query to be used as the worker object
for a
DynamicResults object when this query switches from
preselect to dynamic mode. |
logical |
createResultListEntry()
Creates an entry in the result list for the current row.
|
protected Results |
createResults(Results results)
Override the parent's implementation to intercept result creation, and
always return our adapter, after setting the
results
parameter as the adapter's delegate. |
protected DynamicQuery |
createSimpleQuery(AdaptiveComponent invalidComp)
Create a single-table, dynamic query to be used as the worker object
for a
DynamicResults object when this query switches from
preselect to dynamic mode. |
void |
current(LockType lockType)
Reload the current composite row of results for the query, overriding
the lock type to apply to each record.
|
integer |
currentRow()
Progress-compatible function that returns the 1-based index of the
current row in the result set.
|
integer |
currentRowImpl()
Get the 1-based index of the current row in the result set.
|
logical |
deleteResultListEntry(boolean allowBetweenRows)
Deletes the current row of a query's result list.
|
private boolean |
doubleCheckInvalidation(RecordChangeEvent event)
Given a record change event for which this query is listening, determine
whether invalidation may be avoided.
|
protected boolean |
execute()
Overrides the parent's pure preselect implementation to use a different
retrieval techniques depending upon the current mode of the query.
|
protected Results |
executeQuery(Persistence persistence,
java.lang.String fql,
java.lang.Object[] args)
Execute the query to create a first level result set.
|
protected void |
fetch(boolean available,
LockType lockType,
boolean errorIfNull)
Fetch all records for a given result row into their backing buffers.
|
void |
first(LockType lockType)
Retrieve the first composite row of results for the query.
|
void |
forceDynamicOperation()
Force this query to operate in dynamic retrieval mode, if it supports this mode.
|
boolean |
forward(int rows)
Advance the current cursor position forward by the specified number of
rows.
|
java.lang.Object[] |
getCachedRow()
Assemble an array of primary key IDs 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).
|
protected java.lang.Object[] |
getCurrentIds()
Get array of the primary keys of the records contained in the backing buffers.
|
protected java.lang.Object[] |
getCurrentIds(boolean nullable)
Get array of the primary keys of the records contained in the backing buffers.
|
java.lang.Object[] |
getRow()
Assemble an array of primary key IDs 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).
|
protected void |
handleMissingJoinRecord()
Respond to the condition that a component with a non-null JOIN has a
missing inverse on which to perform the join.
|
AdaptiveQuery |
initialize()
Initialization logic which is typically used for a multi-table query.
|
AdaptiveQuery |
initialize(boolean lenientOffEnd)
Initialization logic which is typically used for a multi-table query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
DataModelObject inverse)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
DataModelObject inverse,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
DataModelObject inverse,
java.lang.Object[] args)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
DataModelObject inverse,
java.lang.Object[] args,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.Object[] args)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.Object[] args,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
DataModelObject inverse)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
DataModelObject inverse,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
DataModelObject inverse,
java.lang.Object[] args)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
DataModelObject inverse,
java.lang.Object[] args,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
java.lang.Object[] args)
Initialization logic designed for a single-table adaptive query.
|
AdaptiveQuery |
initialize(DataModelObject dmo,
java.lang.String where,
java.util.function.Supplier<logical> whereExpr,
java.lang.String sort,
java.lang.String indexInfo,
java.lang.Object[] args,
LockType lockType)
Initialization logic designed for a single-table adaptive query.
|
private void |
invalidate()
Invalidate the query by using the last query component as the invalid component.
|
(package private) void |
invalidate(AdaptiveComponent invalidComponent)
Invalidate the preselected result set of this query, which effectively
switches this query from preselect mode to dynamic mode.
|
private void |
invalidate(RecordChangeEvent event)
Invalidate the preselected result set of this query, which effectively
switches this query from preselect mode to dynamic mode.
|
protected void |
invalidateIfReferenceRowExists()
Invalidate the query if reference row exists.
|
protected boolean |
isGlobalInvalidation()
Report whether this query must check for changes across all sessions and
possibly invalidate its current results if any are found.
|
boolean |
isNativelyPreselect()
Indicate whether this query is a preselect query by its nature.
|
protected boolean |
isNativelyScrolling()
Indicate whether this query type is scrolling by its nature.
|
boolean |
isPreselect()
Indicate whether this query preselects all of its results.
|
void |
last(LockType lockType)
Retrieve the last composite row of results for the 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)
Load all records for a given result row into their backing buffers.
|
void |
next(LockType lockType)
Retrieve the next composite row of results for the query.
|
void |
open()
Open the query, first registering with the
ChangeBroker at
the appropriate scope. |
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 |
prepareParameters(java.util.List<java.lang.Object> args)
Prepare query substitution parameters for this query.
|
void |
previous(LockType lockType)
Retrieve the previous composite row of results for the query.
|
private boolean |
probablyRequiresResort()
Indicate whether the query results as initially fetched are likely to require a re-sort before they
are returned.
|
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. |
void |
reposition(int row)
Reposition the query to the specified row in the result set.
|
protected boolean |
repositionByID(java.lang.Long[] ids,
boolean forceFetch)
Reposition the cursor such that a request to retrieve the next result
will retrieve the result which matches the specified array of primary
key IDs.
|
protected boolean |
repositionByID(java.lang.Long[] ids,
boolean forceFetch,
boolean scan)
Reposition the cursor such that a request to retrieve the next result
will retrieve the result which matches the specified array of primary
key IDs.
|
void |
reset(boolean resolveArgs)
Reset the query by clearing its state to a known default.
|
private void |
resetDynamicScrolling()
If in dynamic mode, reset the cursor underlying the dynamic query in
order to prevent stale data.
|
protected void |
resetResults()
Reset the state of the results adapter to its initial default state and
invoke the superclass' overridden method.
|
void |
resultsChanged()
This function is called when ProgressiveResults has detected changes in retrieved results.
|
private void |
revalidate(java.lang.Object breakValue)
Begin the transition of this query from dynamic to preselect mode.
|
boolean |
sessionEvent(SessionListener.Event event)
Respond to a dirty (i.e., error-driven) session closing event by
invalidating any current, preselected results.
|
void |
setScrolling()
Makes this query scrolling.
|
private void |
setupInvalidationProperties()
Set up the map of DMO implementation classes to sets of properties
which, if changed, would invalidate the current, preselected result set
for this query.
|
protected void |
setWorkerRefererenceRecord(RandomAccessQuery query)
For single-table query: set the first component of the reference row as the reference record
for the worker query.
|
integer |
size()
Return the number of results found for this query.
|
void |
stateChanged(RecordChangeEvent event)
Respond to a record change event by invalidating the current preselect
results, if currently in preselect mode and the state change impacts
the validity of the current results.
|
protected void |
storeReferenceRow(RecordChangeEvent event)
Store the last fetched row as the reference row for future iterations.
|
java.lang.String |
toString()
Create a string representation of this object's state, primarily for debug purposes.
|
protected boolean |
treatPreviousAsLast()
Indicate whether a call to move to the previous record in the result list should be treated
as a call to move to the last record in the list.
|
_isOffEnd, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addComponent, addDynamicFilter, addWhereExpression, anyBoundBufferInComponent, assembleFromClause, assembleOrderByClause, assembleOrderByClause, assembleSelectClause, backward, buildSortCriteria, cacheResults, clearDynamicFilters, clearRepoCache, close, components, coreFetch, current, deleted, deregisteredSessionListener, executeScroll, finished, first, forward, getArgs, getEntities, getExternalBuffers, getHQL, getJoin, getOffEnd, getOffEndListeners, getOriginalWhere, getPersistence, getRecordBuffers, getResults, getSortPhrase, getTableCount, getTemplateQueryRowid, getWhereExpressions, hasWhereExpression, indexInformation, initialize, initialize, isClientWhere, isFullRecords, isLenientOffEnd, isScrolling, isTopLevelCleanup, iterate, last, makeAdaptiveServerJoinComponent, makePreselectServerJoinComponent, next, peekFirst, peekLast, prepareReposition, preserveBuffersOnEmptyResults, previous, processJoin, registerCleaner, releaseBuffers, reposition, repositionByID, repositionByID, repositionByID, retry, setEmptyBuffersUnknown, setFullRecords, setIterationType, setIterationType, setLenientOffEnd, setNonScrolling, setResults, setUnknownRecord, supportsArbitraryIteration, unique, unique, verifyJoins, whereExpressions
_isSkipDeletedRecord, accumulate, addAccumulator, addAccumulator, addBuffer, addBuffer, addExternalBuffers, addQueryOpenListener, addRepositionListener, afterReposition, afterReposition, afterReposition, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, buffersMatch, changeForwardOnly, changeForwardOnly, deleteResultListEntry, exclude, forwardOnly, getCache, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getCurrent, getDefaultLock, 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, loadRowAtCursor, notifyQueryOpenListeners, notifyRepositionListeners, numBuffers, numResults, numResults, prepare, prepare, prepareFetch, prepareString, preprocessSubstitutionArguments, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, removeRepositionListener, setBrowsed, setBuffers, setBuffers, setCache, setCache, setDynamicPredicate, setErrorIfNull, setFatalError, setFetchOnReposition, setFillingBrowseRows, setIndexedReposition, setOmitAlias, setOuter, setParameterFilter, setSkipDeletedRecord, setStandalone, translateSort, translateSort, translateWhere
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getReferencedBuffers, setErrorIfNull, setOuter
addAccumulator, addAccumulator, addExternalBuffers, 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, 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, isDynamicPredicate, isFetchOnReposition, isFillingBrowseRows, isFindByRowid, isFirstOfGroup, isFirstOfGroup, isIndexedReposition, isLastOfGroup, isLastOfGroup, isOffEnd, isSkipDeletedRecord, isStandalone, notifyQueryOpenListeners, notifyRepositionListeners, prepare, prepare, prepareString, queryBackward, queryBackward, queryClose, queryForward, queryForward, queryOpen, queryReposition, queryReposition, queryRepositionByID, queryRepositionByID, removeRepositionListener, resetQuery, setBasicLogging, setBasicLogging, setBrowsed, setCache, setCache, setDynamicPredicate, setFetchOnReposition, setFillingBrowseRows, setIndexedReposition, setParameterFilter, setSkipDeletedRecord, setStandalone
addBuffer, addBuffer, addBuffer, addBuffer, bufferHandle, bufferHandle, bufferHandle, bufferHandle, bufferHandle, numBuffers, setBuffers, setBuffers, setBuffers
entry, initFailure, weight
private static final int MAX_REVALIDATIONS
private static final java.util.logging.Logger LOG
private static final boolean forceGlobalInvalidation
private ResultsAdapter adapter
private boolean globalInvalidation
private Results highLevelResults
private AdaptiveComponent invalidComponent
private java.util.Map<java.lang.String,java.util.Set<java.lang.String>> invalidationProperties
private java.lang.Object breakValue
private int revalCount
private boolean resultsCached
private boolean cacheOnReval
protected boolean errorCondition
protected Cursor cursor
protected boolean foundFirst
private boolean unregisterOnCleanup
public AdaptiveQuery()
initialize()
is
called.public AdaptiveQuery initialize()
addComponent
method variants.
Each component will provide its own sort criteria; they are combined when the query is first executed in preselect mode.
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.
public AdaptiveQuery initialize(boolean lenientOffEnd)
addComponent
method variants.
This variant is used by code which is converted from an OPEN QUERY
statement, which permits advancing off the end of a result set without
raising a QueryOffEndException
.
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.
lenientOffEnd
- true
if advancing past either end of the result
set should NOT raise a QueryOffEndException
;
false
if doing so should raise the exception.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, DataModelObject inverse)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, DataModelObject inverse)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.inverse
- DMO to which this query should join via a foreign relation.
May be null
.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.Object[] args)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.args
- Substitution parameters to be inserted into placeholders within
the where clause.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, java.lang.Object[] args)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.args
- Substitution parameters to be inserted into placeholders within
the where clause.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, DataModelObject inverse, java.lang.Object[] args)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, DataModelObject inverse, java.lang.Object[] args)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, DataModelObject inverse, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, DataModelObject inverse, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.inverse
- DMO to which this query should join via a foreign relation.
May be null
.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.Object[] args, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, java.lang.Object[] args, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, DataModelObject inverse, java.lang.Object[] args, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this query.public AdaptiveQuery initialize(DataModelObject dmo, java.lang.String where, java.util.function.Supplier<logical> whereExpr, java.lang.String sort, java.lang.String indexInfo, DataModelObject inverse, java.lang.Object[] args, LockType lockType)
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.
initialize
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.whereExpr
- Client-side where clause expression. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this query.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, DataModelObject inverse)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, java.lang.Object[] args)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.args
- Substitution parameters to be inserted into placeholders within
the where clause.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, DataModelObject inverse, java.lang.Object[] args)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, LockType lockType)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.lockType
- Lock type to apply to records retrieved by this component of
the query.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, DataModelObject inverse, LockType lockType)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.lockType
- Lock type to apply to records retrieved by this component of
the query.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, java.lang.Object[] args, LockType lockType)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this component of
the query.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, DataModelObject inverse, java.lang.Object[] args, LockType lockType)
NEXT
iteration type
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this component of
the query.public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, java.lang.Object[] args, LockType lockType, int iteration, boolean outer)
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this component of
the query.iteration
- Iteration/retrieval mode for this component of the query.
Only NEXT
is supported.outer
- true
if an outer join is required. At this time,
only inner joins are supported. Future support for outer
joins is expected.java.lang.UnsupportedOperationException
- if outer
is true
(temporary);
if iteration
is not NEXT
(temporary);
if dmo
's associated database is different than
that of a previously added component's database (cross-database
preselect joins are not possible).public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, DataModelObject inverse, java.lang.Object[] args, LockType lockType, int iteration, boolean outer)
addComponent
in class PreselectQuery
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this component of
the query.iteration
- Iteration/retrieval mode for this component of the query.
Only NEXT
is supported.outer
- true
if an outer join is required. At this time,
only inner joins are supported. Future support for outer
joins is expected.java.lang.UnsupportedOperationException
- if outer
is true
(temporary);
if iteration
is not NEXT
(temporary);
if dmo
's associated database is different than
that of a previously added component's database (cross-database
preselect joins are not possible).public void addComponent(DataModelObject dmo, java.lang.String where, java.lang.String sort, java.lang.String indexInfo, DataModelObject inverse, java.lang.Object[] args, LockType lockType, int iteration, boolean outer)
dmo
- DMO proxy which defines buffer and record type.where
- FQL where clause. May be null
.sort
- FQL order by clause.indexInfo
- Index information string as it is returned by INDEX-INFORMATION.
May be null
if it is not an OPEN QUERY case or if
you don't need debug information about selected indexes.inverse
- DMO to which this query should join via a foreign relation.
May be null
.args
- Substitution parameters to be inserted into placeholders within
the where clause.lockType
- Lock type to apply to records retrieved by this component of
the query.iteration
- Iteration/retrieval mode for this component of the query.
Only NEXT
is supported.outer
- true
if an outer join is required. At this time,
only inner joins are supported. Future support for outer
joins is expected.java.lang.UnsupportedOperationException
- if outer
is true
(temporary);
if iteration
is not NEXT
(temporary);
if dmo
's associated database is different than
that of a previously added component's database (cross-database
preselect joins are not possible).public void open()
ChangeBroker
at
the appropriate scope.open
in interface P2JQuery
open
in class PreselectQuery
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
registerRecordChangeListeners
in class PreselectQuery
scope
- Scope at which listeners should be registered with the change
broker.public void first(LockType lockType)
If the query involves outer joins, some of the underlying buffers may be empty when this method returns.
first
in interface P2JQuery
first
in class PreselectQuery
lockType
- Lock type to apply to records retrieved (overrides default
lock type set for each query component).ErrorConditionException
- if the query or the fetch of any record fails, or if no records
are available and the query is set to fail in this case.QueryOffEndException
- if no records are available and the query is set not to fail
in this case.java.lang.IllegalStateException
- if no query component has been added to this query.public void last(LockType lockType)
If the query involves outer joins, some of the underlying buffers may be empty when this method returns.
last
in interface P2JQuery
last
in class PreselectQuery
lockType
- Lock type to apply to records retrieved (overrides default
lock type set for each query component).ErrorConditionException
- if the query or the fetch of any record fails, or if no records
are available and the query is set to fail in this case.QueryOffEndException
- if no records are available and the query is set not to fail
in this case.java.lang.IllegalStateException
- if no query component has been added to this query.public integer currentRowImpl()
currentRowImpl
in interface P2JQuery
currentRowImpl
in class PreselectQuery
public integer currentRow()
currentRow
in interface P2JQuery
currentRow
in class PreselectQuery
public void current(LockType lockType)
If the query involves outer joins, some of the underlying buffers may be empty when this method returns.
current
in interface P2JQuery
current
in class PreselectQuery
lockType
- Lock type which should override that of any query component.ErrorConditionException
- if the reload triggers an error.java.lang.IllegalStateException
- if no query component has been added to this query.public void reposition(int row)
reposition
in interface P2JQuery
reposition
in class PreselectQuery
row
- 1-based index of the target position.ErrorConditionException
- if there is an error repositioning the cursor.public boolean forward(int rows)
forward
in interface P2JQuery
forward
in class PreselectQuery
rows
- Number of rows to scroll the cursor forward.true
if operation was successful and the cursor was moved the exact amount
of rows as specified by the parameter. If false
is returned then it is
possible that cursor's position was moved but not with rows
rows.ErrorConditionException
- if there is an error repositioning the cursor.protected boolean repositionByID(java.lang.Long[] ids, boolean forceFetch)
repositionByID
in class PreselectQuery
ids
- Array of primary key IDs, arranged from left to right to
coincide with the records being joined by the underlying
query.forceFetch
- true
to override the current fetch-on-reposition
setting to true
, in case the underlying
Results
implementation attempts to fetch the
record during repositioning; false
to honor the
current setting.true
if reposition was successful;
false
if unsuccessful.ErrorConditionException
- if there is an error repositioning the cursor.protected boolean repositionByID(java.lang.Long[] ids, boolean forceFetch, boolean scan)
ids
- Array of primary key IDs, arranged from left to right to
coincide with the records being joined by the underlying
query.forceFetch
- true
to override the current fetch-on-reposition
setting to true
, in case the underlying
Results
implementation attempts to fetch the
record during repositioning; false
to honor the
current setting.scan
- For scrolling queries: true
to scan all results in
the event a match is not found in the cache; false
to check the cache only.true
if reposition was successful;
false
if unsuccessful.ErrorConditionException
- if there is an error repositioning the cursor.public integer size()
Note that the first time this method is invoked, the database server may have to scroll to the end of the result set, which may be a time-consuming process for a large result set.
size
in interface P2JQuery
size
in class PreselectQuery
public void next(LockType lockType)
next
in interface P2JQuery
next
in class PreselectQuery
lockType
- Lock type to apply to records retrieved (overrides default
lock type set for each query component).ErrorConditionException
- if the query or the fetch of any record fails, or if no records
are available and the query is set to fail in this case.QueryOffEndException
- if no records are available and the query is set not to fail
in this case.java.lang.IllegalStateException
- if no query component has been added to this query.public java.lang.Object[] peekNext()
peekNext
in interface Scrollable
peekNext
in class PreselectQuery
null
if there is no such result.public java.lang.Object[] peekPrevious()
peekPrevious
in interface Scrollable
peekPrevious
in class PreselectQuery
null
if there is no such result.public void previous(LockType lockType)
previous
in interface P2JQuery
previous
in class PreselectQuery
lockType
- Lock type to apply to records retrieved (overrides default
lock type set for each query component).ErrorConditionException
- if the query or the fetch of any record fails, or if no records
are available and the query is set to fail in this case.QueryOffEndException
- if no records are available and the query is set not to fail
in this case.java.lang.IllegalStateException
- if no query component has been added to this query.public boolean backward(int rows)
backward
in interface P2JQuery
backward
in class PreselectQuery
rows
- Number of rows to scroll the cursor backward.true
if operation was successful and the cursor was moved the exact amount
of rows as specified by the parameter. If false
is returned then it is
possible that cursor's position was moved but not with rows
rows.ErrorConditionException
- if there is an error repositioning the cursor.public void reset(boolean resolveArgs)
This implementation nulls out the current result set, so that the next record retrieval request triggers a new server-side query. Optionally, it also resets resolvable substitution arguments and triggers where expression arguments to be resolved, if a client-side where cause expression is defined.
For scrolling queries cache is reset.
reset
in interface Joinable
reset
in class PreselectQuery
resolveArgs
- true
if query substitution arguments should be
resolved/reset as part of the reset; false
if
existing argument values should be used for the next query
execution.public void load(java.lang.Object[] data, LockType lockType, boolean silentIfNullId) throws MissingRecordException, PersistenceException
In the event an expected value cannot be loaded (e.g., the record has
been deleted or is otherwise no longer available), this method throws
MissingRecordException
, after setting the associated buffer(s)
into unknown mode
. Note that a
record being locked by another session does not constitute a "missing"
record. Note also that this exception is not thrown until all the
elements of data
have been processed to the extent
possible.
load
in interface Joinable
load
in class PreselectQuery
data
- Array of primary key IDs or DMOs, one per table involved in the
query.lockType
- Lock type which should by used. 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.Joinable.getRow()
public java.lang.Object[] getRow()
This method overrides the parent's implementation to handle the case
where we have just transitioned from preselect to dynamic mode, but we
do not yet have a Results
object from which to gather data.
We generate a dynamic Results
object and position to the
first result, then use the parent's implementation to gather the data.
getRow
in interface Joinable
getRow
in class PreselectQuery
load(java.lang.Object[], com.goldencode.p2j.persist.lock.LockType, boolean)
public java.lang.Object[] getCachedRow()
For scrolling queries it gets the row from the cache instead of interrogating
results
. For non-scrolling queries it works in the same way as getRow()
.
load(Object[], LockType, boolean)
public boolean sessionEvent(SessionListener.Event event) throws PersistenceException
On a clean (i.e., no error) session closing event, delegate the event to the results adapter.
sessionEvent
in interface SessionListener
sessionEvent
in class PreselectQuery
event
- Session event type.false
, indicating this
query should not be deregistered as a session listener after
this method returns. Under an error condition, return
true
.PersistenceException
- not thrown (required by interface).public java.lang.String toString()
toString
in class PreselectQuery
public boolean isPreselect()
isPreselect
in interface P2JQuery
isPreselect
in class PreselectQuery
true
if the query currently is in preselect mode,
false
if its result set has been invalidated.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 resultsChanged()
resultsChanged
in interface VirtualResultsListener
public void close(boolean inResource)
close
in interface P2JQuery
close
in class PreselectQuery
inResource
- Flag indicating this query is used in a QUERY legacy resource.public void cleanup()
cleanup
in interface P2JQuery
cleanup
in class PreselectQuery
PreselectQuery.cleanup()
public void setScrolling()
setScrolling
in interface P2JQuery
setScrolling
in class PreselectQuery
public boolean isNativelyPreselect()
isNativelyPreselect
in interface P2JQuery
isNativelyPreselect
in class PreselectQuery
false
.public logical deleteResultListEntry(boolean allowBetweenRows)
deleteResultListEntry
in interface P2JQuery
deleteResultListEntry
in class PreselectQuery
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 PreselectQuery
true
on success.public void forceDynamicOperation()
forceDynamicOperation
in interface Joinable
forceDynamicOperation
in class PreselectQuery
protected boolean isNativelyScrolling()
isNativelyScrolling
in class PreselectQuery
false
.protected boolean isGlobalInvalidation()
true
to require global invalidation checks;
false
to only check locally for changes which may
invalidate results.void addDynamicSortCriterion(FieldReference fr, boolean asc)
Use clearDynamicSortCriteria()
to clean all dynamically added criteria and restore the
sorting order of the query to its original form.
addDynamicSortCriterion
in class PreselectQuery
fr
- A reference to field used as new strongest criterion. The current criteria will
be kept, but with lower priority.asc
- The direction of sorting for this criterion. Use true
for ascending sort
and false
for descending sorting.void clearDynamicSortCriteria()
clearDynamicSortCriteria
in class PreselectQuery
protected HQLExpression assembleWhereClause(java.util.List<SortCriterion> sortCriteria) throws PersistenceException
where ({component0_clause}) [and ({component1_clause}) [...]]
Please refer to the Hibernate reference documentation for permissible syntax of this clause.
assembleWhereClause
in class PreselectQuery
sortCriteria
- List of SortCriterion
objects which describe the
sort behavior for this query.PersistenceException
- if there is an error creating the HQLPreprocessor
from which the preprocessed where clause is retrieved for each
query component.protected java.util.List<SortCriterion> assembleOrderByClause()
order by
clause for an FQL query by combining the sort criteria from each query
component sequentially.
Any text-based sort criteria are augmented with the necessary upper()
and rtrim()
functions.assembleOrderByClause
in class PreselectQuery
SortCriterion
objects which describe the sort behavior for this query.PersistenceException
- if the sort clause of any query component contains any unqualified property names;
if a sort clause contains a reference to an unrecognized record buffer;
if there is an error creating the HQLPreprocessor
from which setup data is required.protected void prepareParameters(java.util.List<java.lang.Object> args) throws PersistenceException
breakValue
as a
parameter if it is non-null. A non-null
breakValue
indicates that the query
is shifting from dynamic mode to preselect mode. All records retrieved from this point
forward must not include those already retrieved, and the breakValue
demarcates
this boundary. The where clause will have been modified to include a comparison operation
with the breakValue
in this case.prepareParameters
in class PreselectQuery
args
- Argument list to be populated.PersistenceException
- if there is an error creating an HQLPreprocessor
during the gathering of
query substitution parameters.protected boolean execute()
In this case, a logical DynamicResults
object is created
the first time through this method after invalidation. Thereafter,
this object is simply used as a regular Results
object, in that
parent's PreselectQuery.fetch(boolean, com.goldencode.p2j.persist.lock.LockType, boolean)
method uses the new results
object without knowing or caring that it has been substituted with a
dynamic implementation.
In addition, if this query is set to check for global DMO change events, such events are collected and processed, which will possibly invalidate the query's current results, or cause a change to dynamic mode.
execute
in class PreselectQuery
true
if the underlying preselect result set was
created during this invocation; false
if query
was executed previously and we already have a preselect result
set.ErrorConditionException
- if an error occurs executing the preselect query.java.lang.IllegalStateException
- if no query component has been added to this query.protected void handleMissingJoinRecord()
This implementation is a placeholder which currently defers to the parent's implementation.
handleMissingJoinRecord
in class PreselectQuery
protected boolean treatPreviousAsLast()
PreselectQuery.treatPreviousAsLast()
, but only if the query is in preselect
mode. That fixes previous mistakenly treated as last after query invalidation.treatPreviousAsLast
in class PreselectQuery
true
to treat a previous request as a request to move to the last
record in the list; else false
.protected Results executeQuery(Persistence persistence, java.lang.String fql, java.lang.Object[] args) throws PersistenceException
If we are executing the query after a re-validation, or if the query's sort phrase does not match
any legacy index, fall back to the superclass' implementation. Otherwise, this implementation creates
an instance of ProgressiveResults
, which defers actually executing the query until
the first request to fetch a result.
executeQuery
in class PreselectQuery
persistence
- Object which is used to execute the query.fql
- FQL query string.args
- Substitution parameters to be inserted into placeholders within the FQL query
string.ProgressiveResults
which fetches progressively larger
brackets of query results as the results are accessed.PersistenceException
- not thrown by this implementation.protected Results createResults(Results results) throws PersistenceException
results
parameter as the adapter's delegate.createResults
in class PreselectQuery
results
- An object which manipulates the database result set returned
from execution of the query.Results
object.PersistenceException
- if there is any error creating results.protected DynamicQuery createSimpleQuery(AdaptiveComponent invalidComp) throws PersistenceException
DynamicResults
object when this query switches from
preselect to dynamic mode. Creates a modified implementation of
RandomAccessQuery
, which does not reset the record buffer
upon instantiation.invalidComp
- Query component which caused this query to be invalidated.RandomAccessQuery
based upon this query's single
component.PersistenceException
- if there is an error creating the HQLPreprocessor
from which setup data is required.protected DynamicQuery createCompoundQuery(AdaptiveComponent invalidComp) throws PersistenceException
DynamicResults
object when this query switches from
preselect to dynamic mode. Uses the parent query's components to
define a Joinable
instance for each of the compound
query's own components.
Single-table AdaptiveQuery
instances are used for every
joinable component, except the one corresponding to the buffer which
caused invalidation of the preselect result set. For the component
corresponding with this buffer, an instance of
RandomAccessQuery
is used instead.
invalidComp
- Query component which caused this query to be invalidated.CompoundQuery
based upon this query's multiple
components.PersistenceException
- if there is an error creating the HQLPreprocessor
from which setup data is required.protected void resetResults()
resetResults
in class PreselectQuery
protected java.lang.Object[] getCurrentIds()
null
if any of the buffers doesn't contain a record.protected java.lang.Object[] getCurrentIds(boolean nullable)
nullable
- If a buffer doesn't contain a record, then depending on the value of this
parameter, null
is returned (if nullable
is
true
) or null
element is added to the resulting array (if
nullable
is false
).null
if any of the buffers doesn't contain a record and
nullable
is true
.protected boolean loadByValues(java.lang.Object[] data, LockType lockType)
data
- An array of primary key IDs or DMOs representing records to be fetched for the
composite row.lockType
- Overriding lock type to apply to fetched records. If null, default lock types are
applied.true
if the record(s) were successfully loaded.protected void fetch(boolean available, LockType lockType, boolean errorIfNull) throws MissingRecordException
fetch
in class PreselectQuery
available
- true
if the most recent scrollable cursor move
left the cursor at an available result row; false
if the cursor cannot read a result at its current position.lockType
- Overriding lock type to apply to fetched records. If
null
, default lock types are applied.errorIfNull
- true
if failed retrievals should raise error.MissingRecordException
- if the record was expected to be available, but wasn't. This
typically indicates the record was deleted between the time it
initially was found by the query and the time it was to be
fetched to store in the record buffer.ErrorConditionException
- if the fetch of any record fails or if no records are available
and the query is set to fail in this case.QueryOffEndException
- if no records are available and the query is set not to fail
in this case.protected void storeReferenceRow(RecordChangeEvent event)
event
- Event caused by update of a record of specific type.protected void invalidateIfReferenceRowExists()
protected void setWorkerRefererenceRecord(RandomAccessQuery query)
query
- Worker query.void invalidate(AdaptiveComponent invalidComponent)
invalidComponent
- Query component which is triggering invalidation.private boolean probablyRequiresResort()
This method makes an assumption (which will not be correct in all cases) that if an index on the first
table exactly matches the sort phrase, it will be used to fetch the results. However, the database
query planner may well select a different index, based on the WHERE clause. In that case, this method
will report incorrectly that a re-sort is not required, which may lead to "chunking" the
result set with ProgressiveResults
when this is not the most efficient approach. However, it
may help detect some cases where a re-sort will take place, avoiding this anti-pattern.
true
if there is no sort phrase, or if the sort phrase does not match any legacy
index of the first query component table.private boolean doubleCheckInvalidation(RecordChangeEvent event)
This additional check is about detecting whether it is possible that a modified or newly inserted record can possibly appear later in the preselected result set than the record we currently are visiting.
event
- Event which describes the DMO state change.true
if invalidation is confirmed;
false
to abandon invalidation.private void resetDynamicScrolling()
private void setupInvalidationProperties() throws PersistenceException
PersistenceException
- if there is an error creating the HQLPreprocessor
from which setup data is required.private void invalidate(RecordChangeEvent event)
event
- Object which holds information about the DMO state change
which occurred.private void invalidate()
private void revalidate(java.lang.Object breakValue)
fetch(boolean, com.goldencode.p2j.persist.lock.LockType, boolean)
and execute()
methods.breakValue
- The sort band break value which indicates that the current,
dynamic query has crossed a sort band boundary.