Class Transaction
- Direct Known Subclasses:
DetachedTransaction
Database
transaction.
Note: this is the lower level, core API for Permazen
. In most cases this API
will only be used indirectly through the higher level Permazen
, PermazenTransaction
,
and PermazenObject
APIs.
Methods in this class can be divided into the following categories:
Transaction Meta-Data
getDatabase()
- Get the associatedDatabase
getKVTransaction()
- Get the underlying key/value store transaction.getSchema()
- Get theSchema
that will be used by this transactiongetUserObject()
- Get user object associated with this instancesetUserObject()
- Set user object associated with this instance
Transaction Lifecycle
commit()
- Commit transactionrollback()
- Roll back transactionisOpen()
- Test whether transaction is still opensetTimeout()
- Set transaction timeoutsetReadOnly()
- Set transaction to read-onlysetRollbackOnly()
- Set transaction for rollack onlyaddCallback()
- Register aTransaction.Callback
on transaction completioncreateDetachedTransaction()
- Create a empty, in-memory transactioncreateSnapshotTransaction()
- Create an in-memory transaction pre-populated with a snapshot of this transactionisDetached()
- Determine whether this transaction is a detached transaction
Schema Management
getObjType()
- Get an object's database object typemigrateSchema()
- Migrate an object's schema to match this transaction's schemaaddSchemaChangeListener()
- Receive notifications about object schema migrationsremoveSchemaChangeListener()
- Unregister a schema migration listenergetSchemaBundle()
- Get allSchema
s registered in the databaseaddSchema()
- Register a newSchema
in the databaseremoveSchema()
- Remove a registeredSchema
from the database
Object Lifecycle
create()
- Create a database objectdelete()
- Delete a database objectcopy()
- Copy an object into a (possibly different) transactionaddCreateListener()
- Register aCreateListener
for notifications about new objectsremoveCreateListener()
- Unregister aCreateListener
addDeleteListener()
- Register aDeleteListener
for notifications about deleted objectsremoveDeleteListener()
- Unregister aDeleteListener
Object Queries
getAll()
- Get all objectsgetAll(String)
- Get all objects of a specific object typeexists()
- Test whether a database object exists
Index Queries
querySimpleIndex()
- Query an index on aSimpleField
or aComplexField
sub-fieldqueryListElementIndex()
- Query an index on aListField
's elements, also returning their corresponding list indexesqueryMapValueIndex()
- Query an index on aMapField
's values, also returning their corresponding keysqueryCompositeIndex2()
- Query a composite index on two fieldsqueryCompositeIndex3()
- Query a composite index on three fieldsqueryCompositeIndex4()
- Query a composite index on four fieldsquerySchemaIndex()
- Query the index that groups objects by their schema
Field Access
readSimpleField()
- Read the value of aSimpleField
in an objectwriteSimpleField()
- Write the value of aSimpleField
in an objectreadCounterField()
- Read the value of aCounterField
in an objectwriteCounterField()
- Write the value of aCounterField
in an objectadjustCounterField()
- Adjust the value of aCounterField
in an objectreadSetField()
- Access aSetField
in an object as aNavigableSet
readListField()
- Access aListField
in an object as aList
readMapField()
- Access aMapField
in an object as aNavigableMap
getKey(ObjId)
- Get theKVDatabase
key prefix corresponding to an object
Field Change Notifications
addSimpleFieldChangeListener()
- Register aSimpleFieldChangeListener
for notifications of changes in aSimpleField
, as seen through a path of object referencesaddSetFieldChangeListener()
- Register aSetFieldChangeListener
for notifications of changes in aSetField
, as seen through a path of object referencesaddListFieldChangeListener()
- Register aListFieldChangeListener
for notifications of changes in aListField
, as seen through a path of object referencesaddMapFieldChangeListener()
- Register aMapFieldChangeListener
for notifications of changes in aMapField
, as seen through a path of object referencesremoveSimpleFieldChangeListener()
- Unregister a previously registeredSimpleFieldChangeListener
removeSetFieldChangeListener()
- Unregister a previously registeredSetFieldChangeListener
removeListFieldChangeListener()
- Unregister a previously registeredListFieldChangeListener
removeMapFieldChangeListener()
- Unregister a previously registeredMapFieldChangeListener
Reference Paths
followReferencePath()
- Find all objects referred to by any element in a given set of starting objects through a specified reference pathinvertReferencePath()
- Find all objects that refer to any element in a given set of target objects through a specified reference path
Listener Sets
snapshotListeners()
- Create an immutable snapshot of all registered listenerssetListeners()
- Bulk registration of listeners from a previously created snapshot
All methods returning a set of values return a NavigableSet
.
The NavigableSets
utility class provides methods for the efficient intersection
,
union
, difference
, and
symmetric difference
of NavigableSet
s containing the same elements and
ordering, thereby providing the equivalent of traditional database joins.
Instances of this class are thread safe.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic interface
Callback interface for notification of transaction completion events.static class
Adapter class forTransaction.Callback
.static final class
A fixed collection of listeners (CreateListener
s,DeleteListener
s,SchemaChangeListener
s,SimpleFieldChangeListener
s,SetFieldChangeListener
s,ListFieldChangeListener
s, andMapFieldChangeListener
s) that can be efficiently registered on aTransaction
all at once. -
Field Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
addCallback
(Transaction.Callback callback) Register a transactionTransaction.Callback
to be invoked when this transaction completes.void
addCreateListener
(int storageId, CreateListener listener) Add aCreateListener
to this transaction.void
addDeleteListener
(int[] path, KeyRanges[] filters, DeleteListener listener) Add aDeleteListener
to this transaction.void
addFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, Object listener) Monitor for changes within this transaction to the specifiedField
as seen through a path of references.void
addListFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, ListFieldChangeListener listener) Monitor for changes within this transaction to the specifiedListField
as seen through a path of references.void
addMapFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, MapFieldChangeListener listener) Monitor for changes within this transaction to the specifiedMapField
as seen through a path of references.boolean
addSchema
(SchemaModel schemaModel) Manually record the given non-empty schema in the database.void
addSchemaChangeListener
(int storageId, SchemaChangeListener listener) Add aSchemaChangeListener
to this transaction that listens for schema migrations of the specified object type.void
addSetFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, SetFieldChangeListener listener) Monitor for changes within this transaction to the specifiedSetField
as seen through a path of references.void
addSimpleFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, SimpleFieldChangeListener listener) Monitor for changes within this transaction of the value of the given field, as seen through a path of references.void
adjustCounterField
(ObjId id, String name, long offset, boolean migrateSchema) Adjust the value of aCounterField
in an object by some amount, optionally updating the object's schema.void
commit()
Commit this transaction.boolean
copy
(ObjId source, Transaction dest, boolean migrateSchema, boolean notifyListeners, ObjIdMap<ReferenceField> deletedAssignments, ObjIdMap<ObjId> objectIdMap) Copy an object into a (possibly different) transaction.boolean
Create a new object with the given object ID, if it doesn't already exist.boolean
Create a new object with the given object ID, if it doesn't already exist.Create a new object with a randomly assigned object ID and having the given type.Create a new object with a randomly assigned object ID and having the given type and schema.Create an in-memory detached transaction.Create a detached transaction pre-populated with a snapshot of this transaction.boolean
Delete an object.boolean
Determine if an object exists.followReferencePath
(Stream<? extends ObjId> startObjects, int[] path, KeyRanges[] filters) Find all objects referred to by any object in the given start set through the specified path of references.generateId
(String typeName) Generate a random, unusedObjId
for the given object type.getAll()
Get all objects in the database.Get all objects whose object type has the specified name.Get the database with which this transaction is associated.getFieldDescription
(ObjId id, String name) Get a description of the given object field.byte[]
Get thebyte[]
key prefix in the underlying key/value store corresponding to the specified object.Get the underlying key/value store transaction.Get a description of the given object.getObjType
(ObjId id) Get the given object'sObjType
.Get the database schema associated with this transaction.Get the database's schema bundleGet a description of the given object's type.getTypeName
(int storageId) Get the object type assigned to the given storage ID.Get the object with this instance bysetUserObject()
, if any.invertReferencePath
(int[] path, KeyRanges[] filters, Stream<? extends ObjId> targetObjects) Find all objects that refer to any object in the given target set through the specified path of references.boolean
Determine whether this instance is aDetachedTransaction
.boolean
isOpen()
Determine whether this transaction is still open.boolean
Determine whether this transaction is read-only.boolean
Determine whether this transaction is marked rollback only.boolean
migrateSchema
(ObjId id) Migrate the specified object, if necessary, to the schema associated with this transaction.CoreIndex2<?,
?, ObjId> queryCompositeIndex2
(int storageId) Query aCompositeIndex
on two fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.CoreIndex3<?,
?, ?, ObjId> queryCompositeIndex3
(int storageId) Query aCompositeIndex
on three fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.CoreIndex4<?,
?, ?, ?, ObjId> queryCompositeIndex4
(int storageId) Query aCompositeIndex
on four fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.queryIndex
(int storageId) Query any simple or composite index.queryListElementIndex
(int storageId) Query aListElementIndex
to find all values stored in some list field and, for each value, the set of all objects having that value as an element in the list and the corresponding list index.CoreIndex2<?,
ObjId, ?> queryMapValueIndex
(int storageId) Query aMapValueIndex
to find all values stored in some map field and, for each value, the set of all objects having that value as a value in the map and the corresponding key.Query objects by schema.CoreIndex1<?,
ObjId> querySimpleIndex
(int storageId) Query aSimpleIndex
to find all values stored in some field and, for each value, the set of all objects having that value in the field.long
readCounterField
(ObjId id, String name, boolean migrateSchema) Read the value of aCounterField
from an object, optionally updating the object's schema.List<?>
readListField
(ObjId id, String name, boolean migrateSchema) Access aListField
associated with an object, optionally updating the object's schema.NavigableMap<?,
?> readMapField
(ObjId id, String name, boolean migrateSchema) Access aMapField
associated with an object, optionally updating the object's schema.NavigableSet<?>
readSetField
(ObjId id, String name, boolean migrateSchema) Access aSetField
associated with an object, optionally updating the object's schema.readSimpleField
(ObjId id, String name, boolean migrateSchema) Read the value of aSimpleField
from an object, optionally migrating the object's schema.void
removeCreateListener
(int storageId, CreateListener listener) Remove anCreateListener
from this transaction.void
removeDeleteListener
(int[] path, KeyRanges[] filters, DeleteListener listener) Remove aDeleteListener
from this transaction.void
removeFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, Object listener) Remove a field monitor previously added viaaddSimpleFieldChangeListener()
,addSetFieldChangeListener()
,addListFieldChangeListener()
,addMapFieldChangeListener()
, oraddFieldChangeListener()
.void
removeListFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, ListFieldChangeListener listener) Remove a field monitor previously added viaaddListFieldChangeListener()
(oraddFieldChangeListener()
).void
removeMapFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, MapFieldChangeListener listener) Remove a field monitor previously added viaaddMapFieldChangeListener()
(oraddFieldChangeListener()
).boolean
removeSchema
(SchemaId schemaId) Manually remove the given schema from the database.void
removeSchemaChangeListener
(int storageId, SchemaChangeListener listener) Remove aSchemaChangeListener
from this transaction previously registered viaaddSchemaChangeListener()
.void
removeSetFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, SetFieldChangeListener listener) Remove a field monitor previously added viaaddSetFieldChangeListener()
(oraddFieldChangeListener()
).void
removeSimpleFieldChangeListener
(int storageId, int[] path, KeyRanges[] filters, SimpleFieldChangeListener listener) Remove a field monitor previously added viaaddSimpleFieldChangeListener()
(oraddFieldChangeListener()
).void
rollback()
Roll back this transaction.void
setListeners
(Transaction.ListenerSet listeners) Apply a snapshot created viasnapshotListeners()
to this instance.void
setReadOnly
(boolean readOnly) Enable or disable read-only mode.void
Mark this transaction for rollback only.void
setTimeout
(long timeout) Change the timeout for this transaction from its default value (optional operation).void
setUserObject
(Object obj) Associate an arbitrary object with this instance.Create a read-only snapshot of all (CreateListener
s,DeleteListener
s,SchemaChangeListener
s,SimpleFieldChangeListener
s,SetFieldChangeListener
s,ListFieldChangeListener
s, andMapFieldChangeListener
s currently registered on this instance.void
withWeakConsistency
(Runnable action) Apply weaker transaction consistency while performing the given action, if supported.void
writeCounterField
(ObjId id, String name, long value, boolean migrateSchema) Set the value of aCounterField
in an object, optionally updating the object's schema.void
writeSimpleField
(ObjId id, String name, Object value, boolean migrateSchema) Change the value of aSimpleField
in an object, optionally updating the object's schema.
-
Field Details
-
log
-
-
Method Details
-
getDatabase
Get the database with which this transaction is associated.- Returns:
- associated database
-
getSchemaBundle
Get the database's schema bundleThis returns all of the schemas currently recorded in the database as seen by this transaction.
- Returns:
- database schema bundle
-
getSchema
Get the database schema associated with this transaction.This is the target schema for newly created and migrated objects.
- Returns:
- this transaction's schema
-
getKVTransaction
Get the underlying key/value store transaction.Warning: making changes directly to the key/value store directly is not supported. If changes are made, future behavior is undefined.
- Returns:
- the associated key/value transaction
-
addSchema
Manually record the given non-empty schema in the database.If successful, this transaction's schema bundle will be updated.
This transaction's current schema does not change.
This method is dangerous and should normally not be used except by low-level tools.
- Returns:
- true if the schema was added, false if it was already in the schema bundle
- Throws:
InvalidSchemaException
- ifschemaModel
is invalid (i.e., does not pass validation checks)SchemaMismatchException
- ifschemaModel
has explicit storage ID assignments that conflict with storage ID assignments already recorded in the databaseStaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- ifschemaModel
is emptyIllegalArgumentException
- ifschemaModel
is null
-
removeSchema
Manually remove the given schema from the database.If successful, this transaction's schema bundle will be updated.
If the removed schema is also this transaction's current schema, then this transaction's schema reverts to the empty schema. The empty schema itself is never recorded in a database, so it will never be found by this method.
This method is dangerous and should normally not be used except by low-level tools.
- Returns:
- true if the schema was removed, false if it was not found
- Throws:
IllegalArgumentException
- if any objects in the schema still existStaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- ifschemaId
is null
-
commit
public void commit()Commit this transaction.- Throws:
StaleTransactionException
- if this transaction is no longer usableRetryKVTransactionException
- fromKVTransaction.commit()
RollbackOnlyTransactionException
- if this instance has been marked rollback only; this instance will be automatically rolled back
-
rollback
public void rollback()Roll back this transaction.This method may be invoked at any time, even after a previous invocation of
commit()
orrollback()
, in which case the invocation will be ignored. -
isOpen
public boolean isOpen()Determine whether this transaction is still open.In other words, other methods in this class won't throw
StaleTransactionException
.- Returns:
- true if this instance is still usable
-
isReadOnly
public boolean isReadOnly()Determine whether this transaction is read-only.This method just invokes
KVTransaction.isReadOnly()
on the underlying key/value transaction.- Returns:
- true if this instance is read-only
- Throws:
StaleTransactionException
- if this transaction is no longer usable
-
setReadOnly
public void setReadOnly(boolean readOnly) Enable or disable read-only mode.Read-only transactions allow mutations, but all changes are discarded on
commit()
. RegisteredTransaction.Callback
s are still processed normally.This method just invokes
KVTransaction.setReadOnly(boolean)
on the underlying key/value transaction.- Parameters:
readOnly
- read-only setting- Throws:
StaleTransactionException
- if this transaction is no longer usable
-
isRollbackOnly
public boolean isRollbackOnly()Determine whether this transaction is marked rollback only.- Returns:
- true if this instance is marked for rollback only
-
setRollbackOnly
public void setRollbackOnly()Mark this transaction for rollback only.Once a transaction is marked rollback only, any subsequent
commit()
attempt will throw an exception. -
setTimeout
public void setTimeout(long timeout) Change the timeout for this transaction from its default value (optional operation).This method just invokes
KVTransaction.setTimeout(long)
on the underlying key/value transaction.- Parameters:
timeout
- transaction timeout in milliseconds, or zero for unlimited- Throws:
UnsupportedOperationException
- if this transaction does not support timeoutsIllegalArgumentException
- iftimeout
is negativeStaleTransactionException
- if this transaction is no longer usable
-
addCallback
Register a transactionTransaction.Callback
to be invoked when this transaction completes.Callbacks will be invoked in the order they are registered, but duplicate registrations are ignored (based on comparison via
Object.equals(java.lang.Object)
).Note: if you are using Spring for transaction demarcation (via
PermazenTransactionManager
), then you may also use Spring'sTransactionSynchronizationManager.registerSynchronization()
instead of this method.- Parameters:
callback
- callback to invoke- Throws:
IllegalArgumentException
- ifcallback
is nullStaleTransactionException
- if this transaction is no longer usable
-
createDetachedTransaction
Create an in-memory detached transaction.The detached transaction will be initialized with the same schema meta-data as this instance but will be otherwise empty (i.e., contain no objects). It can be used as a destination for in-memory copies of objects made via
copy()
.The returned
DetachedTransaction
does not supportcommit()
orrollback()
. It can be used indefinitely after this transaction closes, but it must beclose()
'd when no longer needed to release any associated resources.- Returns:
- empty in-memory detached transaction with compatible schema information
- See Also:
-
createSnapshotTransaction
Create a detached transaction pre-populated with a snapshot of this transaction.The returned transaction will have the same schema meta-data and object content as this instance. It will be a mutable transaction, but being detached, changes can't be committed.
This method requires the underlying key/value transaction to support
KVTransaction.readOnlySnapshot()
. As with any other information extracted from this transaction, the returned content is not guaranteed to be valid until this transaction has been successfully committed.The returned
DetachedTransaction
does not supportcommit()
orrollback()
. It can be used indefinitely after this transaction closes, but it must beclose()
'd when no longer needed to release any associated resources.- Returns:
- in-memory copy of this transaction
- Throws:
UnsupportedOperationException
- if they underlying key/value transaction doesn't supportKVTransaction.readOnlySnapshot()
-
isDetached
public boolean isDetached()Determine whether this instance is aDetachedTransaction
.- Returns:
- true if this instance is a
DetachedTransaction
, otherwise false
-
withWeakConsistency
Apply weaker transaction consistency while performing the given action, if supported.Some key/value implementations support reads with weaker consistency guarantees, where reads generate fewer transaction conflicts in exchange for returning possibly out-of-date information.
Depending on the key/value implementation, in this mode writes may not be supported; instead, they would generate a
IllegalStateException
or just be ignored.The weaker consistency is only applied for the current thread, and it ends when this method returns.
This method is for experts only; inappropriate use can result in a corrupted database. In general, after this method returns you should not make any changes to the database that are based on any information read by the
action
.- Parameters:
action
- the action to perform- Throws:
IllegalArgumentException
- ifaction
is null
-
create
Create a new object with the given object ID, if it doesn't already exist.If the object already exists, nothing happens.
If the object doesn't already exist, all fields are set to their default values and the object's schema is set to the schema associated with this transaction.
- Parameters:
id
- object ID- Returns:
- true if the object did not exist and was created, false if the object already existed
- Throws:
UnknownTypeException
- ifid
does not correspond to an object type in this transaction's schemaIllegalArgumentException
- ifid
is nullStaleTransactionException
- if this transaction is no longer usable
-
create
Create a new object with the given object ID, if it doesn't already exist. If it does exist, nothing happens.If the object doesn't already exist, the object's schema is set to the specified schema and all fields are set to their default values.
- Parameters:
id
- object IDschemaId
- the schema to use for the newly created object- Returns:
- true if the object did not exist and was created, false if the object already existed
- Throws:
UnknownTypeException
- ifid
does not correspond to a known object type in the specified schemaInvalidSchemaException
- ifschemaId
is invalidIllegalArgumentException
- ifid
orschemaId
is nullStaleTransactionException
- if this transaction is no longer usable
-
create
Create a new object with a randomly assigned object ID and having the given type.All fields will be set to their default values. The object's schema will be set to the associated with this transaction.
- Parameters:
typeName
- object type name- Returns:
- object id of newly created object
- Throws:
UnknownTypeException
- iftypeName
does not correspond to a known object type in this transaction's schemaIllegalArgumentException
- iftypeName
is nullStaleTransactionException
- if this transaction is no longer usable
-
create
Create a new object with a randomly assigned object ID and having the given type and schema.All fields will be set to their default values. The object's schema will be set to the specified schema.
- Parameters:
typeName
- object type nameschemaId
- ID of the schema to use for the newly created object- Returns:
- object id of newly created object
- Throws:
UnknownTypeException
- iftypeName
does not correspond to a known object type in the specified schemaInvalidSchemaException
- ifschemaId
is invalidIllegalArgumentException
- ifid
orschemaId
is nullStaleTransactionException
- if this transaction is no longer usable
-
generateId
Generate a random, unusedObjId
for the given object type.- Parameters:
typeName
- object type name- Returns:
- random unassigned object id
- Throws:
UnknownTypeException
- iftypeName
does not correspond to any known object typeIllegalArgumentException
- iftypeName
is nullStaleTransactionException
- if this transaction is no longer usable
-
delete
Delete an object. Does nothing if object does not exist (e.g., has already been deleted).This method does not change the object's schema if it is different from this transaction's schema.
Notifications
If the object exists,
DeleteListener
's will be notified synchronously by this method before the object is actually deleted. Therefore it's possible for aDeleteListener
to (perhaps indirectly) re-entrantly invoke this method with the sameid
. In such cases, false is returned matchingDeleteListener
s are not (redundantly) notified.Secondary Deletions
Deleting an object can trigger additional automatic secondary deletions. Specifically, (a) if the object contains reference fields with forward delete cascade enabled, any objects referred to through those fields will also be deleted, and (b) if the object is referred to by any other objects through fields configured for
DeleteAction.DELETE
, those referring objects will be deleted.In any case, deletions occur one at a time, and only after an object is actually deleted do any associated secondary deletions take place. However, the order in which secondary deletions occur is unspecified. For an example of where this ordering matters, consider an object
A
referring to objectsB
andC
with delete cascading references, where B also refers to C with aDeleteAction.EXCEPTION
reference. Then ifA
is deleted, it's indeterminate whether aReferencedObjectException
will be thrown, as that depends on whetherB
orC
is deleted first (with the answer being, respectively, no and yes).- Parameters:
id
- object ID of the object to delete- Returns:
- true if object was found and deleted, false if object does not exist or this method is
being invoked re-entrantly with the same
id
- Throws:
ReferencedObjectException
- if the object is referenced by some other object through a reference field configured forDeleteAction.EXCEPTION
IllegalArgumentException
- ifid
is nullStaleTransactionException
- if this transaction is no longer usable
-
exists
Determine if an object exists.This method does not change the object's schema if it exists and is different from this transaction's schema.
- Parameters:
id
- object ID of the object to find- Returns:
- true if object was found, false if object was not found, or if
id
specifies an unknown object type - Throws:
StaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- ifid
is null
-
copy
public boolean copy(ObjId source, Transaction dest, boolean migrateSchema, boolean notifyListeners, ObjIdMap<ReferenceField> deletedAssignments, ObjIdMap<ObjId> objectIdMap) Copy an object into a (possibly different) transaction.This copies the object, including all of its field data, to
dest
. If the object already exists indest
, the existing copy is completely replaced, otherwise it will be created automatically.Object Schemas
In order to perform the copy,
source
's schema must also already exist indest
. If it does not, aSchemaMismatchException
is thrown.But first, if
migrateSchema(io.permazen.core.ObjId)
is true,source
's schema is first migrated to match this transaction, if needed.Notifications
CreateListener
s in the destination transaction will be notified if the target object must be created, and field change listeners in the destination transaction will be notified for non-trivial changes to the target object's fields as each field is copied. These notifications may be disabled by settingnotifyListeners
to false.Matching
SchemaChangeListener
s in this transaction are notified if/whensource
is migrated due tomigrateSchema(io.permazen.core.ObjId)
being true.Deleted Assignments
If a reference field configured to disallow deleted assignments is copied, but the referenced object does not exist in
dest
, then aDeletedObjectException
is thrown and no copy is performed. However, this presents an impossible chicken-and-egg situation when multiple objects need to be copied and there are cycles in the graph of references between objects.To handle that situation, if
deletedAssignments
is non-null, then instead of triggering an exception, illegal references to deleted objects are collected indeletedAssignments
; each entry maps a deleted object to (some) referring field in the copied object. This lets the caller to decide what to do about them.Object ID Remapping
By default, the
ObjId
ofsource
is also theObjId
of the target object indest
, and all reference fields are copied as-is. The optionalobjectIdMap
allows the caller to remap theseObjId
s arbitrarily, as long as the implied object types are the same. IfobjectIdMap
maps anObjId
to null, then a new, unusedObjId
indest
will be chosen and updated inobjectIdMap
.Return Value
If
dest
is this instance, and thesource
is not remapped, no fields are changed and false is returned, otherwise true is returned. Even if false is returned, a schema migration can still occur (ifmigrateSchema
is true), and deleted assignment checks are still applied.Deadlock Avoidance
If two threads attempt to copy objects between the same two transactions at the same time but in opposite directions, deadlock can result.
- Parameters:
source
- object ID of the source object in this transactiondest
- destination for the copy ofsource
(possibly this transaction)migrateSchema
- whether to migratesource
's schema (if necessary) to match this transaction prior to the copynotifyListeners
- whether to notifyCreateListener
s and field change listeners indest
deletedAssignments
- if not null, where to collect assignments to deleted objects instead of throwingDeletedObjectException
s; the map key is the deleted object and the map value is some referring fieldobjectIdMap
- if not null, a remapping of object ID's in this transaction to object ID's indest
- Returns:
- false if the target object already existed in
dest
, true if it was newly created - Throws:
DeletedObjectException
- if no object with ID equal tosource
exists in this transactionDeletedObjectException
- ifdeletedAssignments
is null, and a non-null reference field insource
that disallows deleted assignments contains a reference to an object that does not exist indest
UnknownTypeException
- ifsource
or anObjId
inobjectIdMap
specifies an unknown object typeIllegalArgumentException
- ifobjectIdMap
mapssource
to a different object typeIllegalArgumentException
- ifobjectIdMap
maps the value of a reference field to an incompatible object typeIllegalArgumentException
- if any parameter is nullStaleTransactionException
- if this transaction ordest
is no longer usableSchemaMismatchException
- ifsource
's schema does not exist indest
SchemaMismatchException
- if the object's ID indest
does not match the assigned storage ID for its typeTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schema
-
addCreateListener
Add aCreateListener
to this transaction.- Parameters:
storageId
- storage ID of the object type to listen for creationlistener
- the listener to add- Throws:
UnknownTypeException
- ifstorageId
specifies an unknown object typeIllegalArgumentException
- iflistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeCreateListener
Remove anCreateListener
from this transaction.- Parameters:
storageId
- storage ID of the object type to listen for creation- Throws:
UnknownTypeException
- ifstorageId
specifies an unknown object typeStaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- iflistener
is nullIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
addDeleteListener
Add aDeleteListener
to this transaction.- Parameters:
path
- path of reference fields (represented by storage IDs) through which to monitor for deletion; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on object deletion- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeDeleteListener
Remove aDeleteListener
from this transaction.- Parameters:
path
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on object deletion- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
getObjType
Get the given object'sObjType
.- Parameters:
id
- object id- Returns:
- object's object type
- Throws:
DeletedObjectException
- if no such object existsUnknownTypeException
- ifid
specifies an unknown object typeStaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- ifid
is null
-
getTypeName
Get the object type assigned to the given storage ID.- Parameters:
storageId
- object type storage ID- Returns:
- the corresponding object type name
- Throws:
UnknownTypeException
- ifstorageId
specifies an unknown object type
-
migrateSchema
Migrate the specified object, if necessary, to the schema associated with this transaction.If a schema change occurs, any matching
SchemaChangeListener
s will be notified prior to this method returning.- Parameters:
id
- object ID of the object to migrate- Returns:
- true if the object's schema was migrated, false if it's schema already matched
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundIllegalArgumentException
- ifid
is nullTypeNotInSchemaException
- if the object's type is not defined in this transaction's schema
-
querySchemaIndex
Query objects by schema.This returns all objects in the database grouped by
Schema
. The keys in the returned map are schema indexes; usegetSchemaBundle()
and thenSchemaBundle.getSchemasBySchemaIndex()
to access the correspondingSchema
s.- Returns:
- read-only, real-time view of all database objects grouped by schema
- Throws:
StaleTransactionException
- if this transaction is no longer usable
-
addSchemaChangeListener
Add aSchemaChangeListener
to this transaction that listens for schema migrations of the specified object type.- Parameters:
storageId
- storage ID of the object type to listen to for schema changeslistener
- the listener to add- Throws:
UnknownTypeException
- ifstorageId
specifies an unknown object typeIllegalArgumentException
- iflistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeSchemaChangeListener
Remove aSchemaChangeListener
from this transaction previously registered viaaddSchemaChangeListener()
.- Parameters:
storageId
- storage ID of the object type to listen to for schema changeslistener
- the listener to remove- Throws:
UnknownTypeException
- ifstorageId
specifies an unknown object typeStaleTransactionException
- if this transaction is no longer usableIllegalArgumentException
- iflistener
is nullIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
getAll
Get all objects in the database.The returned set includes objects from all schemas. Use
querySchemaIndex()
to access objects with a specific schema.The returned set is mutable, with the exception that
add()
is not supported. Deleting an element results in deleting the corresponding object.- Returns:
- a live view of all database objects
- Throws:
StaleTransactionException
- if this transaction is no longer usable- See Also:
-
getAll
Get all objects whose object type has the specified name.The returned set includes objects of the specified type from all schemas in the database. The returned set is mutable, with the exception that
add()
is not supported. Deleting an element results in deleting the corresponding object.- Parameters:
typeName
- object type name- Returns:
- a live view of all database objects having the specified type
- Throws:
UnknownTypeException
- iftypeName
does not correspond to any known object typeIllegalArgumentException
- iftypeName
is nullStaleTransactionException
- if this transaction is no longer usable- See Also:
-
readSimpleField
Read the value of aSimpleField
from an object, optionally migrating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary, prior to reading the field.- Parameters:
id
- object ID of the objectname
- field namemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Returns:
- value of the field in the object
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noSimpleField
corresponding toname
exists in the objectIllegalArgumentException
- ifid
is nullTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schema
-
writeSimpleField
Change the value of aSimpleField
in an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary, prior to writing the field.- Parameters:
id
- object ID of the objectname
- field namevalue
- new value for the fieldmigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noSimpleField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifvalue
is not an appropriate value for the fieldIllegalArgumentException
- ifid
is null
-
getTypeDescription
Get a description of the given object's type.- Parameters:
id
- object ID- Returns:
- textual description of the specified object's type
- Throws:
IllegalArgumentException
- ifid
is null
-
getObjDescription
Get a description of the given object.- Parameters:
id
- object ID- Returns:
- textual description of the specified object
- Throws:
IllegalArgumentException
- ifid
is null
-
getFieldDescription
Get a description of the given object field.- Parameters:
id
- object IDname
- field's name- Returns:
- textual description of the specified object field
- Throws:
IllegalArgumentException
- ifid
orname
is null
-
readCounterField
Read the value of aCounterField
from an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary, prior to reading the field.- Parameters:
id
- object ID of the objectname
- field namemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Returns:
- value of the counter in the object
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noCounterField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
writeCounterField
Set the value of aCounterField
in an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary, prior to writing the field.- Parameters:
id
- object ID of the objectname
- field namevalue
- new counter valuemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noCounterField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
adjustCounterField
Adjust the value of aCounterField
in an object by some amount, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary, prior to adjusting the field.- Parameters:
id
- object ID of the objectname
- field nameoffset
- offset value to add to counter valuemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noCounterField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
readSetField
Access aSetField
associated with an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary.- Parameters:
id
- object ID of the objectname
- field namemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Returns:
- set field value
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noSetField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
readListField
Access aListField
associated with an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary.- Parameters:
id
- object ID of the objectname
- field namemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Returns:
- list field value
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noListField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
readMapField
Access aMapField
associated with an object, optionally updating the object's schema.If
migrateSchema
is true, the object will be automatically migrated to match the schema associated with this transaction, if necessary.- Parameters:
id
- object ID of the objectname
- field namemigrateSchema
- true to first automatically migrate the object's schema, false to not change it- Returns:
- map field value
- Throws:
StaleTransactionException
- if this transaction is no longer usableDeletedObjectException
- if no object with ID equal toid
is foundUnknownTypeException
- ifid
specifies an unknown object typeUnknownFieldException
- if noMapField
corresponding toname
exists in the objectTypeNotInSchemaException
-migrateSchema
is true and the object's schema could not be migrated because the object's type does not exist in this transaction's schemaIllegalArgumentException
- ifid
is null
-
getKey
Get thebyte[]
key prefix in the underlying key/value store corresponding to the specified object.Notes:
- This method does not check whether the object actually exists.
- Objects utilize multiple keys; the return value is the common prefix of all such keys.
- The
KVDatabase
should not be modified directly, otherwise behavior is undefined
- Parameters:
id
- object ID- Returns:
- the
KVDatabase
key corresponding toid
- Throws:
UnknownTypeException
- ifid
specifies an unknown object typeIllegalArgumentException
- ifid
is null- See Also:
-
addSimpleFieldChangeListener
public void addSimpleFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, SimpleFieldChangeListener listener) Monitor for changes within this transaction of the value of the given field, as seen through a path of references.When the specified field is changed in some object T, a listener notification will be delivered for each object R that refers to object T through the specified path of reference fields (if
path
is empty, then R = T). Notifications are delivered at the end of the mutation operation just prior to returning to the caller. If the listener method performs additional mutation(s) which are themselves being listened for, those notifications will also be delivered prior to the returning to the original caller. Therefore, care must be taken to avoid change notification dependency loops when listeners can themselves mutate fields, to avoid infinite loops.The
filters
, if any, are applied toObjId
's at the corresponding steps in the path:filters[0]
is applied to the starting objects R,filters[1]
is applied to the objects reachable from R viapath[0]
, etc., up tofilters[path.length]
, which applies to the target objects T.filters
or any element therein may be null to indicate no restriction.A referring object R may refer to the changed object T through more than one sequence of objects matching
path
; if so, R will still appear only once in theNavigableSet
provided to the listener (this is of course required by set semantics).Although the reference back-tracking algorithm does consolidate multiple paths between the same two objects, be careful to avoid an explosion of notifications when objects in the
path
have a high degree of fan-in.When a
ReferenceField
inpath
also happens to be the field being changed, then there is ambiguity about how the set of referring objects is calculated: does it use the field's value before or after the change? This API guarantees that the answer is "after the change"; however, if another listener on the same field is invoked beforelistener
and mutates any reference field(s) inpath
, then whether that additional change is also be included in the calculation is undefined.Therefore, for consistency, avoid changing any
ReferenceField
from within a listener callback when that field is also in some other listener's reference path, and both listeners are watching the same field.Permazen allows a field's type to change across schemas, therefore some schema may exist in which the field associated with
storageId
is not aSimpleField
. In such cases,listener
will receive notifications about those changes if it also happens to implement the other listener interface. In other words, this method delegates directly toaddFieldChangeListener()
.- Parameters:
storageId
- storage ID of the field to monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
addSetFieldChangeListener
public void addSetFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, SetFieldChangeListener listener) Monitor for changes within this transaction to the specifiedSetField
as seen through a path of references.See
addSimpleFieldChangeListener()
for details on how notifications are delivered.Permazen allows a field's type to change across schemas, therefore some schema may exist in which the field associated with
storageId
is not aSetField
. In such cases,listener
will receive notifications about those changes if it also happens to implement the other listener interface. In other words, this method delegates directly toaddFieldChangeListener()
.- Parameters:
storageId
- storage ID of the field to monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
addListFieldChangeListener
public void addListFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, ListFieldChangeListener listener) Monitor for changes within this transaction to the specifiedListField
as seen through a path of references.See
addSimpleFieldChangeListener()
for details on how notifications are delivered.Permazen allows a field's type to change across schemas, therefore some schema may exist in which the field associated with
storageId
is not aListField
. In such cases,listener
will receive notifications about those changes if it also happens to implement the other listener interface. In other words, this method delegates directly toaddFieldChangeListener()
.- Parameters:
storageId
- storage ID of the field to monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
addMapFieldChangeListener
public void addMapFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, MapFieldChangeListener listener) Monitor for changes within this transaction to the specifiedMapField
as seen through a path of references.See
addSimpleFieldChangeListener()
for details on how notifications are delivered.Permazen allows a field's type to change across schemas, therefore some schema may exist in which the field associated with
storageId
is not aMapField
. In such cases,listener
will receive notifications about those changes if it also happens to implement the other listener interface. In other words, this method delegates directly toaddFieldChangeListener()
.- Parameters:
storageId
- storage ID of the field to monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
addFieldChangeListener
Monitor for changes within this transaction to the specifiedField
as seen through a path of references.See
addSimpleFieldChangeListener()
for details on how notifications are delivered.Permazen allows a field's type to change across schemas, therefore in different schemas the specified field may have different types. The
listener
will receive notifications about a field change if it implements the interface appropriate for the field's current type (i.e.,SimpleFieldChangeListener
,ListFieldChangeListener
,SetFieldChangeListener
, orMapFieldChangeListener
) at the time of the change.- Parameters:
storageId
- storage ID of the field to monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeSimpleFieldChangeListener
public void removeSimpleFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, SimpleFieldChangeListener listener) Remove a field monitor previously added viaaddSimpleFieldChangeListener()
(oraddFieldChangeListener()
).- Parameters:
storageId
- storage ID of the field to no longer monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeSetFieldChangeListener
public void removeSetFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, SetFieldChangeListener listener) Remove a field monitor previously added viaaddSetFieldChangeListener()
(oraddFieldChangeListener()
).- Parameters:
storageId
- storage ID of the field to no longer monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeListFieldChangeListener
public void removeListFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, ListFieldChangeListener listener) Remove a field monitor previously added viaaddListFieldChangeListener()
(oraddFieldChangeListener()
).- Parameters:
storageId
- storage ID of the field to no longer monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeMapFieldChangeListener
public void removeMapFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, MapFieldChangeListener listener) Remove a field monitor previously added viaaddMapFieldChangeListener()
(oraddFieldChangeListener()
).- Parameters:
storageId
- storage ID of the field to no longer monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
removeFieldChangeListener
public void removeFieldChangeListener(int storageId, int[] path, KeyRanges[] filters, Object listener) Remove a field monitor previously added viaaddSimpleFieldChangeListener()
,addSetFieldChangeListener()
,addListFieldChangeListener()
,addMapFieldChangeListener()
, oraddFieldChangeListener()
.- Parameters:
storageId
- storage ID of the field to no longer monitorpath
- path of reference fields (represented by storage IDs) through which to monitor field; negated values denote inverse traversal of the fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathlistener
- callback for notifications on changes in value- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifpath
orlistener
is nullStaleTransactionException
- if this transaction is no longer usableIllegalStateException
- ifsetListeners()
has been invoked on this instance
-
followReferencePath
public NavigableSet<ObjId> followReferencePath(Stream<? extends ObjId> startObjects, int[] path, KeyRanges[] filters) Find all objects referred to by any object in the given start set through the specified path of references.Each value in
path
represents a reference field traversed in the path to some target object(s); if a value inpath
is negated, then the field is traversed in the inverse direction.If
path
is empty, then the contents ofstartObjects
is returned.The
filters
, if any, are applied toObjId
's at the corresponding steps in the path:filters[0]
is applied tostartObjects
,filters[1]
is applied to the objects reachable fromstartObjects
viapath[0]
, etc., up tofilters[path.length]
, which applies to the final target objects.filters
or any element therein may be null to indicate no restriction.- Parameters:
startObjects
- starting objectspath
- path of zero or more reference fields (represented by storage IDs) through which to reach the target objects; negated values denote an inverse traversal of the corresponding reference fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the path- Returns:
- read-only set of objects referred to by the
startObjects
viapath
restricted byfilters
- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- ifstartObjects
orpath
is nullIllegalArgumentException
- iffilters
is not null and does not have lengthpath.length + 1
StaleTransactionException
- if this transaction is no longer usable
-
invertReferencePath
public NavigableSet<ObjId> invertReferencePath(int[] path, KeyRanges[] filters, Stream<? extends ObjId> targetObjects) Find all objects that refer to any object in the given target set through the specified path of references.Each value in
path
represents a reference field traversed in the path to the target object(s); if a value inpath
is negated, then the field is traversed in the inverse direction.If
path
is empty, then the contents oftargetObjects
is returned.The
filters
, if any, are applied toObjId
's at the corresponding steps in the path:filters[path.length]
is applied totargetObjects
,filters[path.length - 1]
is applied to the objects referring totargetObjects
viapath[path.length - 1]
, etc., down tofilters[0]
, which applies to the objects at the start of the path being inverted.filters
or any element therein may be null to indicate no restriction.- Parameters:
path
- path of zero or more reference fields (represented by storage IDs) through which to reach the target objects; negated values denote an inverse traversal of the corresponding reference fieldfilters
- if not null, an array of lengthpath.length + 1
containing optional filters to be applied to object ID's after the corresponding steps in the pathtargetObjects
- target objects- Returns:
- read-only set of objects that refer to the
targetObjects
viapath
restricted byfilters
- Throws:
UnknownFieldException
- ifpath
contains a storage ID that does not correspond to aReferenceField
IllegalArgumentException
- iftargetObjects
orpath
is nullIllegalArgumentException
- iffilters
is not null and does not have lengthpath.length + 1
StaleTransactionException
- if this transaction is no longer usable
-
queryIndex
Query any simple or composite index.The returned view will have type
CoreIndex1
,CoreIndex2
,CoreIndex3
, etc., corresponding to the number of fields in the index.- Parameters:
storageId
- the storage ID associated with the field (if simple) or composite index- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsStaleTransactionException
- if this transaction is no longer usable
-
querySimpleIndex
Query aSimpleIndex
to find all values stored in some field and, for each value, the set of all objects having that value in the field.Use this method to acquire a plain
CoreIndex1
on complex sub-fields.- Parameters:
storageId
- the storage ID associated with the field- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsStaleTransactionException
- if this transaction is no longer usable
-
queryListElementIndex
Query aListElementIndex
to find all values stored in some list field and, for each value, the set of all objects having that value as an element in the list and the corresponding list index.- Parameters:
storageId
- the storage ID associated with the field- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsStaleTransactionException
- if this transaction is no longer usable
-
queryMapValueIndex
Query aMapValueIndex
to find all values stored in some map field and, for each value, the set of all objects having that value as a value in the map and the corresponding key.- Parameters:
storageId
- the storage ID associated with the field- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsStaleTransactionException
- if this transaction is no longer usable
-
queryCompositeIndex2
Query aCompositeIndex
on two fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.- Parameters:
storageId
- the storage ID associated with the composite index- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsUnknownIndexException
- if the index is not on two fieldsStaleTransactionException
- if this transaction is no longer usable
-
queryCompositeIndex3
Query aCompositeIndex
on three fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.- Parameters:
storageId
- the storage ID associated with the composite index- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsUnknownIndexException
- if the index is not on three fieldsStaleTransactionException
- if this transaction is no longer usable
-
queryCompositeIndex4
Query aCompositeIndex
on four fields to find all value tuples stored in the corresponding field tuple and, for each value tuple, the set of all objects having those values in those fields.- Parameters:
storageId
- the storage ID associated with the composite index- Returns:
- read-only, real-time view of the index
- Throws:
UnknownIndexException
- if no such index existsUnknownIndexException
- if the index is not on four fieldsStaleTransactionException
- if this transaction is no longer usable
-
snapshotListeners
Create a read-only snapshot of all (CreateListener
s,DeleteListener
s,SchemaChangeListener
s,SimpleFieldChangeListener
s,SetFieldChangeListener
s,ListFieldChangeListener
s, andMapFieldChangeListener
s currently registered on this instance.The snapshot can be applied to other transactions having compatible schemas via
setListeners()
. Use of aTransaction.ListenerSet
also allows certain internal optimizations.- Returns:
- snapshot of listeners associated with this instance
- See Also:
-
setListeners
Apply a snapshot created viasnapshotListeners()
to this instance.Any currently registered listeners are unregistered and replaced by the listeners in
listeners
. This method may be invoked multiple times; however, once this method has been invoked, any subsequent attempts to register or unregister individual listeners will result in anIllegalStateException
.- Parameters:
listeners
- listener set created bysnapshotListeners()
- Throws:
IllegalArgumentException
- iflisteners
was created from a transaction with an incompatible schemaIllegalArgumentException
- iflisteners
is null
-
setUserObject
Associate an arbitrary object with this instance.- Parameters:
obj
- user object
-
getUserObject
Get the object with this instance bysetUserObject()
, if any.- Returns:
- the associated user object, or null if none has been set
-