public final class Updates
extends java.lang.Object
UpdatePrimitive
2. All update primitives for a snapshot/query are collected here
3. Primitives are kept separately for each database that is addressed. This
way we can operate on PRE values instead of node IDs, skip mapping
overhead and further optimize the update process.
DatabaseUpdates
4. Primitives are further kept separately for each database node - each
individual target PRE value. There's a specific container for this:
NodeUpdates
5. Transform expressions are executed in an 'isolated' updating environment,
see TransformModifier. All the other updates are executed by
a DatabaseModifier.
6. Fn:put statements are treated exactly like an update primitive. They are
represented by an update primitive.
7. After the query has been parsed and all update primitives have been added
to the list, constraints, which cannot be taken care of on the fly, are
checked. If no problems occur, updates are TO BE carried out.
8. Updates are carried out separately for each database, the following
way:
1. Update primitives are sorted by the PRE value of their target node
in a descending manner. Applying updates from the highest to the
lowest PRE value ensures that updates, not-yet carried out, are not
affected by PRE value shifts. PRE value shifts are a result of
structural changes of the table - which occur each time a node is
inserted or deleted, for more see PrimitiveType.
2. For each specific target node, updates which are collected in a
NodeUpdates container are executed in a specific
order, depending on their type PrimitiveType. This order
relates more or less to the XQUF specification, at least it leads to
the same result.
3. Neighboring text nodes have to be merged together (see XQuery Data
Model). Adjacent text nodes can only be a result of structural
updates. With our approach this takes some extra effort, but can be
carried out on-the-fly, applying the two following steps:
1. An NodeUpdates container holds all update
primitives for a specific database node N. If all updates with
target N (all updates in the current container) are carried out,
text node adjacency can only occur on the child axis, or the
sibling axis of N.
Regarding adjacency on the child axis, this can be taken care off
by first applying all updates on this axis and subsequently
checking the affected PRE positions for adjacent text nodes.
The sibling axis of N can only be checked for adjacent text nodes
after an eventual left sibling target container has executed its
updates. Example: We have two siblings A(1) and B(2). A is a text
node, B is an element. The numbers in brackets are their PRE
values. If A is target of a delete primitive and B is target of
an insert before primitive (text 'foo' is inserted) the following
happens: insert before is executed on B, A is deleted, location
around B is checked for adjacent text nodes. No merges occur. We
repeat this for every target node and only apply text node merges
if updates of the next container have been carried out.
If we would carry out text merges immediately, the following
(which leads to inconsistency) happens: insert before
is executed on B, 'foo' is adjacent to A and therefore the two
nodes are merged together, A is finally deleted. As a result we
loose the text node 'foo' during the process, as it is merged
with A and subsequently deleted together with A (consider the pre
value shifts!).
XQUF SPECIALTIES WITH BASEX
Fn:put: the target node of an fn:put statement cannot be deleted, but it
can be among the deleted nodes as a result of a 'replace element content'
statement.| Modifier and Type | Field and Description |
|---|---|
ContextModifier |
mod
Current context modifier.
|
| Constructor and Description |
|---|
Updates() |
| Modifier and Type | Method and Description |
|---|---|
void |
add(UpdatePrimitive up,
QueryContext ctx)
Adds an update primitive to the current context modifier.
|
void |
apply()
Executes all updates.
|
DBNode |
determineDataRef(ANode target,
QueryContext ctx)
Determines the data reference and pre value for an update primitive
which has a fragment as a target node.
|
int |
size()
Number of updates on the pending update list.
|
public ContextModifier mod
public void add(UpdatePrimitive up, QueryContext ctx) throws QueryException
up - update primitivectx - query contextQueryException - query exceptionpublic DBNode determineDataRef(ANode target, QueryContext ctx)
target - target fragmentctx - query contextpublic void apply()
throws QueryException
QueryException - query exceptionpublic int size()