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.
|
private static class |
RecordBuffer.ScopeBufferName
Container immutable class that holds temporarily data needed for restoring a buffer's name
configuration.
|
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 than this one
|
private java.util.BitSet |
cumulativeDirtyProps
Properties made dirty since current record was loaded.
|
private Record |
currentRecord
DMO data record which currently backs this buffer
|
private DataModelAst |
dataModelAst
The data model AST for this buffer.
|
protected boolean |
delayed
Flag indicating the finalizable processing for this buffer will be delayed for when the
external procedure gets deleted
|
private DirtyShareContext |
dirtyContext
Object which manages dirty read sharing across sessions
|
private boolean |
dirtyCopy
Is current record actually a dirty copy from the dirty database?
|
private java.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
|
private boolean |
dynamic
Determines if this buffer is dynamic.
|
private java.util.Map<java.lang.String,java.lang.Integer> |
extentMap
Map of property names to extents for DMO array properties
|
private boolean |
fake
Flags this record buffer as a "fake" buffer (e.g., the old buffer in a write trigger)
|
protected FastFindCache |
ffCache
Cache for FIND results
|
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 |
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 java.util.Map<java.lang.String,java.lang.reflect.Method> |
legacyGetterMap
Map of property names to getter methods for legacy fields only
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
legacySetterMap
Map of property names to setter methods for legacy fields only
|
private 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 java.util.logging.Logger |
LOG
Logger
|
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.
|
protected java.util.Set<java.lang.String> |
ooFields
Collects all
Progress.Lang.Object fields of the record. |
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 boolean |
pendingRollbackProcessed
Track whether a rollback action is pending
|
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
|
private ProcedureManager.ProcedureHelper |
pm
Helper to use the ProcedureManager without any context local lookups.
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
pojoGetterMap
Map of property names to getter methods for simple POJO fields only
|
private java.util.Map<java.lang.String,java.lang.reflect.Method> |
pojoSetterMap
Map of property names to setter methods for simple POJO fields only
|
private java.util.Map<java.lang.reflect.Method,PropertyMeta> |
propsByGetter
Map of getter methods of the current DMO interface to property's meta data
|
private java.util.Map<java.lang.reflect.Method,PropertyMeta> |
propsBySetter
Map of setter methods of the current DMO interface to property's meta data
|
private boolean |
readonly
Flags this record buffer as readonly.
|
private boolean |
recordChanged
Flag to mark this buffer as changed by another user on a multi-user
environment.
|
protected int |
registeredWithGlobalScope
If this buffer was ever registered with a persistent procedure, remember the scope it was
open at (-1 in fact because the assignment is performed (and later compared) before
incrementing the
openScopeCount ). |
protected java.util.Set<P2JQuery> |
relatedQueries
List of queries which should be closed when the scope of this buffer is closing
|
private boolean |
retrying
Flag indicating that the block to which the buffer is scoped is retrying
|
private ProgressAst |
schemaTableAst
The table schema AST for this buffer.
|
private java.util.Map<java.lang.Integer,RecordBuffer.ScopeBufferName> |
scopeNameStack
The old/overrided names of the buffer from calling procedures.
|
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 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 java.util.BitSet |
uniqueProperties
Properties which participate in unique indexes of the backing table
|
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 |
---|---|
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().
|
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(boolean) and endBatch(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.
|
(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.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsB4Map,
java.util.List<RecordBuffer.DatumAccess> pkDstProps,
java.util.List<RecordBuffer.DatumAccess> pkDstB4Props,
java.util.List<RecordBuffer.DatumAccess> pkSrcProps,
java.util.List<RecordBuffer.DatumAccess> pkSrcB4Props,
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 int |
decrementDMOUseCount(Record dmo)
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.
|
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(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.
|
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.
|
protected 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).
|
Dialect |
getDialect()
Convenience method to get the
Dialect in use for this record buffer. |
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.
|
protected java.lang.String |
getDynamicName()
Gets the legacy name assigned to a dynamically prepared temp-table.
|
java.lang.String |
getEntityName()
Get the entity name associated with this buffer, which is the fully
qualified name of the DMO implementation class.
|
protected java.util.Map<java.lang.String,java.lang.Integer> |
getExtentMap()
Get the map of DMO property names to extents for the DMO type associated with this buffer,
initializing it first if necessary.
|
protected java.util.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.util.Map<java.lang.String,java.lang.reflect.Method> |
getLegacyGetterMap()
Get a map of converted DMO property names to corresponding, legacy, getter methods.
|
protected java.lang.String |
getLegacyName()
Get the table/buffer legacy name.
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getLegacySetterMap()
Get a map of converted DMO property names to corresponding, legacy, setter methods.
|
(package private) 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.
|
TempTable |
getParentTable()
Get parent table.
|
protected Database |
getPDB(java.lang.String ldbName)
Get the database information object associated with the given logical database name.
|
protected java.lang.String |
getPDBName(java.lang.String ldbName)
Get the physical database name associated with the given logical name.
|
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 java.util.Map<java.lang.String,java.lang.reflect.Method> |
getPojoGetterMap()
Get a map of converted DMO property names corresponding to simple, bean getter methods.
|
protected java.util.Map<java.lang.String,java.lang.reflect.Method> |
getPojoSetterMap()
Get a map of converted DMO property names corresponding to simple, bean setter methods.
|
protected ProcedureManager.ProcedureHelper |
getProcedureManager()
Return the procedure manager associated with this buffer
|
protected java.util.Map<java.lang.reflect.Method,PropertyMeta> |
getPropsByGetter()
Getter for the
propsByGetter map. |
protected java.util.Map<java.lang.reflect.Method,PropertyMeta> |
getPropsBySetter()
Getter for the
propsBySetter map. |
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.
|
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 int |
incrementDMOUseCount(Record dmo)
Increment the context local use count for the specific instance of the
given record.
|
boolean |
initialize()
Initialize the core data on which this buffer relies.
|
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.
|
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.
|
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 |
isPendingRollbackProcessed()
Get current state of 'pending rollback processed' flag.
|
(package private) 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.
|
(package private) 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.
|
protected 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 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.
|
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.
|
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 |
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 |
resetPendingRollbackProcessed()
Reset 'pending rollback processed' flag.
|
protected void |
resourceDeleted()
A no-op implementation called during scope cleanup (
finishedImpl() ), which should
be overridden by a subclass needing to perform some action at this point. |
protected void |
restoreDMOAlias()
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.
|
protected void |
setDataModelAst(DataModelAst dataModelAst)
Cache the
dataModelAst . |
protected void |
setDMOAlias(java.lang.String var)
Set the DMO variable name associated with this buffer instance.
|
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,
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.
|
static void |
startBatch(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.
|
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 |
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.
|
private 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, wait
entry, initFailure, weight
private static final java.util.logging.Logger LOG
private static final java.lang.reflect.Method[] doNotProxy
protected final ChangeBroker changeBroker
protected final BufferManager bufferManager
protected final TransactionManager.TransactionHelper txHelper
protected FastFindCache ffCache
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 TemporaryBuffer
s.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 final java.util.Map<java.lang.reflect.Method,PropertyMeta> propsBySetter
private final java.util.Map<java.lang.reflect.Method,PropertyMeta> propsByGetter
private final java.util.Map<java.lang.String,RecordBuffer.DatumAccess> setterDatums
RecordBuffer.DatumAccess
setter instances, for each property.private final 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 final TriggerTracker triggerTracker
private final UniqueTracker uniqueTracker
private final UniqueTracker.Context uniqueTrackerCtx
private final ProcedureManager.ProcedureHelper pm
private boolean worldScope
private java.lang.String oldVariable
private java.lang.String variable
private final java.util.Map<java.lang.Integer,RecordBuffer.ScopeBufferName> scopeNameStack
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 final java.util.BitSet indexedProperties
private final java.util.BitSet uniqueProperties
private RecordBuffer.PinnedLocks pinnedLocks
private BufferReference dmoProxy
private java.util.Map<java.lang.String,java.lang.reflect.Method> legacyGetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> legacySetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> pojoGetterMap
private java.util.Map<java.lang.String,java.lang.reflect.Method> pojoSetterMap
private java.util.Map<java.lang.String,java.lang.Integer> extentMap
private LegacyFieldNameMap legacyFieldNameMap
private 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 boolean isTouched
recordChanged
that tracks external changes (from other users), this boolean value tracks
write-touches only from current user.private boolean firingRowUpdate
protected final java.util.Set<java.lang.String> ooFields
Progress.Lang.Object
fields of the record. Only makes sense for temp
tables. When empty, the OO support (ref-counting) is disabled.private boolean dynamic
protected boolean createRowCallback
private final QueryOffEndListener offEndListener
private boolean pendingRollbackProcessed
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 final java.util.BitSet cumulativeDirtyProps
private RecordMeta metadata
private DataModelAst dataModelAst
private ProgressAst schemaTableAst
private org.roaringbitmap.RoaringBitmap byLegacyNameScopes
byLegacyName
.private org.roaringbitmap.RoaringBitmap allBufferScopes
allBuffers
.private org.roaringbitmap.RoaringBitmap loadedBuffersScopes
loadedBuffers
.private org.roaringbitmap.RoaringBitmap openBuffersScopes
openBuffers
.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 new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, character table, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widgwet pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, character table, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses the table-name.
The new new buffer will be created in the specified widget pool.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer. null
if it is not explicitly specified.widgetPool
- The name of the widget pool that contains the dynamic buffer. null
if
the unnamed pool must be used.public static void create(handle h, java.lang.String table, java.lang.String bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, java.lang.String table, character bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, character table, java.lang.String bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, character table, character bufName)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, java.lang.String table)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.public static void create(handle h, character table)
CREATE-BUFFER
statement that uses the table-name.h
- The handle to which the created buffer is assigned to.table
- The name of the table to create the buffer for.public static void create(handle h, Temporary tt)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.public static void create(handle h, Temporary tt, java.lang.String bufName)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, Temporary tt, character bufName)
CREATE-BUFFER
statement that uses
a temporary table reference.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, Temporary tt, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, Temporary tt, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses
a temporary table reference. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.tt
- The temporary table to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.public static void create(handle h, handle hsrc, java.lang.String bufName)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, handle hsrc, character bufName)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.public static void create(handle h, handle hsrc, java.lang.String bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, java.lang.String bufName, character widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, character bufName, java.lang.String widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widgwet pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static void create(handle h, handle hsrc, character bufName, character widgetPool)
CREATE-BUFFER
statement that uses a another
buffer already assigned to a handle. The new new buffer will be created in the specified
widget pool.h
- The handle to which the created buffer is assigned to.hsrc
- The handle to table or other table buffer to create the buffer for.bufName
- The name for the buffer or null
if it is not explicitly specified.widgetPool
- The name of the widget pool that contains the dynamic buffer.public static 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(boolean)
and endBatch(boolean)
calls.code
- The block of code to execute in batch assign mode.startBatch(boolean)
,
endBatch(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(boolean internal)
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(boolean)
public static int endBatch(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.
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(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.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 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.Map<RecordBuffer.DatumAccess,RecordBuffer.DatumAccess> propsB4Map, java.util.List<RecordBuffer.DatumAccess> pkDstProps, java.util.List<RecordBuffer.DatumAccess> pkDstB4Props, java.util.List<RecordBuffer.DatumAccess> pkSrcProps, java.util.List<RecordBuffer.DatumAccess> pkSrcB4Props, boolean validate)
srcBuf
- Source record buffer.dstBuf
- Destination record buffer.propsMap
- Map of properties in source record buffer to properties in destination record bufferpropsB4Map
- Map of properties in source record before-buffer to properties in destination record
before-buffer.validate
- true
to validate the destination buffer after the copy.pkDstProps
- List of destination table DatumAccess
instances where to copy the source PK.pkDstB4Props
- List of destination before-table DatumAccess
instances where to copy the source PK.pkSrcProps
- List of source table DatumAccess
instances where to copy the destination PK.pkSrcB4Props
- List of source before-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 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 RecordChangeListener
public void stateChanged(RecordChangeEvent event) throws PersistenceException
If the event indicates a record delete operation, we check if the deleted record is the same as our current record. If so, we clear it from the buffer, since that record should no longer be available in any buffer, once it has been deleted.
In the special case where a different, local buffer created the record we have loaded, and the record is not yet flushed, we will be notified of the flush event here. Stop tracking the creating buffer.
stateChanged
in interface RecordChangeListener
event
- Event which describes the DMO state change.PersistenceException
- not thrown; required by the interface.public java.lang.String getEntityName()
public IndexHelper getIndexHelper()
IndexHelper
instance used by this buffer.IndexHelper
instance.public 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 Commitable
transaction
- true
if this is a full transaction and false
if this is
only a sub-transaction (a nested scope with transaction support). This method will
only be invoked outside a transaction for no-undo temp-table buffers.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 Commitable
transaction
- 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 Commitable
transaction
- true
if this commit represents the master transaction rollback;
false
if it represents a sub-transaction rollback.public void finished()
finished
in interface Finalizable
public void deleted()
deleted
in interface Finalizable
public final void iterate()
iterate
in interface Finalizable
public final void retry()
retry
in interface Finalizable
public 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 BufferReference
this
).public final RecordBuffer definition()
definition
in interface BufferReference
public Record getCurrentRecord()
null
if the buffer currently is empty.public LockType getPinnedLockType(java.lang.Long id)
id
- Record identifier.RecordLockContext
public void setPinnedLockType(java.lang.Long id, LockType pinnedLockType)
id
- Record identifier.pinnedLockType
- New pinned lock type.RecordLockContext
public boolean isWorldScope()
worldScope
flag.public int getScopeOpenDepth()
public recid recordID()
This method will return a 32-bit recid which represents the internal row ID of the given record. If the actual row ID (which is implemented as a wider integer) cannot fit due to overflow, an error condition will be raised.
dmo
, a recid
initialized as unknown value is returned.ErrorConditionException
- if the actual record ID is too wide to fit within a 32-bit
integer.public rowid rowID()
dmo
, a
rowid
initialized as unknown value is returned.public handle tableHandle()
public java.lang.Class<? 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.Object
public final boolean equals(java.lang.Object o)
equals
in class java.lang.Object
o
- Object to test for equality.true
if equivalent, else false
.public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.String tableDefinition()
public BufferReference getDMOProxy()
null
only if this object is incompletely constructed.public TempTable 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; 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 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 recordInserted()
DirtyShareContext.earlyInserts
.protected void pruneSessionCache()
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.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()
protected void onCloseOutermostScope()
protected Record instantiateDMO() throws java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException
java.lang.InstantiationException
- if the class cannot be instantiated.java.lang.IllegalAccessException
- if the DMO class' target constructor cannot be accessed.java.lang.reflect.InvocationTargetException
- if the underlying constructor throws an exception.protected void openScope()
BufferManager
is tracking this buffer for block scope entries
and exits within transactions, such that this buffer can be registered
with the TransactionManager
for commit/rollback
notifications. The buffer is also registered for finish processing so
that the appropriate record and lock transition processing can occur
when the buffer scope closes.protected void openScopeAt(int blockDepth)
BufferManager
is tracking this buffer for block scope entries and exits
within transactions, such that this buffer can be registered with the
TransactionManager
for commit/rollback notifications. The buffer is also
registered for finish processing so that the appropriate record and lock transition
processing can occur when the buffer scope closes.blockDepth
- Zero-based depth of the block (starting from the outermost scope) at which the buffer
scope is opened.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.
protected 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 HQL where clause snippet which defines the restriction criteria to apply to the
delete. All references to properties in a DMO must be unqualified.args
- Query substitution parameters required by the where clause.PersistenceException
- 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 HQL where clause snippet which defines the restriction
criteria to apply to the delete. All references to properties
in a DMO must be unqualified.args
- Query substitution parameters required by the where clause.PersistenceException
- if an error occurs performing the bulk delete operation.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 java.util.Map<java.lang.String,java.lang.reflect.Method> getLegacyGetterMap()
int
parameter as the subscript value for extent fields. Even if an
extent field has been denormalized, the latter is provided for backward compatibility, as
some runtime code may not have been converted to use the denormalized methods directly.protected java.util.Map<java.lang.String,java.lang.reflect.Method> getLegacySetterMap()
int
parameter as the subscript value for extent fields. Even if an
extent field has been denormalized, the latter is provided for backward compatibility, as
some runtime code may not have been converted to use the denormalized methods directly.protected java.util.Map<java.lang.String,java.lang.reflect.Method> getPojoGetterMap()
protected java.util.Map<java.lang.String,java.lang.reflect.Method> getPojoSetterMap()
protected java.util.Map<java.lang.String,java.lang.Integer> getExtentMap()
protected 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 int incrementDMOUseCount(Record dmo)
decrementDMOUseCount(com.goldencode.p2j.persist.Record)
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.dmo
after incrementing.protected int decrementDMOUseCount(Record dmo)
incrementDMOUseCount(com.goldencode.p2j.persist.Record)
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.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.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
- HQL 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
- HQL 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
- HQL 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
- HQL 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
- HQL 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 reset()
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, SortIndex sortIndex, OffEnd offEnd, boolean inverseSorting, boolean dirtyCopy, boolean allowWriteTrigger)
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).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(Record,
LockType,
boolean,
SortIndex,
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 void setDMOAlias(java.lang.String var)
var
- The variable name.public Persistence getPersistence()
protected 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
,
InverseSyncher
private java.util.BitSet getDirtyProperties(boolean indexesOnly)
indexesOnly
- Filter only dirty properties that are part of index in backing table.null
.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 boolean isPendingRollbackProcessed()
true
if pending rollback was processed.protected void resetPendingRollbackProcessed()
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 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 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.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
.private 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 HQL aggregate function (e.g., "count").column
- An expression indicating the name of the column to aggregate. May be the wildcard
character ("*") for COUNT.num
- Variable into which to store the aggregate result.where
- HQL where clause used to filter the records.args
- Query substitution arguments.ErrorConditionException
- if an error occurs performing the aggregate operation.private void checkActive()
java.lang.IllegalStateException
- if the buffer has not been initialized.protected void finishedImpl()
private 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 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.reflect.Method,PropertyMeta> getPropsBySetter()
propsBySetter
map.protected java.util.Map<java.lang.reflect.Method,PropertyMeta> getPropsByGetter()
propsByGetter
map.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.PersistenceException
java.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.