コード例 #1
0
///////////////////////////////////////////////////////////////////////////////
/// \brief
/// Checks to see if the specified resource exists.
///
bool MgResourceDefinitionManager::ResourceExists(const string& mbResourcePathname)
{
    bool found = false;

    MG_RESOURCE_SERVICE_TRY()

    XmlManager& xmlManager = m_container.getManager();
    XmlQueryContext queryContext = xmlManager.createQueryContext();
    XmlResults results = IsTransacted() ?
        m_container.lookupIndex(GetXmlTxn(), queryContext,
            DbXml::metaDataNamespace_uri, DbXml::metaDataName_name,
            "unique-node-metadata-equality-string",
            XmlValue(mbResourcePathname), 0) :
        m_container.lookupIndex(queryContext,
            DbXml::metaDataNamespace_uri, DbXml::metaDataName_name,
            "unique-node-metadata-equality-string",
            XmlValue(mbResourcePathname), 0);

    if (results.size() > 0)
    {
        assert(1 == results.size());
        found = true;
    }

    MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgResourceDefinitionManager.ResourceExists")

    return found;
}
コード例 #2
0
std::string getValue( XmlTransaction &txn, XmlManager &mgr, const XmlDocument &document,
					 const std::string &XPath, XmlQueryContext &context )
{
	/////////////////////////////////////////////////////////////////////////////////
	///////////    Return specific information from a document. /////////////////////
	///////////   !!!!!! Assumes a result set of size 1 !!!!!!! /////////////////////
	/////////////////////////////////////////////////////////////////////////////////

	// Exception handling omitted....

	//Perform the query
	XmlQueryExpression doc_expr = mgr.prepare(txn, XPath, context);
	XmlResults result = doc_expr.execute( txn, XmlValue(document), context);

	//We require a result set size of 1.
	assert( result.size() == 1 );

	//Get the value. If we allowed the result set to be larger than size 1,
	//we would have to loop through the results, processing each as is
	//required by our application.
	XmlValue value;
	result.next(value);

	return value.asString();

}
コード例 #3
0
bool XmlQueryContext::getVariableValue(const string &name,
				       XmlValue &value) const
{
	CHECK_POINTER;

	XmlResults results;
	bool success = queryContext_->getVariableValue(name, results);
	if(!success) return false;

	if(results.size() > 1) {
		throw XmlException(XmlException::INVALID_VALUE,
			"Variable has more than one value assigned to it");
	}

	results.reset();
	results.next(value);

	return true;
}
コード例 #4
0
ファイル: queryTxn.cpp プロジェクト: cajus/dbxml-debian
int
main(int argc, char **argv)
{
	// This program uses a named container, which will apear
	// on disk
	std::string containerName = "people.dbxml";
	std::string content = "<people><person><name>joe</name></person><person><name>mary</name></person></people>";
	std::string docName = "people";
	// Note that the query uses a variable, which must be set
	// in the query context
	std::string queryString =
		"collection('people.dbxml')/people/person[name=$name]";
	std::string environmentDir = ".";

	// Berkeley DB environment flags
	u_int32_t envFlags = DB_RECOVER|DB_CREATE|DB_INIT_MPOOL|
		DB_INIT_LOCK|DB_INIT_TXN|DB_INIT_LOG;
	// Berkeley DB cache size (25 MB).  The default is quite small
	u_int32_t envCacheSize = 25*1024*1024;

	// argument parsing should really use getopt(), but
	// avoid it for platform-independence
	if (argc == 3) {
		if (std::string(argv[1]) != std::string("-h"))
			usage(argv[0]);
		environmentDir = argv[2];
	} else if (argc != 1)
		usage(argv[0]);

	// Create and open a Berkeley DB Transactional Environment.
	int dberr;
	DB_ENV *dbEnv = 0;
	dberr = db_env_create(&dbEnv, 0);
	if (dberr == 0) {
		dbEnv->set_cachesize(dbEnv, 0, envCacheSize, 1);
		dbEnv->set_errcall(dbEnv, errcall); // set error callback
		dbEnv->set_lk_detect(dbEnv, DB_LOCK_DEFAULT); // handle deadlocks
		dberr = dbEnv->open(dbEnv, environmentDir.c_str(), envFlags, 0);
	}
	if (dberr) {
		std::cout << "Unable to create environment handle due to the following error: " <<
			db_strerror(dberr) << std::endl;
		if (dbEnv) dbEnv->close(dbEnv, 0);
		return -1;
	}

	try {
		// All BDB XML programs require an XmlManager instance.
		// Create it from the DbEnv
		XmlManager mgr(dbEnv, DBXML_ADOPT_DBENV);

		// Because the container will exist on disk, remove it
		// first if it exists
		if (mgr.existsContainer(containerName))
			mgr.removeContainer(containerName);

		/* Create a container that is transactional.  The container
		* type is NodeContainer, which is the default container type,
		* and the index is on nodes, which is the default for a
		* NodeContainer container.  XmlContainerConfig can be used
		* to set the container type and index type.
		*/
		XmlContainerConfig config;
		config.setTransactional(true);
		XmlContainer cont = mgr.createContainer(
			containerName,
			config);

		// All Container modification operations need XmlUpdateContext
		XmlUpdateContext uc = mgr.createUpdateContext();

		// The following putDocument call will auto-transact
		// and will abort/cleanup if the operation deadlocks or
		// otherwise fails
		cont.putDocument(docName, content, uc);

		// Querying requires an XmlQueryContext
		XmlQueryContext qc = mgr.createQueryContext();

		// Add a variable to the query context, used by the query
		qc.setVariableValue("name", "mary");

		// Use try/catch and while to handle deadlock/retry
		int retry = 0;
		while (retry < 5) { // hard-code 5 retries
			// Create a new transaction for the query
			XmlTransaction txn = mgr.createTransaction();

			try {
				// o Note the passing of txn to both methods
				// o Often the XmlQueryExpression object will be created and
				// saved for reuse in order to amortize the cost of parsing a query
				XmlQueryExpression expr = mgr.prepare(txn, queryString, qc);
				XmlResults res = expr.execute(txn, qc);

				// Note use of XmlQueryExpression::getQuery() and
				// XmlResults::size()
				std::cout << "The query, '" << expr.getQuery() << "' returned " <<
					(unsigned int)res.size() << " result(s)" << std::endl;

				// Process results -- just print them
				XmlValue value;
				std::cout << "Result: " << std::endl;
				while (res.next(value)) {
					std::cout << "\t" << value.asString() << std::endl;
				}

				// done with the transaction
				txn.commit();
				break;
			} catch (XmlException &x) {
				txn.abort(); // unconditional
				if ((x.getExceptionCode() == XmlException::DATABASE_ERROR) &&
					(x.getDbErrno() == DB_LOCK_DEADLOCK)) {
						++retry;
						continue; // try again
				}
				throw; // re-throw -- not deadlock
			}
		}
		// In C++, resources are released as objects go out
		// of scope.
	} catch (XmlException &xe) {
		std::cout << "XmlException: " << xe.what() << std::endl;
	}

	return 0;
}
コード例 #5
0
void MgResourceDefinitionManager::DeleteResource(
    MgResourceIdentifier* resource, bool strict)
{
    assert(NULL != resource);

    MG_RESOURCE_SERVICE_TRY()

    string resourcePathname;
    MgUtil::WideCharToMultiByte(resource->ToString(), resourcePathname);

    // Set up an XQuery.

    string query;

    if (resource->IsFolder())
    {
        query  = "for $i in collection('";
        query += m_container.getName();
        query += "')";
        query += "/*[starts-with(dbxml:metadata('dbxml:name'),'";
        query += resourcePathname;
        query += "')]";
        query += " order by dbxml:metadata('dbxml:name', $i) descending return $i";
    }
    else
    {
        query  = "collection('";
        query += m_container.getName();
        query += "')";
        query += "/*[dbxml:metadata('dbxml:name')='";
        query += resourcePathname;
        query += "']";
    }

    // Execute the XQuery.

    XmlManager& xmlManager = m_container.getManager();
    XmlQueryContext queryContext = xmlManager.createQueryContext();
    queryContext.setNamespace(MgResourceInfo::sm_metadataPrefix,
        MgResourceInfo::sm_metadataUri);
    XmlResults results = IsTransacted() ?
        xmlManager.query(GetXmlTxn(), query, queryContext, 0) :
        xmlManager.query(query, queryContext, 0);

    if (0 == results.size())
    {
        if (!strict || (IsResourceContentManager() && resource->IsFolder()))
        {
            return;
        }
        else
        {
            m_repositoryMan.ThrowResourceNotFoundException(*resource,
                L"MgResourceDefinitionManager.DeleteResource",
                __LINE__, __WFILE__);
        }
    }

    // Delete the resources.

    MgResourceIdentifier currResource;
    XmlUpdateContext updateContext = xmlManager.createUpdateContext();
    XmlValue xmlValue;

    while (results.next(xmlValue))
    {
        XmlDocument xmlDoc = xmlValue.asDocument();

        currResource.SetResource(MgUtil::MultiByteToWideChar(xmlDoc.getName()));

        if (!currResource.IsRoot())
        {
            DeleteDocument(currResource, xmlDoc, updateContext);
        }
    }

    if (!resource->IsRoot())
    {
        m_repositoryMan.UpdateDateModifiedResourceSet(resource->GetFullPath(true));
    }

    MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgResourceDefinitionManager.DeleteResource")
}