Search in sources :

Example 6 with MutableDocumentSet

use of org.exist.dom.persistent.MutableDocumentSet in project exist by eXist-db.

the class FunIdRef method eval.

/**
 * @see org.exist.xquery.Expression#eval(Sequence, Item)
 */
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    if (getArgumentCount() < 1) {
        throw new XPathException(this, ErrorCodes.XPST0017, "function id requires one argument");
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    Sequence result;
    boolean processInMem = false;
    final Expression arg = getArgument(0);
    final Sequence idrefval = arg.eval(contextSequence);
    if (idrefval.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        String nextId;
        DocumentSet docs = null;
        if (getArgumentCount() == 2) {
            // second argument should be a node, whose owner document will be
            // searched for the id
            final Sequence nodes = getArgument(1).eval(contextSequence);
            if (nodes.isEmpty()) {
                throw new XPathException(this, ErrorCodes.XPDY0002, "no node or context item for fn:idref");
            }
            if (!Type.subTypeOf(nodes.itemAt(0).getType(), Type.NODE)) {
                throw new XPathException(this, ErrorCodes.XPTY0004, "fn:idref() argument is not a node");
            }
            NodeValue node = (NodeValue) nodes.itemAt(0);
            if (node.getImplementationType() == NodeValue.IN_MEMORY_NODE) // TODO : how to enforce this ?
            // If $node, or the context item if the second argument is omitted,
            // is a node in a tree whose root is not a document node [err:FODC0001] is raised                    processInMem = true;
            {
                processInMem = true;
            } else {
                MutableDocumentSet ndocs = new DefaultDocumentSet();
                ndocs.add(((NodeProxy) node).getOwnerDocument());
                docs = ndocs;
            }
            contextSequence = node;
        } else if (contextSequence == null) {
            throw new XPathException(this, ErrorCodes.XPDY0002, "no context item specified");
        } else if (!Type.subTypeOf(contextSequence.getItemType(), Type.NODE)) {
            throw new XPathException(this, ErrorCodes.XPTY0004, "context item is not a node");
        } else {
            if (contextSequence.isPersistentSet()) {
                docs = contextSequence.toNodeSet().getDocumentSet();
            } else {
                processInMem = true;
            }
        }
        if (processInMem) {
            result = new ValueSequence();
        } else {
            result = new ExtArrayNodeSet();
        }
        for (final SequenceIterator i = idrefval.iterate(); i.hasNext(); ) {
            nextId = i.nextItem().getStringValue();
            if (nextId.isEmpty()) {
                continue;
            }
            if (XMLNames.isNCName(nextId)) {
                if (processInMem) {
                    getIdRef(result, contextSequence, nextId);
                } else {
                    getIdRef((NodeSet) result, docs, nextId);
                }
            }
        }
    }
    result.removeDuplicates();
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) SequenceIterator(org.exist.xquery.value.SequenceIterator) XPathException(org.exist.xquery.XPathException) Expression(org.exist.xquery.Expression) ValueSequence(org.exist.xquery.value.ValueSequence) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) DocumentSet(org.exist.dom.persistent.DocumentSet) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet)

Example 7 with MutableDocumentSet

use of org.exist.dom.persistent.MutableDocumentSet in project exist by eXist-db.

the class AbstractUpdateTest method update.

@Test
public final void update() throws EXistException, DatabaseConfigurationException, LockException, SAXException, PermissionDeniedException, IOException, ParserConfigurationException, XPathException {
    BrokerPool.FORCE_CORRUPTION = true;
    BrokerPool pool = startDb();
    try {
        final TransactionManager transact = pool.getTransactionManager();
        try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
            final DocumentImpl doc = init(broker, transact);
            final MutableDocumentSet docs = new DefaultDocumentSet();
            docs.add(doc);
            doUpdate(broker, transact, docs);
            pool.getJournalManager().get().flush(true, false);
        }
        BrokerPool.FORCE_CORRUPTION = false;
        existEmbeddedServer.restart(false);
        pool = existEmbeddedServer.getBrokerPool();
        read(pool);
    } finally {
        existEmbeddedServer.stopDb(true);
    }
}
Also used : MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) TransactionManager(org.exist.storage.txn.TransactionManager) DocumentImpl(org.exist.dom.persistent.DocumentImpl) Test(org.junit.Test)

Example 8 with MutableDocumentSet

use of org.exist.dom.persistent.MutableDocumentSet in project exist by eXist-db.

the class LocalXPathQueryService method beginProtected.

/**
 * Execute all following queries in a protected environment.
 * Protected means: it is guaranteed that documents referenced by the
 * query or the result set are not modified by other threads
 * until {@link #endProtected} is called.
 */
@Override
public void beginProtected() throws XMLDBException {
    try {
        int retries = BEGIN_PROTECTED_MAX_LOCKING_RETRIES == -1 ? -1 : BEGIN_PROTECTED_MAX_LOCKING_RETRIES - 2;
        boolean deadlockCaught;
        do {
            reservedBroker = brokerPool.get(Optional.of(user));
            deadlockCaught = false;
            MutableDocumentSet docs = null;
            try {
                final org.exist.collections.Collection coll = reservedBroker.getCollection(collection.getPathURI());
                lockedDocuments = new LockedDocumentMap();
                docs = new DefaultDocumentSet();
                coll.allDocs(reservedBroker, docs, true, lockedDocuments, LockMode.WRITE_LOCK);
                return;
            } catch (final LockException e) {
                LOG.warn("Deadlock detected. Starting over again. Docs: {}; locked: {}. Cause: {}", docs.getDocumentCount(), lockedDocuments.size(), e.getMessage());
                lockedDocuments.unlock();
                reservedBroker.close();
                deadlockCaught = true;
            } catch (final PermissionDeniedException e) {
                throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "Permission denied on document");
            }
            retries--;
        } while (deadlockCaught && retries >= -1);
    } catch (final EXistException e) {
        if (reservedBroker != null) {
            reservedBroker.close();
        }
        throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
    }
    throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "Unable to beginProtected after " + BEGIN_PROTECTED_MAX_LOCKING_RETRIES + " retries");
}
Also used : MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) LockException(org.exist.util.LockException) LockedDocumentMap(org.exist.storage.lock.LockedDocumentMap) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException)

Example 9 with MutableDocumentSet

use of org.exist.dom.persistent.MutableDocumentSet in project exist by eXist-db.

the class LocalXUpdateQueryService method updateResource.

@Override
public long updateResource(final String id, final String commands) throws XMLDBException {
    return this.<Long>withDb((broker, transaction) -> {
        final long start = System.currentTimeMillis();
        final MutableDocumentSet docs = this.<MutableDocumentSet>read(broker, transaction, collection.getPathURI()).apply((collection, broker1, transaction1) -> {
            MutableDocumentSet d = new DefaultDocumentSet();
            if (id == null) {
                d = collection.allDocs(broker1, d, true);
            } else {
                try {
                    final XmldbURI resourceURI = XmldbURI.xmldbUriFor(id);
                    try (final LockedDocument lockedDocument = collection.getDocumentWithLock(broker1, resourceURI, Lock.LockMode.READ_LOCK)) {
                        // NOTE: early release of Collection lock inline with Asymmetrical Locking scheme
                        collection.close();
                        final DocumentImpl doc = lockedDocument == null ? null : lockedDocument.getDocument();
                        if (doc == null) {
                            throw new XMLDBException(ErrorCodes.INVALID_RESOURCE, "Resource not found: " + id);
                        }
                        d.add(doc);
                    }
                } catch (final URISyntaxException e) {
                    throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage(), e);
                }
            }
            return d;
        });
        try (final Reader reader = new StringReader(commands)) {
            if (processor == null) {
                processor = new XUpdateProcessor(broker, docs);
            } else {
                processor.setBroker(broker);
                processor.setDocumentSet(docs);
            }
            final Modification[] modifications = processor.parse(new InputSource(reader));
            long mods = 0;
            for (Modification modification : modifications) {
                mods += modification.process(transaction);
                broker.flush();
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("xupdate took {}ms.", System.currentTimeMillis() - start);
            }
            return mods;
        } catch (final ParserConfigurationException | SAXException | LockException e) {
            throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage(), e);
        } finally {
            if (processor != null) {
                processor.reset();
            }
        }
    });
}
Also used : XUpdateProcessor(org.exist.xupdate.XUpdateProcessor) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) Modification(org.exist.xupdate.Modification) InputSource(org.xml.sax.InputSource) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) XMLDBException(org.xmldb.api.base.XMLDBException) Reader(java.io.Reader) StringReader(java.io.StringReader) URISyntaxException(java.net.URISyntaxException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) SAXException(org.xml.sax.SAXException) LockException(org.exist.util.LockException) LockedDocument(org.exist.dom.persistent.LockedDocument) StringReader(java.io.StringReader) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException)

Example 10 with MutableDocumentSet

use of org.exist.dom.persistent.MutableDocumentSet in project exist by eXist-db.

the class UpdateRecoverTest method store.

private void store(final BrokerPool pool) throws EXistException, PermissionDeniedException, IOException, SAXException, LockException, ParserConfigurationException, XPathException {
    final TransactionManager transact = pool.getTransactionManager();
    try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
        DocumentImpl doc;
        try (final Txn transaction = transact.beginTransaction()) {
            final Collection root = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
            assertNotNull(root);
            broker.saveCollection(transaction, root);
            final Collection test2 = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI2);
            assertNotNull(test2);
            broker.saveCollection(transaction, test2);
            broker.storeDocument(transaction, TestConstants.TEST_XML_URI, new StringInputSource(TEST_XML), MimeType.XML_TYPE, test2);
            doc = test2.getDocument(broker, TestConstants.TEST_XML_URI);
            // TODO : unlock the collection here ?
            transact.commit(transaction);
        }
        try (final Txn transaction = transact.beginTransaction()) {
            final MutableDocumentSet docs = new DefaultDocumentSet();
            docs.add(doc);
            final XUpdateProcessor proc = new XUpdateProcessor(broker, docs);
            assertNotNull(proc);
            // insert some nodes
            for (int i = 1; i <= 200; i++) {
                final String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:insert-before select=\"/products/product[1]\">" + "       <product>" + "           <description>Product " + i + "</description>" + "           <price>" + (i * 2.5) + "</price>" + "           <stock>" + (i * 10) + "</stock>" + "       </product>" + "   </xu:insert-before>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                modifications[0].process(transaction);
                proc.reset();
            }
            // add attribute
            for (int i = 1; i <= 200; i++) {
                final String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:append select=\"/products/product[" + i + "]\">" + "         <xu:attribute name=\"id\">" + i + "</xu:attribute>" + " </xu:append>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                modifications[0].process(transaction);
                proc.reset();
            }
            // replace some
            for (int i = 1; i <= 100; i++) {
                final String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:replace select=\"/products/product[" + i + "]\">" + "     <product id=\"" + i + "\">" + "         <description>Replaced product</description>" + "         <price>" + (i * 0.75) + "</price>" + "     </product>" + " </xu:replace>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                long mods = modifications[0].process(transaction);
                proc.reset();
            }
            // remove some
            for (int i = 1; i <= 100; i++) {
                final String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:remove select=\"/products/product[last()]\"/>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                modifications[0].process(transaction);
                proc.reset();
            }
            for (int i = 1; i <= 100; i++) {
                final String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:append select=\"/products\">" + "       <product>" + "           <xu:attribute name=\"id\"><xu:value-of select=\"count(/products/product) + 1\"/></xu:attribute>" + "           <description>Product " + i + "</description>" + "           <price>" + (i * 2.5) + "</price>" + "           <stock>" + (i * 10) + "</stock>" + "       </product>" + "   </xu:append>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                final Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                modifications[0].process(transaction);
                proc.reset();
            }
            // rename element "description" to "descript"
            String xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:rename select=\"/products/product/description\">descript</xu:rename>" + "</xu:modifications>";
            proc.setBroker(broker);
            proc.setDocumentSet(docs);
            Modification[] modifications = proc.parse(new InputSource(new StringReader(xupdate)));
            assertNotNull(modifications);
            modifications[0].process(transaction);
            proc.reset();
            // update attribute values
            for (int i = 1; i <= 200; i++) {
                xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:update select=\"/products/product[" + i + "]/@id\">" + i + "u</xu:update>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                long mods = modifications[0].process(transaction);
                proc.reset();
            }
            // append new element to records
            for (int i = 1; i <= 200; i++) {
                xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:append select=\"/products/product[" + i + "]\">" + "       <date><xu:value-of select=\"current-dateTime()\"/></date>" + "   </xu:append>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                modifications[0].process(transaction);
                proc.reset();
            }
            // update element content
            for (int i = 1; i <= 200; i++) {
                xupdate = "<xu:modifications version=\"1.0\" xmlns:xu=\"http://www.xmldb.org/xupdate\">" + "   <xu:update select=\"/products/product[" + i + "]/price\">19.99</xu:update>" + "</xu:modifications>";
                proc.setBroker(broker);
                proc.setDocumentSet(docs);
                modifications = proc.parse(new InputSource(new StringReader(xupdate)));
                assertNotNull(modifications);
                long mods = modifications[0].process(transaction);
                proc.reset();
            }
            transact.commit(transaction);
        }
    }
}
Also used : XUpdateProcessor(org.exist.xupdate.XUpdateProcessor) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) Modification(org.exist.xupdate.Modification) StringInputSource(org.exist.util.StringInputSource) InputSource(org.xml.sax.InputSource) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) Txn(org.exist.storage.txn.Txn) DocumentImpl(org.exist.dom.persistent.DocumentImpl) StringInputSource(org.exist.util.StringInputSource) TransactionManager(org.exist.storage.txn.TransactionManager) StringReader(java.io.StringReader) Collection(org.exist.collections.Collection)

Aggregations

DefaultDocumentSet (org.exist.dom.persistent.DefaultDocumentSet)10 MutableDocumentSet (org.exist.dom.persistent.MutableDocumentSet)10 TransactionManager (org.exist.storage.txn.TransactionManager)5 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 Txn (org.exist.storage.txn.Txn)4 StringReader (java.io.StringReader)3 CollectionConfigurationManager (org.exist.collections.CollectionConfigurationManager)3 BrokerPool (org.exist.storage.BrokerPool)3 DBBroker (org.exist.storage.DBBroker)3 LockException (org.exist.util.LockException)3 StringInputSource (org.exist.util.StringInputSource)3 Modification (org.exist.xupdate.Modification)3 XUpdateProcessor (org.exist.xupdate.XUpdateProcessor)3 InputSource (org.xml.sax.InputSource)3 ExtArrayNodeSet (org.exist.dom.persistent.ExtArrayNodeSet)2 PermissionDeniedException (org.exist.security.PermissionDeniedException)2 Reader (java.io.Reader)1 URISyntaxException (java.net.URISyntaxException)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 EXistException (org.exist.EXistException)1