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.Record) 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 |
|---|---|
private static class |
RecordBuffer.ArgumentBuffer
Used as a handler for buffers which are referenced through a buffer parameter.
|
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.PinnedLocks
This class manages the record lock types pinned by this buffer.
|
| Modifier and Type | Field and Description |
|---|---|
protected int |
activeScopeDepth
Block depth at which outermost scope was opened
|
private org.roaringbitmap.RoaringBitmap |
allBufferScopes
The set of scopes where the buffer was registered with
allBuffers. |
private boolean |
ambiguous
Indicates if last find failed because criteria was ambiguous
|
private java.util.ArrayList<AssociationSyncher> |
assocSynchers
Foreign association synchronization helper objects
|
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?
|
private org.roaringbitmap.RoaringBitmap |
byLegacyNameScopes
The set of scopes where the buffer was registered with
byLegacyName. |
protected ChangeBroker |
changeBroker
Context-local ChangeBroker
|
private boolean |
commitPending
Is a transaction commit necessary upon ending a batch assign?
|
protected boolean |
createRowCallback
Marker for a CREATE-ROW callback in process.
|
private int |
createScope
Scope depth at which transient record was created
|
private RecordBuffer |
creatingBuffer
Buffer which created current, unflushed record, if different from this one
|
private Record |
currentRecord
DMO data record which currently backs this buffer
|
private DataModelAst |
dataModelAst
The data model AST for this buffer.
|
protected DatabaseTriggerManager |
dbTrigManager
The database trigger manager for this context.
|
private static NanoTimer |
DEF_BUFFER
|
private java.lang.Class<?> |
definingType
The defining type where this buffer is constructed.
|
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.lang.Class<? extends Buffer> |
dmoBufInterface
Grouping DMO and Buffer interface associated with this buffer.
|
private java.lang.Class<? extends Record> |
dmoClass
Class which defines DMO's implementation
|
private DmoMeta |
dmoInfo
The DMO meta information for this buffer.
|
private java.lang.Class<? extends DataModelObject> |
dmoInterface
Interface which defines DMO's API and
Table metadata annotation. |
private BufferReference |
dmoProxy
Convenience reference to associated DMO proxy
|
private static java.lang.reflect.Method[] |
doNotProxy
Array of methods not to be proxied
|
protected static java.lang.reflect.Method[] |
doNotProxyRes
Array of methods not to be proxied from the
HandleResource. |
private boolean |
dynamic
Determines if this buffer is dynamic.
|
private boolean |
fake
Flags this record buffer as a "fake" buffer (e.g., the old buffer in a write trigger)
|
private boolean |
firingRowUpdate
Flag used to avoid recursive call while invoking ROW-UPDATE event procedure while another block is
finished.
|
private java.util.List<ForeignNuller> |
foreignNullers
Helpers which null out foreign key references to deleted DMOs
|
private java.util.Map<java.lang.String,RecordBuffer.DatumAccess> |
getterDatums
Map of
RecordBuffer.DatumAccess getter instances, for each property. |
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
|
protected boolean |
ignoreBeforeTracking
If
true this flag makes the change-tracking of this dataset AFTER-BUFFER ignore
changes and skip storing changes to associated BEFORE-BUFFER. |
private java.util.BitSet |
indexedProperties
Properties which participate in any indexes of the backing table
|
private IndexHelper |
indexHelper
Object which identifies modified indexes
|
private boolean |
isTemporary
Flag that indicates whether this buffer is backed by a temporary table.
|
private boolean |
isTouched
Flags whether the record stored has been write-touched.
|
private int |
iterateReleaseOverrideScope
Scope at which iterate should not release the current record
|
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 org.roaringbitmap.RoaringBitmap |
loadedBuffersScopes
The set of scopes where the buffer was registered with
loadedBuffers. |
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 CentralLogger |
LOG
Logger
|
private static java.lang.String |
LOG_MSG_DB_UNEXP_REF
Log message.
|
private static java.lang.String |
LOG_MSG_SIGN_BROKEN
Log message.
|
private static java.lang.String |
LOG_MSG_SIGN_UNIMPL
Log message.
|
private java.lang.String |
logicalDatabase
Logical name of database associated with this buffer
|
private RecordMeta |
metadata
The metadata of the record to be stored in 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
|
private java.lang.String |
oldVariable
The old name of the buffer, after it was overridden by a proxy.
|
private org.roaringbitmap.RoaringBitmap |
openBuffersScopes
The set of scopes where the buffer was registered with
openBuffers. |
protected int |
openScopeCount
Number of open scopes for this buffer (open scopes can be nested)
|
private java.lang.String |
overrideLegacyName
Temporary override of legacy name.
|
private Persistence |
persistence
Persistence service object
|
protected Persistence.Context |
persistenceContext
Current persistence context
|
private java.lang.Object |
persistentProc
The persistent procedure which defined this buffer.
|
private RecordBuffer.PinnedLocks |
pinnedLocks
Object which tracks locks pinned by this buffer
|
protected ProcedureManager.ProcedureHelper |
pm
Helper to use the ProcedureManager without any context local lookups.
|
private boolean |
readonly
Flags this record buffer as readonly.
|
private java.util.List<RecordBuffer> |
recordBuffers
Cache of the list returned by
recordBuffers(). |
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 ProgressAst |
schemaTableAst
The table schema AST for this buffer.
|
private java.util.Map<java.lang.String,RecordBuffer.DatumAccess> |
setterDatums
Map of
RecordBuffer.DatumAccess setter instances, for each property. |
private Record |
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 Record |
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<Record> |
tempRecords
Temporary record stack used for purposes such as sorting
|
private java.util.Map<java.lang.Object,TriggerTracker> |
triggerMap
Cache the trigger map from
TriggerTracker. |
private TriggerTracker |
triggerTracker
Helper object to manage database trigger information.
|
protected TransactionManager.TransactionHelper |
txHelper
Transaction helper object
|
private RecordBuffer.LightweightUndoable |
undoable
The undoable instance for this buffer.
|
private static int |
unimplementedFastCopyWarningCounter
Count the warnings with the intent of reducing the number of log messages.
|
private UniqueTracker |
uniqueTracker
Helper object to track unique constraint information for uncommitted transactions
|
private UniqueTracker.Context |
uniqueTrackerCtx
Context-local API for unique constraint tracker
|
private boolean |
unknownMode
Marks the
currentRecord as being set from an OUTER query. |
private java.lang.Object[][] |
unreportedChanges
Property changes pending submission to the ChangeBroker
|
private java.lang.String |
variable
Legacy name of this buffer and transaction manager's lookup key for this buffer
|
private boolean |
vst
This flags that the record held is a VST.
|
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()
Implicit constructor.
|
protected |
RecordBuffer(java.lang.Class<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable)
Constructor.
|
protected |
RecordBuffer(java.lang.Class<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable,
int blockDepth)
Constructor.
|
| Modifier and Type | Method and Description |
|---|---|
java.lang.Long |
_rowID()
Get the row ID of the current buffer's current record, if any.
|
protected void |
_setDynamic()
Mark the buffer as dynamic.
|
(package private) void |
addAllBufferScope(int scope)
Add a scope where this buffer was registered with
allBuffers. |
(package private) void |
addByLegacyNameScope(int scope)
Add a scope where this buffer was registered with
byLegacyName. |
protected 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.
|
(package private) void |
addLoadedBuffersScope(int scope)
Add a scope where this buffer was registered with
loadedBuffers. |
(package private) void |
addOpenBuffersScope(int scope)
Add a scope where this buffer was registered with
openBuffers. |
private void |
addUnreportedChanges(int propIndex,
int extent,
java.lang.Object[] diffs)
Adds the information about new change to
unreportedChanges2 structure. |
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.
|
(package private) static boolean |
areDMOsSame(Record dmo1,
Record dmo2)
Indicate whether two DMO instances represent the same record, as
determined by a comparison of their primary key identifiers.
|
protected void |
armCurrentChanged()
Prepares for an immediate reload().
|
private static void |
armWriteTrigger(RecordBuffer rb,
boolean useOpenScope)
Makes sure the specified record buffer has the trigger tracked armed (ready to fire at next flush).
|
void |
associate(DataModelObject dmo)
Load the
DataModelObject sent as parameter in this buffer with associate it with the persistence
session of the buffer. |
protected 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.
|
static void |
batch(java.lang.Runnable code)
Worker method that executes a given block of code in batch assign mode, by bracketing the call in
startBatch(com.goldencode.p2j.persist.BufferManager, boolean) and endBatch(com.goldencode.p2j.persist.BufferManager, boolean) calls. |
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). |
private void |
checkReadOnlyVstBuffer()
Checks whether the table is read-only.
|
protected void |
cleanup()
Do clean-up in case the buffer runs out of (outermost) scope.
|
(package private) static void |
cleanupBatchMode(BufferManager bufferManager)
Reset to default values the state variables related to batch assign mode.
|
(package private) static void |
cleanupBatchMode(java.util.Set<RecordBuffer> bufs)
Reset to default values the state variables related to batch assign mode.
|
private void |
clearUnreportedChanges()
Clears the unreported changes associated with this buffer.
|
protected void |
closeRelatedQueries()
Close related queries.
|
void |
commit(boolean transaction)
Process a commit event for the current buffer.
|
(package private) static java.util.List<java.lang.String> |
compare(DataModelObject dmo1,
DataModelObject dmo2,
java.lang.String[] fieldList,
boolean noLobs,
BufferCompare.Mode mode,
boolean exclusive,
boolean exhaustive)
BUFFER-COMPARE statement runtime, returning the list of legacy fields that are different.
|
(package private) static logical |
compare(RecordBuffer srcBuf,
RecordBuffer dstBuf,
BufferCompare.Mode mode,
character except,
character pairs,
logical noLobs)
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,
BufferCompare.Mode mode,
boolean exhaustive)
This method compares given fields between the source buffer and the target buffer.
|
protected static logical |
copy(DataModelObject srcDMO,
DataModelObject dstDMO,
java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap,
java.util.List<RecordBuffer.DatumAccess> pkProps)
Perform a bulk copy of data from a source record to a destination
record.
|
(package private) static void |
copy(DataModelObject srcDmo,
DataModelObject dstDmo,
java.lang.String[] srcFields,
boolean exclusive,
boolean noLobs,
boolean validate)
BUFFER-COPY statement runtime.
|
(package private) static logical |
copy(RecordBuffer dstBuf,
RecordBuffer srcBuf,
character except,
character pairs,
logical noLobs)
BUFFER-COPY() handle-based method runtime.
|
private static logical |
copy(RecordBuffer srcBuf,
RecordBuffer dstBuf,
java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap,
java.util.List<RecordBuffer.DatumAccess> pkDstProps,
java.util.List<RecordBuffer.DatumAccess> pkSrcProps,
boolean validate)
This method copies given fields from the source buffer to the receiving buffer.
|
(package private) static void |
copyCommonFields(Record target,
Record source)
Copy the content of a DMO to another.
|
protected 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.
|
protected boolean |
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 <T extends Buffer> |
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<?> 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,
RecordBuffer srcBuf,
RecordBuffer dstBuf,
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.Integer> srcExtents,
java.util.Map<java.lang.String,java.lang.Integer> dstExtents,
java.util.Map<java.lang.String,java.lang.String> srcLegacyFieldsMap,
java.util.Map<java.lang.String,java.lang.String> dstLegacyFieldsMap,
java.util.Map<java.lang.reflect.Method,PropertyMeta> srcProps,
java.util.Map<java.lang.reflect.Method,PropertyMeta> dstProps,
java.util.Map<java.lang.String,RecordBuffer.DatumAccess> srcDatums,
java.util.Map<java.lang.String,RecordBuffer.DatumAccess> dstDatums,
boolean noLobs,
RecordBuffer.OperationType operationType)
Creates simple properties map with mapping properties with the same legacy names.
|
void |
datasourceRowid(rowid sourceRowid)
Sets the
datasource-rowid for AFTER-TABLE record. |
protected long |
decrementDMOUseCount(Record dmo,
boolean transient_)
Decrement the context local use count for the specific instance of the
given record.
|
protected void |
decrementObjectCountRef(object<?> obj)
Decrements the counter-reference for the specified object.
|
static <T extends Buffer> |
define(java.lang.Class<?> def,
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 extends Buffer> |
define(java.lang.Class<?> def,
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 extends Buffer> |
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 extends Buffer> |
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 extends Buffer> |
defineAlias(java.lang.Class<T> dmoBufIface,
Buffer aliasOf,
java.lang.String varName,
java.lang.String legacyName)
When a buffer is passed as a parameter, a new instance should be created in order to
differentiate the references.
|
static <T extends Buffer> |
defineReadOnly(java.lang.Class<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String database,
Record roValue,
boolean fake)
Define a new buffer which is based upon the specified interface.
|
private static <T extends Buffer> |
defineReadOnlyImpl(java.lang.Class<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String database,
Record roValue,
boolean fake)
Define a new buffer which is based upon the specified interface.
|
RecordBuffer |
definition()
Resolve the instance as it exists when the external program or 4GL class was
initially instantiated.
|
protected void |
delete()
Delete the current record from the database.
|
protected void |
delete(DataModelObject[] suppDMOs,
java.lang.String where,
java.lang.Object... args)
Perform a bulk delete, restricted by the given where clause and query substitution
parameters.
|
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 boolean |
delete(java.util.function.Supplier<logical> valexp,
java.util.function.Supplier<character> valmsg)
Delete the current record from the database.
|
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.
|
protected 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 int |
endBatch(BufferManager bufMan,
boolean error)
Exit batch assign mode in the current context, triggering pending
validation on all buffers which were modified while in this mode.
|
boolean |
equals(java.lang.Object o)
Determine whether this object is equivalent to the specified object.
|
protected java.lang.Integer |
errorFlags()
Gets
errorFlag of this record. |
private void |
errorNotAvailable()
Record or throw a "record not available" error condition for
the current DMO type.
|
private static void |
errorNotAvailable(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
protected void |
errorNotOnFile()
Record or throw a "record not on file" error condition for
the current DMO type.
|
protected character |
errorString()
Gets
error string of this record. |
protected void |
errorString(Text string)
Sets the
error string of this record. |
protected boolean |
evictDMOIfUnused(Record dmo)
Evict the given DMO from the current Hibernate session if it is not
referenced by any buffer or other resource.
|
private static boolean |
fastCopy(RecordBuffer srcBuf,
RecordBuffer dstBuf,
boolean forcePair,
boolean noLobs,
boolean validate,
boolean hasBefore)
Fast way to do the buffer-copy.
|
java.lang.Boolean |
fastHasRecords()
Indicate whether the table backing this buffer contains records.
|
void |
finished()
Called by the transaction manager just before a buffer scope closes.
|
protected void |
finishedImpl()
Called by the transaction manager just before a buffer scope closes.
|
private void |
fit(java.lang.StringBuilder sb,
java.lang.String text,
int size,
int type)
Helper method for
sqlTableContent(int). |
void |
flush()
Validate the current record and flush it to the database, if validation passes.
|
private void |
flush(boolean retryInvalid)
Validate the current record and flush it to the database, if validation passes.
|
private static java.lang.String |
formatProperty(java.lang.Object value)
Helper method to format a property value.
|
(package private) static RecordBuffer |
get(DataModelObject dmo)
Get the buffer instance which corresponds with the given DMO proxy.
|
(package private) int[] |
getAllBuferScopes()
Get the list of scopes in
allBufferScopes. |
protected java.util.Map<java.lang.String,java.lang.String> |
getBoundPropertyMappings()
Get the mappings of property names, from definition to bound buffer.
|
protected BufferManager |
getBufferManager()
Get the buffer manager associated with this buffer.
|
protected BufferType |
getBufferType()
Get the buffer type hash key associated with this buffer.
|
(package private) int[] |
getByLegacyNameScopes()
Get the list of scopes in
byLegacyNameScopes. |
protected ChangeBroker |
getChangeBroker()
Return the change broker associated with this buffer
|
static character |
getCodePage(BufferField field)
Get code page of the specified CLOB field.
|
static character |
getCodePage(FieldReference field)
Get code page of the specified CLOB field.
|
java.lang.String |
getCodePage(java.lang.String property)
Get code page of the specified CLOB field.
|
protected static java.util.Set<java.lang.String> |
getCommonFields(java.util.Set<java.lang.String> set1,
java.util.Set<java.lang.String> set2,
java.lang.String[] fieldList,
boolean exclusive)
Given two sets of legacy field names, an additional list of legacy field names (optional),
and a flag indicating whether the additional list is inclusive or exclusive, find the
appropriate intersection of field names.
|
Record |
getCurrentRecord()
Get the DMO which represents the database record currently held in the buffer.
|
Database |
getDatabase()
Get the physical database name associated with this buffer.
|
protected DataModelAst |
getDataModelAst()
Get the cached
dataModelAst tree. |
protected RecordBuffer |
getDefaultBuffer()
Get default buffer (for temporary tables only).
|
protected java.lang.Class<?> |
getDefiningType()
Get the buffer's defining type.
|
Dialect |
getDialect()
Convenience method to get the
Dialect in use for this record buffer. |
protected java.lang.Object |
getDirectField(int offset)
Direct access to the field value on the specified offset.
|
protected DirtyShareContext |
getDirtyContext()
Get the dirty share context used by this buffer.
|
private java.util.BitSet |
getDirtyProperties(boolean indexesOnly)
Get a set of dirty properties.
|
java.lang.String |
getDMOAlias()
Get the variable name associated with this buffer instance.
|
protected java.lang.Class<? extends Buffer> |
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. |
private java.lang.Class<?> |
getDMOClass()
Return the DMO class associated with this buffer
|
protected java.lang.Class<? extends Record> |
getDMOImplementationClass()
Report the DMO implementation class associated with this buffer.
|
protected java.lang.String |
getDMOImplementationName()
Get the unqualified name of the DMO implementation class.
|
DmoMeta |
getDmoInfo()
Get the meta information of the DMO associated with the buffer.
|
java.lang.Class<? extends DataModelObject> |
getDMOInterface()
Get the DMO interface associated with this buffer.
|
protected java.lang.String |
getDMOName()
Get the unqualified name of the DMO's interface.
|
BufferReference |
getDMOProxy()
Get the DMO proxy which references this buffer instance.
|
static java.lang.reflect.Method[] |
getDoNotProxy()
Getter for doNotProxy array;
|
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.
|
FastFindCache |
getFastFindCache()
Get the
FastFindCache instance for the database associated with this buffer. |
protected java.util.Map<java.lang.String,RecordBuffer.DatumAccess> |
getGetterDatums()
Getter for the
getterDatums map. |
private RecordBuffer.Handler |
getHandler()
Return the handler associated with this buffer
|
private java.util.BitSet |
getIndexedProperties(boolean unique)
Retrieve the set of all properties 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.lang.String |
getLegacyName()
Get the table/buffer legacy name.
|
(package private) int[] |
getLoadedBuffersScope()
Get the list of scopes in
loadedBuffersScopes. |
protected java.lang.String |
getLogicalDatabase()
Get the logical database name associated with this buffer.
|
protected RecordBuffer |
getMasterBuffer()
Retrieve the master record buffer for this buffer.
|
private RecordMeta |
getMetadata()
Get the record metadata associated with this buffer's DMO class.
|
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.
|
protected RecordNursery |
getNursery()
Get the record nursery of the current persistence context.
|
protected 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[] |
getOpenBuffersScope()
Get the list of scopes in
openBuffersScopes. |
protected int |
getOpenScopeCount()
Get the number of scopes currently open for this buffer.
|
AbstractTempTable |
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.
|
Persistence |
getPersistence()
Get the persistence service object associated with this buffer.
|
protected Persistence.Context |
getPersistenceContext()
Get the persistence context for this buffer.
|
java.lang.Object |
getPersistentProc()
Returns the persistent procedure which is responsible for this record buffer.
|
LockType |
getPinnedLockType(java.lang.Long 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 ProcedureManager.ProcedureHelper |
getProcedureManager()
Return the procedure manager associated with this 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,
java.util.Map<java.lang.reflect.Method,PropertyMeta> dstPropMeta,
java.util.Map<java.lang.String,RecordBuffer.DatumAccess> dstDatums,
character except,
character pairs,
logical noLobs,
RecordBuffer.OperationType opType,
java.util.List<RecordBuffer.DatumAccess> pkDstProps,
java.util.List<RecordBuffer.DatumAccess> pkSrcProps)
This method establishes the map of properties being compared or copied.
|
protected QueryOffEndListener |
getQueryOffEndListener()
Get the
QueryOffEndListener instance for this record buffer. |
protected RecordLockContext |
getRecordLockContext()
Get the record lock context helper.
|
protected java.lang.String |
getSchema()
Get the schema name of the database associated with this buffer.
|
(package private) static SchemaDictionary |
getSchemaDictionary(java.util.List<Buffer> buffers)
Get a local instance of the schema dictionary which is configured to resolve references
related to the given list of buffers, when parsing a dynamic query or validation expression.
|
protected ProgressAst |
getSchemaTableAst()
Get the cached
schemaTableAst tree. |
int |
getScopeOpenDepth()
Get the depth of the scope at which this buffer was first opened.
|
Session |
getSession()
Get the currently active ORM database session, if any.
|
Session |
getSession(boolean create)
Get the currently active ORM database session, optionally creating one if it does not exist.
|
protected java.util.Map<java.lang.String,RecordBuffer.DatumAccess> |
getSetterDatums()
Getter for the
setterDatums map. |
Record |
getSnapshot()
Get a representation of the latest DMO to be held in the buffer.
|
protected java.lang.String |
getTable()
Get the name of the table associated with this buffer.
|
private Record |
getTempRecord()
Get the currently active temporary record.
|
java.lang.String |
getTenantId()
Get the id of the tenant (if any) from the persistence context.
|
protected TriggerTracker |
getTriggerTracker()
Return the trigger tracker associated with this buffer
|
protected TransactionManager.TransactionHelper |
getTxHelper()
Return the transaction helper associated with this buffer
|
java.lang.Long |
getTxNestingId()
Get the zero-based transaction block nesting level, where 0 indicates the current block is a full
transaction block, 1 indicates the current block is the first level of nested subtransaction, and so
on.
|
LazyUndoable |
getUndoable()
Get the
undoable instance. |
protected 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 boolean |
inChangeScope()
Determine whether the current open buffer scope is at or lower than the current high-water mark
open buffer scope depth at which an undoable change has been made.
|
protected long |
incrementDMOUseCount(Record dmo,
boolean transient_)
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.
|
boolean |
initialize(boolean fromDefine)
Initialize the core data on which this buffer relies.
|
protected void |
initPinnedLockTypes()
Initializes the map that contains primary keys of past and present records held by this buffer,
mapped to their pinned LockTypes.
|
protected Record |
instantiateDMO()
Create a new instance of the DMO implementation class associated with
this buffer.
|
void |
invalidateFFCache(int index)
Invalidates all or a specific index for this buffer's table.
|
protected boolean |
isActive()
Indicate whether this buffer is active.
|
private static boolean |
isAssignableTypes(java.lang.reflect.Method srcMethod,
java.lang.reflect.Method dstMethod,
boolean noLobs,
RecordBuffer.OperationType operationType)
This method checks that two getter or setter methods have compatible corresponding return
or parameter types for given operation type.
|
boolean |
isAutoCommit()
Indicate whether this is a temp-table buffer and we are not currently within an existing
database transaction.
|
protected boolean |
isAvailable()
Indicate whether a backing data record currently is available.
|
boolean |
isBufferScopeLeaking()
Very specific method to check if a buffer is still dangling in
ConnectionManager. |
protected boolean |
isBulkCopy()
Get the
bulkCopy flag. |
private boolean |
isCommitPending()
Indicate whether a commit is pending for the most recent changes made
to the current record.
|
protected boolean |
isDirtyCopy()
Indicate whether the record currently in the buffer represents a copy of
a DMO from the dirty database.
|
protected boolean |
isDynamic()
Determines if the buffer is dynamic.
|
protected boolean |
isFake()
Indicate whether this buffer is a "fake" buffer.
|
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.
|
boolean |
isMutable()
Check whether this buffer is associated with a persistent table from a mutable database (i.e., that
its DMO is generated at runtime by a
database scan). |
protected 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).
|
protected boolean |
isPropertyIndexed(int propertyIndex)
Indicate whether the given property participates in any index.
|
protected boolean |
isReadonly()
Checks if this buffer is a read-only buffer.
|
protected 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 either: (a) not exist; or (b) contain no
rows.
|
boolean |
isTemporary()
Convenience method to indicate whether this buffer is backed by a
temporary table.
|
protected boolean |
isTouched()
Get the state of the
isTouched flag. |
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.
|
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 |
isVst()
Checks whether the record contained is a virtual system table (VST).
|
boolean |
isWorldScope()
Get the state of the
worldScope flag. |
void |
iterate()
Called by the transaction manager after each iteration of a repeating
block.
|
(package private) java.util.List<java.lang.String> |
listDirtyIndexes(boolean unique,
boolean fullMatch,
boolean cumulative)
Cross reference dirty DMO properties with indexes containing them, creating a list of indexes which have
been updated.
|
private void |
load(Record target,
LockType lockType,
boolean undo,
boolean allowWriteTrigger)
Load the specified record, if any, from the database.
|
void |
loadRecord(Record newCrtRecord)
Set the DMO implementation instance which backs this buffer with a another record, loaded from database.
|
protected 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) static <T> T |
makeArgumentBuffer(java.lang.Class<T> dmoBufIface,
Buffer proxy,
java.lang.String varName,
java.lang.String legacyName)
Creates a proxy with an argument buffer as handler.
|
protected void |
markChangeScope()
Potentially set the current high-water block depth at which an undoable change has been
made.
|
protected void |
markPersisted()
Mark the buffer's current record as no longer transient by resetting it
create scope to its default value.
|
protected 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.
|
private void |
maybeFireRowUpdateEvent()
Checks whether the conditions for firing ROW-UPDATE event are met.
|
boolean |
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.
|
protected 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.lang.Long |
nextPrimaryKey()
Returns the primary key for a new DMO associated with this buffer.
|
protected void |
onCloseOutermostScope()
Perform any actions needed when this buffer's outermost scope closes.
|
protected void |
onOpenOutermostScope()
Perform any actions needed when this buffer's outermost scope opens (or if the buffer was not active
when that scope was opened, when the buffer is first activated thereafter).
|
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.
|
void |
originRowid(rowid peer)
Sets the
origin-rowid for AFTER-TABLE record. |
protected boolean |
overrideDMOAlias(java.lang.String newVariable)
Makes a backup of the current variable and it replaces it with another one.
|
protected boolean |
overrideLegacyName(java.lang.String newName)
Makes a backup of the current legacy name and temporarily it replaces it with another one.
|
protected rowid |
peerRowid()
Gets
rowid of the peer record. |
protected void |
peerRowid(rowid peer)
Sets the
rowid value of the peer record. |
protected void |
popTempContext()
Pop the current, temporary record context from this buffer.
|
private void |
processChange()
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 |
pruneSessionCache()
Prune the session cache of all records associated with this buffer's backing table.
|
protected void |
pushTempContext()
Push a temporary record context onto the buffer for purposes such as
client-side sorting.
|
protected void |
reclaimKeys(java.util.List<java.lang.Long> 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.
|
void |
recordFlushed()
Notification that the record in this buffer has been flushed.
|
recid |
recordID()
Get the record ID of the current buffer's current record, if any.
|
void |
recordInserted()
Use this method to notify this object that the record it holds was successfully inserted into the
database.
|
static character |
recordNotAvailableCharacter(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static comhandle |
recordNotAvailableComhandle(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static date |
recordNotAvailableDate(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static datetime |
recordNotAvailableDatetime(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static datetimetz |
recordNotAvailableDatetimetz(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static decimal |
recordNotAvailableDecimal(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static handle |
recordNotAvailableHandle(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static int64 |
recordNotAvailableInt64(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static integer |
recordNotAvailableInteger(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static logical |
recordNotAvailableLogical(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static raw |
recordNotAvailableRaw(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static recid |
recordNotAvailableRecid(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
static rowid |
recordNotAvailableRowid(java.lang.String buffer)
Record or throw a "record not available" error condition for
the current DMO type.
|
boolean |
referenceOnly()
Check whether this instance was defined as REFERENCE-ONLY.
|
protected void |
registerRelatedQuery(P2JQuery query)
Register a query that should be closed when the scope of this buffer is closed.
|
protected void |
release(boolean allowWriteTrigger)
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.
|
protected void |
release(boolean undo,
boolean allowWriteTrigger)
Possibly 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.
|
protected void |
release(boolean undo,
boolean allowWriteTrigger,
boolean honorMultipleReferences)
Possibly 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.
|
protected 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(Record dmo,
boolean insert,
boolean delete)
Report any pending changes in the current record's state to the
ChangeBroker for broadcast to interested listeners. |
protected static void |
reportValidationException(ValidationException exc,
RecordBuffer buffer,
boolean fieldUpdate)
Helper method to report and possibly log a validation exception.
|
protected void |
reset()
Release the current record and discard the reference record snapshot.
|
protected void |
resetChangeScope()
Reset to its default state the current high-water mark block depth at which an undoable
change has been made.
|
protected void |
resetSnapshot()
Discard the reference record snapshot.
|
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. |
protected void |
restoreDMOAlias()
Restores the DMO alias by replacing the current variable with the one stored in the backup.
|
protected void |
restoreLegacyName()
Restores the DMO alias by replacing the current variable with the one stored in the backup.
|
void |
retry()
Called by the transaction manager before a block is retried after an
error.
|
void |
rollback(boolean transaction)
Process a rollback event for the current buffer.
|
rowid |
rowID()
Get the row ID of the current buffer's current record, if any.
|
protected integer |
rowState()
Gets the current value of the
ROW-STATE property for this record. |
protected void |
rowState(java.lang.Integer state)
Sets the value of the
ROW-STATUS property for this record. |
protected void |
setAmbiguous(boolean ambiguous)
Set the flag indicating whether the last record retrieval attempt
failed because the query criteria was ambiguous.
|
protected void |
setBulkCopy(boolean bulk)
Set the
bulkCopy flag. |
private void |
setCommitPending(boolean commitPending)
Set the commit pending state.
|
private static BufferCompare.Mode |
setCompareMode(BaseDataType datum,
BufferCompare.Mode mode)
Sets compare mode to data type instance for BUFFER-COPY and BUFFER-COMPARE methods.
|
private void |
setCurrentRecord(Record newCrtRecord,
boolean undo,
boolean newlyCreated,
boolean dirtyCopy,
boolean allowWriteTrigger)
Set the DMO implementation instance which backs this buffer, or release the record currently
stored in the buffer.
|
private void |
setCurrentRecord(Record newCrtRecord,
boolean undo,
boolean newlyCreated,
boolean dirtyCopy,
boolean allowWriteTrigger,
boolean honorMultipleReferences)
Set the DMO implementation instance which backs this buffer, or release the record currently
stored in the buffer.
|
protected void |
setDataModelAst(DataModelAst dataModelAst)
Cache the
dataModelAst. |
protected void |
setDirectField(java.lang.Object value,
int offset)
Direct assignment of a field, accessing the record's datum.
|
private void |
setDMOProxy(BufferReference dmoProxy)
Set the DMO proxy which references this buffer instance.
|
protected void |
setDynamic()
Mark the buffer as dynamic.
|
private void |
setFake(boolean fake)
Set the fake flag associated with this buffer
|
protected void |
setLocked(boolean locked)
Set the flag indicating whether the last record retrieval attempt
failed because another user had the target record locked.
|
protected void |
setOffEnd(OffEnd offEnd)
Set the off-end status for the query most recently involving this buffer.
|
void |
setPinnedLockType(java.lang.Long 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).
|
private void |
setReadOnly(boolean readonly)
Set the read only flag associated with this buffer
|
protected void |
setRecord(Record currentRecord,
LockType lockType,
boolean errorIfNull,
boolean lenientOffEnd,
SortIndex sortIndex,
OffEnd offEnd,
boolean inverseSorting,
boolean dirtyCopy,
boolean allowWriteTrigger)
Set the DMO implementation instance which backs this buffer.
|
protected void |
setSchemaTableAst(ProgressAst schemaTableAst)
Cache the
schemaTableAst. |
protected void |
setTempRecord(Record tempRecord)
Set a temporary record into the buffer for purposes such as client-side
sorting.
|
protected 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. |
(package private) void |
shareDirty(PropertyMeta propMeta)
Share the value to dirty database if needed.
|
static boolean |
silentBatch(java.lang.Runnable code)
Worker method that executes a given block of code in batch assign mode, having the silent
error mode enabled.
|
java.lang.String |
sqlTableContent(int limit)
Obtain a string representation of the table content stored on SQL.
|
protected void |
sqlTableContentJson(java.lang.StringBuilder resultString)
Save the JSON representation of the content of a SQL table into a StringBuilder parameter.
|
static void |
startBatch(BufferManager bufMan,
boolean internal)
Enter batch assign mode in the current context.
|
void |
stateChanged(RecordChangeEvent event)
Respond to a record change event.
|
protected 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.
|
java.lang.String |
tableDefinition()
Constructs and returns a string containing the P4GL schema definition of the table.
|
handle |
tableHandle()
Returns TABLE-HANDLE for the buffer.
|
TempTable |
tableHandleResource()
Get the associated temp-table (for tempporary buffers).
|
protected 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(Record 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).
|
protected 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.
|
protected void |
updateCachedRecords(java.util.function.Consumer<BaseRecord> work)
Apply the given update to all the cached records.
|
protected void |
updateCurrentChanged()
Updates the
recordChanged flag. |
protected void |
updateErrorFlags(int errFlag,
boolean set)
Sets or removes the
errorFlag value this peer record. |
private void |
updateNoUndoState()
Store the undoability of this buffer in the record's state.
|
void |
upgradeLock()
Attempt to upgrade to an exclusive lock on the current record, if we do
not already have one.
|
boolean |
validate(boolean throwValidationException)
Validate the record, if any, currently in the buffer.
|
void |
validate(boolean transaction,
boolean aggressiveFlush)
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(Record dmo)
Perform a full validation (all unique constraints and non-nullable properties) of the given record.
|
private static boolean |
validate(java.util.function.Supplier<logical> valexp,
java.util.function.Supplier<character> valmsg)
Processes validation rules, error checking and any other user-defined constraint processing
that needs to be applied.
|
protected java.lang.Object[] |
validateMaybeFlush(Record dmo,
boolean flush,
boolean explicit)
Creates a new
Validation instance using the passed arguments, and calls
Validation.validateMaybeFlush(). |
protected boolean |
wasAmbiguous()
Indicate whether the last record retrieval attempt failed because the
query criteria was ambiguous.
|
protected boolean |
wasLocked()
Indicate whether the last record retrieval attempt was denied because
the target record was locked.
|
clone, finalize, getClass, notify, notifyAll, wait, wait, waitentry, initFailure, weightprivate static final CentralLogger LOG
private static final java.lang.String LOG_MSG_SIGN_BROKEN
private static final java.lang.String LOG_MSG_SIGN_UNIMPL
private static final java.lang.String LOG_MSG_DB_UNEXP_REF
private static final NanoTimer DEF_BUFFER
private static final java.lang.reflect.Method[] doNotProxy
protected static final java.lang.reflect.Method[] doNotProxyRes
HandleResource.protected final ChangeBroker changeBroker
protected final BufferManager bufferManager
protected final DatabaseTriggerManager dbTrigManager
protected final TransactionManager.TransactionHelper txHelper
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 boolean ignoreBeforeTracking
true this flag makes the change-tracking of this dataset AFTER-BUFFER ignore
changes and skip storing changes to associated BEFORE-BUFFER. This is needed by
REJECT-CHANGES when CHANGE-TRACKING is still on. Although the flag is visible for permanent
tables, it is false for them, and only changed for TemporaryBuffers.protected Persistence.Context persistenceContext
private final int hashCode
private final java.lang.String ldbOrAlias
private final RecordBuffer.Handler handler
private final java.lang.Class<? extends Buffer> dmoBufInterface
dmo-path.Foo_1$Buf or dmo-path.Bar_1_1$Buf for temp-tables.private final java.lang.Class<? extends DataModelObject> dmoInterface
Table metadata annotation.
(Ex: dmo-path.Foo or dmo-path.Bar_1 for temp-tables).private final DmoMeta dmoInfo
private java.util.Map<java.lang.String,RecordBuffer.DatumAccess> setterDatums
RecordBuffer.DatumAccess setter instances, for each property.private java.util.Map<java.lang.String,RecordBuffer.DatumAccess> getterDatums
RecordBuffer.DatumAccess getter instances, for each property.private final java.util.Set<java.lang.reflect.Method> getters
private java.lang.Object[][] unreportedChanges
private TriggerTracker triggerTracker
private final UniqueTracker uniqueTracker
private final UniqueTracker.Context uniqueTrackerCtx
protected final ProcedureManager.ProcedureHelper pm
private boolean worldScope
private java.lang.String overrideLegacyName
private java.lang.String oldVariable
private java.lang.String variable
private RecordLockContext lockContext
private DirtyShareContext dirtyContext
private RecordBuffer creatingBuffer
private java.lang.Object persistentProc
private java.lang.String table
private BufferType bufferType
private final java.lang.Class<? extends Record> dmoClass
private Persistence persistence
private java.lang.String logicalDatabase
private java.util.ArrayList<AssociationSyncher> assocSynchers
private java.util.Set<java.lang.String> legacyForeignKeys
private IndexHelper indexHelper
private java.util.BitSet indexedProperties
private RecordBuffer.PinnedLocks pinnedLocks
private BufferReference dmoProxy
private Record currentRecord
private Record snapshot
private java.util.List<Record> tempRecords
private java.util.List<ForeignNuller> foreignNullers
private int createScope
private boolean newlyCreated
private boolean unknownMode
currentRecord as being set from an OUTER query. In this case, the error 91,
No <buffer> record is available. is NOT emitted when a field is accessed in read-only mode but
the buffer is empty. This is somewhat logical because the buffer is expected not to be loaded with a
record.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 fake
private final boolean vst
private final boolean isTemporary
private boolean isTouched
recordChanged that tracks external changes (from other users), this boolean value tracks
write-touches only from current user.private boolean firingRowUpdate
private boolean dynamic
protected boolean createRowCallback
private final QueryOffEndListener offEndListener
private boolean recordChanged
private Record 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
private RecordMeta metadata
private DataModelAst dataModelAst
private ProgressAst schemaTableAst
private final org.roaringbitmap.RoaringBitmap byLegacyNameScopes
byLegacyName.private final org.roaringbitmap.RoaringBitmap allBufferScopes
allBuffers.private final org.roaringbitmap.RoaringBitmap loadedBuffersScopes
loadedBuffers.private final org.roaringbitmap.RoaringBitmap openBuffersScopes
openBuffers.private LegacyFieldNameMap legacyFieldNameMap
private static int unimplementedFastCopyWarningCounter
private java.util.List<RecordBuffer> recordBuffers
recordBuffers().private final java.lang.Class<?> definingType
private final java.util.Map<java.lang.Object,TriggerTracker> triggerMap
TriggerTracker.protected RecordBuffer()
protected RecordBuffer(java.lang.Class<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable)
define(java.lang.Class<T>, java.lang.String, java.lang.String) factory method.def - The currently executing OE class or external program.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<?> def,
java.lang.Class<T> dmoBufIface,
java.lang.String ldbOrAlias,
java.lang.String variable,
int blockDepth)
define(java.lang.Class<T>, java.lang.String, java.lang.String) factory method.def - The currently executing OE class or external program.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 extends Buffer> T defineReadOnly(java.lang.Class<?> def, java.lang.Class<T> dmoBufIface, java.lang.String database, Record roValue, boolean fake)
T - Record type.def - The currently executing OE class or external program.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.fake - true to mark this buffer as a "fake" buffer.isFake()public static <T extends Buffer> 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 extends Buffer> 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 extends Buffer> T define(java.lang.Class<?> def, java.lang.Class<T> dmoBufIface, java.lang.String database, java.lang.String variable, java.lang.String legacyName)
T - Record type.def - The currently executing OE class or external program.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 extends Buffer> T define(java.lang.Class<?> def, java.lang.Class<T> dmoBufIface, java.lang.String database, java.lang.String variable, java.lang.String legacyName, int blockDepth)
T - Record type.def - The currently executing OE class or external program.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 extends Buffer> T defineAlias(java.lang.Class<T> dmoBufIface, Buffer aliasOf, java.lang.String varName, java.lang.String legacyName)
RecordBuffer; any access to this
buffer should be done using the handler, otherwise inconsistent data will be returned.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 buffer.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 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.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 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.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 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.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 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.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 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.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 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.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 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.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 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 buffer will be created in the specified widget 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 buffer will be created in the specified widget 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 buffer will be created in the specified widget 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 buffer will be created in the specified widget 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 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.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 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.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 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.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 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 character recordNotAvailableCharacter(java.lang.String buffer)
buffer - The legacy buffer name.character type.ErrorConditionException - if silent error mode is suppressed.public static comhandle recordNotAvailableComhandle(java.lang.String buffer)
buffer - The legacy buffer name.comhandle type.ErrorConditionException - if silent error mode is suppressed.public static date recordNotAvailableDate(java.lang.String buffer)
buffer - The legacy buffer name.date type.ErrorConditionException - if silent error mode is suppressed.public static datetime recordNotAvailableDatetime(java.lang.String buffer)
buffer - The legacy buffer name.datetime type.ErrorConditionException - if silent error mode is suppressed.public static datetimetz recordNotAvailableDatetimetz(java.lang.String buffer)
buffer - The legacy buffer name.datetimetz type.ErrorConditionException - if silent error mode is suppressed.public static decimal recordNotAvailableDecimal(java.lang.String buffer)
buffer - The legacy buffer name.decimal type.ErrorConditionException - if silent error mode is suppressed.public static handle recordNotAvailableHandle(java.lang.String buffer)
buffer - The legacy buffer name.handle type.ErrorConditionException - if silent error mode is suppressed.public static integer recordNotAvailableInteger(java.lang.String buffer)
buffer - The legacy buffer name.integer type.ErrorConditionException - if silent error mode is suppressed.public static int64 recordNotAvailableInt64(java.lang.String buffer)
buffer - The legacy buffer name.int64 type.ErrorConditionException - if silent error mode is suppressed.public static logical recordNotAvailableLogical(java.lang.String buffer)
buffer - The legacy buffer name.logical type.ErrorConditionException - if silent error mode is suppressed.public static raw recordNotAvailableRaw(java.lang.String buffer)
buffer - The legacy buffer name.raw type.ErrorConditionException - if silent error mode is suppressed.public static recid recordNotAvailableRecid(java.lang.String buffer)
buffer - The legacy buffer name.recid type.ErrorConditionException - if silent error mode is suppressed.public static rowid recordNotAvailableRowid(java.lang.String buffer)
buffer - The legacy buffer name.rowid type.ErrorConditionException - if silent error mode is suppressed.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 batch(java.lang.Runnable code)
startBatch(com.goldencode.p2j.persist.BufferManager, boolean) and endBatch(com.goldencode.p2j.persist.BufferManager, boolean) calls.code - The block of code to execute in batch assign mode.startBatch(com.goldencode.p2j.persist.BufferManager, boolean),
endBatch(com.goldencode.p2j.persist.BufferManager, boolean)public static boolean silentBatch(java.lang.Runnable code)
code - The block of code to execute in batch assign mode.batch(Runnable),
ErrorManager.silent(Runnable)public static void startBatch(BufferManager bufMan, boolean internal)
bufMan - The BufferManager instance.internal - Use false for a programmer required batch assign mode. These can be started at most one
at each scope depth.true for a FWD internal maintenance batch block when some data must be processed
"in batch". In this case the depth, is not checked. Only one level of this can be added as the
top-level. This mode must be be ended before starting any new batch.java.lang.IllegalStateException - if batch mode already is active in the current block or was started but never
ended in a previous block.endBatch(com.goldencode.p2j.persist.BufferManager, boolean)public static int endBatch(BufferManager bufMan, boolean error)
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.
bufMan - The BufferManager instance.error - false all assignments end without issues. Validate them.
true if some error occurred during the batch. In this case all assignments performed
in the batch block MUST be reverted!
TODO: implement this case!
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(com.goldencode.p2j.persist.BufferManager, boolean)public static character getCodePage(FieldReference field)
field - field reference.public static character getCodePage(BufferField field)
field - field reference.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.public static java.lang.reflect.Method[] getDoNotProxy()
protected static <T> T createProxy(java.lang.Class<?> dmoBufIface,
RecordBuffer buffer,
java.lang.String legacyName)
T - Record type.dmoBufIface - Interface which defines DMO's public API methods.buffer - Record buffer instance associated with the created proxy.legacyName - Legacy name of the buffer.protected static java.util.Set<java.lang.String> getCommonFields(java.util.Set<java.lang.String> set1,
java.util.Set<java.lang.String> set2,
java.lang.String[] fieldList,
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 fieldList is
provided, as follows:
exclusive is true, all elements of fieldList are excluded
from the intersection of set1 and set2.
exclusive is false, only those elements present in set1
and in set2 and in fieldList are included in the final result.
set1 - First set of legacy field names.set2 - Second set of legacy field names.fieldList - An optional array of legacy field names; may be null.exclusive - if true, fieldList is an exclusive list of field names;
if false, propList is an inclusive list. Ignored if fieldList is null.protected static logical copy(DataModelObject srcDMO, DataModelObject dstDMO, java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap, java.util.List<RecordBuffer.DatumAccess> pkProps) 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 bufferpkProps - When not null, a list of destination properties which need to be set to the source
DMO PK.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, RecordBuffer srcBuf, RecordBuffer dstBuf, 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.Integer> srcExtents, java.util.Map<java.lang.String,java.lang.Integer> dstExtents, java.util.Map<java.lang.String,java.lang.String> srcLegacyFieldsMap, java.util.Map<java.lang.String,java.lang.String> dstLegacyFieldsMap, java.util.Map<java.lang.reflect.Method,PropertyMeta> srcProps, java.util.Map<java.lang.reflect.Method,PropertyMeta> dstProps, java.util.Map<java.lang.String,RecordBuffer.DatumAccess> srcDatums, java.util.Map<java.lang.String,RecordBuffer.DatumAccess> dstDatums, boolean noLobs, 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).srcBuf - The source buffer.dstBuf - The destination buffer.srcGetters - Map of source DMO methods.dstSetters - Map of destination DMO methods.srcExtents - Map of source extent properties.dstExtents - Map of destination extent properties.srcLegacyFieldsMap - Map of legacy field names to properties for source buffer.dstLegacyFieldsMap - Map of legacy field names to properties for destination buffer.srcProps - Map of source accessor methods to the property meta.dstProps - Map of destination accessor methods to the property meta.srcDatums - Map of source properties to their RecordBuffer.DatumAccess instance.dstDatums - Map of destination properties to their RecordBuffer.DatumAccess instance.noLobs - If true, exclude any BLOB/CLOB fields from the operation, else include
these fields.operationType - Operation type (COMPARE/COPY).protected static void reportValidationException(ValidationException exc, RecordBuffer buffer, boolean fieldUpdate)
exc - The validation exception.buffer - The affected buffer.fieldUpdate - if true the error message 142 is also displayed.static SchemaDictionary getSchemaDictionary(java.util.List<Buffer> buffers)
buffers - List of buffers referenced in the dynamic expression.static void copy(DataModelObject srcDmo, DataModelObject dstDmo, java.lang.String[] srcFields, boolean exclusive, boolean noLobs, 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).dstDmo - Destination DMO instance returned by a previous call to define(java.lang.Class<T>, java.lang.String, java.lang.String).srcFields - 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.noLobs - If true, exclude any BLOB/CLOB fields from the copy, else include these
fields.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.static logical compare(RecordBuffer srcBuf, RecordBuffer dstBuf, BufferCompare.Mode mode, character except, character pairs, logical noLobs)
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.noLobs - If true, BLOB and CLOB fields are ignored during the comparison. May be
false or null to include such fields.true if all fields values are equal, otherwise false.static <T extends Buffer> 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 void copyCommonFields(Record target, Record source)
target - The target DMO.source - The source DMO.static logical copy(RecordBuffer dstBuf, RecordBuffer srcBuf, character except, character pairs, logical noLobs)
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.noLobs - If true, BLOB and CLOB fields are ignored during the comparison. May be
false or null to include such fields.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 void cleanupBatchMode(java.util.Set<RecordBuffer> bufs)
bufs - The set of buffers altered in the assign block.static boolean areDMOsSame(Record dmo1, Record 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.static java.util.List<java.lang.String> compare(DataModelObject dmo1, DataModelObject dmo2, java.lang.String[] fieldList, boolean noLobs, BufferCompare.Mode mode, boolean exclusive, boolean exhaustive)
If a list of additional legacy field 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).fieldList - Legacy names of those fields to be included or excluded from the comparison,
depending upon exclusive. May be null.noLobs - If true, exclude any BLOB/CLOB fields from the comparison, else include
these fields.mode - Comparison mode. May be null.exclusive - true if fieldList 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.static <T> T makeArgumentBuffer(java.lang.Class<T> dmoBufIface,
Buffer proxy,
java.lang.String varName,
java.lang.String legacyName)
dmoBufIface - The DMO buffer interface.proxy - The buffer proxy.varName - The new DMO alias which should be adopted by the record buffer when referenced
through this argument buffer.legacyName - The name which should be adopted by the buffer impl when referenced through this
argument buffer.private static <T extends Buffer> T defineReadOnlyImpl(java.lang.Class<?> def, java.lang.Class<T> dmoBufIface, java.lang.String database, Record roValue, boolean fake)
T - Record type.def - The currently executing OE class or external program.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.fake - true to mark this buffer as a "fake" buffer.isFake()private static void armWriteTrigger(RecordBuffer rb, boolean useOpenScope)
rb - The buffer to be armed.useOpenScope - If true uses the number of open scopes to set DMO, else uses the
scope depth at which transient record was created.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, java.util.Map<java.lang.reflect.Method,PropertyMeta> dstPropMeta, java.util.Map<java.lang.String,RecordBuffer.DatumAccess> dstDatums, character except, character pairs, logical noLobs, RecordBuffer.OperationType opType, java.util.List<RecordBuffer.DatumAccess> pkDstProps, java.util.List<RecordBuffer.DatumAccess> pkSrcProps)
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.dstPropMeta - Map of destination accessor methods to the property meta.dstDatums - Map of destination properties to their RecordBuffer.DatumAccess instance.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.noLobs - If true, exclude any BLOB/CLOB fields from the operation, else include
these fields.opType - Operation type (COMPARE/COPY).pkDstProps - A list of DatumAccess objects where to copy the source PK (for pairs which are
specified like rowid(tt-src),tt-dst.f-rowid). If null, these
will not be reported back (BUFFER-COMPARE ignores these kind of mappings).pkSrcProps - A list of DatumAccess objects where to copy the destination PK (for pairs which
are specified like rowid(tt-src),tt-dst.f-rowid). If null, these
will not be reported back (BUFFER-COMPARE ignores these kind of mappings).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 java.lang.String formatProperty(java.lang.Object value)
value - BaseDataType or Object property value.private static boolean isAssignableTypes(java.lang.reflect.Method srcMethod,
java.lang.reflect.Method dstMethod,
boolean noLobs,
RecordBuffer.OperationType operationType)
srcMethod - Source method for given operation.dstMethod - Destination method for given operation.noLobs - If true, return false if the source method has a BLOB/CLOB return
type.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 BufferCompare.Mode setCompareMode(BaseDataType datum, BufferCompare.Mode mode)
#2080, note 93: ... when you get the value for a DMO property (via getter.invoke), you get a copy, not the actual reference which is saved at the DMO. Thus, is enough to use setCaseSensitive() for that Text instance, without having to worry to restore the previous state (as we work with a copy which will get discarded once its job is done). About the threading issue: Text.caseSens is a field which is set per each character/longchar var instance. Currently, all communication is done sync (with some few CTRL-C exceptions), so no two threads should be able to change the Text.caseSens field for the same instance.
datum - Data type instance.mode - A buffer compare mode constant.private static java.util.List<java.lang.String> compare(RecordBuffer srcBuf, RecordBuffer dstBuf, java.util.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsMap, BufferCompare.Mode 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, java.util.List<RecordBuffer.DatumAccess> pkDstProps, java.util.List<RecordBuffer.DatumAccess> pkSrcProps, 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.pkDstProps - List of destination table DatumAccess instances where to copy the source PK.pkSrcProps - List of source table DatumAccess instances where to copy the destination PK.true if copy is successful, otherwise false.private static boolean validate(java.util.function.Supplier<logical> valexp, java.util.function.Supplier<character> valmsg)
valexp - The validation expression to evaluate.valmsg - The error message to display when validation fails.true if the validation succeeded and the record can be deleted.ErrorConditionException - if the database trigger or the validation will failprivate static boolean fastCopy(RecordBuffer srcBuf, RecordBuffer dstBuf, boolean forcePair, boolean noLobs, boolean validate, boolean hasBefore)
srcBuf - The source buffer from which the copy is done.dstBuf - The destination buffer to which the copy is done.forcePair - Flag to indicate if an explicit pair of fields should be copied / not copied.noLobs - Flag to indicate if lobs should be omitted from the copy.validate - true to validate the destination buffer after the copy.hasBefore - Flag to indicate if the buffer have before buffer which should be also copied.true if the fast copy is eligible and could be done.
false if the fast copy couldn't be applied for these buffers.public FastFindCache getFastFindCache()
FastFindCache instance for the database associated with this buffer.public LazyUndoable getUndoable()
undoable instance.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 RecordChangeListenerpublic 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 RecordChangeListenerevent - 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 Record 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,
boolean aggressiveFlush)
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 Commitabletransaction - 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.aggressiveFlush - true if transaction manager is in aggressive subtransaction
flush mode, indicating that any transient buffers should be validated and
flushed, regardless of other state.ErrorConditionException - If validation fails.public void commit(boolean transaction)
commit in interface Commitabletransaction - true if this commit represents the master transaction commit;
false if it represents a sub-transaction commit.public void rollback(boolean transaction)
Auto-commit buffers are never rolled back.
rollback in interface Commitabletransaction - true if this commit represents the master transaction rollback;
false if it represents a sub-transaction rollback.public void finished()
finished in interface Finalizablepublic void deleted()
deleted in interface Finalizablepublic final void iterate()
iterate in interface Finalizablepublic final void retry()
retry in interface Finalizablepublic boolean isVst()
true when the record contained is a VST.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 BufferReferencethis).public final RecordBuffer definition()
definition in interface BufferReferencepublic Record getCurrentRecord()
null if the buffer currently is empty.public LockType getPinnedLockType(java.lang.Long id)
id - Record identifier.RecordLockContextpublic void setPinnedLockType(java.lang.Long id,
LockType pinnedLockType)
id - Record identifier.pinnedLockType - New pinned lock type.RecordLockContextpublic 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 java.lang.Long _rowID()
dmo, a null value is returned.public handle tableHandle()
public TempTable tableHandleResource()
null.public java.lang.Class<? extends DataModelObject> getDMOInterface()
public DmoMeta getDmoInfo()
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.private void flush(boolean retryInvalid)
throws ValidationException
retryInvalid - if true, retry the validation and flush even if the record previously was marked as
invalid; if false, abort if the record is already marked as invalid.ValidationException - if validation on the buffer fails.ErrorConditionException - if there is an error accessing the database while persisting the record.public java.lang.String getCodePage(java.lang.String property)
property - DMO property name of the CLOB field.private void checkReadOnlyVstBuffer()
public final int hashCode()
hashCode in class java.lang.Objectpublic final boolean equals(java.lang.Object o)
equals in class java.lang.Objecto - Object to test for equality.true if equivalent, else false.public java.lang.String toString()
toString in class java.lang.Objectpublic java.lang.String tableDefinition()
public BufferReference getDMOProxy()
null only if this object is incompletely constructed.public AbstractTempTable getParentTable()
TempTable object for temporary buffers or null
for permanent buffers.public java.lang.Long getTxNestingId()
public Session getSession()
null if none is active.public Session getSession(boolean create)
create - If true and there is no current database session, create one. Otherwise return the
current session, even if it is null.null.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.java.lang.RuntimeException - if the backing DMO implementation class does not implement a
constructor which accepts a multiplex ID.public java.lang.String getTenantId()
public boolean initialize(boolean fromDefine)
fromDefine - true to acknowledge that this is an early initialization from a define statement
and the scope shouldn't have been opened before-hand.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.public boolean isTransient()
true if record is new, else false.public boolean isAutoCommit()
false for permanent table buffers; subclasses should override for
different behavior.public java.lang.Object getPersistentProc()
public boolean isTemporary()
false.public boolean isMutable()
database scan).
TODO: this only checks whether the backing database is configured as mutable; the current assumption is that all tables in a mutable database are mutable, but in the future, we may need to support mutable databases with a mix of static and dynamic tables.
public boolean referenceOnly()
false all the time.false.public Dialect getDialect()
Dialect in use for this record buffer.public void invalidateFFCache(int index)
index - If not null, it represents the index to be invalidated in ff cache. Otherwise all indices
are invalidated.public void recordFlushed()
public void recordInserted()
DirtyShareContext.earlyInserts.protected java.lang.Class<?> getDefiningType()
definingType.protected void pruneSessionCache()
protected void updateCachedRecords(java.util.function.Consumer<BaseRecord> work)
WARNING: this must be called only for temp-tables, and it must be used with a direct SQL on the same temp-table records, so that the cached and the sql table records have the same state.
work - The code to apply on the cached records.protected integer rowState()
ROW-STATE property for this record. Valid values
are defined as constants in Buffer interface. Additionally, unknown value is
returned if property is not available.unknown value.protected void rowState(java.lang.Integer state)
ROW-STATUS property for this record. Valid values are defined
as constants in Buffer interface. Additionally null value is allowed if
property is not available.state - The new value of the ROW-STATE property for this record as explained above.protected rowid peerRowid()
rowid of the peer record. Exclusively, for a BEFORE-TABLE record this is the
after-rowid and before-rowid for AFTER-TABLE record.unknown value.protected void peerRowid(rowid peer)
rowid value of the peer record. Exclusively, for a BEFORE-TABLE record this
is the after-rowid and before-rowid for AFTER-TABLE record.peer - The new rowid value of the peer record or null.public void originRowid(rowid peer)
origin-rowid for AFTER-TABLE record.peer - The new rowid value of the record or null.public void datasourceRowid(rowid sourceRowid)
datasource-rowid for AFTER-TABLE record.sourceRowid - The new long rowid value of the record or null.protected java.lang.Integer errorFlags()
errorFlag of this record.errorFlag of this record or null if it was not configured. If not null,
the value is a bitwise combination of ERROR and REJECTED attribute. It's up to the called to
extract the bit(s) it needs.unknown
value.protected void updateErrorFlags(int errFlag,
boolean set)
errorFlag value this peer record. The error attribute of the record
is composed of multiple bit flags. This method manages its value based on the parameters it receives.errFlag - The error bit to be set or removed.set - Use true to set the flag and false to remove it.protected character errorString()
error string of this record.unknown value.protected void errorString(Text string)
error string of this record.string - The new error string of this record.protected final void markChangeScope()
protected final void resetChangeScope()
protected final boolean inChangeScope()
true if the current open scope depth is within the scope of any reversible
changes that need to be managed; else false.protected RecordBuffer getDefaultBuffer()
null is returned.protected void closeRelatedQueries()
protected void resourceDeleted()
finishedImpl()), which should
be overridden by a subclass needing to perform some action at this point.protected boolean isTouched()
isTouched flag.protected void setBulkCopy(boolean bulk)
bulkCopy flag.bulk - true if buffer currently the destination of a bulk copy operation.protected boolean isUndoable()
true.true.protected boolean isTableDefinitelyEmpty()
false to indicate it is not definitively known whether the backing table exists or
might have rows.public java.lang.Boolean fastHasRecords()
true if the table surely has records, false if the table surely doesn't have
records, null if this can't be computed wihout actually querying the database.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 onOpenOutermostScope()
public boolean isBufferScopeLeaking()
ConnectionManager.
This should be called only in extra-ordinary execution paths that may involve
native Java integrations outside the persist framework. This should be called in case of
fail-safes to avoid memory leaks.
DON'T use this method for trivial checks on whether the buffer has its scope opened or not.
This should be used only to detect unexpected leaks inside ConnectionManager that can't
be solved by the normal lifecycle of TransactionManager or BufferManager.
For example, invoking generic triggers that do not properly manage the buffer lifecycle may result in memory leaks. Therefore, attempt to detect this case and improve the fault tolerance on persistence layer side.
true if this buffer still resides in ConnectionManager due to a
bad handling of the buffer from native Java integrations like generic triggers.protected void onCloseOutermostScope()
protected Record instantiateDMO() throws java.lang.ReflectiveOperationException
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.java.lang.ReflectiveOperationExceptionprotected 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.public 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.
public boolean maybeFireWriteTrigger()
true if the associated trigger might have been executed.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.ErrorConditionException - if the database trigger or the validation will failprotected boolean delete(java.util.function.Supplier<logical> valexp, java.util.function.Supplier<character> valmsg) throws PersistenceException
null if the deletion is
successful. Reclaim the record's primary key for later re-use.valexp - The validation expression to evaluate.valmsg - The error message to display when validation fails.true if operation is successful and false otherwise.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(DataModelObject[] suppDMOs, java.lang.String where, java.lang.Object... args) throws PersistenceException
This method is invalid in base class so it will always throw an exception. It must be
overwritten by TemporaryBuffer.delete(java.lang.String, java.lang.Object...) with correct logic.
suppDMOs - The DMOs for the external (additional) buffers that are accessed in inner
subselect, or null in case of a simple where predicate.where - An FQL 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 - always.protected void delete(java.lang.String where,
java.lang.Object... args)
throws PersistenceException
This default implementation uses a looping, record-by-record delete, which is substantially slower than an SQL-driven bulk delete. This is necessary for persistent tables which may be accessed concurrently.
where - An FQL 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.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.lang.Long> keys)
keys - A list of primary keys which are available for re-use. Must
not be null.protected DataModelAst getDataModelAst()
dataModelAst tree.protected void setDataModelAst(DataModelAst dataModelAst)
dataModelAst.dataModelAst - The data model AST.protected ProgressAst getSchemaTableAst()
schemaTableAst tree.protected void setSchemaTableAst(ProgressAst schemaTableAst)
schemaTableAst.schemaTableAst - The schema table AST.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 long incrementDMOUseCount(Record dmo, boolean transient_)
decrementDMOUseCount(com.goldencode.p2j.persist.Record, boolean) to
track a DMO's in-use state.
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.transient_ - true if this is a transient reference (usually from a presort query)dmo after incrementing.protected long decrementDMOUseCount(Record dmo, boolean transient_)
incrementDMOUseCount(com.goldencode.p2j.persist.Record, boolean) to
track a DMO's in-use state.
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.transient_ - true if this is a transient reference (usually from a presort query)dmo after decrementing.protected boolean evictDMOIfUnused(Record 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(Record 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 java.lang.String describe()
public void upgradeLock()
throws PersistenceException
PersistenceException - if the current context does not have a share lock (or greater)
on the current record.public void associate(DataModelObject dmo) throws PersistenceException
DataModelObject sent as parameter in this buffer with associate it with the persistence
session of the buffer. It will automatically receive a primary key and all properties will be marked as
'dirty' to allow the object to be saved to database. If there is a record already in the buffer, that
record is validated, its WRITE trigger fired and then flushed to database before setting the new record.dmo - The object to be associated.PersistenceException - if there was an error while retrieving the next primary key.private java.util.BitSet getIndexedProperties(boolean unique)
unique - false to get all indexed properties; true to get only those that participate
in unique indexes.null.protected java.lang.String toString(Record 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.lang.Long nextPrimaryKey()
throws PersistenceException
PersistenceException - if there was an error while retrieving the next primary key.protected void initPinnedLockTypes()
Initialize the set which will hold the primary keys of records affected by a rollback in the current scope.
protected void decrementObjectCountRef(object<?> obj)
This is only active for TEMP-TABLES, for permanent tables this has no effect as they cannot
store object fields.
obj - The object whose reference need to be decremented.protected boolean isGlobal()
false.protected Persistence.Context getPersistenceContext()
null if this buffer has not yet
been initialized.protected void registerRelatedQuery(P2JQuery query)
query - Query to register.protected void unregisterRelatedQuery(P2JQuery query)
query - Query to unregister.protected java.lang.String getLegacyName()
protected 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 - FQL where clause used to filter the records.args - Query substitution arguments.ErrorConditionException - if an error occurs performing the aggregate operation.protected 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 - FQL where clause used to filter the records.args - Optional query substitution arguments.ErrorConditionException - if an error occurs performing the aggregate operation.protected 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 - FQL where clause used to filter the records.args - Query substitution arguments.ErrorConditionException - if an error occurs performing the aggregate operation.protected 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 - FQL where clause used to filter the records.args - Query substitution arguments.ErrorConditionException - if an error occurs performing the aggregate operation.protected 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 - FQL where clause used to filter the records.args - Query substitution arguments.ErrorConditionException - if an error occurs performing the aggregate operation.protected boolean isActive()
true if the buffer has been initialized.protected void errorNotOnFile()
ErrorConditionException - if silent error mode is suppressed.protected int getOpenScopeCount()
protected void release(boolean allowWriteTrigger)
allowWriteTrigger - true to allow a write trigger to be fired on this release. This generally
should be true for non-iterating queries and releases invoked explicitly
by business logic. It should be false for iterating queries. Other implicit
releases depend on the situation.ErrorConditionException - if validation of the current buffer record (if any) fails.protected void release(boolean undo,
boolean allowWriteTrigger)
undo - true if currently processing an undo, else false. The outgoing
record, if any, is not validated and flushed if this parameter is true.allowWriteTrigger - true to allow a write trigger to be fired on this release. This generally
should be true for non-iterating queries and releases invoked explicitly
by business logic. It should be false for iterating queries. Other implicit
releases depend on the situation.ErrorConditionException - if validation of the current buffer record (if any) fails.protected void release(boolean undo,
boolean allowWriteTrigger,
boolean honorMultipleReferences)
undo - true if currently processing an undo, else false. The outgoing
record, if any, is not validated and flushed if this parameter is true.allowWriteTrigger - true to allow a write trigger to be fired on this release. This generally
should be true for non-iterating queries and releases invoked explicitly
by business logic. It should be false for iterating queries. Other implicit
releases depend on the situation.honorMultipleReferences - true if the released record should be flushed only if this buffer was the
only one referencing it. If this is false, even if the release buffer is
loaded in other buffers, it will be flushed.ErrorConditionException - if validation of the current buffer record (if any) fails.protected void reset()
protected void resetSnapshot()
protected 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.protected 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).protected void setRecord(Record currentRecord, LockType lockType, boolean errorIfNull, boolean lenientOffEnd, SortIndex sortIndex, OffEnd offEnd, boolean inverseSorting, boolean dirtyCopy, boolean allowWriteTrigger) throws QueryOffEndException
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.
Note: the access level of this method must be at least protected. Although this is not required
at compile time, some applications may stop with a NullPointerException because the
not be proxied otherwise.
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).lenientOffEnd - 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.allowWriteTrigger - true to allow a WRITE trigger to be fired on this event, else false.QueryOffEndException - if currentRecord is null and errorIfNull is false.getOffEnd(SortIndex,boolean)protected void throwOffEnd()
QueryOffEndException.QueryOffEndException - always.protected 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(com.goldencode.p2j.persist.Record, com.goldencode.p2j.persist.lock.LockType, boolean, boolean, com.goldencode.p2j.persist.SortIndex, com.goldencode.p2j.persist.OffEnd, boolean, boolean, boolean)protected void setOffEnd(OffEnd offEnd)
offEnd - Off-end status.protected QueryOffEndListener getQueryOffEndListener()
QueryOffEndListener instance for this record buffer.QueryOffEndListener instance for this record buffer.protected 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.
protected 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()protected void setTempRecord(Record tempRecord)
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.protected java.lang.Class<? extends Buffer> getDMOBufInterface()
protected java.lang.Class<? extends Record> getDMOImplementationClass()
java.lang.IllegalStateException - if the buffer fails the initialization verification.protected java.lang.String getDMOName()
protected java.lang.String getDMOImplementationName()
public java.lang.String getDMOAlias()
public boolean isUnknownMode()
true if in unknown mode, else false.protected boolean overrideDMOAlias(java.lang.String newVariable)
newVariable - The new DMO alias which should be temporarily used by this RecordBuffer.true if the overriding was successful, false otherwise.protected void restoreDMOAlias()
protected boolean overrideLegacyName(java.lang.String newName)
restoreLegacyName to restore the real name.newName - The new legacy name which should be temporarily used by this RecordBuffer.true if the overriding was successful, false otherwise.protected void restoreLegacyName()
public Persistence getPersistence()
public Database getDatabase()
protected java.lang.String getSchema()
protected java.lang.String getLogicalDatabase()
protected java.lang.String getTable()
protected DirtyShareContext getDirtyContext()
protected RecordLockContext getRecordLockContext()
protected 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.protected boolean create()
true if operation is successful and a fresh new record can be found in the buffer.ErrorConditionException - if there is an error retrieving the next available primary key
from the database or locking the record.public boolean validate(boolean throwValidationException)
throws ValidationException
throwValidationException - What to do in case the validation fails. If true, throw a ValidationException
otherwise return true if validation is successful and false otherwise.true if validation passed OK.ValidationException - if the buffer fails validation.ErrorConditionException - if the buffer fails validation.void validate(Record dmo) throws ValidationException, PersistenceException
dmo - DMO to be validated.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.protected 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.protected 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 otherwiseprotected boolean isReadonly()
DatabaseTriggerManager when processing a WRITE event trigger with OLD buffer. It is also
used as an optimization for tables which contain read-only data.true if the buffer can only contain read-only data.protected boolean isFake()
true if the buffer is a fake buffer, as described above.protected 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.protected void setLocked(boolean locked)
locked - New value of the flag.protected boolean isNewlyCreated()
true if record is newly created, else
false.protected boolean wasAmbiguous()
true if the query was ambiguous;
false if the attempt succeeded, or if no attempt
has yet been made.protected boolean isDynamic()
true if it is a dynamic buffer.protected void setDynamic()
protected void _setDynamic()
protected void setAmbiguous(boolean ambiguous)
ambiguous - New value of the flag.protected void disableReleaseOnIterate()
iterate() method.
This is necessary for the outer buffers in a compound query.protected boolean isDirtyCopy()
true if current record is a dirty copy, else
false.protected void markPersisted()
protected void addLegacyForeignKeys(java.util.Collection<java.lang.String> properties)
properties - A collection of DMO property names.AssociationSyncher,
LocalSyncher,
InverseSyncherprivate java.util.BitSet getDirtyProperties(boolean indexesOnly)
indexesOnly - Filter only dirty properties that are part of index in backing table.null.protected boolean isPropertyIndexed(int propertyIndex)
propertyIndex - Property name.true if property participates in an index, else false.protected BufferType getBufferType()
BufferType key associated with this buffer, or
null if the buffer has not yet been initialized.protected BaseDataType getValue(java.lang.String field)
field - The property name of the field.protected void armCurrentChanged()
recordChanged settings and free of the temporary compare buffer.protected java.lang.Object getDirectField(int offset)
offset - The field offset in the record's datum.protected void setDirectField(java.lang.Object value,
int offset)
value - The field's value. This is not a BDT type, this will be a Java type.offset - The field offset in the record's datum.protected 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 void sqlTableContentJson(java.lang.StringBuilder resultString)
throws PersistenceException,
java.sql.SQLException
resultString - A StringBuilder where the JSON representation of the table will be saved.PersistenceExceptionjava.sql.SQLException - If any issue was encountered. Since this method is supposed to be called only in debug mode,
it's up to programmer to decide what went wrong.protected java.util.Map<java.lang.String,java.lang.String> getBoundPropertyMappings()
null.protected TransactionManager.TransactionHelper getTxHelper()
protected ChangeBroker getChangeBroker()
protected ProcedureManager.ProcedureHelper getProcedureManager()
protected RecordNursery getNursery()
null is returned.public void loadRecord(Record newCrtRecord)
This is a dedicated method accessible only from a very specific places within the persistence package. When the new record is set, the one eventually existing is released.
Note that the triggers are NOT fired when using this method.
newCrtRecord - DMO instance which represents the record currently backing this buffer. If null, the
record (and possibly its corresponding lock) is released.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.setCurrentRecord(Record, boolean, boolean, boolean, boolean)final void addAllBufferScope(int scope)
allBuffers.scope - The scope, as distance from the global scope.final void addByLegacyNameScope(int scope)
byLegacyName.scope - The scope, as distance from the global scope.final void addLoadedBuffersScope(int scope)
loadedBuffers.scope - The scope, as distance from the global scope.final void addOpenBuffersScope(int scope)
openBuffers.scope - The scope, as distance from the global scope.final int[] getAllBuferScopes()
allBufferScopes.final int[] getByLegacyNameScopes()
byLegacyNameScopes.final int[] getLoadedBuffersScope()
loadedBuffersScopes.final int[] getOpenBuffersScope()
openBuffersScopes.protected java.lang.Object[] validateMaybeFlush(Record dmo, boolean flush, boolean explicit) throws PersistenceException, ValidationException
Validation instance using the passed arguments, and calls
Validation.validateMaybeFlush(). Depending on the Validation.wasFlushed()
state, it will report the change so that listeners will be notified.dmo - Record whose data is to be validated and optionally flushed to the database.flush - true to validate and persist DMO's data; false to validate only.explicit - true if this validation was explicitly requested by business logic; false if
it is implicit/organic (e.g., in response to a record being updated).null if there is no current record or if we are in
batch mode.PersistenceException - if there was a database error during validation or data persistence. This
generally will not be recoverable.ValidationException - if there was a validation error. This represents an application level data
validation failure and is recoverable.private RecordMeta getMetadata()
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 FQL 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 - FQL 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.protected void finishedImpl()
protected void cleanup()
finishedImpl()). Its goal is to release any unwanted references thatprivate void processChange()
throws PersistenceException
ReversibleUpdate object and reporting the change to the
ChangeBroker for further distribution to registered listeners.PersistenceException - if a problem occurs reporting the change to registered
listeners.private Record getTempRecord()
setTempRecord(Record)private RecordBuffer.Handler getHandler()
private java.lang.Class<?> getDMOClass()
private void clearUnreportedChanges()
private void addUnreportedChanges(int propIndex,
int extent,
java.lang.Object[] diffs)
unreportedChanges2 structure.propIndex - The index of the property in the Record.data table.extent - If this is an extent, the index of the property. Otherwise 0.diffs - The differences. Contains the values before and after.protected TriggerTracker getTriggerTracker()
private void setReadOnly(boolean readonly)
private void setFake(boolean fake)
private void load(Record target, LockType lockType, boolean undo, boolean allowWriteTrigger)
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 databaseallowWriteTrigger - true to allow a write trigger to be fired on this event, else false.ErrorConditionException - if there is no record loaded into the buffer and the error
manager is not in silent mode.private void setDMOProxy(BufferReference dmoProxy)
dmoProxy - DMO proxy object.private void setCurrentRecord(Record newCrtRecord, boolean undo, boolean newlyCreated, boolean dirtyCopy, boolean allowWriteTrigger)
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, its count usage decremented and, if its use count
reaches zero, the old record is detached from the current Hibernate session.
If not null, the new DMO is registered with the current Hibernate session and its
use 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. The outgoing
record, if any, is not validated and flushed if this parameter is true.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.allowWriteTrigger - true to allow a write trigger to be fired on this event, else false.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.release(boolean)private void setCurrentRecord(Record newCrtRecord, boolean undo, boolean newlyCreated, boolean dirtyCopy, boolean allowWriteTrigger, boolean honorMultipleReferences)
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, its count usage decremented and, if its use count
reaches zero, the old record is detached from the current Hibernate session.
If not null, the new DMO is registered with the current Hibernate session and its
use 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. The outgoing
record, if any, is not validated and flushed if this parameter is true.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.allowWriteTrigger - true to allow a write trigger to be fired on this event, else false.honorMultipleReferences - Honor the flushing suppressing of the existing record if is also loaded in another buffer.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.release(boolean)private void maybeFireRowUpdateEvent()
private void updateNoUndoState()
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 static void errorNotAvailable(java.lang.String buffer)
buffer - The legacy buffer name.ErrorConditionException - if silent error mode is suppressed.private void errorNotAvailable()
ErrorConditionException - if silent error mode is suppressed.java.util.List<java.lang.String> listDirtyIndexes(boolean unique,
boolean fullMatch,
boolean cumulative)
unique - If true, only unique indexes are checked. If false, only non-unique indexes are
checked.fullMatch - If true every property in an index must be dirty for that index to be considered dirty.
If false, any dirty property in an index is enough to consider that index dirty.cumulative - Only in the case of non-unique indexes. If true, collect all indexes that were marked
dirty since the record was loaded. If false, only indexes marked dirty since the last
validation/share.void shareDirty(PropertyMeta propMeta) throws PersistenceException
Dirty database insertion is managed by the RecordNursery.
propMeta - Metadata for the property that triggered the event.PersistenceException - When something went wrong accessing the dirty database.protected java.util.Map<java.lang.String,RecordBuffer.DatumAccess> getSetterDatums()
setterDatums map.protected java.util.Map<java.lang.String,RecordBuffer.DatumAccess> getGetterDatums()
getterDatums map.public java.lang.String sqlTableContent(int limit)
throws PersistenceException,
java.sql.SQLException
limit - The maximum number of rows to be retrieved. Use 0 or negative to get them all.PersistenceExceptionjava.sql.SQLException - If any issue was encountered. Since this method is supposed to be called only in debug mode,
it's up to programmer to decide what went wrong.private void fit(java.lang.StringBuilder sb,
java.lang.String text,
int size,
int type)
sqlTableContent(int). Used for generating the tabular pretty format.sb - StringBuilder to put the result into.
Thetext - The value to be formatted.size - The available space.type - The column type. Used for alignment.