Пример #1
0
  /**
   * Returns pre values.
   *
   * @param ids unique node ids
   * @param off start offset
   * @param len number of ids
   * @return sorted pre values
   */
  public final int[] pre(final int[] ids, final int off, final int len) {
    if (meta.updindex) return idmap.pre(ids, off, len);

    final IntList p = new IntList(ids.length);
    for (int i = off; i < len; ++i) p.add(preold(ids[i]));
    return p.sort().toArray();
  }
Пример #2
0
    @Override
    public void execute(final GUI gui) {
      final DialogExport dialog = new DialogExport(gui);
      if (!dialog.ok()) return;

      final IOFile root = new IOFile(dialog.path());

      // check if existing files will be overwritten
      if (root.exists()) {
        IO file = null;
        boolean overwrite = false;
        final Data d = gui.context.data();
        final IntList il = d.resources.docs();
        final int is = il.size();
        for (int i = 0; i < is; i++) {
          file = root.merge(Token.string(d.text(il.get(i), true)));
          if (file.exists()) {
            if (overwrite) {
              // more than one file will be overwritten; check remaining tests
              file = null;
              break;
            }
            overwrite = true;
          }
        }
        if (overwrite) {
          // show message for overwriting files or directories
          final String msg = file == null ? FILES_REPLACE_X : FILE_EXISTS_X;
          if (file == null) file = root;
          if (!BaseXDialog.confirm(gui, Util.info(msg, file))) return;
        }
      }
      DialogProgress.execute(gui, new Export(root.path()));
    }
Пример #3
0
 @Override
 protected void indexDelete(final int pre, final int size) {
   final boolean textI = meta.textindex, attrI = meta.attrindex;
   if (textI || attrI) {
     // collect all keys and ids
     indexBegin();
     final int l = pre + size;
     for (int p = pre; p < l; ++p) {
       final int k = kind(p);
       // consider nodes which are attribute, text, comment, or proc. instruction
       final boolean text = k == TEXT || k == COMM || k == PI;
       if (textI && text || attrI && k == ATTR) {
         final byte[] key = text(p, text);
         if (key.length <= meta.maxlen) {
           final TokenObjMap<IntList> m = text ? txtBuffer : atvBuffer;
           IntList ids = m.get(key);
           if (ids == null) {
             ids = new IntList(1);
             m.put(key, ids);
           }
           ids.add(id(p));
         }
       }
     }
     indexDelete();
   }
 }
Пример #4
0
  @Override
  protected long index(final int pre, final int id, final byte[] value, final int kind) {
    final DataAccess store;
    final TokenObjMap<IntList> map;
    if (kind == ATTR) {
      store = values;
      map = meta.attrindex ? atvBuffer : null;
    } else {
      store = texts;
      // don't index document names
      map = meta.textindex && kind != DOC ? txtBuffer : null;
    }

    // add text to map to index later
    if (meta.updindex && map != null && value.length <= meta.maxlen) {
      IntList ids = map.get(value);
      if (ids == null) {
        ids = new IntList(1);
        map.put(value, ids);
      }
      ids.add(id);
    }

    // add text to text file
    // inline integer value...
    final long v = toSimpleInt(value);
    if (v != Integer.MIN_VALUE) return v | IO.OFFNUM;

    // store text
    final long off = store.length();
    final byte[] val = COMP.get().pack(value);
    store.writeToken(off, val);
    return val == value ? off : off | IO.OFFCOMP;
  }
Пример #5
0
  /**
   * Inserts a data instance at the specified pre value. Note that the specified data instance must
   * differ from this instance.
   *
   * @param ipre value at which to insert new data
   * @param ipar parent pre value of node
   * @param clip data clip
   */
  public final void insert(final int ipre, final int ipar, final DataClip clip) {
    meta.update();

    // update value and document indexes
    if (meta.updindex) indexBegin();
    resources.insert(ipre, clip);

    final int dsize = clip.size();
    final int buf = Math.min(dsize, IO.BLOCKSIZE >> IO.NODEPOWER);
    // resize buffer to cache more entries
    buffer(buf);

    // find all namespaces in scope to avoid duplicate declarations
    final TokenMap nsScope = nspaces.scope(ipar, this);

    // loop through all entries
    final IntList preStack = new IntList();
    final NSNode nsRoot = nspaces.current();
    final HashSet<NSNode> newNodes = new HashSet<NSNode>();
    final IntList flagPres = new IntList();

    // indicates if database only contains a dummy node
    final Data data = clip.data;
    int c = 0;
    for (int dpre = clip.start; dpre < clip.end; ++dpre, ++c) {
      if (c != 0 && c % buf == 0) insert(ipre + c - buf);

      final int pre = ipre + c;
      final int dkind = data.kind(dpre);
      final int dpar = data.parent(dpre, dkind);
      // ipar < 0 if document nodes on top level are added
      final int dis = dpar >= 0 ? dpre - dpar : ipar >= 0 ? pre - ipar : 0;
      final int par = dis == 0 ? -1 : pre - dis;

      if (c == 0) nspaces.root(par, this);

      while (!preStack.isEmpty() && preStack.peek() > par) nspaces.close(preStack.pop());

      switch (dkind) {
        case DOC:
          // add document
          nspaces.prepare();
          final int s = data.size(dpre, dkind);
          doc(pre, s, data.text(dpre, true));
          meta.ndocs++;
          preStack.push(pre);
          break;
        case ELEM:
          // add element
          nspaces.prepare();
          boolean ne = false;
          if (data.nsFlag(dpre)) {
            final Atts at = data.ns(dpre);
            for (int a = 0; a < at.size(); ++a) {
              // see if prefix has been declared/ is part of current ns scope
              final byte[] old = nsScope.get(at.name(a));
              if (old == null || !eq(old, at.value(a))) {
                // we have to keep track of all new NSNodes that are added
                // to the Namespace structure, as their pre values must not
                // be updated. I.e. if an NSNode N with pre value 3 existed
                // prior to inserting and two new nodes are inserted at
                // location pre == 3 we have to make sure N and only N gets
                // updated.
                newNodes.add(nspaces.add(at.name(a), at.value(a), pre));
                ne = true;
              }
            }
          }
          byte[] nm = data.name(dpre, dkind);
          elem(
              dis,
              tagindex.index(nm, null, false),
              data.attSize(dpre, dkind),
              data.size(dpre, dkind),
              nspaces.uri(nm, true),
              ne);
          preStack.push(pre);
          break;
        case TEXT:
        case COMM:
        case PI:
          // add text
          text(pre, dis, data.text(dpre, true), dkind);
          break;
        case ATTR:
          // add attribute
          nm = data.name(dpre, dkind);
          // check if prefix already in nsScope or not
          final byte[] attPref = prefix(nm);
          // check if prefix of attribute has already been declared, otherwise
          // add declaration to parent node
          if (data.nsFlag(dpre) && nsScope.get(attPref) == null) {
            nspaces.add(
                par,
                preStack.isEmpty() ? -1 : preStack.peek(),
                attPref,
                data.nspaces.uri(data.uri(dpre, dkind)),
                this);
            // save pre value to set ns flag later for this node. can't be done
            // here as direct table access would interfere with the buffer
            flagPres.add(par);
          }
          attr(
              pre,
              dis,
              atnindex.index(nm, null, false),
              data.text(dpre, false),
              nspaces.uri(nm, false),
              false);
          break;
      }
    }
    // finalize and update namespace structure
    while (!preStack.isEmpty()) nspaces.close(preStack.pop());
    nspaces.root(nsRoot);

    if (bp != 0) insert(ipre + c - 1 - (c - 1) % buf);
    // reset buffer to old size
    buffer(1);

    // set ns flags
    for (int f = 0; f < flagPres.size(); f++) {
      final int fl = flagPres.get(f);
      table.write2(fl, 1, name(fl) | 1 << 15);
    }

    // increase size of ancestors
    int p = ipar;
    while (p >= 0) {
      final int k = kind(p);
      size(p, k, size(p, k) + dsize);
      p = parent(p, k);
    }

    if (meta.updindex) {
      // add the entries to the ID -> PRE mapping:
      idmap.insert(ipre, id(ipre), dsize);
      indexEnd();
    }

    if (!cache) updateDist(ipre + dsize, dsize);

    // propagate PRE value shifts to namespaces
    if (ipar != -1) nspaces.insert(ipre, dsize, newNodes);
  }
Пример #6
0
  /**
   * Constructor.
   *
   * @param args command-line arguments
   * @throws IOException I/O exception
   */
  public BaseX(final String... args) throws IOException {
    super(args);

    // create session to show optional login request
    session();

    console = true;
    try {
      // loop through all commands
      final StringBuilder bind = new StringBuilder();
      SerializerOptions sopts = null;
      boolean v = false, qi = false, qp = false;
      final int os = ops.size();
      for (int o = 0; o < os; o++) {
        final int c = ops.get(o);
        String val = vals.get(o);

        if (c == 'b') {
          // set/add variable binding
          if (bind.length() != 0) bind.append(',');
          // commas are escaped by a second comma
          val = bind.append(val.replaceAll(",", ",,")).toString();
          execute(new Set(MainOptions.BINDINGS, val), false);
        } else if (c == 'c') {
          // evaluate commands
          final IO io = IO.get(val);
          String base = ".";
          if (io.exists() && !io.isDir()) {
            val = io.string();
            base = io.path();
          }
          execute(new Set(MainOptions.QUERYPATH, base), false);
          execute(val);
          execute(new Set(MainOptions.QUERYPATH, ""), false);
          console = false;
        } else if (c == 'D') {
          // hidden option: show/hide dot query graph
          execute(new Set(MainOptions.DOTPLAN, null), false);
        } else if (c == 'i') {
          // open database or create main memory representation
          execute(new Set(MainOptions.MAINMEM, true), false);
          execute(new Check(val), verbose);
          execute(new Set(MainOptions.MAINMEM, false), false);
        } else if (c == 'I') {
          // set/add variable binding
          if (bind.length() != 0) bind.append(',');
          // commas are escaped by a second comma
          val = bind.append("=").append(val.replaceAll(",", ",,")).toString();
          execute(new Set(MainOptions.BINDINGS, val), false);
        } else if (c == 'o') {
          // change output stream
          if (out != System.out) out.close();
          out = new PrintOutput(val);
          session().setOutputStream(out);
        } else if (c == 'q') {
          // evaluate query
          execute(new XQuery(val), verbose);
          console = false;
        } else if (c == 'Q') {
          // evaluate file contents or string as query
          final IO io = IO.get(val);
          String base = ".";
          if (io.exists() && !io.isDir()) {
            val = io.string();
            base = io.path();
          }
          execute(new Set(MainOptions.QUERYPATH, base), false);
          execute(new XQuery(val), verbose);
          execute(new Set(MainOptions.QUERYPATH, ""), false);
          console = false;
        } else if (c == 'r') {
          // parse number of runs
          execute(new Set(MainOptions.RUNS, Strings.toInt(val)), false);
        } else if (c == 'R') {
          // toggle query evaluation
          execute(new Set(MainOptions.RUNQUERY, null), false);
        } else if (c == 's') {
          // set/add serialization parameter
          if (sopts == null) sopts = new SerializerOptions();
          final String[] kv = val.split("=", 2);
          sopts.assign(kv[0], kv.length > 1 ? kv[1] : "");
          execute(new Set(MainOptions.SERIALIZER, sopts), false);
        } else if (c == 't') {
          // evaluate query
          execute(new Test(val), verbose);
          console = false;
        } else if (c == 'u') {
          // (de)activate write-back for updates
          execute(new Set(MainOptions.WRITEBACK, null), false);
        } else if (c == 'v') {
          // show/hide verbose mode
          v ^= true;
        } else if (c == 'V') {
          // show/hide query info
          qi ^= true;
          execute(new Set(MainOptions.QUERYINFO, null), false);
        } else if (c == 'w') {
          // toggle chopping of whitespaces
          execute(new Set(MainOptions.CHOP, null), false);
        } else if (c == 'x') {
          // show/hide xml query plan
          execute(new Set(MainOptions.XMLPLAN, null), false);
          qp ^= true;
        } else if (c == 'X') {
          // show query plan before/after query compilation
          execute(new Set(MainOptions.COMPPLAN, null), false);
        } else if (c == 'z') {
          // toggle result serialization
          execute(new Set(MainOptions.SERIALIZE, null), false);
        }
        verbose = qi || qp || v;
      }
      if (console) console();
    } finally {
      quit();
    }
  }
Пример #7
0
  @Override
  protected final void parseArgs() throws IOException {
    ops = new IntList();
    vals = new StringList();

    final MainParser arg = new MainParser(this);
    while (arg.more()) {
      final char c;
      String v = null;
      if (arg.dash()) {
        c = arg.next();
        if (c == 'd') {
          // activate debug mode
          Prop.debug = true;
        } else if (c == 'b'
            || c == 'c'
            || c == 'C'
            || c == 'i'
            || c == 'I'
            || c == 'o'
            || c == 'q'
            || c == 'r'
            || c == 's'
            || c == 't' && local()) {
          // options followed by a string
          v = arg.string();
        } else if (c == 'D' && local()
            || c == 'u' && local()
            || c == 'R'
            || c == 'v'
            || c == 'V'
            || c == 'w'
            || c == 'x'
            || c == 'X'
            || c == 'z') {
          // options to be toggled
          v = "";
        } else if (!local()) {
          // client options: need to be set before other options
          if (c == 'n') {
            // set server name
            context.soptions.set(StaticOptions.HOST, arg.string());
          } else if (c == 'p') {
            // set server port
            context.soptions.set(StaticOptions.PORT, arg.number());
          } else if (c == 'P') {
            // specify password
            context.soptions.set(StaticOptions.PASSWORD, arg.string());
          } else if (c == 'U') {
            // specify user name
            context.soptions.set(StaticOptions.USER, arg.string());
          } else {
            throw arg.usage();
          }
        } else {
          throw arg.usage();
        }
      } else {
        v = arg.string().trim();
        // interpret as command file if input string ends with command script suffix
        c = v.endsWith(IO.BXSSUFFIX) ? 'c' : 'Q';
      }
      if (v != null) {
        ops.add(c);
        vals.add(v);
      }
    }
  }