public class RecordBuffer extends java.lang.Object implements BufferReference, RecordChangeListener, Commitable, Finalizable
Client code does not manipulate DMO implementation class instances
directly, nor does it manage instances of RecordBuffer
directly. Rather, DMOs are exposed to client code by proxy. Each DMO
defines a business-domain interface, which is the means by which client
code manages data records. A new buffer is defined using the define(java.lang.Class<T>, java.lang.String, java.lang.String)
factory method. This method returns a dynamic proxy to a
particular DMO interface; however, the proxy initially is not backed by
any DMO implementation instance. A backing instance is only created by
either invoking the create(com.goldencode.p2j.util.handle, java.lang.String, java.lang.String, java.lang.String)
method, or by passing the proxy to
a query and successfully retrieving a data record. Prior to the creation
of a backing DMO implementation instance in a buffer by one of these
means, any invocation of the DMO interface methods against the proxy will
result in an exception. Likewise, if any attributes of the buffer which
require a backing record are manipulated before such a record is available,
an exception is thrown.
The dynamic proxy created at buffer definition actually implements more
than just the DMO-specific interface. It also implements the BufferReference
interface. This package private interface allows other
persistence framework classes to access the record buffer associated with
a DMO proxy, when the proxy is passed in as a parameter from client code.
The proxy invocation handler
will detect
method calls destined for this interface and will retrieve the record
buffer object reference.
The primary responsibility of the invocation handler, though, is to dispatch DMO interface getter and setter method calls invoked against the proxy, to the correct backing DMO. This decoupled architecture is leveraged to provide support for the Progress early constraint checking semantic, whereby not-null and uniqueness constraints are checked at data value assignment time, rather than at record commit time. We also take advantage of this hook to perform reverse foreign record resolution.
Reverse foreign record resolution is the process whereby a foreign record
associated with the current record DMO must be updated at runtime, as
application code modifies the properties which represent the database
fields upon which Progress relied as a foreign key. During conversion,
natural joins between tables are detected and any legacy foreign keys are
replaced with a foreign key which refers to the foreign table's surrogate
primary key. Since this explicit foreign key reference did not exist in
the pre-conversion Progress code, we must maintain relational integrity by
manually updating this foreign key as the legacy key values change. This
is the job of AssociationSyncher
and its subclasses. The DMO
proxy invocation handler is used to detect when the value of such a legacy
key is modified, and the foreign key is reset immediately, unless the
current context is running within an assignment batch (see below where
batch processing is described with respect to validation). In the case of
an active batch, the foreign record resolution is deferred until the batch
ends.
In some cases, client code must make multiple updates to a DMO instance,
and validation must be deferred until the last update is made, where it
would not be meaningful to validate while the DMO is in an intermediate
state. Batch assign mode is designed to handle this requirement. Once
batch assign mode is started
, validation for all
buffers in the current context is deferred until batch mode is ended
. At this point, all buffers which were updated during
batch assign mode are validated, in the order in which they were updated.
Each new instance registers a lightweight implementation of the
Undoable
interface to enable the TransactionManager
to preserve
the state of the buffer, such that it can be restored in an undo situation.
This class implements the Finalizable
interface, so that it
can release locks and records when a buffer scope closes. The actual time
of release also depends upon the current state of the transaction manager.
This class implements the Commitable
interface to enable the
TransactionManager
to
commit database transactions and subtransactions.
Upon instantiation, a buffer is associated with a logical database. From that point on, it can only be used with that database instance.
In certain circumstances (for outer join queries, particularly), a record buffer may not have a database record loaded, but must still be able to service proxied, DMO method calls without failing. Unknown mode is intended to support this need. A record buffer can temporarily be placed into this mode, such that getter methods invoked on the associated proxy return unknown value, instead of raising an error condition. This mode only is used internally by this package.
A similar feature is temporary record mode. Not to be confused
with temp-table support (see TemporaryBuffer
), this mode is used
in certain cases where the buffer must temporarily hold some record data,
in order to allow evaluation of an expression involving the associated
DMO. This is done, for instance, when presorting preselected query
results, and when filtering query results against a client-side where
clause filter. This mode only is used internally by this package. The
query invokes this mode by invoking the setTempRecord(com.goldencode.p2j.persist.Persistable)
method first
with a non-null
value, then executing the target expression
possibly repeating this sequence multiple times, and finally clears the
mode by invoking the setTempRecord
method again, this time
with a null
argument. Setting the buffer's temp record does
not trigger all of the locking and other baggage normally associated with
setting the buffer's current record.
TODO: combine many boolean flags into a bit field.
TODO: currently, when there are multiple buffers defined for the same table, the BufferManager keeps together all reversibles related to the same table belonging to the same database. This ensures proper reversible processing on rollback.
But, the rollback related part in Commitable
can be reworked
to allow multiple buffers for a certain table in a database. This
will eliminate the small overhead of rolling back a buffer which
has nothing to do (rollback was performed by one of its siblings).
Note: a case which needs to be taken into consideration and checked is when the foreign-keys are enabled. In this case, if the child is rolled back first in a Child.Parent relation, there might be some problems.
CompoundQuery
,
PreselectQuery
,
PresortQuery
,
RandomAccessQuery
Modifier and Type | Class and Description |
---|---|
protected class |
RecordBuffer.AbstractBulkReversible
A
Reversible version which affects more than one record. |
protected static class |
RecordBuffer.DatumAccess
Information needed by a getter or setter method to affect the datum of one property (or one
element within an extent property), namely, the property's name and optional extent index,
if accessing a single element in an extent property.
|
private class |
RecordBuffer.Handler
Handler for methods invoked on the DMO proxy provided to client code.
|
protected class |
RecordBuffer.LightweightUndoable
A lightweight implementation of the
Undoable interface
which restores to the record buffer the current record and snapshot
which were active at the time of backup. |
protected static class |
RecordBuffer.MethodType
Possible method types
|
protected static class |
RecordBuffer.OperationType
Possible buffer operation types
|
private class |
RecordBuffer.ReversibleCreate
Concrete implementation of
Reversible which on rollback
reverses a record create action by deleting its DMO in the underlying
persistence session. |
private class |
RecordBuffer.ReversibleDelete
Concrete implementation of
Reversible which on rollback
reverses a record delete action by reattaching its DMO to the underlying
persistence session. |
private class |
RecordBuffer.ReversibleUpdate
Concrete implementation of
Reversible which on rollback
reverses one or more updates made to a record's properties. |
private static class |
RecordBuffer.ScopeBufferName
Container immutable class that holds temporarily data needed for restoring a buffer's name
configuration.
|
protected class |
RecordBuffer.ValidationHelper
Helper class for validation processing.
|
Modifier and Type | Field and Description |
---|---|
protected int |
activeScopeDepth
Block depth at which outermost scope was opened
|
private boolean |
ambiguous
Indicates if last find failed because criteria was ambiguous
|
private java.util.ArrayList<AssociationSyncher> |
assocSynchers
Foreign association synchronization helper objects
|
protected int |
blockDepth
Current block scope depth
|
protected BufferManager |
bufferManager
Object which manages this and all buffers in the current context
|
private BufferType |
bufferType
Buffer type (key consisting of database, table, and undoable flag)
|
private boolean |
bulkCopy
Is buffer currently the destination of a bulk copy operation?
|
protected ChangeBroker |
changeBroker
Context-local ChangeBroker
|
private boolean |
commitPending
Is a transaction commit necessary upon ending a batch assign?
|
private int |
createScope
Scope depth at which transient record was created
|
private RecordBuffer |
creatingBuffer
Buffer which created current, unflushed record, if different than this one
|
private Persistable |
currentRecord
DMO data record which currently backs this buffer
|
protected boolean |
delayed
Flag indicating the finalizable processing for this buffer will be delayed for when the
external procedure gets deleted
|
private DirtyShareContext |
dirtyContext
Object which manages dirty read sharing across sessions
|
private boolean |
dirtyCopy
Is current record actually a dirty copy from the dirty database?
|
private java.util.Set<java.lang.String> |
dirtyLegacyKeyProps
Legacy key properties whose setters have been invoked
|
private java.util.Map<java.lang.String,java.lang.Object> |
dirtyProps
Map of DMO properties to pending update values
|
private java.lang.Class<?> |
dmoBufInterface
Grouping DMO and Buffer interface associated with this buffer
|
private java.lang.Class<?> |
dmoClass
Class which defines DMO's implementation
|
private java.lang.Class<?> |
dmoInterface
Interface which defines DMO's API
|
private BufferReference |
dmoProxy
Convenience reference to associated DMO proxy
|
private static java.lang.reflect.Method[] |
doNotProxy
Array of methods not to be proxied
|
private boolean |
dynamic
Determines if this buffer is dynamic.
|
private java.util.Map<java.lang.String,java.lang.Integer> |
extentMap
Map of property names to extents for DMO array properties
|
private java.util.List<ForeignNuller> |
foreignNullers
Helpers which null out foreign key references to deleted DMOs
|
private java.util.Set<java.lang.reflect.Method> |
getters
Set of getter methods of the current DMO interface
|
private RecordBuffer.Handler |
handler
Invocation handler for DMO proxy associated with this buffer
|
private int |
hashCode
Cached hash code
|
private java.util.Set<java.lang.String> |
indexedProperties
Properties which participate in any indexes of the backing table
|
private IndexHelper |
indexHelper
Object which identifies modified indexes
|
private int |
iterateReleaseOverrideScope
Scope at which iterate should not release the current record
|
private java.util.List<java.lang.reflect.Method> |
lazyExtentTriggers
Getter methods to trigger loading of lazy collections for extents
|
private java.lang.String |
ldbOrAlias
Logical database or database alias associated with this buffer
|
private LegacyFieldNameMap |
legacyFieldNameMap
Bi-directional map of legacy field names (lower case) to DMO property names
|
private java.util.Set<java.lang.String> |
legacyForeignKeys
Names of properties which represent legacy foreign keys
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
legacyGetterMap
Map of property names to getter methods for legacy fields only
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
legacySetterMap
Map of property names to setter methods for legacy fields only
|
private RecordLockContext |
lockContext
Record locking context for the current user session
|
private boolean |
locked
Indicates if last find failed because record could not be locked
|
private static java.util.logging.Logger |
LOG
Logger
|
private java.lang.String |
logicalDatabase
Logical name of database associated with this buffer
|
private boolean |
newlyCreated
Is current record newly created (not read from the database)?
|
private int |
numFields
Number of fields in the legacy table associated with this buffer (initialized lazily)
|
private OffEnd |
offEnd
Off-end status of query which last updated this buffer
|
private QueryOffEndListener |
offEndListener
The query off-end listener associated with this record buffer.
|
private boolean |
offEndRollback
Flag indicating the rollback is caused by a off-end query
|
protected int |
openScopeCount
Number of open scopes for this buffer (open scopes can be nested)
|
private boolean |
pendingRollbackProcessed
Track whether a rollback action is pending
|
private Persistence |
persistence
Persistence service object
|
protected Persistence.Context |
persistenceContext
Current persistence context
|
private ScopedDictionary<java.io.Serializable,LockType> |
pinnedLockTypes
Maps primary keys of past and present currentRecords to their pinned LockTypes
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
pojoGetterMap
Map of property names to getter methods for simple POJO fields only
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
pojoSetterMap
Map of property names to setter methods for simple POJO fields only
|
private java.util.Map<java.lang.reflect.Method,java.lang.String> |
propsBySetter
Map of setter methods of the current DMO interface to property names
|
private boolean |
readonly
Flags this record buffer as readonly.
|
private boolean |
recordChanged
Flag to mark this buffer as changed by another user on a multi-user
environment.
|
protected int |
registeredWithGlobalScope
If this buffer was ever registered with a persistent procedure, remember the scope it was
open at (-1 in fact because the assignment is performed (and later compared) before
incrementing the
openScopeCount ). |
protected java.util.Set<P2JQuery> |
relatedQueries
List of queries which should be closed when the scope of this buffer is closing
|
private boolean |
retrying
Flag indicating that the block to which the buffer is scoped is retrying
|
private RecordBuffer.ReversibleCreate |
reversibleCreate
Current
ReversibleCreate , if any |
private java.util.Map<java.lang.Integer,RecordBuffer.ScopeBufferName> |
scopeNameStack
The old/overrided names of the buffer from calling procedures.
|
private Persistable |
shadowCopyRecord
Temporary copy of the
currentRecord used to detect if its value has changed
as a result of refreshing from db (FIND CURRENT / GET CURRENT). |
private Persistable |
snapshot
Latest DMO data record to back this buffer
|
private SortIndex |
sortIndex
Sort index last used by a query updating the contents of this buffer
|
private java.lang.String |
table
Name of (post-conversion) database table associated with this buffer
|
private java.util.List<Persistable> |
tempRecords
Temporary record stack used for purposes such as sorting
|
private TriggerTracker |
triggerTracker
Helper object to manage database trigger information
|
private RecordBuffer.LightweightUndoable |
undoable
The undoable instance for this buffer.
|
private java.util.Set<java.lang.String> |
uniqueProperties
Properties which participate in unique indexes of the backing table
|
private boolean |
unknownMode
Safe mode where record is null but DMO getters return unknown value
|
private java.util.Map<java.lang.String,java.lang.Object> |
unreportedChanges
Property changes pending submission to the ChangeBroker
|
private RecordBuffer.ValidationHelper |
validationHelper
Validation helper object
|
private java.lang.String |
variable
Legacy name of this buffer and transaction manager's lookup key for this buffer
|
private boolean |
worldScope
Flag indicating if a buffer is exposed to the world until its creator procedure gets
deleted, in cases when its associated procedure is ran persistent
|
Modifier | Constructor and Description |
---|---|
protected |
RecordBuffer(java.lang.Class<?> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable)
Constructor.
|
protected |
RecordBuffer(java.lang.Class<?> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable,
int blockDepth)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
(package private) void |
addLegacyForeignKeys(java.util.Collection<java.lang.String> properties)
Add all property names in the given collection to the set of legacy key
properties being monitored for foreign association synchronization
purposes.
|
private void |
aggregate(java.lang.String aggregate,
java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Worker method which aggregates the values in the table backing this buffer.
|
protected boolean |
allowsBulkActions()
Indicate whether this buffer implementation allows bulk actions.
|
private boolean |
anyUniqueConstraint(java.util.Set<java.lang.String> properties)
Check if any of the given properties is part of a unique constraint.
|
(package private) static boolean |
areDMOsSame(Persistable dmo1,
Persistable dmo2)
Indicate whether two DMO instances represent the same record, as
determined by a comparison of their primary key identifiers.
|
(package private) void |
armCurrentChanged()
Prepares for an immediate reload().
|
(package private) void |
average(java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Aggregate method which averages the values of a single column across rows in the table
backing this buffer.
|
RecordBuffer |
buffer()
Return a reference to this object instance.
|
private void |
checkActive()
Verify that the record buffer has been initialized.
|
private boolean |
checkBufferName(FieldInfo fieldInfo)
Check whether the given
fieldInfo object has a buffer name qualifier, and if
so, whether it matches the buffer's variable name or the dynamically assigned temp-table
name (if this is the buffer for a dynamically prepared temp-table). |
(package private) static void |
cleanupBatchMode(BufferManager bufferManager)
Reset to default values the state variables related to batch assign
mode.
|
protected void |
closeConnectionManagerScope()
Deregister this buffer with the connection manager.
|
protected void |
closeRelatedQueries()
Close related queries.
|
void |
commit(boolean transaction)
Commit the changes made within a subtransaction.
|
static void |
compare(DataModelObject dmo1,
DataModelObject dmo2)
Compares two buffers.
|
static void |
compare(DataModelObject dmo1,
DataModelObject dmo2,
boolean caseSensitive,
character result)
Compare the contents of the properties which two DMO instances have in
common.
|
static void |
compare(DataModelObject dmo1,
DataModelObject dmo2,
boolean caseSensitive,
logical result)
Compare the contents of the properties which two DMO instances have in
common.
|
static void |
compare(DataModelObject dmo1,
DataModelObject dmo2,
character result)
Case insensitive compare the contents of the properties which two DMO instances have in
common.
|
static void |
compare(DataModelObject dmo1,
DataModelObject dmo2,
logical result)
Case insensitive compare the contents of the properties which two DMO instances have in
common.
|
private static java.util.List<java.lang.String> |
compare(DataModelObject dmo1,
DataModelObject dmo2,
java.lang.String[] propList,
boolean caseSensitive,
boolean exclusive,
boolean exhaustive)
BUFFER-COMPARE statement runtime, returning the list of legacy fields that are different.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
boolean caseSensitive,
character result)
BUFFER-COMPARE statement runtime.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
boolean caseSensitive,
FieldReference fieldReference)
Compare the contents of the properties which two DMO instances have in
common.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
boolean caseSensitive,
logical result)
BUFFER-COMPARE statement runtime.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
character result)
BUFFER-COMPARE statement runtime.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
FieldReference fieldReference)
Case-insensitive compare the contents of the properties which two DMO instances have in
common.
|
static void |
compare(DataModelObject dmo1,
java.lang.String[] propList,
boolean exclusive,
DataModelObject dmo2,
logical result)
BUFFER-COMPARE statement runtime.
|
static logical |
compare(RecordBuffer srcBuf,
RecordBuffer dstBuf,
character mode,
character except,
character pairs)
Conversion of BUFFER-COMPARE() method (KW_BUF_COMP).
|
private static java.util.List<java.lang.String> |
compare(RecordBuffer srcBuf,
RecordBuffer dstBuf,
java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap,
character mode,
boolean exhaustive)
This method compares given fields between the source buffer and the target buffer.
|
static void |
copy(DataModelObject srcDMO,
DataModelObject dstDMO,
boolean validate)
BUFFER-COPY statement runtime.
|
protected static logical |
copy(DataModelObject srcDMO,
DataModelObject dstDMO,
java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap,
java.util.Map<java.lang.String,java.lang.reflect.Method> getters,
java.util.Map<java.lang.String,java.lang.reflect.Method> setters,
java.util.Map<java.lang.String,java.lang.Integer> extents)
Perform a bulk copy of data from a source record to a destination
record.
|
static void |
copy(DataModelObject srcDMO,
java.lang.String[] srcProps,
boolean exclusive,
DataModelObject dstDMO,
boolean validate)
BUFFER-COPY statement runtime.
|
(package private) static logical |
copy(RecordBuffer dstBuf,
RecordBuffer srcBuf,
character except,
character pairs)
BUFFER-COPY() handle-based method runtime.
|
private static logical |
copy(RecordBuffer srcBuf,
RecordBuffer dstBuf,
java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap,
boolean validate)
This method copies given fields from the source buffer to the receiving buffer.
|
(package private) void |
count(java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Aggregate method which counts the rows in the table backing this buffer.
|
(package private) void |
create()
Instantiate a data record to back the specified DMO and to be added to
to the database upon transaction commit.
|
static void |
create(handle h,
character table)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
character bufName)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
character bufName,
character widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
character bufName,
java.lang.String widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
java.lang.String bufName)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
java.lang.String bufName,
character widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
character table,
java.lang.String bufName,
java.lang.String widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
character bufName)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
character bufName,
character widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
character bufName,
java.lang.String widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
java.lang.String bufName)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
java.lang.String bufName,
character widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
handle hsrc,
java.lang.String bufName,
java.lang.String widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
character bufName)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
character bufName,
character widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
character bufName,
java.lang.String widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
java.lang.String bufName)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
java.lang.String bufName,
character widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
java.lang.String table,
java.lang.String bufName,
java.lang.String widgetPool)
Creates a dynamic buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
character bufName)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
character bufName,
character widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
character bufName,
java.lang.String widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
java.lang.String bufName)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
java.lang.String bufName,
character widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
static void |
create(handle h,
Temporary tt,
java.lang.String bufName,
java.lang.String widgetPool)
Dynamically creates a new buffer and assign it to handle h.
|
(package private) static DataModelObject |
createDynamicBufferForPermTable(java.lang.Class<?> dmoIface,
java.lang.String bufferName,
java.lang.String ldbName)
Create a dynamic buffer for the permanent table.
|
protected static <T> T |
createProxy(java.lang.Class<T> dmoBufIface,
RecordBuffer buffer,
java.lang.String legacyName)
Create a proxy object which client code will use to interact with the
backing DMO.
|
protected static java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> |
createSimplePropsMap(java.util.Collection<java.lang.String> legacyFields,
java.util.Map<java.lang.String,java.lang.reflect.Method> srcGetters,
java.util.Map<java.lang.String,java.lang.reflect.Method> dstSetters,
java.util.Map<java.lang.String,java.lang.String> srcLegacyFieldsMap,
java.util.Map<java.lang.String,java.lang.String> dstLegacyFieldsMap,
RecordBuffer.OperationType operationType)
Creates simple properties map with mapping properties with the same legacy names.
|
protected int |
decrementDMOUseCount(Persistable dmo)
Decrement the context local use count for the specific instance of the
given record.
|
static <T> T |
define(java.lang.Class<T> dmoBufIface,
java.lang.String database,
java.lang.String variable)
Define a new buffer which is based upon the specified interface.
|
static <T> T |
define(java.lang.Class<T> dmoBufIface,
java.lang.String database,
java.lang.String variable,
java.lang.String legacyName)
Define a new buffer which is based upon the specified interface.
|
static <T> T |
define(java.lang.Class<T> dmoBufIface,
java.lang.String database,
java.lang.String variable,
java.lang.String legacyName,
int blockDepth)
Define a new buffer which is based upon the specified interface.
|
static <T> T |
defineAlias(java.lang.Class<T> dmoBufIface,
Buffer aliasOf,
java.lang.String varName,
java.lang.String legacyName)
This method registers the given buffer with BufferManager under the new temporary name.
|
static <T> T |
defineReadOnly(java.lang.Class<T> dmoBufIface,
java.lang.String database,
Persistable roValue)
Define a new buffer which is based upon the specified interface.
|
protected void |
delete()
Delete the current record from the database.
|
protected void |
delete(java.lang.String where,
java.lang.Object[] args)
Perform a bulk delete, restricted by the given where clause and query
substitution parameters.
|
protected void |
deleteAll()
Perform a bulk delete of all records in the table associated with this buffer.
|
void |
deleted()
Provides a notification that the external program scope in which the object is registered is
is being deleted and the object's reference will be lost after this method is called.
|
protected java.lang.String |
describe()
Provide a short descriptor of this buffer instance for debugging and
logging purposes.
|
(package private) void |
disableReleaseOnIterate()
Disable the buffer's default behavior of releasing its current record
when the transaction manager invokes its
iterate() method. |
private static boolean |
doBuffersExist(RecordBuffer srcBuf,
RecordBuffer dstBuf,
RecordBuffer.MethodType methodType)
This method checks that two buffer correspond not null records and displayOrRecordError
otherwise.
|
static void |
endBatch()
Exit batch assign mode in the current context, triggering pending
validation on all buffers which were modified while in this mode.
|
protected void |
enterBlock(int blockDepth,
boolean transaction)
Called by the
BufferManager when a new block scope has been entered. |
boolean |
equals(java.lang.Object o)
Determine whether this object is equivalent to the specified object.
|
private void |
errorNotAvailable()
Record or throw a "record not available" error condition for
the current DMO type.
|
(package private) void |
errorNotOnFile()
Record or throw a "record not on file" error condition for
the current DMO type.
|
protected boolean |
evictDMOIfUnused(Persistable dmo)
Evict the given DMO from the current Hibernate session if it is not
referenced by any buffer or other resource.
|
protected void |
exitBlock(int blockDepth,
boolean transaction)
Called by the
BufferManager when the current block scope is about to end. |
void |
finished()
Called by the transaction manager just before a buffer scope closes.
|
private void |
finishedImpl()
Called by the transaction manager just before a buffer scope closes.
|
void |
flush()
Validate the current record and attach it to the current persistence session if it has been
newly created and not yet saved.
|
(package private) static RecordBuffer |
get(DataModelObject dmo)
Get the buffer instance which corresponds with the given DMO proxy.
|
(package private) int |
getBlockDepth()
Get this buffer's current block depth.
|
protected BufferManager |
getBufferManager()
Get the buffer manager associated with this buffer.
|
(package private) BufferType |
getBufferType()
Get the buffer type hash key associated with this buffer.
|
protected static java.util.Set<java.lang.String> |
getCommonProperties(java.util.Set<java.lang.String> set1,
java.util.Set<java.lang.String> set2,
java.lang.String[] propList,
boolean exclusive)
Given two sets of property names, an additional list of names
(optional), and a flag indicating whether the additional list is
inclusive or exclusive, find the appropriate intersection of property
names.
|
Persistable |
getCurrentRecord()
Get the DMO which represents the database record currently held in the buffer.
|
(package private) Database |
getDatabase()
Get the physical database name associated with this buffer.
|
(package private) P2JDialect |
getDialect()
Convenience method to get the
P2JDialect in use for this record buffer. |
(package private) DirtyShareContext |
getDirtyContext()
Get the dirty share context used by this buffer.
|
(package private) java.util.Map<java.lang.String,java.lang.Object> |
getDirtyProperties(boolean indexesOnly)
Get a map of dirty properties.
|
(package private) java.lang.String |
getDMOAlias()
Get the variable name associated with this buffer instance.
|
(package private) java.lang.Class<?> |
getDMOBufInterface()
Get the combined DMO and Buffer grouping interface associated with this
buffer.
|
static java.lang.Class<?> |
getDMOBufInterfaceForObject(java.lang.Object obj)
Get the backing, DMO and
Buffer grouping interface for the given object. |
(package private) java.lang.Class<?> |
getDMOImplementationClass()
Report the DMO implementation class associated with this buffer.
|
(package private) java.lang.String |
getDMOImplementationName()
Get the unqualified name of the DMO implementation class.
|
java.lang.Class<?> |
getDMOInterface()
Get the DMO interface associated with this buffer.
|
(package private) java.lang.String |
getDMOName()
Get the unqualified name of the DMO's interface.
|
(package private) BufferReference |
getDMOProxy()
Get the DMO proxy which references this buffer instance.
|
protected java.lang.String |
getDynamicName()
Gets the legacy name assigned to a dynamically prepared temp-table.
|
java.lang.String |
getEntityName()
Get the entity name associated with this buffer, which is the fully
qualified name of the DMO implementation class.
|
protected java.util.Map<java.lang.String,java.lang.Integer> |
getExtentMap()
Get the map of DMO property names to extents for the DMO type associated with this buffer,
initializing it first if necessary.
|
protected java.util.Set<java.lang.String> |
getIndexedProperties(boolean unique)
Retrieve the set of all property names for this buffer's DMO entity,
which represent database columns that participate in an index on the
entity's backing table, or only the subset which participate in unique
indexes.
|
IndexHelper |
getIndexHelper()
Get
IndexHelper instance used by this buffer. |
protected java.lang.String |
getLDBName(java.lang.String ldbOrAlias)
Get the logical database name associated with the given parameter.
|
protected LegacyFieldNameMap |
getLegacyFieldNameMap()
Get bi-directional runtime mapping of DMO properties to their associated (lower case)
legacy table names.
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getLegacyGetterMap()
Get a map of converted DMO property names to corresponding, legacy, getter methods.
|
(package private) java.lang.String |
getLegacyName()
Get the table/buffer legacy name
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getLegacySetterMap()
Get a map of converted DMO property names to corresponding, legacy, setter methods.
|
(package private) java.lang.String |
getLogicalDatabase()
Get the logical database name associated with this buffer.
|
protected RecordBuffer |
getMasterBuffer()
Retrieve the master record buffer for this buffer.
|
protected java.lang.Integer |
getMultiplexID()
Get the multiplex ID of this buffer.
|
protected int |
getNumFields()
Get the number of fields in the legacy table represented by this buffer.
|
(package private) OffEnd |
getOffEnd(SortIndex sortIndex,
boolean inverseSorting)
Get an indication whether the last current record set by a query:
was
null (meaning the query was off-end), and if so
whether it used the same sort index as the one specified, and if
so
in which direction the query ran off-end. |
(package private) int |
getOpenScopeCount()
Get the number of scopes currently open for this buffer.
|
(package private) TempTable |
getParentTable()
Get parent table.
|
protected Database |
getPDB(java.lang.String ldbName)
Get the database information object associated with the given logical database name.
|
protected java.lang.String |
getPDBName(java.lang.String ldbName)
Get the physical database name associated with the given logical name.
|
(package private) Persistence |
getPersistence()
Get the persistence service object associated with this buffer.
|
(package private) Persistence.Context |
getPersistenceContext()
Get the persistence context for this buffer.
|
LockType |
getPinnedLockType(java.io.Serializable id)
Get the lock type which potentially "pins" the communal record lock on
the record with the given identifier (the record was ever or is
currently loaded into this buffer)
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getPojoGetterMap()
Get a map of converted DMO property names corresponding to simple, bean getter methods.
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getPojoSetterMap()
Get a map of converted DMO property names corresponding to simple, bean setter methods.
|
private static java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> |
getPropsMap(RecordBuffer srcBuf,
RecordBuffer dstBuf,
java.util.Map<java.lang.String,java.lang.reflect.Method> dstMethods,
character except,
character pairs,
RecordBuffer.OperationType opType)
This method establishes the map of properties being compared or copied.
|
(package private) QueryOffEndListener |
getQueryOffEndListener()
Get the
QueryOffEndListener instance for this record buffer. |
(package private) java.lang.String |
getSchema()
Get the schema name of the database associated with this buffer.
|
int |
getScopeOpenDepth()
Get the depth of the scope at which this buffer was first opened.
|
Persistable |
getSnapshot()
Get a representation of the latest DMO to be held in the buffer.
|
(package private) java.lang.String |
getTable()
Get the name of the table associated with this buffer.
|
private Persistable |
getTempRecord()
Get the currently active temporary record.
|
(package private) BaseDataType |
getValue(java.lang.String field)
Returns the value of a field in the record of this buffer.
|
int |
hashCode()
Return the hash code for this object.
|
protected int |
incrementDMOUseCount(Persistable dmo)
Increment the context local use count for the specific instance of the
given record.
|
boolean |
initialize()
Initialize the core data on which this buffer relies.
|
private void |
initializeLazyExtents()
Trigger the initialization of persistent collections which represent
extent fields by invoking a getter method for each such collection.
|
protected void |
initPinnedLockTypes()
Initializes the map that contains primary keys of past and present
currentRecords and their pinned LockTypes.
|
protected RecordBuffer.ValidationHelper |
initValidationHelper()
Initialize the validation helper object.
|
protected Persistable |
instantiateDMO()
Create a new instance of the DMO implementation class associated with
this buffer.
|
(package private) boolean |
isActive()
Indicate whether this buffer is active.
|
private static boolean |
isAssignableTypes(java.lang.reflect.Method srcMethod,
java.lang.reflect.Method dstMethod,
RecordBuffer.OperationType operationType)
This method checks that two getter or setter methods have compatible corresponding return
or parameter types for given operation type.
|
protected boolean |
isAutoCommit()
Indicate whether this is a temp-table buffer and we are not currently within an existing
database transaction.
|
(package private) boolean |
isAvailable()
Indicate whether a backing data record currently is available.
|
private boolean |
isCommitPending()
Indicate whether a commit is pending for the most recent changes made
to the current record.
|
(package private) boolean |
isDirtyCopy()
Indicate whether the record currently in the buffer represents a copy of
a DMO from the dirty database.
|
(package private) boolean |
isDynamic()
Determines if the buffer is dynamic.
|
protected boolean |
isGlobal()
Check if this buffer is associated with a global buffer.
|
protected boolean |
isMultiplexed()
Indicate whether the backing table for this buffer is multiplexed; that
is, whether the backing table represents multiple, virtual tables by
using a multiplex ID to differentiate table segments.
|
(package private) boolean |
isNewlyCreated()
Indicate whether the buffer currently contains a record, and whether
that record was newly created (as opposed to having been read from the
database).
|
(package private) boolean |
isPendingRollbackProcessed()
Get current state of 'pending rollback processed' flag.
|
(package private) boolean |
isPropertyIndexed(java.lang.String property)
Indicate whether the given property participates in any index.
|
(package private) boolean |
isReadonly()
Checks if this buffer contains a read-only record.
|
(package private) boolean |
isRecordChanged()
Checks if the record in the buffer has changed in database since the
last
FIND CURRENT or GET CURRENT . |
protected boolean |
isTableDefinitelyEmpty()
Indicate whether the table backing this buffer is known to contain no
rows.
|
protected boolean |
isTemporary()
Convenience method to indicate whether this buffer is backed by a
temporary table.
|
(package private) boolean |
isTransient()
Indicate whether the buffer currently contains a record, and whether
that record is transient.
|
protected boolean |
isUndoable()
Indicate whether changes made to records managed by this buffer can be
undone during a rollback.
|
(package private) boolean |
isUnknownMode()
Report whether this buffer is in unknown mode, due to an outer join not finding a record.
|
private boolean |
isValidExtent(int extentIndex,
java.lang.String property)
Report whether the given extent index is valid for the given property.
|
boolean |
isWorldScope()
Get the state of the
worldScope flag. |
void |
iterate()
Called by the transaction manager after each iteration of a repeating
block.
|
private void |
load(Persistable target,
LockType lockType,
boolean undo)
Load the specified record, if any, from the database.
|
(package private) void |
loadTemplateRecord(long templateId)
Loads the template record for this buffer.
|
protected int |
lookupNumFields()
Look up the number of fields in the legacy table represented by this buffer.
|
(package private) void |
markPersisted()
Mark the buffer's current record as no longer transient by resetting it
create scope to its default value.
|
(package private) void |
maximum(java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Aggregate method which finds the maximum value of a single column across rows in the table
backing this buffer.
|
protected void |
maybeFireWriteTrigger()
Fire write triggers, if any are pending, using the record currently in the buffer as the
current value, and a snapshot of that record taken when it was first changed as the old
value.
|
private void |
mergeReversibles()
Merge the reversibles (or re-roll actions, for no-undo temp-tables) from
the current scope with the list from the parent scope.
|
(package private) void |
minimum(java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Aggregate method which finds the minimum value of a single column across rows in the table
backing this buffer.
|
protected java.io.Serializable |
nextPrimaryKey()
Returns the primary key for a new DMO associated with this buffer.
|
protected void |
openConnectionManagerScope()
Register this buffer with the connection manager.
|
protected void |
openScope()
Open a new buffer scope for this record buffer.
|
static void |
openScope(DataModelObject... dmos)
Open a new buffer scope for the record buffer which backs the specified
DMO.
|
protected void |
openScopeAt(int blockDepth)
Open a new buffer scope for this record buffer at the specified block depth.
|
static void |
openScopeAt(int blockDepth,
DataModelObject... dmos)
Open a new buffer scope at the specified block depth for the record buffer which backs
the specified DMO.
|
protected void |
popPinnedLockScope(boolean transaction,
boolean undo)
Pop the current scope from the pinned lock types scoped dictionary,
propagating all entries in this scope up to the next higher scope, if
any.
|
(package private) void |
popTempContext()
Pop the current, temporary record context from this buffer.
|
private void |
processChange(boolean setPendingFlush)
Process one or more DMO property changes by creating or updating a
ReversibleUpdate object and reporting the change to the
ChangeBroker for further distribution to registered listeners. |
protected void |
processMiddleBlocks(int outermostLevel)
When a scope is opened for a dynamic buffer at some nested block level using
openScopeAt(int) , the blocks at the "middle" levels between the level at which the
scope is opened (outermost level) and the current nesting level have to be processed in
order to emulate normal scope opening procedure. |
protected void |
pushPinnedLockScope()
Push a new scope onto the pinned lock types scoped dictionary.
|
(package private) void |
pushTempContext()
Push a temporary record context onto the buffer for purposes such as
client-side sorting.
|
protected void |
reclaimKeys(java.util.List<java.io.Serializable> keys)
Reclaim the given list of primary keys for re-use.
|
java.util.Iterator<RecordBuffer> |
recordBuffers()
Report the record buffers for whose changes this object is interested
in listening.
|
recid |
recordID()
Get the record ID of the current buffer's current record, if any.
|
(package private) void |
registerRelatedQuery(P2JQuery query)
Register a query that should be closed when the scope of this buffer is closed.
|
private void |
registerWithNewName(java.lang.String newName,
BufferImpl bufferImpl,
java.lang.String legacyName)
Re-register the buffer to buffer manager with a new name.
|
(package private) void |
release()
Validate and release the current record in this buffer and release its
lock, if any, according to the following rules:
the lock is released at the later of:
end of the current transaction (if any);
end of the current buffer scope.
|
(package private) void |
reload(LockType lockType,
boolean errorIfNull)
Reload the current record, if any, from the database.
|
private boolean |
reportBadBufferName(FieldInfo fieldInfo,
java.lang.String fieldSpec)
Check whether the given
fieldInfo object has a buffer name qualifier, and if
so, whether it matches the buffer's variable name. |
protected void |
reportChange(Persistable dmo,
boolean insert,
boolean delete)
Report any pending changes in the current record's state to the
ChangeBroker for broadcast to interested listeners. |
protected void |
reportChange(Persistable dmo,
boolean insert,
boolean delete,
boolean setPendingFlush)
Report any pending changes in the current record's state to the
ChangeBroker for broadcast to interested listeners. |
protected static void |
reportValidationException(ValidationException exc)
Helper method to report and possibly log a validation exception.
|
(package private) void |
reset()
Release the current record and discard the reference record snapshot.
|
(package private) void |
resetPendingRollbackProcessed()
Reset 'pending rollback processed' flag.
|
protected void |
resourceDeleted()
A no-op implementation called during scope cleanup (
finishedImpl() ), which should
be overridden by a subclass needing to perform some action at this point. |
void |
retry()
Called by the transaction manager before a block is retried after an
error.
|
void |
rollback(boolean transaction)
Restores this buffer's state to that which it had at the beginning of
the current block.
|
void |
rollbackPending()
When the rollback is pending to be processed by a parent block, we must
rollup (i.e.
|
rowid |
rowID()
Get the row ID of the current buffer's current record, if any.
|
(package private) void |
setAmbiguous(boolean ambiguous)
Set the flag indicating whether the last record retrieval attempt
failed because the query criteria was ambiguous.
|
private void |
setCommitPending(boolean commitPending)
Set the commit pending state.
|
private static void |
setCompareMode(BaseDataType baseDataType,
character mode)
Sets compare mode to data type instance for BUFFER-COPY and BUFFER-COMPARE methods.
|
private void |
setCurrentRecord(Persistable newCrtRecord,
boolean undo,
boolean newlyCreated,
boolean dirtyCopy)
Set the DMO implementation instance which backs this buffer, or release the record currently
stored in the buffer.
|
private void |
setDMOProxy(BufferReference dmoProxy)
Set the DMO proxy which references this buffer instance.
|
(package private) void |
setDynamic()
Mark the buffer as dynamic.
|
(package private) void |
setLocked(boolean locked)
Set the flag indicating whether the last record retrieval attempt
failed because another user had the target record locked.
|
(package private) void |
setOffEnd(OffEnd offEnd)
Set the off-end status for the query most recently involving this buffer.
|
void |
setPinnedLockType(java.io.Serializable id,
LockType pinnedLockType)
Set the lock type which potentially "pins" the communal record lock on
the record with the given id (the record was ever or is currently loaded
into this buffer).
|
(package private) void |
setRecord(Persistable currentRecord,
LockType lockType,
boolean errorIfNull,
SortIndex sortIndex,
OffEnd offEnd,
boolean inverseSorting,
boolean dirtyCopy)
Set the DMO implementation instance which backs this buffer.
|
private void |
setReversibleCreate()
Create and set the current reversible action for the given record.
|
private void |
setReversibleDelete()
Create and set the current reversible action for the given record.
|
private void |
setReversibleEntry(Reversible item)
Set the current reversible action which is associated with the current
record.
|
(package private) void |
setTempRecord(Persistable tempRecord)
Set a temporary record into the buffer for purposes such as client-side
sorting.
|
(package private) void |
setUnknownMode()
Enter into a safe mode where current record is
null , but
calls to DMO getter methods return unknown value instead of raising an
error condition. |
static void |
startBatch()
Enter batch assign mode in the current context.
|
void |
stateChanged(RecordChangeEvent event)
Respond to a record change event.
|
(package private) void |
sum(java.lang.String column,
NumberType num,
java.lang.String where,
java.lang.Object... args)
Aggregate method which sums the values of a single column across rows in the table
backing this buffer.
|
private void |
syncForeignRelations(boolean inverse)
Attempt to synchronize the foreign keys of any records linked to this
buffer's current record, based upon changes made to relevant properties
in the current record.
|
handle |
tableHandle()
Returns TABLE-HANDLE for the buffer.
|
(package private) void |
throwOffEnd()
Throw a
QueryOffEndException . |
java.lang.String |
toString()
Get a string representation of the internal state of this object,
primarily for debugging purposes.
|
protected java.lang.String |
toString(Persistable record)
Generate a formatted description of the contents of
record . |
private static java.lang.String |
trimFieldSpec(java.lang.String fieldSpec,
FieldInfo fieldInfo)
Trim the extent dereference portion (if any) from a field specifier and return the root
specifier, including buffer name qualifier (if any).
|
private void |
undoDirty()
Revert all dirty properties of the current record to their previous
state and clear the
dirtyProps map. |
(package private) void |
unregisterRelatedQuery(P2JQuery query)
Unregister a query from the list of the queries that should be closed when the scope of
this buffer is closed.
|
(package private) void |
updateCurrentChanged()
Updates the
recordChanged flag. |
protected void |
upgradeLock()
Attempt to upgrade to an exclusive lock on the current record, if we do
not already have one.
|
(package private) void |
validate()
Validate the record, if any, currently in the buffer.
|
void |
validate(boolean transaction)
Notifies that a block is about to be normally exited or normally iterated and that any
deferred validation processing may need to be executed.
|
(package private) void |
validate(Persistable dmo,
boolean share)
Perform a full validation (all unique constraints and non-nullable
properties) of the given record.
|
(package private) boolean |
wasAmbiguous()
Indicate whether the last record retrieval attempt failed because the
query criteria was ambiguous.
|
(package private) boolean |
wasLocked()
Indicate whether the last record retrieval attempt was denied because
the target record was locked.
|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
initFailure
private static final java.util.logging.Logger LOG
private static final java.lang.reflect.Method[] doNotProxy
protected final ChangeBroker changeBroker
protected final BufferManager bufferManager
protected int blockDepth
protected int activeScopeDepth
protected int openScopeCount
protected int registeredWithGlobalScope
openScopeCount
). If never registered with global scope it stays -1.
It is used to unregister from the global scope of ChangeBroker when openScopeCount
reaches back to this value.
This flag only applies to static buffers from procedures run in PERSISTENT mode.protected boolean delayed
protected java.util.Set<P2JQuery> relatedQueries
protected Persistence.Context persistenceContext
private final int hashCode
private final java.lang.String ldbOrAlias
private final RecordBuffer.Handler handler
private final java.lang.Class<?> dmoBufInterface
private final java.lang.Class<?> dmoInterface
private final java.util.Map<java.lang.reflect.Method,java.lang.String> propsBySetter
private final java.util.Set<java.lang.reflect.Method> getters
private final java.util.Map<java.lang.String,java.lang.Object> dirtyProps
private final java.util.Map<java.lang.String,java.lang.Object> unreportedChanges
private final TriggerTracker triggerTracker
private boolean worldScope
private java.lang.String variable
private java.util.Map<java.lang.Integer,RecordBuffer.ScopeBufferName> scopeNameStack
private RecordLockContext lockContext
private DirtyShareContext dirtyContext
private RecordBuffer.ValidationHelper validationHelper
private RecordBuffer creatingBuffer
private java.lang.String table
private BufferType bufferType
private java.lang.Class<?> dmoClass
private Persistence persistence
private java.lang.String logicalDatabase
private java.util.ArrayList<AssociationSyncher> assocSynchers
private java.util.Set<java.lang.String> legacyForeignKeys
private java.util.Set<java.lang.String> dirtyLegacyKeyProps
private IndexHelper indexHelper
private java.util.Set<java.lang.String> indexedProperties
private java.util.Set<java.lang.String> uniqueProperties
private ScopedDictionary<java.io.Serializable,LockType> pinnedLockTypes
private BufferReference dmoProxy
private java.util.Map<java.lang.String,java.lang.reflect.Method> legacyGetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> legacySetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> pojoGetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> pojoSetterMap
private java.util.Map<java.lang.String,java.lang.Integer> extentMap
private LegacyFieldNameMap legacyFieldNameMap
private java.util.List<java.lang.reflect.Method> lazyExtentTriggers
private Persistable currentRecord
private Persistable snapshot
private java.util.List<Persistable> tempRecords
private RecordBuffer.ReversibleCreate reversibleCreate
ReversibleCreate
, if anyprivate java.util.List<ForeignNuller> foreignNullers
private int createScope
private boolean newlyCreated
private boolean unknownMode
private boolean locked
private boolean ambiguous
private boolean commitPending
private boolean bulkCopy
private int iterateReleaseOverrideScope
private SortIndex sortIndex
private OffEnd offEnd
private boolean dirtyCopy
private boolean offEndRollback
private boolean retrying
private boolean readonly
private boolean dynamic
private QueryOffEndListener offEndListener
private boolean pendingRollbackProcessed
private boolean recordChanged
private Persistable shadowCopyRecord
currentRecord
used to detect if its value has changed
as a result of refreshing from db (FIND CURRENT / GET CURRENT).
This field is normally null except for armCurrentChanged/updateCurrentChanged bracketing.private int numFields
private RecordBuffer.LightweightUndoable undoable
protected RecordBuffer(java.lang.Class<?> dmoBufIface, java.lang.String ldbOrAlias, java.lang.String variable)
define(java.lang.Class<T>, java.lang.String, java.lang.String)
factory method.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.ldbOrAlias
- Logical name of database with which this buffer will be
associated permanently, or an alias previously created for the
target database.variable
- Name of the variable with which the record buffer is associated
for the purposes of differentiating multiple buffers backed by
the same DMO type.protected RecordBuffer(java.lang.Class<?> dmoBufIface, java.lang.String ldbOrAlias, java.lang.String variable, int blockDepth)
define(java.lang.Class<T>, java.lang.String, java.lang.String)
factory method.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.ldbOrAlias
- Logical name of database with which this buffer will be associated permanently, or
an alias previously created for the target database.variable
- Name of the variable with which the record buffer is associated for the purposes of
differentiating multiple buffers backed by the same DMO type.blockDepth
- Zero-based depth of the block (from the outermost scope) at which the buffer is
created or -1
for the current scope.public static <T> T defineReadOnly(java.lang.Class<T> dmoBufIface, java.lang.String database, Persistable roValue)
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.database
- Name of the database which will be associated with the new record buffer.roValue
- The read-only value.public static <T> T define(java.lang.Class<T> dmoBufIface, java.lang.String database, java.lang.String variable)
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.database
- Name of the database which will be associated with the new
record buffer.variable
- Name of the variable with which the record buffer is associated
for the purposes of differentiating multiple buffers backed by
the same DMO type.public static <T> T define(java.lang.Class<T> dmoBufIface, java.lang.String database, java.lang.String variable, java.lang.String legacyName)
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.database
- Name of the database which will be associated with the new
record buffer.variable
- Name of the variable with which the record buffer is associated
for the purposes of differentiating multiple buffers backed by
the same DMO type.legacyName
- Legacy name of the buffer.public static <T> T define(java.lang.Class<T> dmoBufIface, java.lang.String database, java.lang.String variable, java.lang.String legacyName, int blockDepth)
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.database
- Name of the database which will be associated with the new
record buffer.variable
- Name of the variable with which the record buffer is associated
for the purposes of differentiating multiple buffers backed by
the same DMO type.legacyName
- Legacy name of the buffer.blockDepth
- Zero-based depth of the block (starting from the outermost scope) at which the
buffer is defined or -1
for the current scope.public static <T> T defineAlias(java.lang.Class<T> dmoBufIface, Buffer aliasOf, java.lang.String varName, java.lang.String legacyName)
It must be called in the init() method of the procedure, called during the opening the new scope!
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.aliasOf
- The buffer to be aliased.varName
- The converted variable name.legacyName
- The legacy variable name.aliasOf
.public static void create(handle h, java.lang.String table, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, character table, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widget pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer. null
if it is not explicitly specified.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, java.lang.String bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, java.lang.String table, character bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, character table, java.lang.String bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, character table, character bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, java.lang.String table)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.public static void create(handle h, character table)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.public static void create(handle h, Temporary tt)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.public static void create(handle h, Temporary tt, java.lang.String bufName)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, Temporary tt, character bufName)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, Temporary tt, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.public static void create(handle h, handle hsrc, java.lang.String bufName)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, handle hsrc, character bufName)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, handle hsrc, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widget pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer or null
if it is not explicitly specified.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void copy(DataModelObject srcDMO, DataModelObject dstDMO, boolean validate)
The destination buffer is optionally validated after the copy.
srcDMO
- Source DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dstDMO
- Source DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.validate
- true
to validate the destination buffer after the copy.ErrorConditionException
- if destination buffer is validated and fails; if there is no
record in the source buffer.public static void copy(DataModelObject srcDMO, java.lang.String[] srcProps, boolean exclusive, DataModelObject dstDMO, boolean validate)
If a list of source properties is provided, the copy behaves
differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the copy;
false
, the listed properties are the only properties copied.
The destination buffer is optionally validated after the copy.
srcDMO
- Source DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.srcProps
- Names of those source properties to be included or excluded from the copy,
depending upon exclusive
. May be null
.exclusive
- true
if srcProps
represents an exclusive list;
false
if it represents an inclusive list.dstDMO
- Destination DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.validate
- true
to validate the destination buffer after the copy.ErrorConditionException
- if destination buffer is validated and fails; if there is no
record in the source buffer.public static void compare(DataModelObject dmo1, DataModelObject dmo2)
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.public static void compare(DataModelObject dmo1, DataModelObject dmo2, logical result)
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.result
- A variable into which the result of the comparison is saved.
Set to true
if all common properties compared as
equal; else set to false
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, DataModelObject dmo2, boolean caseSensitive, logical result)
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.result
- A variable into which the result of the comparison is saved.
Set to true
if all common properties compared as
equal; else set to false
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, DataModelObject dmo2, boolean caseSensitive, character result)
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.result
- A variable into which the result of the comparison is saved.
Set to the comma-separated list of legacy field names which
failed to compare as equal. If this variable contains the
empty string after invocation of this method, this indicates
that all common properties compared as equal.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, DataModelObject dmo2, character result)
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.result
- A variable into which the result of the comparison is saved.
Set to the comma-separated list of legacy field names which
failed to compare as equal. If this variable contains the
empty string after invocation of this method, this indicates
that all common properties compared as equal.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, logical result)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.result
- A variable into which the result of the comparison is saved.
Set to true
if all common properties compared as
equal; else set to false
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, boolean caseSensitive, logical result)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.result
- A variable into which the result of the comparison is saved.
Set to true
if all common properties compared as
equal; else set to false
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, boolean caseSensitive, character result)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.result
- A variable into which the result of the comparison is saved.
Set to the comma-separated list of legacy field names which
failed to compare as equal. If this variable contains the
empty string after invocation of this method, this indicates
that all common properties compared as equal.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, character result)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.result
- A variable into which the result of the comparison is saved.
Set to the comma-separated list of legacy field names which
failed to compare as equal. If this variable contains the
empty string after invocation of this method, this indicates
that all common properties compared as equal.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, FieldReference fieldReference)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.fieldReference
- Reference to a buffer field, used for "SAVE RESULT IN" result-field
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static void compare(DataModelObject dmo1, java.lang.String[] propList, boolean exclusive, DataModelObject dmo2, boolean caseSensitive, FieldReference fieldReference)
If a list of additional property names is provided, the comparison
behaves differently, depending upon the value of exclusive
:
true
, the listed properties are excluded from the
compare;
false
, the listed properties are the only
properties compared.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the
comparison, depending upon exclusive
. May be
null
.exclusive
- true
if propsList
represents an
exclusive list; false
if it represents an
inclusive list.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.fieldReference
- Reference to a buffer field, used for "SAVE RESULT IN" result-field
.ErrorConditionException
- if one or both buffers are empty, such that a comparison could
not be performed; if there is a problem extracting data from
a buffer.public static logical compare(RecordBuffer srcBuf, RecordBuffer dstBuf, character mode, character except, character pairs)
srcBuf
- Source record buffer.dstBuf
- Destination record buffer.mode
- If mode-exp is given, it must evaluate to either "binary" or "case-sensitive"
to provide that type of comparison. BUFFER-COMPARE( ) method supports binary
and case-sensitive comparisons between CLOB as well as CHARACTER fields.except
- A character expression that evaluates to a comma-separated list of field names
to be excluded from the compare.pairs
- A character expression that evaluates to a comma-delimited list of field-name
pairs to be compared.true
if all fields values are equal, otherwise false
.public static void openScope(DataModelObject... dmos)
BufferManager
is tracking this
buffer for block scope entries and exits within transactions.dmos
- Variable length list of DMO instances returned by previous
calls to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.public static void openScopeAt(int blockDepth, DataModelObject... dmos)
BufferManager
is tracking this buffer for
block scope entries and exits within transactions.blockDepth
- Zero-based depth of the block (starting from the outermost block) at which the
buffer scopes are opened.dmos
- Variable length list of DMO instances returned by previous
calls to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.public static void startBatch()
java.lang.IllegalStateException
- if batch mode already is active in the current block or was started but never
ended in a previous block.endBatch()
public static void endBatch()
Implementation Note: as a simplification, dirty buffers are validated in their entirety, not only the fields that were modified during the most recent batch. However, this should be safe (though possibly less efficient), since the buffers must already have been valid upon entering batch mode.
java.lang.IllegalStateException
- if the current context is not in batch mode when this method
is invoked.ErrorConditionException
- if validation fails on any buffer which was modified in batch
mode; if there is any error accessing the database.startBatch()
public static java.lang.Class<?> getDMOBufInterfaceForObject(java.lang.Object obj)
Buffer
grouping interface for the given object. If the
object is not a BufferReference
or is null, return null.obj
- The assumed DMO for which the interface is needed.protected static <T> T createProxy(java.lang.Class<T> dmoBufIface, RecordBuffer buffer, java.lang.String legacyName)
T
- Record type.dmoBufIface
- Interface which defines DMO's public API plus all Buffer
methods.buffer
- Record buffer instance associated with the created proxy.legacyName
- Legacy name of the buffer.protected static java.util.Set<java.lang.String> getCommonProperties(java.util.Set<java.lang.String> set1, java.util.Set<java.lang.String> set2, java.lang.String[] propList, boolean exclusive)
The resulting set will contain at most the intersection of
set1
and set2
. However, this set may be
further restricted if a non-null
propList
is
provided, as follows:
exclusive
is true
, all elements of
propList
are excluded from the intersection of
set1
and set2
.
exclusive
is false
, only those
elements present in set1
and in set2
and in propList
are included in the final result.
set1
- A set of DMO property names.set2
- A set of DMO property names.propList
- An optional array of property names; may be null
.exclusive
- if true
, propList
is an exclusive
list of property names; if false
,
propList
is an inclusive list. Ignored if
propList
is null
.protected static logical copy(DataModelObject srcDMO, DataModelObject dstDMO, java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap, java.util.Map<java.lang.String,java.lang.reflect.Method> getters, java.util.Map<java.lang.String,java.lang.reflect.Method> setters, java.util.Map<java.lang.String,java.lang.Integer> extents) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
propsMap
.
Other properties of the source and destination DMOs are ignored.srcDMO
- Source DMO record (an actual record, not a proxy)dstDMO
- Destination DMO, which may be a dynamic proxy or the backing
data model object. A proxy should be used in cases where it
is necessary to take advantage of flushing/validating logic
implemented in the proxy invocation handler. The backing DMO
instance should be used if a raw copy is all that is needed.
In the latter case, calling code is responsible for creating
the record, optionally validating it, and persisting it to the
database at the appropriate time.propsMap
- Map of property access info objects in source record buffer to those in destination
record buffergetters
- Map of property names to getter methods for the source record.setters
- Map of property names to setter methods for the destination
record.extents
- Map of property names to extents for the source record.true
if copy is successful, otherwise false
.java.lang.IllegalAccessException
- if a getter or setter method cannot be invoked because it is not accessible.java.lang.reflect.InvocationTargetException
- if an invoked getter or setter method throws an exception.protected static java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> createSimplePropsMap(java.util.Collection<java.lang.String> legacyFields, java.util.Map<java.lang.String,java.lang.reflect.Method> srcGetters, java.util.Map<java.lang.String,java.lang.reflect.Method> dstSetters, java.util.Map<java.lang.String,java.lang.String> srcLegacyFieldsMap, java.util.Map<java.lang.String,java.lang.String> dstLegacyFieldsMap, RecordBuffer.OperationType operationType)
srcLegacyFieldsMap
and dstLegacyFieldsMap
are used to obtain the
properties names and srcGetters and dstSetters are used to check if the types of properties
have the same type (are directly assignable).legacyFields
- The list of fields to be mapped (legacy fields names).srcGetters
- Map of source DMO methods.dstSetters
- Map of destination DMO methods.srcLegacyFieldsMap
- Map of legacy field names to properties for source buffer.dstLegacyFieldsMap
- Map of legacy field names to properties for destination buffer.operationType
- Operation type (COMPARE/COPY).protected static void reportValidationException(ValidationException exc)
exc
- The validation exception.static DataModelObject createDynamicBufferForPermTable(java.lang.Class<?> dmoIface, java.lang.String bufferName, java.lang.String ldbName)
dmoIface
- DMO interface associated with the table.bufferName
- Target buffer name (4GL form).ldbName
- Logical name of permanent database associated with table.static logical copy(RecordBuffer dstBuf, RecordBuffer srcBuf, character except, character pairs)
dstBuf
- Destination record buffer.srcBuf
- Source record buffer.except
- A comma-separated list of fields that will be ignored in the copy process.pairs
- A character expression that evaluates to a comma-separated list of field-name
pairs to be copied.true
if copy is successful, otherwise false
.static RecordBuffer get(DataModelObject dmo)
dmo
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo
.static void cleanupBatchMode(BufferManager bufferManager)
bufferManager
- Context-local BufferManager
instance.static boolean areDMOsSame(Persistable dmo1, Persistable dmo2)
null
, nor have
a null
primary key identifier.dmo1
- First record to compare.dmo2
- Second record to compare.true
if both records are non-null
and have the same non-null
primary keys.private static java.util.List<java.lang.String> compare(DataModelObject dmo1, DataModelObject dmo2, java.lang.String[] propList, boolean caseSensitive, boolean exclusive, boolean exhaustive)
If a list of additional property names is provided, the comparison behaves differently,
depending upon the value of exclusive
:
true
, the listed properties are excluded from the compare;
false
, the listed properties are the only properties compared.
Implementation Note: this is not a full replacement for the Progress BUFFER-COMPARE statement. In particular, it does not handle the EXPLICIT COMPARES option.
dmo1
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.dmo2
- DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String)
.propList
- Names of those properties to be included or excluded from the comparison, depending
upon exclusive
. May be null
.caseSensitive
- if true
, directs to perform a case-sensitive comparison.exclusive
- true
if propsList
represents an exclusive list;
false
if it represents an inclusive list.exhaustive
- if true
, all common properties are compared; if false
,
the comparison ends immediately after the first time a pair of properties fails to
compare as equal.null
only if one or both
buffers are empty, indicating a comparison could not be performed.ErrorConditionException
- if one or both buffers are empty, such that a comparison could not be performed;
if there is a problem extracting data from a buffer.private static java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> getPropsMap(RecordBuffer srcBuf, RecordBuffer dstBuf, java.util.Map<java.lang.String,java.lang.reflect.Method> dstMethods, character except, character pairs, RecordBuffer.OperationType opType)
srcBuf
- Source buffer for copy or compare operation.dstBuf
- Destination buffer for copy or compare operation.dstMethods
- Map of legacy field names to DMO getter or setter methods for the destination
buffer.except
- A character expression that evaluates to a comma-separated list of field names
to be excluded from the copy or compare operation.pairs
- A character expression that evaluates to a comma-delimited list of field-name
pairs to be copied or compared.opType
- Operation type (COMPARE/COPY).DatumAccess
objects for the source buffer to objects of the
same type for the destination buffer, which is used to perform the copy or compare
operation, or null
if an error occurs during the mapping analysis.ErrorConditionException
- if any Progress-defined error occurs during the mapping analysis and not in silent
error mode.private static java.lang.String trimFieldSpec(java.lang.String fieldSpec, FieldInfo fieldInfo)
fieldSpec
- Full field specifier.fieldInfo
- FieldInfo
object which represents the given specifier.private static boolean isAssignableTypes(java.lang.reflect.Method srcMethod, java.lang.reflect.Method dstMethod, RecordBuffer.OperationType operationType)
srcMethod
- Source method for given operation.dstMethod
- Destination method for given operation.operationType
- Operation type (COMPARE/COPY).true
if methods are compatible, otherwise false
.private static boolean doBuffersExist(RecordBuffer srcBuf, RecordBuffer dstBuf, RecordBuffer.MethodType methodType)
srcBuf
- Source record buffer.dstBuf
- Destination record buffer.true
if both records are not nulls, otherwise false
.private static void setCompareMode(BaseDataType baseDataType, character mode)
baseDataType
- Data type instance.mode
- "case-sensitive" or "binary". Mode is only acceptible for CLOBs (not supported
so far) and Text (it seems there is no difference between "case-sensitive"
and "binary" for this type).private static java.util.List<java.lang.String> compare(RecordBuffer srcBuf, RecordBuffer dstBuf, java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap, character mode, boolean exhaustive)
srcBuf
- Source record buffer.dstBuf
- Destination record buffer.propsMap
- Map of properties in source record buffer to properties in destination
record buffermode
- If mode-exp is given, it must evaluate to either "binary" or "case-sensitive"
to provide that type of comparison.BUFFER-COMPARE( ) method supports binary
and case-sensitive comparisons between CLOB as well as CHARACTER fields.exhaustive
- if true
, all common properties are compared; if false
,
the comparison ends immediately after the first time a pair of properties fails
to compare as equal.null
to indicate a comparison
could not be performed.private static logical copy(RecordBuffer srcBuf, RecordBuffer dstBuf, java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap, boolean validate)
srcBuf
- Source record buffer.dstBuf
- Destination record buffer.propsMap
- Map of properties in source record buffer to properties in destination
record buffervalidate
- true
to validate the destination buffer after the copy.true
if copy is successful, otherwise false
.public java.util.Iterator<RecordBuffer> recordBuffers()
ChangeBroker
to receive notifications of any change to DMOs whose
interface types match those returned by the getDMOInterface()
methods of the returned buffers.recordBuffers
in interface RecordChangeListener
public void stateChanged(RecordChangeEvent event) throws PersistenceException
If the event indicates a record delete operation, we check if the deleted record is the same as our current record. If so, we clear it from the buffer, since that record should no longer be available in any buffer, once it has been deleted.
In the special case where a different, local buffer created the record we have loaded, and the record is not yet flushed, we will be notified of the flush event here. Stop tracking the creating buffer.
stateChanged
in interface RecordChangeListener
event
- Event which describes the DMO state change.PersistenceException
- not thrown; required by the interface.public java.lang.String getEntityName()
public IndexHelper getIndexHelper()
IndexHelper
instance used by this buffer.IndexHelper
instance.public Persistable getSnapshot()
This is used to enable a query to keep its place when navigating to a record, based upon the data in the last record held in the buffer, even if that record is no longer available.
null
if the
buffer never held a current record.public void validate(boolean transaction)
A normal exit or iteration is one that occurs naturally by hitting the end of the block (or
loop). A LEAVE
, NEXT
and RETURN
are also considered
normal exits or iterations so long as they were not preceded by an UNDO
.
Likewise, a QUIT
is a normal exit so long as it is not inside a block that has
an ON QUIT UNDO, <action>
.
If the buffer is active and we are at a full transaction boundary or the boundary of the buffer scope, we fire any write triggers that are pending. Also, if the current record is transient, i.e., nothing has triggered a flush by the time the creating block is about to exit/iterate, we validate and flush the record.
validate
in interface Commitable
transaction
- true
if this is a full transaction and false
if this is
only a sub-transaction (a nested scope with transaction support). This method will
only be invoked outside a transaction for no-undo temp-table buffers.ErrorConditionException
- If validation fails.public void commit(boolean transaction)
Nothing is done if this is a full transaction commit, because no rollback will be possible at the parent scope once the database-level transaction is committed.
commit
in interface Commitable
transaction
- true
if this commit represents the master
transaction commit; false
if it represents a
sub-transaction commit.public void rollbackPending()
mergeReversibles()
) the reversibles up the
parent stack.rollbackPending
in interface Commitable
public void rollback(boolean transaction)
BufferManager
.
Auto-commit buffers are never rolled back.
rollback
in interface Commitable
transaction
- true
if this commit represents the master
transaction rollback; false
if it represents a
sub-transaction rollback.public void finished()
finished
in interface Finalizable
public void deleted()
deleted
in interface Finalizable
public final void iterate()
iterate
in interface Finalizable
public final void retry()
retry
in interface Finalizable
public final RecordBuffer buffer()
BufferReference
interface, and provides a
means for the persistence layer to retrieve a reference to the backing
RecordBuffer
instance for a DMO proxy object provided by
client code. It is invoked by the enclosed invocation handler
implementation, which services proxied method invocations on DMO proxy
objects.buffer
in interface BufferReference
this
).public Persistable getCurrentRecord()
null
if the buffer currently is empty.public LockType getPinnedLockType(java.io.Serializable id)
id
- Record identifier.RecordLockContext
public void setPinnedLockType(java.io.Serializable id, LockType pinnedLockType)
id
- Record identifier.pinnedLockType
- New pinned lock type.RecordLockContext
public boolean isWorldScope()
worldScope
flag.public int getScopeOpenDepth()
public recid recordID()
This method will return a 32-bit recid which represents the internal row ID of the given record. If the actual row ID (which is implemented as a wider integer) cannot fit due to overflow, an error condition will be raised.
dmo
, a recid
initialized as unknown value is returned.ErrorConditionException
- if the actual record ID is too wide to fit within a 32-bit
integer.public rowid rowID()
dmo
, a
rowid
initialized as unknown value is returned.public handle tableHandle()
public java.lang.Class<?> getDMOInterface()
public void flush() throws ValidationException
ValidationException
- if validation on the buffer fails.ErrorConditionException
- if there is an error accessing the database while persisting the record.public final int hashCode()
hashCode
in class java.lang.Object
public final boolean equals(java.lang.Object o)
equals
in class java.lang.Object
o
- Object to test for equality.true
if equivalent, else false
.public java.lang.String toString()
toString
in class java.lang.Object
public boolean initialize()
true
if the buffer was initialized with this call; false
if the buffer had been initialized with a previous call to this method.java.lang.IllegalArgumentException
- if no implementation class is found for the given database and interface; if setup
for an invalid foreign relation fails.StopConditionException
- if index information cannot be obtained for backing table or if database isn't
connected.protected void closeRelatedQueries()
protected void resourceDeleted()
finishedImpl()
), which should
be overridden by a subclass needing to perform some action at this point.protected boolean isAutoCommit()
false
for permanent table buffers; subclasses should override for
different behavior.protected boolean isUndoable()
true
.true
.protected boolean isTemporary()
false
.protected boolean isTableDefinitelyEmpty()
false
to indicate it is not definitively known
whether the backing table might have rows.protected java.lang.String getLDBName(java.lang.String ldbOrAlias)
ldbOrAlias
- A logical database name or database alias.null
if ldbOrAlias
is not a valid and
connected logical database name or alias.protected java.lang.String getPDBName(java.lang.String ldbName)
ldbName
- A logical database name.protected Database getPDB(java.lang.String ldbName)
ldbName
- A logical database name.ldbName
.protected void openConnectionManagerScope()
protected void closeConnectionManagerScope()
protected Persistable instantiateDMO() throws java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
java.lang.InstantiationException
- if the class cannot be instantiated.java.lang.IllegalAccessException
- if the DMO class' target constructor cannot be accessed.java.lang.reflect.InvocationTargetException
- if the underlying constructor throws an exception.protected void openScope()
BufferManager
is tracking this buffer for block scope entries
and exits within transactions, such that this buffer can be registered
with the TransactionManager
for commit/rollback
notifications. The buffer is also registered for finish processing so
that the appropriate record and lock transition processing can occur
when the buffer scope closes.protected void openScopeAt(int blockDepth)
BufferManager
is tracking this buffer for block scope entries and exits
within transactions, such that this buffer can be registered with the
TransactionManager
for commit/rollback notifications. The buffer is also
registered for finish processing so that the appropriate record and lock transition
processing can occur when the buffer scope closes.blockDepth
- Zero-based depth of the block (starting from the outermost scope) at which the buffer
scope is opened.protected void processMiddleBlocks(int outermostLevel)
openScopeAt(int)
, the blocks at the "middle" levels between the level at which the
scope is opened (outermost level) and the current nesting level have to be processed in
order to emulate normal scope opening procedure.outermostLevel
- Zero-based block depth (starting from the outermost scope) at which the buffer scope
was opened.protected java.lang.Integer getMultiplexID()
null
, but subclasses may return a
non-null
value.null
.protected boolean isMultiplexed()
This default implementation always returns false
and should
be overridden by subclasses which require a different return value.
false
.protected boolean allowsBulkActions()
false
.protected RecordBuffer getMasterBuffer()
This only is meaningful for shared temp tables and should be overridden by subclasses.
protected void maybeFireWriteTrigger()
protected void delete() throws PersistenceException
PersistenceException
- if no record currently is loaded in the buffer, or if there is
an error deleting the current record from the database.protected void delete(java.lang.String where, java.lang.Object[] args) throws PersistenceException
This default implementation is an unsupported operation and raises an exception. Subclasses which support bulk delete must override this method.
where
- An HQL where clause snippet which defines the restriction
criteria to apply to the delete. All references to properties
in a DMO must be unqualified.args
- Query substitution parameters required by the where clause.PersistenceException
- if an error occurs performing the bulk delete operation.java.lang.UnsupportedOperationException
- always in the default implementation.protected void deleteAll()
DELETE FOR was also tested with Progress 4GL with WHERE clause. It is not needed for this method, but behaviour is the same. As result it is noticed that even such statement also waits for whole table even if only one record is locked independently whether this record satisfies WHERE clause or not . So, it seems idea of table-level locking is correct.
java.lang.IllegalArgumentException
- if no implementation class is found for the given database and interface;
if setup for an invalid foreign relation fails.StopConditionException
- if index information cannot be obtained for backing table or if database isn't
connected.protected void reclaimKeys(java.util.List<java.io.Serializable> keys)
keys
- A list of primary keys which are available for re-use. Must
not be null
.protected java.util.Map<java.lang.String,java.lang.reflect.Method> getLegacyGetterMap()
int
parameter as the subscript value for extent fields. Even if an
extent field has been denormalized, the latter is provided for backward compatibility, as
some runtime code may not have been converted to use the denormalized methods directly.protected java.util.Map<java.lang.String,java.lang.reflect.Method> getLegacySetterMap()
int
parameter as the subscript value for extent fields. Even if an
extent field has been denormalized, the latter is provided for backward compatibility, as
some runtime code may not have been converted to use the denormalized methods directly.protected java.util.Map<java.lang.String,java.lang.reflect.Method> getPojoGetterMap()
protected java.util.Map<java.lang.String,java.lang.reflect.Method> getPojoSetterMap()
protected java.util.Map<java.lang.String,java.lang.Integer> getExtentMap()
protected final int getNumFields()
protected int lookupNumFields()
protected LegacyFieldNameMap getLegacyFieldNameMap()
protected java.lang.String getDynamicName()
null
and should be overridden by subclasses which require a
non-null
name to be returned.null
.protected BufferManager getBufferManager()
protected int incrementDMOUseCount(Persistable dmo)
decrementDMOUseCount(com.goldencode.p2j.persist.Persistable)
to
implement an aggressive DMO eviction policy. Records are evicted from
the current persistence session when their use counts reach zero.
Use counts must be maintained because multiple buffers may hold the same instance of a record. A record must not be evicted while any buffer still needs it.
dmo
- DMO instance whose reference count is to be incremented.dmo
after incrementing.BufferManager.incrementDMOUseCount(com.goldencode.p2j.persist.Persistable)
protected int decrementDMOUseCount(Persistable dmo) throws PersistenceException
incrementDMOUseCount(com.goldencode.p2j.persist.Persistable)
to
implement an aggressive DMO eviction policy. Records are evicted from
the current persistence session when their use counts reach zero.
Use counts must be maintained because multiple buffers may hold the same instance of a record. A record must not be evicted while any buffer still needs it.
dmo
- DMO instance whose reference count is to be decremented.dmo
after decrementing.PersistenceException
- if an error occurs detaching dmo
from the
persistence session.BufferManager.decrementDMOUseCount(com.goldencode.p2j.persist.Persistable)
protected boolean evictDMOIfUnused(Persistable dmo) throws PersistenceException
dmo
- DMO instance whose reference count is to be decremented.true
if the DMO was evicted; false
if it was referenced by other resources.PersistenceException
- if an error occurs detaching dmo
from the
persistence session.protected void reportChange(Persistable dmo, boolean insert, boolean delete) throws PersistenceException
ChangeBroker
for broadcast to interested listeners. A change includes
any modification to a property or the deletion of the record. If there
is no change to report, this method returns immediately.
If this buffer has not previously taken a snapshot of its current
record, a deep copy is made of dmo
(which represents the
post-modification state of this buffer's current record). Any
unreported changes are then rolled back from this copy, so that the
copy represents a snapshot of the record at the time it was first
stored in the buffer.
This seemingly tortuous method of lazy initialization of the snapshot is used because it allows us in certain cases to avoid ever making a deep copy of the buffer's current record. If that record represents a Hibernate proxy which was never initialized, we avoid the overhead of ever hydrating the proxy, which in tight loops can result in a HUGE time savings.
The snapshot is then passed along with dmo
, this buffer,
and a map of property names to getter method indexes (for extent/array
properties), to the change broker for dispatching to listeners.
dmo
- DMO which represents the post-modification state of the
current record. In the case of record deletion, this object
represents the state of the record just before deletion.insert
- true
if change represents a record insertion,
otherwise false
.delete
- true
if change represents a record deletion,
otherwise false
.PersistenceException
- if any reflection error occurs taking the snapshot, or if the
change broker forwards an exception from one of its listeners.protected void reportChange(Persistable dmo, boolean insert, boolean delete, boolean setPendingFlush) throws PersistenceException
ChangeBroker
for broadcast to interested listeners. A change includes
any modification to a property or the deletion of the record. If there
is no change to report, this method returns immediately.
If this buffer has not previously taken a snapshot of its current
record, a deep copy is made of dmo
(which represents the
post-modification state of this buffer's current record). Any
unreported changes are then rolled back from this copy, so that the
copy represents a snapshot of the record at the time it was first
stored in the buffer.
This seemingly tortuous method of lazy initialization of the snapshot is used because it allows us in certain cases to avoid ever making a deep copy of the buffer's current record. If that record represents a Hibernate proxy which was never initialized, we avoid the overhead of ever hydrating the proxy, which in tight loops can result in a HUGE time savings.
The snapshot is then passed along with dmo
, this buffer,
and a map of property names to getter method indexes (for extent/array
properties), to the change broker for dispatching to listeners.
dmo
- DMO which represents the post-modification state of the
current record. In the case of record deletion, this object
represents the state of the record just before deletion.insert
- true
if change represents a record insertion,
otherwise false
.delete
- true
if change represents a record deletion,
otherwise false
.setPendingFlush
- If true
, the notification to the ChangeBroker
will
force a pending flush for persistent (non-transient) records.PersistenceException
- if any reflection error occurs taking the snapshot, or if the
change broker forwards an exception from one of its listeners.protected java.lang.String describe()
protected void upgradeLock() throws PersistenceException
PersistenceException
- if the current context does not have a share lock (or greater)
on the current record.protected java.util.Set<java.lang.String> getIndexedProperties(boolean unique)
unique
- false
to get all indexed properties;
true
to get only those that participate in unique
indexes.null
.StopConditionException
- if there is any error querying index metadata from the JDBC
driver of the associated database.protected java.lang.String toString(Persistable record)
record
.
The report includes the name and current value of every data property
within the record.record
- Record whose contents are to be written to the report.record
's contents.protected java.io.Serializable nextPrimaryKey() throws PersistenceException
PersistenceException
- if there was an error while retrieving the next primary key.protected RecordBuffer.ValidationHelper initValidationHelper()
protected void initPinnedLockTypes()
Add a user defined object to the initial scope, which is a set which will hold the primary keys of records affected by a rollback in that scope. The same instance of this set is pushed onto every new scope, so this information remains available as scopes are popped off the stack.
protected void pushPinnedLockScope()
protected void popPinnedLockScope(boolean transaction, boolean undo)
transaction
- true
if we are at a full transaction boundary,
else false
.undo
- true
if we are processing an undo on the current
scope, else false
.protected void enterBlock(int blockDepth, boolean transaction)
BufferManager
when a new block scope has been entered. Called
for all blocks.blockDepth
- 1-based depth of the block being entered, relative to the outermost block.transaction
- true
if currently in an application-level transaction, else
false
.protected void exitBlock(int blockDepth, boolean transaction)
BufferManager
when the current block scope is about to end.
Called for all blocks.blockDepth
- 1-based depth of the block being exited, relative to the outermost block.transaction
- true
if currently in an application-level transaction, else
false
.Persistence.Context getPersistenceContext()
null
if this buffer has not yet
been initialized.int getBlockDepth()
void registerRelatedQuery(P2JQuery query)
query
- Query to register.void unregisterRelatedQuery(P2JQuery query)
query
- Query to unregister.java.lang.String getLegacyName()
void average(java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
column
- An expression indicating the name of the column to aggregate.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.void count(java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
column
- An expression indicating the name of the column to aggregate. May be the wildcard
character ("*").num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Optional query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.void minimum(java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
column
- An expression indicating the name of the column to aggregate.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.void maximum(java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
column
- An expression indicating the name of the column to aggregate.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.void sum(java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
column
- An expression indicating the name of the column to aggregate.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.boolean isActive()
true
if the buffer has been initialized.void errorNotOnFile()
ErrorConditionException
- if silent error mode is suppressed.int getOpenScopeCount()
void release()
ErrorConditionException
- if validation of the current buffer record (if any) fails.void reset()
void reload(LockType lockType, boolean errorIfNull)
lockType
is higher than
the current lock type, it is upgraded immediately. If lower, it is downgraded immediately
only if outside of a transaction. If inside a transaction, the lock is marked for downgrade
to the specified type upon transaction end.lockType
- Requested lock type.errorIfNull
- true
if the current record being null should raise an error; else
false
.ErrorConditionException
- if there is no record loaded into the buffer, the error manager is not in silent
mode, and the caller considers this an error.void loadTemplateRecord(long templateId)
By convention, the template records have negative rowid/recid.
templateId
- The id of the template record.java.lang.IllegalArgumentException
- if the templateId
is not the rowid of a template record (it is positive).void setRecord(Persistable currentRecord, LockType lockType, boolean errorIfNull, SortIndex sortIndex, OffEnd offEnd, boolean inverseSorting, boolean dirtyCopy)
Setting the value to null
may result in an error or query
off-end condition, depending upon the value of errorIfNull
and the current silent error mode.
It is expected that the calling query specify the sort index which was
in use and whether the query ran off-end (and in which direction). This
information is useful to find queries
which must
determine an appropriate starting point for their search.
currentRecord
- DMO instance which represents the record currently backing
this buffer.lockType
- Lock type (already applied to a non-null
currentRecord
), which will be pinned by this
record buffer.errorIfNull
- false
to raise an end condition if the record
being set is null
; else true
(caller is responsible for handling appropriately in the
latter case).sortIndex
- Sort index which was in use at the time the given record was
fetched.offEnd
- Enum indicating whether query is off-end, and if so, in which
direction.inverseSorting
- Indicates whether offEnd
is specified against the
inverse sorting direction.dirtyCopy
- Indicates whether currentRecord
represents a copy
of a DMO found in the dirty database.QueryOffEndException
- if currentRecord
is null
and
errorIfNull
is false
.getOffEnd(SortIndex,boolean)
void throwOffEnd()
QueryOffEndException
.QueryOffEndException
- always.OffEnd getOffEnd(SortIndex sortIndex, boolean inverseSorting)
null
(meaning the query was off-end), and if so
In the event no query has yet set a record in this buffer, a value of
OffEnd.FRONT
will be returned. In the event the last query
neither ran off-end, nor used the given sort index, a value of
OffEnd.NONE
will be returned.
sortIndex
- Sort index to compare with the last sort index used to
populate (or clear) the buffer.inverseSorting
- Indicates whether the off-end is requested by a query having
the inverse sorting direction.setRecord(Persistable,
LockType,
boolean,
SortIndex,
OffEnd,
boolean,
boolean)
void setOffEnd(OffEnd offEnd)
offEnd
- Off-end status.QueryOffEndListener getQueryOffEndListener()
QueryOffEndListener
instance for this record buffer.QueryOffEndListener
instance for this record buffer.void pushTempContext()
setting a temporary record
is possible.
A context allows one or more temporary records to be set for a specific
operation, such as the execution of client-side where clause
expressions by a query, and for such operations to be nested. For
example, a client-side where expression may eventually execute a query
which then itself may execute a client-side where expression. Each
level of client-side where clause expression must execute within its
own temporary record context, such that the state of the outer where
clause expression is not lost when the inner expression is finished.
When client code is finished with a temporary record context, it should
pop
the current context.
Pushes and pops of the temporary record context must be balanced. This is the responsibility of the caller.
void popTempContext() throws PersistenceException
As a convenience, the currently active temporary record for this buffer
is set to null
first.
PersistenceException
- if setting the current, temporary record to null
triggers a failure to evict the temporary record from the
active Hibernate session.pushTempContext()
void setTempRecord(Persistable tempRecord) throws PersistenceException
The default value of the temporary record is null
. It is
only set to a non-null
reference in order to do some work
with the buffer. When the work is complete, it is critical that the
temporary record be set back to null
.
Temporary records increment the context-wide DMO use count while they are active and decrement it when they are released. This may result in a temporary record being evicted from the persistence session when it is replaced.
tempRecord
- Record which will temporarily back the buffer.PersistenceException
- if there is an error evicting a temporary record from the
persistence session after it is used.java.lang.Class<?> getDMOBufInterface()
java.lang.Class<?> getDMOImplementationClass()
java.lang.IllegalStateException
- if the buffer fails the initialization verification.java.lang.String getDMOName()
java.lang.String getDMOImplementationName()
java.lang.String getDMOAlias()
Persistence getPersistence()
Database getDatabase()
P2JDialect getDialect()
P2JDialect
in use for this record buffer.java.lang.String getSchema()
java.lang.String getLogicalDatabase()
java.lang.String getTable()
DirtyShareContext getDirtyContext()
boolean isUnknownMode()
true
if in unknown mode, else false
.void setUnknownMode()
null
, but
calls to DMO getter methods return unknown value instead of raising an
error condition. This is intended to support outer join.void create()
ErrorConditionException
- if there is an error retrieving the next available primary key
from the database or locking the record.void validate()
ErrorConditionException
- if the buffer fails validation.void validate(Persistable dmo, boolean share) throws ValidationException, PersistenceException
dmo
- DMO to be validated.share
- Whether or not to share information about dirty properties
with other contexts via the dirty share manager.ValidationException
- if the DMO state fails any unique or non-nullable constraint
check.PersistenceException
- if there is any error gathering index metadata or a database
error performing validation.boolean isAvailable()
create(com.goldencode.p2j.util.handle, java.lang.String, java.lang.String, java.lang.String)
or
retrieved in a query.true
if data is available, false
if
no record backs this buffer.boolean isRecordChanged()
FIND CURRENT
or GET CURRENT
.
P2J implementation of 4GL function CURRENT-CHANGED
.true
if the database record differs from the
value in memory buffer that was queried with the last
FIND
and false
otherwiseboolean isReadonly()
DatabaseTriggerManager
when processing a WRITE event trigger with OLD buffer.true
if the buffer contain read-only data.boolean wasLocked()
true
if the record was locked; false
if the attempt succeeded, or if this query has not yet
attempted to retrieve a record.void setLocked(boolean locked)
locked
- New value of the flag.boolean isNewlyCreated()
true
if record is newly created, else
false
.boolean wasAmbiguous()
true
if the query was ambiguous;
false
if the attempt succeeded, or if no attempt
has yet been made.boolean isDynamic()
true
if it is a dynamic buffer.void setDynamic()
TempTable getParentTable()
TempTable
object for temporary buffers or null
for permanent buffers.void setAmbiguous(boolean ambiguous)
ambiguous
- New value of the flag.void disableReleaseOnIterate()
iterate()
method.
This is necessary for the outer buffers in a compound query.boolean isDirtyCopy()
true
if current record is a dirty copy, else
false
.boolean isTransient()
true
if record is new, else false
.void markPersisted()
BufferReference getDMOProxy()
void addLegacyForeignKeys(java.util.Collection<java.lang.String> properties)
properties
- A collection of DMO property names.AssociationSyncher
,
LocalSyncher
,
InverseSyncher
java.util.Map<java.lang.String,java.lang.Object> getDirtyProperties(boolean indexesOnly)
indexesOnly
- Filter only dirty properties that are part of index in backing table.null
.boolean isPropertyIndexed(java.lang.String property)
property
- Property name.true
if property
participates in an
index, else false
.BufferType getBufferType()
BufferType
key associated with this buffer, or
null
if the buffer has not yet been initialized.boolean isPendingRollbackProcessed()
true
if pending rollback was processed.void resetPendingRollbackProcessed()
BaseDataType getValue(java.lang.String field)
field
- The property name of the field.void armCurrentChanged()
recordChanged
settings and free of the temporary compare buffer.void updateCurrentChanged()
recordChanged
flag.
This must be called right after an armCurrentChanged()
followed by a
reload()
.
This checks the current value stored in currentRecord
against the value
temporarily saved and updates the recordChanged
accordingly. After that, the
temp data is freed.protected boolean isGlobal()
false
.private boolean checkBufferName(FieldInfo fieldInfo)
fieldInfo
object has a buffer name qualifier, and if
so, whether it matches the buffer's variable name or the dynamically assigned temp-table
name (if this is the buffer for a dynamically prepared temp-table).fieldInfo
- Object which contains parsed field specifier information.true
if there is no buffer qualifier, or if there is one and it has
the expected value; false
if there is a mismatched qualifier.private boolean reportBadBufferName(FieldInfo fieldInfo, java.lang.String fieldSpec)
fieldInfo
object has a buffer name qualifier, and if
so, whether it matches the buffer's variable name. Report an error if there is a qualifier
and it does not match the buffer's variable name.fieldInfo
- Object which contains parsed field specifier information.fieldSpec
- Field specifier string (used only to generate an error message).true
if there is no buffer qualifier, or if there is one and it has
the expected value; false
if there is a mismatched qualifier, and we
are in silent error mode.ErrorConditionException
- if fieldInfo
contains a mismatched buffer name qualifier and we are
not in silent error mode.private boolean isValidExtent(int extentIndex, java.lang.String property)
property
, if it represents an extent field.extentIndex
- A non-negative, zero-based array index to be tested for validity.property
- Name of the property to be checked.true
if property
represents an extent field and
extentIndex
is non-negative and is not out of bounds;
false
if extentIndex
is negative or property
does not represent an extent field, or extentIndex
is out of bounds.private void aggregate(java.lang.String aggregate, java.lang.String column, NumberType num, java.lang.String where, java.lang.Object... args)
aggregate
- Name of HQL aggregate function (e.g., "count").column
- An expression indicating the name of the column to aggregate. May be the wildcard
character ("*") for COUNT.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.private void checkActive()
java.lang.IllegalStateException
- if the buffer has not been initialized.private void finishedImpl()
private void registerWithNewName(java.lang.String newName, BufferImpl bufferImpl, java.lang.String legacyName)
newName
- The new name the buffer will be registered.bufferImpl
- The BufferImpl that will carry the new legacy name and will have to restore it
when the procedure scope finishes.legacyName
- The new 'local' legacy name for the buffer.private void mergeReversibles()
private void undoDirty() throws PersistenceException
dirtyProps
map.
If there is no current record or no pending changes to the current record, the method returns immediately.
PersistenceException
- if there is an error using reflection to set DMO properties.private void processChange(boolean setPendingFlush) throws PersistenceException
ReversibleUpdate
object and reporting the change to the
ChangeBroker
for further distribution to registered listeners.setPendingFlush
- If true
, the notification to the ChangeBroker
via
reportChange(com.goldencode.p2j.persist.Persistable, boolean, boolean)
will force a pending flush for persistent
(non-transient) records.PersistenceException
- if a problem occurs reporting the change to registered
listeners.private boolean anyUniqueConstraint(java.util.Set<java.lang.String> properties)
properties
- A set of properties to be checked if any is part of an unique
constraint.true
if any of the specified property is part
of an unique constraint.private Persistable getTempRecord()
setTempRecord(Persistable)
private void load(Persistable target, LockType lockType, boolean undo)
lockType
is higher than the current lock type, it is
upgraded immediately. If lower, it is downgraded immediately only if
outside of a transaction. If inside a transaction, the lock is marked
for downgrade to the specified type upon transaction end.target
- DMO to be reloaded. If null
, an exception will be
raised.lockType
- Requested lock type.undo
- true
if currently processing an undo or
false
if currently processing a reload from databaseErrorConditionException
- if there is no record loaded into the buffer and the error
manager is not in silent mode.private void initializeLazyExtents()
private void syncForeignRelations(boolean inverse)
inverse
- If true
then inverse synchronization is performed.
Otherwise only synchronization triggered by changes to the DMO at
the "local" end of the association is performed.InverseSyncher
,
LocalSyncher
private void setDMOProxy(BufferReference dmoProxy)
dmoProxy
- DMO proxy object.private void setCurrentRecord(Persistable newCrtRecord, boolean undo, boolean newlyCreated, boolean dirtyCopy)
If a new DMO is set to this buffer, the WRITE
trigger is fired and the existing one
(if any) is flushed to backing database, count usage decremented and, if the case, the old
record is detached from persistence.
If not null, the new DMO is registered with Hibernate and its usage count is incremented.
newCrtRecord
- DMO instance which represents the record currently backing this buffer. If
null
, the record (and possibly its corresponding lock) is released.undo
- true
if currently processing an undo, else false
.newlyCreated
- true
if the record being stored in the buffer is newly created.dirtyCopy
- Indicates whether newCrtRecord
represents a copy of a DMO found in the
dirty database.ErrorConditionException
- if there is an error transitioning a lock when releasing the current record; if
there is an error validating or saving a transient record during flush.private boolean isCommitPending()
true
if a commit is pending, else
false
.private void setCommitPending(boolean commitPending)
commitPending
- true
if we are currently in batch assign mode and
the changes made while in this mode should be committed to the
database immediately upon completing this mode;
false
if the commit pending state should be reset
such that no commit should occur.private void setReversibleCreate()
RecordBuffer.ReversibleCreate
instance.
If this buffer is not undoable, this method is a no-op (queues a RecordBuffer.ReversibleDelete
).
private void setReversibleDelete()
ReversibleDelete
instance.
If this buffer is not undoable, this method is a no-op.
private void setReversibleEntry(Reversible item)
item
- New, "current" reversible action.private void errorNotAvailable()
ErrorConditionException
- if silent error mode is suppressed.