package org.basex.query.up.primitives; import static org.basex.util.Token.*; import org.basex.data.Data; import org.basex.util.InputInfo; /** * Base class for all update primitives that lead to structural changes / * pre value shifts on the database table. * * @author BaseX Team 2005-12, BSD License * @author Lukas Kircher */ public abstract class StructuralUpdate extends UpdatePrimitive { /** Number of pre value shifts on the table introduced by this primitive. */ int shifts; /** * Constructor. * @param t Primitive type * @param p pre * @param d data * @param i input info */ StructuralUpdate(final PrimitiveType t, final int p, final Data d, final InputInfo i) { super(t, p, d, i); } /** * Returns the number of pre value shifts that are introduced by this * primitive, if applied. I.e. for an insert primitive, the value is equal * to the number of inserted nodes by this primitive. * @return number of pre value shifts */ public final int preShifts() { return shifts; } /** * Checks whether adjacent text nodes have been introduced as a result * of this update primitive. Text node adjacency can only be taken * care of if no more updates are to be expected for the left sibling * of this target node. The total number of deleted/inserted nodes * on the preceding axis of this target node is given recalculate the * actual pre value of this target. * * @param c pre value shifts introduced by updates on the preceding sibling * axis of this target node * @return adjacent text nodes have been found and merged */ public abstract boolean adjacentTexts(final int c); /** * Merges two adjacent text nodes in a database. The two node arguments must * be sorted in ascending order, otherwise the text of the two nodes is * concatenated in the wrong order. * @param d data reference * @param a node pre value * @param b node pre value * @return true if nodes have been merged */ static boolean mergeTexts(final Data d, final int a, final int b) { // some pre value checks to prevent database errors final int s = d.meta.size; if(a >= s || b >= s || a < 0 || b < 0) return false; if(d.kind(a) != Data.TEXT || d.kind(b) != Data.TEXT) return false; if(d.parent(a, Data.TEXT) != d.parent(b, Data.TEXT)) return false; d.update(a, Data.TEXT, concat(d.text(a, true), d.text(b, true))); d.delete(b); return true; } }