public class Validation extends java.lang.Object implements DmoState
Validation consists of an optional (configurable) maximum index size check, a non-null field check, and a unique constraint violation check.
Instances of this class are meant for a single use.
Modifier and Type | Field and Description |
---|---|
private RecordBuffer |
buffer
Record buffer requesting validation
|
private java.lang.String |
bufferName
The name of the buffer.
|
private BaseRecord |
dmo
Record whose data is to be validated and optionally flushed to the database
|
private boolean |
flush
Whether to flush the record;
false to validate only |
private boolean |
flushed
Flag indicating the record was flushed to the database (either newly inserted or updated)
|
private java.lang.Integer |
multiplex
The optional multiplex value, in case of validation of temp-table, otherwise ignored.
|
private RecordNursery |
nursery
Incubator for newly created records, until they are first flushed to the database
|
private static int |
P4GL_MAX_INDEX_SIZE
The maximum permitted size for all combined fields of an index.
|
private boolean |
singleProp
Whether we are validating the most recently updated DMO property only, or the entire DMO
|
private UniqueTracker |
uniqueTracker
Tracks unique constraints in uncommitted transactions
|
private UniqueTracker.Context |
uniqueTrackerCtx
Context-local API helper for unique constraint tracking
|
private boolean |
updateState
Whether to update the DMO state as a side effect of validation
|
Constructor and Description |
---|
Validation(RecordBuffer buffer,
BaseRecord dmo,
java.lang.Integer multiplex,
java.lang.String bufferName,
RecordNursery nursery,
UniqueTracker uniqueTracker,
UniqueTracker.Context uniqueTrackerCtx,
boolean flush,
boolean updateState)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
private void |
checkIndexSize(int p4glSize,
int sqlSize,
int dialectMaxSize,
int indexPos,
boolean unique)
Validates an intermediary index size against the maximum P4GL and dialect specific
constraints.
|
private void |
checkMaxIndexSize()
This method checks whether the record fits the maximum allowable index size for 4GL and the
current configured dialect.
|
private int |
checkNotNull(boolean onlyCheckDirty)
Check whether any property is both mandatory and is currently
null . |
private void |
checkNotNull(int offset)
Check whether a single property is both mandatory and is currently
null . |
private boolean |
confirmUniqueConstraintViolation(Session session,
int pos,
java.util.BitSet index,
java.lang.String sql,
RecordMeta recordMeta,
PropertyMeta[] props)
Verify a unique constraint violation detected by querying the database, by confirming that the record
found to be causing the constraint violation does not have unflushed changes associated with it in
memory, awaiting its own validation and flush operation.
|
private void |
failNotNull(int offset)
The property at the given offset is mandatory but is currently
null . |
private void |
flush()
Flush the record being validated to the database.
|
static java.lang.String |
getFailUniqueIndexMessage(java.util.BitSet uIndex,
java.lang.String bufferName,
BaseRecord dmo)
Constructs and returns the message that is printed with error 132 when the attempt to save (update or
insert) a record will lead to a collision in a unique index.
|
private void |
indexUpdated(java.util.BitSet indices,
boolean unique)
One or more indices were updated as the result of the record's properties being touched.
|
private int |
setUniqueQueryParameters(java.sql.PreparedStatement ps,
java.util.BitSet uIndex,
RecordMeta recordMeta,
PropertyMeta[] props,
int psOffset)
Set the substitution parameters for a prepared statement used to check uniqueness against the records
in a database.
|
java.lang.Object[] |
validateMaybeFlush()
This method will check whether the record is in a state which requires validation and
flushing, and will perform both if it is.
|
private void |
validateUniqueByQuery(java.util.BitSet check)
Iterate the specified unique indices and decide whether a record already exists with the unique
combination of index components in the DMO being validated.
|
private void |
validateUniqueIndices(java.util.BitSet check)
Validate the unique indices represented by the given index bit set.
|
boolean |
wasFlushed()
Get the state of the
flushed flag. |
private final RecordBuffer buffer
private final BaseRecord dmo
private final RecordNursery nursery
private final java.lang.String bufferName
private final UniqueTracker uniqueTracker
private final UniqueTracker.Context uniqueTrackerCtx
private final boolean flush
false
to validate onlyprivate final boolean updateState
private final boolean singleProp
private final java.lang.Integer multiplex
private boolean flushed
private static final int P4GL_MAX_INDEX_SIZE
Set it to 0 to disable P4GL index-key limit check. The dialect specific limit is still enforced by each dialect because otherwise irrecoverable errors may occur when persisting records with wider key length.
public Validation(RecordBuffer buffer, BaseRecord dmo, java.lang.Integer multiplex, java.lang.String bufferName, RecordNursery nursery, UniqueTracker uniqueTracker, UniqueTracker.Context uniqueTrackerCtx, boolean flush, boolean updateState)
buffer
- Record buffer which requested validation be performed.dmo
- Record whose data is to be validated and optionally flushed to the database.multiplex
- The optional multiplex value, in case of validation of temp-table, otherwise ignored. It is
used only when invalidating the FastFind cache for the current table. Must be null
for
permanent tables. Must be positive for temp-tables.bufferName
- The name of the buffer. It is used when printing the error message, if any.nursery
- Incubator for newly created records, until they are first flushed to the database.uniqueTracker
- Tracks unique constraints in uncommitted transactions.uniqueTrackerCtx
- Context-local API helper for unique constraint tracking.flush
- true
to validate and persist DMO's data; false
to validate only.updateState
- Update the DMO's index and validation state as a side effect of validation. This should be set
to true
for implicit/organic validation; false
for explicit validation.public static java.lang.String getFailUniqueIndexMessage(java.util.BitSet uIndex, java.lang.String bufferName, BaseRecord dmo)
uIndex
- The index that failed validation, as a BitSet
of its components.bufferName
- The legacy buffer name that failed the validation.dmo
- The record currently stored in buffer that caused the validation failure.public java.lang.Object[] validateMaybeFlush() throws PersistenceException, ValidationException, StaleRecordException
persist
option set to true
.
The successful completion of this method indicates that either validation and flushing were determined to not yet be appropriate, or that they were, and the operation(s) completed successfully. Callers should check the state of the record after this method returns to determine which case it was.
If validation is determined to be appropriate, but it fails, an exception is thrown.
null
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.StaleRecordException
- if the record being validated/flushed is stale. A stale record should not get this
far under normal circumstances.private void validateUniqueIndices(java.util.BitSet check) throws PersistenceException, ValidationException, StaleRecordException
check
- A bit set whose set bits represent the 0-based positions of the unique indices to be
validated in the target record's unique index array, as stored in the DMO's RecordMeta
structure.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.StaleRecordException
- if the record being validated/flushed is stale. A stale record should not get this
far under normal circumstances.private void indexUpdated(java.util.BitSet indices, boolean unique)
indices
- Bit set representing those indices that were updated.unique
- true
if indices
refers to unique indices; else false
.private void flush() throws PersistenceException, ValidationException, StaleRecordException
PersistenceException
- if there is any non-validation database error.ValidationException
- if there is an error validating a unique or not-null constraint.StaleRecordException
- if the record being flushed is stale. A stale record should not get this far under normal
circumstances.public boolean wasFlushed()
flushed
flag.private void checkMaxIndexSize() throws ValidationException
ValidationException
is thrown. Otherwise the method returns
peacefully.ValidationException
private void checkIndexSize(int p4glSize, int sqlSize, int dialectMaxSize, int indexPos, boolean unique) throws ValidationException
p4glSize
- The current calculated size of the space occupied by dmo
in P4GL. May be
incomplete.sqlSize
- The current calculated size of the space occupied by dmo
in SQL. May be
incomplete.dialectMaxSize
- The maximum supported index size by the dialect used in FWD.indexPos
- The position of the index.unique
- true
only if the current index is unique.ValidationException
- When the p4glSize
already overflows the index size constraint.private void checkNotNull(int offset) throws ValidationException
null
. If so,
throw an exception.offset
- Offset of the property to be checked in the DMO.ValidationException
- if the property is mandatory and is currently null
.private int checkNotNull(boolean onlyCheckDirty) throws ValidationException
null
. If so, throw an exception.
This method should be invoked only for transient records which have the initial/default value set to
unknown (?). Normally the field assignment is tested for null/unknown values at the assign moment.ValidationException
private void failNotNull(int offset) throws ValidationException
null
. Throw an
exception to signal the error.offset
- Offset of the property in the DMO.ValidationException
- always, to indicate the mandatory property error.private void validateUniqueByQuery(java.util.BitSet check) throws PersistenceException, ValidationException
check
- A bit set whose set bits represent the positions of the unique indices in the DMO's array
of unique indices to be checked. If null
, check all the unique indices.ValidationException
- when the method detects a collision of current DMO with another record stored in the database.PersistenceException
- if an error occurred while accessing the database.private int setUniqueQueryParameters(java.sql.PreparedStatement ps, java.util.BitSet uIndex, RecordMeta recordMeta, PropertyMeta[] props, int psOffset) throws java.sql.SQLException
ps
- Prepared statement.uIndex
- A bit set describing which data elements participate in the unique index being checked by the
query.recordMeta
- Metadata for the DMOs associated with the table being queried.props
- Array of DMO metadata objects, each describing a property of the DMO interface associated with
the table being queried.psOffset
- Zero-based offset of the first parameter to be substituted in the prepared statement by this
method (this method can be called multiple times for the same prepared statement, if multiple
individual statements are UNION'd together for a unique constraint check).java.sql.SQLException
- if there is a SQL error substituting parameters.private boolean confirmUniqueConstraintViolation(Session session, int pos, java.util.BitSet index, java.lang.String sql, RecordMeta recordMeta, PropertyMeta[] props) throws PersistenceException, java.sql.SQLException
session
- Current database session.pos
- The position of the unique index being tested in the array of the target DMO's unique indices.index
- A bit set describing which data elements participate in the unique index being tested.sql
- The original SQL statement associated with the unique constraint check for the unique index
being tested. It is modified to return the primary key of the violating record.recordMeta
- Metadata for the DMOs associated with the table being queried.props
- Array of DMO metadata objects, each describing a property of the DMO interface associated with
the table being queried.true
if the unique constraint violation was confirmed; false
if it was
rejected based on unflushed, in-memory changes.PersistenceException
- if there is an error getting a JDBC connection or accessing the session cache.java.sql.SQLException
- if there is an error preparing or executing the query.