Example #1
0
int DocumentDatabase::removeContentAndIndex(const Document &document,
					    UpdateContext &context,
					    KeyStash &stash,
					    bool updateStats)
{
	Indexer &indexer = context.getIndexer();
	OperationContext &oc = context.getOperationContext();

	// Index the document
	IndexSpecification &index = context.getIndexSpecification();
	index.set(Index::INDEXER_DELETE);

	indexer.indexMetaData(index, document, stash, /*checkModified*/false);
	ScopedPtr<NsPushEventSource>
		source(document.getContentAsEventSource(
			       oc.txn(), /*needsValidation*/false,
			       indexer.getContainer()->nodesIndexed()));
	if (source.get()) {
		indexer.initIndexContent(index, document.getID(),
					 source.get(), stash, updateStats,
					 false, /*isDelete*/true);
		source.get()->start();
	}

	// Delete the content
	deleteID(oc, document.getID()); // a no-op
	document.getID().setDbtFromThis(oc.key());
	int err = content_.del(oc.txn(), &oc.key(), 0);
	if (err == DB_NOTFOUND)
		err = 0; // no-content doc
	
	return err;
}
Example #2
0
int DocumentDatabase::updateContentAndIndex(Document &new_document,
					    UpdateContext &context,
					    KeyStash &stash, bool validate,
					    bool updateStats)
{
	OperationContext &oc = context.getOperationContext();
	DocID id = new_document.getID();
	Indexer &indexer = context.getIndexer();
	IndexSpecification &index = context.getIndexSpecification();
	int err = 0;
	bool resetId = false;

	// Add DB_RMW if transacted to reduce deadlocks
	u_int32_t flags =  ((oc.txn() && !content_.isCDBEnv()) ? DB_RMW : 0);
	
	// Check to see if the old document exists, first
	// If ID is non-zero, let's trust it.  If not, get by name.
	// Retrieve the old document
	XmlDocument old_document;
	if (id == 0) {
		// will throw if name is bad or doc doesn't exist
		err = indexer.getContainer()->getDocument(
			oc, new_document.getName(), old_document, flags);
		if (err == 0) {
			id = ((Document&)old_document).getID();
			new_document.getIDToSet() = id;
			resetId = true;
		}
	} else {
		err = indexer.getContainer()->getDocument(
			oc, id, old_document, flags);
	}
	if(err != 0) return err;
	
	// Index the new document
	indexer.indexMetaData(index, new_document, stash, true);
	if(new_document.isContentModified()) {
		// Will need the Dbt later, so get it now.  This also
		// allows the content to be used more than once in case
		// definitiveContent_ is INPUTSTREAM
		(void) new_document.getContentAsDbt();
		// use private method that explicitly assumes Dbt content
		ScopedPtr<NsPushEventSource>
			source(new_document.dbt2events(
				       oc.txn(), /*needsValidation*/validate,
				       indexer.getContainer()->nodesIndexed()));
		if (source.get()) {
			indexer.initIndexContent(index, id,
				source.get(), stash, updateStats,
				true, /*isDelete*/false);
			source.get()->start();
		}
	}

	// Set the modified flags of the old document to the same as the
	// new document, so that when we index, we only generate keys for
	// things that have actually changed.
	MetaData::const_iterator end = new_document.metaDataEnd();
	for(MetaData::const_iterator i = new_document.metaDataBegin();
	    i != end; ++i) {
		if((*i)->isModified()) {
			const MetaDatum *md = ((Document&)old_document)
				.getMetaDataPtr((*i)->getName());
			if(md != 0) const_cast<MetaDatum*>(md)->setModified(true);
		}
	}

	// Remove the index keys for the old document
	IndexSpecification delete_index(index);
	delete_index.set(Index::INDEXER_DELETE);
	indexer.indexMetaData(delete_index, old_document, stash, true);
	if(new_document.isContentModified()) {
		ScopedPtr<NsPushEventSource>
			source(((Document&)old_document).
			       getContentAsEventSource(
				       oc.txn(),
				       /*needsValidation*/false,
				       indexer.getContainer()->nodesIndexed()));
		if (source.get()) {
			indexer.initIndexContent(delete_index, id,
				source.get(), stash, updateStats,
				false, /*isDelete*/true);
			source.get()->start();
		}
	}

	// Update the content
	if(new_document.isContentModified()) {
		OperationContext &oc = context.getOperationContext();
		id.setDbtFromThis(oc.key());
		DbXmlDbt *dbt = (DbXmlDbt*)new_document.getContentAsDbt();
		err = addContent(oc.txn(), oc.key(),dbt, 0);
	}

	if(err == 0) new_document.setContentModified(false);
	if (resetId)
		new_document.getIDToSet() = 0;
	return err;
}