Search in sources :

Example 91 with Txn

use of org.exist.storage.txn.Txn in project exist by eXist-db.

the class Insert method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.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 (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    Sequence contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    final Sequence inSeq = select.eval(contextSequence);
    /* If we try and Insert a node at an invalid location,
         * trap the error in a context variable,
         * this is then accessible from xquery via. the context extension module - deliriumsky
         * TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
         * TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt insert node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application 
         */
    if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
        // Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
        ValueSequence prevUpdateErrors = null;
        final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
        final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
        if (ctxVarObj == null) {
            prevUpdateErrors = new ValueSequence();
        } else {
            prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
        }
        prevUpdateErrors.add(new StringValue(xpe.getMessage()));
        context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
        if (!inSeq.isEmpty()) {
            // TODO: should we trap this instead of throwing an exception - deliriumsky?
            throw xpe;
        }
    }
    if (!inSeq.isEmpty()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Found: {} nodes", inSeq.getItemCount());
        }
        context.pushInScopeNamespaces();
        contentSeq = deepCopy(contentSeq);
        // start a transaction
        try (final Txn transaction = getTransaction()) {
            final StoredNode[] ql = selectAndLock(transaction, inSeq);
            final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
            final NodeList contentList = seq2nodeList(contentSeq);
            for (final StoredNode node : ql) {
                final DocumentImpl doc = node.getOwnerDocument();
                if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
                    throw new PermissionDeniedException("User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
                }
                // update the document
                if (mode == INSERT_APPEND) {
                    node.appendChildren(transaction, contentList, -1);
                } else {
                    final NodeImpl parent = (NodeImpl) getParent(node);
                    switch(mode) {
                        case INSERT_BEFORE:
                            parent.insertBefore(transaction, contentList, node);
                            break;
                        case INSERT_AFTER:
                            parent.insertAfter(transaction, contentList, node);
                            break;
                    }
                }
                doc.setLastModified(System.currentTimeMillis());
                modifiedDocuments.add(doc);
                context.getBroker().storeXMLResource(transaction, doc);
                notifier.notifyUpdate(doc, UpdateListener.UPDATE);
            }
            finishTriggers(transaction);
            // commit the transaction
            transaction.commit();
        } catch (final PermissionDeniedException | EXistException | LockException | TriggerException e) {
            throw new XPathException(this, e.getMessage(), e);
        } finally {
            unlockDocuments();
            context.popInScopeNamespaces();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : NodeImpl(org.exist.dom.persistent.NodeImpl) XPathException(org.exist.xquery.XPathException) NodeList(org.w3c.dom.NodeList) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) LockException(org.exist.util.LockException) ValueSequence(org.exist.xquery.value.ValueSequence) PermissionDeniedException(org.exist.security.PermissionDeniedException) StringValue(org.exist.xquery.value.StringValue) TriggerException(org.exist.collections.triggers.TriggerException) StoredNode(org.exist.dom.persistent.StoredNode)

Example 92 with Txn

use of org.exist.storage.txn.Txn in project exist by eXist-db.

the class Update method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.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 (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    final Sequence contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    final Sequence inSeq = select.eval(contextSequence);
    /* If we try and Update a node at an invalid location,
         * trap the error in a context variable,
         * this is then accessible from xquery via. the context extension module - deliriumsky
         * TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
         * TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt update node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application
         */
    if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
        // Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
        ValueSequence prevUpdateErrors = null;
        final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
        final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
        if (ctxVarObj == null) {
            prevUpdateErrors = new ValueSequence();
        } else {
            prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
        }
        prevUpdateErrors.add(new StringValue(xpe.getMessage()));
        context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
        if (!inSeq.isEmpty()) {
            // TODO: should we trap this instead of throwing an exception - deliriumsky?
            throw xpe;
        }
    }
    if (!inSeq.isEmpty()) {
        context.pushInScopeNamespaces();
        // start a transaction
        try (final Txn transaction = getTransaction()) {
            final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
            final StoredNode[] ql = selectAndLock(transaction, inSeq);
            for (final StoredNode node : ql) {
                final DocumentImpl doc = node.getOwnerDocument();
                if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
                    throw new XPathException(this, "User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
                }
                // update the document
                switch(node.getNodeType()) {
                    case Node.ELEMENT_NODE:
                        final NodeListImpl content = new NodeListImpl();
                        for (final SequenceIterator j = contentSeq.iterate(); j.hasNext(); ) {
                            final Item next = j.nextItem();
                            if (Type.subTypeOf(next.getType(), Type.NODE)) {
                                content.add(((NodeValue) next).getNode());
                            } else {
                                final TextImpl text = new TextImpl(next.getStringValue());
                                content.add(text);
                            }
                        }
                        ((ElementImpl) node).update(transaction, content);
                        break;
                    case Node.TEXT_NODE:
                        final ElementImpl textParent = (ElementImpl) node.getParentNode();
                        final TextImpl text = new TextImpl(contentSeq.getStringValue());
                        text.setOwnerDocument(doc);
                        textParent.updateChild(transaction, node, text);
                        break;
                    case Node.ATTRIBUTE_NODE:
                        final ElementImpl attrParent = (ElementImpl) ((Attr) node).getOwnerElement();
                        if (attrParent == null) {
                            LOG.warn("parent node not found for {}", node.getNodeId());
                            break;
                        }
                        final AttrImpl attr = (AttrImpl) node;
                        final AttrImpl attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
                        attribute.setOwnerDocument(doc);
                        attrParent.updateChild(transaction, node, attribute);
                        break;
                    default:
                        throw new XPathException(this, "unsupported node-type");
                }
                doc.setLastModified(System.currentTimeMillis());
                modifiedDocuments.add(doc);
                context.getBroker().storeXMLResource(transaction, doc);
                notifier.notifyUpdate(doc, UpdateListener.UPDATE);
            }
            finishTriggers(transaction);
            // commit the transaction
            transaction.commit();
        } catch (final LockException | EXistException | TriggerException e) {
            throw new XPathException(this, e.getMessage(), e);
        } finally {
            unlockDocuments();
            context.popInScopeNamespaces();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : NodeListImpl(org.exist.dom.NodeListImpl) XPathException(org.exist.xquery.XPathException) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) AttrImpl(org.exist.dom.persistent.AttrImpl) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) TextImpl(org.exist.dom.persistent.TextImpl) Item(org.exist.xquery.value.Item) ElementImpl(org.exist.dom.persistent.ElementImpl) SequenceIterator(org.exist.xquery.value.SequenceIterator) LockException(org.exist.util.LockException) ValueSequence(org.exist.xquery.value.ValueSequence) StringValue(org.exist.xquery.value.StringValue) TriggerException(org.exist.collections.triggers.TriggerException) StoredNode(org.exist.dom.persistent.StoredNode)

Example 93 with Txn

use of org.exist.storage.txn.Txn in project exist by eXist-db.

the class RecoveryTest2 method store.

@Test
public void store() throws DatabaseConfigurationException, EXistException, PermissionDeniedException, IOException, SAXException, BTreeException, LockException {
    BrokerPool.FORCE_CORRUPTION = true;
    final BrokerPool pool = startDb();
    final TransactionManager transact = pool.getTransactionManager();
    try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
        final Txn transaction = transact.beginTransaction()) {
        Collection root = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
        assertNotNull(root);
        broker.saveCollection(transaction, root);
        Collection test2 = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI2);
        assertNotNull(test2);
        broker.saveCollection(transaction, test2);
        DOMFile domDb = ((NativeBroker) broker).getDOMFile();
        assertNotNull(domDb);
        try (final Writer writer = new StringWriter()) {
            domDb.dump(writer);
        }
        // store some documents. Will be replaced below
        final Path dir = Paths.get(xmlDir);
        final List<Path> docs = FileUtils.list(dir);
        for (final Path f : docs) {
            broker.storeDocument(transaction, XmldbURI.create(FileUtils.fileName(f)), new InputSource(f.toUri().toASCIIString()), MimeType.XML_TYPE, test2);
        }
        transact.commit(transaction);
    }
}
Also used : Path(java.nio.file.Path) InputSource(org.xml.sax.InputSource) StringWriter(java.io.StringWriter) TransactionManager(org.exist.storage.txn.TransactionManager) Collection(org.exist.collections.Collection) Txn(org.exist.storage.txn.Txn) DOMFile(org.exist.storage.dom.DOMFile) StringWriter(java.io.StringWriter) Writer(java.io.Writer) Test(org.junit.Test)

Example 94 with Txn

use of org.exist.storage.txn.Txn in project exist by eXist-db.

the class RemoveCollectionTest method storeDocs.

private Collection storeDocs(final DBBroker broker, final TransactionManager transact) throws PermissionDeniedException, IOException, SAXException, CollectionConfigurationException, LockException, EXistException {
    Collection test;
    try (final Txn transaction = transact.beginTransaction()) {
        test = broker.getOrCreateCollection(transaction, TestConstants.TEST_COLLECTION_URI);
        assertNotNull(test);
        broker.saveCollection(transaction, test);
        transact.commit(transaction);
    }
    try (final Txn transaction = transact.beginTransaction()) {
        final TestDataGenerator generator = new TestDataGenerator("xdb", COUNT);
        final Path[] files = generator.generate(broker, test, generateXQ);
        for (final Path file : files) {
            final InputSource is = new InputSource(file.toUri().toASCIIString());
            broker.storeDocument(transaction, XmldbURI.create(file.getFileName().toString()), is, MimeType.XML_TYPE, test);
        }
        generator.releaseAll();
        transact.commit(transaction);
    }
    return test;
}
Also used : Path(java.nio.file.Path) InputSource(org.xml.sax.InputSource) Collection(org.exist.collections.Collection) Txn(org.exist.storage.txn.Txn) TestDataGenerator(org.exist.TestDataGenerator)

Example 95 with Txn

use of org.exist.storage.txn.Txn in project exist by eXist-db.

the class RemoveCollectionTest method removeResources.

public void removeResources(final BrokerPool pool) throws PermissionDeniedException, IOException, SAXException, EXistException, LockException, CollectionConfigurationException, DatabaseConfigurationException {
    final TransactionManager transact = pool.getTransactionManager();
    try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
        final Collection test = storeDocs(broker, transact);
        try (final Txn transaction = transact.beginTransaction()) {
            for (final Iterator<DocumentImpl> i = test.iterator(broker); i.hasNext(); ) {
                final DocumentImpl doc = i.next();
                broker.removeXMLResource(transaction, doc);
            }
            broker.saveCollection(transaction, test);
            transact.commit(transaction);
        }
    }
}
Also used : TransactionManager(org.exist.storage.txn.TransactionManager) Collection(org.exist.collections.Collection) Txn(org.exist.storage.txn.Txn) DocumentImpl(org.exist.dom.persistent.DocumentImpl)

Aggregations

Txn (org.exist.storage.txn.Txn)358 DBBroker (org.exist.storage.DBBroker)215 BrokerPool (org.exist.storage.BrokerPool)179 Collection (org.exist.collections.Collection)162 TransactionManager (org.exist.storage.txn.TransactionManager)129 Sequence (org.exist.xquery.value.Sequence)84 StringInputSource (org.exist.util.StringInputSource)83 Test (org.junit.Test)80 XmldbURI (org.exist.xmldb.XmldbURI)55 EXistException (org.exist.EXistException)50 PermissionDeniedException (org.exist.security.PermissionDeniedException)38 Source (org.exist.source.Source)37 StringSource (org.exist.source.StringSource)37 DocumentImpl (org.exist.dom.persistent.DocumentImpl)35 InputSource (org.xml.sax.InputSource)33 XQuery (org.exist.xquery.XQuery)32 IOException (java.io.IOException)31 LockedDocument (org.exist.dom.persistent.LockedDocument)28 InputStream (java.io.InputStream)27 Path (java.nio.file.Path)24