void ContainerQueryCommand::execute(Args &args, Environment &env)
{
	if(args.size() != 2) {
		throw CommandException("Wrong number of arguments");
	}
	env.testContainer();
	env.deleteResults();

	std::string fullQuery = "collection('" + env.container()->getName() + "')/(" + args[1] + ")";

	u_int32_t flags = DBXML_LAZY_DOCS;
	if(env.documentProjection())
		flags |= DBXML_DOCUMENT_PROJECTION;

	if(env.txn()) {
		XmlQueryExpression expr = env.db().prepare(*env.txn(), fullQuery, env.context());
		env.results() = new XmlResults(expr.execute(*env.txn(), env.context(), flags));
	} else {
		XmlQueryExpression expr = env.db().prepare(fullQuery, env.context());
		env.results() = new XmlResults(expr.execute(env.context(), flags));
	}

	if(env.context().getEvaluationType() == XmlQueryContext::Eager) {
		if(env.verbose())
			cout << (unsigned int) env.results()->size()
			     << " objects returned for eager expression '"
			     << args[1] << "'" << endl << endl;
	} else {
		if(env.verbose())
			cout << "Lazy expression '" << args[1]
			     << "' completed" << endl << endl;
	}
}
示例#2
0
BdRetVal bdbXMLInterface::insert_new_node(container_index container_type, const string& docname, const string &node_path,
		const string &node_name, vector<string>* attr_list, const string& element)
{
	if (m_manager == NULL)
	{
		throw XmlException(XmlException::NULL_POINTER, "m_manager", __FILE__, __LINE__);
//                return xml_exception;
	}


	if (container_type >= CONT_IDX_NUM)
	{
		throw XmlException(XmlException::INVALID_VALUE, "contianer_type", __FILE__, __LINE__);
//                return para_error;
	}
	string query_string = "insert nodes ";

	query_string += "\n<" + node_name;
	if (attr_list != NULL)
	{
		for (int i=0; i < attr_list->size(); i++)
		{
			query_string += "\n"; 
			query_string += (*attr_list)[i];
		}
	}

	query_string += ">\n" + element;
	query_string += "\n</" + node_name + ">\n";

	query_string += " into "; 

	query_string += "doc(\"dbxml:/" 
		+ container_names[container_type] 
		+ ".dbxml/" 
		+ docname
		+ "\")" + node_path;

	XmlQueryContext context = m_manager->createQueryContext();

	XmlQueryExpression qe;
	XmlResults results;
	try
	{
		qe = m_manager->prepare(query_string, context);
		results = qe.execute(context);
	}
	catch (XmlException &xe)
	{
		debugOut() << "insert operation: " << query_string << endl;
		debugOut() << "insert exception: " << xe.what() << endl;
		throw xe;
	}

	return no_error;
}
示例#3
0
void ContextItemQueryCommand::execute(Args &args, Environment &env)
{
    if(args.size() != 2) {
        throw CommandException("Wrong number of arguments");
    }
    env.testResults();
    XmlResults newResults = env.db().createResults();
    env.results()->reset();

    u_int32_t flags = DBXML_LAZY_DOCS;
    if(env.documentProjection())
        flags |= DBXML_DOCUMENT_PROJECTION;

    if(env.txn()) {
        XmlQueryExpression expr = env.db().prepare(*env.txn(), args[1], env.context());

        XmlValue value;
        while(env.results()->next(value)) {
            XmlResults tmpResults = expr.execute(*env.txn(), value, env.context(), flags);

            XmlValue tmpValue;
            while(tmpResults.next(tmpValue)) {
                newResults.add(tmpValue);
            }
        }
    } else {
        XmlQueryExpression expr = env.db().prepare(args[1], env.context());

        XmlValue value;
        while(env.results()->next(value)) {
            XmlResults tmpResults = expr.execute(value, env.context(), flags);

            XmlValue tmpValue;
            while(tmpResults.next(tmpValue)) {
                newResults.add(tmpValue);
            }
        }
    }

    env.deleteResults();
    env.results() = new XmlResults(newResults);

    if(env.verbose())
        cout << (unsigned int)env.results()->size()
             << " objects returned for expression '"
             << args[1] << "'\n" << endl;
}
示例#4
0
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
/** 
 * @breif  
 * 		Get the number of nodes in a xml file
 * 
 * @Param container_type
 * 	should be value defined in container_index enum
 * @Param doc
 * 	the document name of xml file
 * @Param node_path
 * 	the xpath path of node to be search
 *
 * @Returns   
 * 		the node number
 */
int bdbXMLInterface::get_node_element_num (container_index container_type, 
		const string *doc, 
		const string *node_path)
{
	string query_string;
	int res = 0;

	if (m_manager == NULL)
	{
		throw XmlException(XmlException::NULL_POINTER, "m_manager", __FILE__, __LINE__);
//                return xml_exception;
	}


	if (container_type >= CONT_IDX_NUM)
	{
		throw XmlException(XmlException::INVALID_VALUE, "contianer_type", __FILE__, __LINE__);
//                return para_error;
	}

	if (doc == NULL)
	{
		query_string += "count(collection('"
			+ container_names[container_type]
			+ ".dbxml')";
	}
	else
	{
		query_string += "count(doc(\"dbxml:/" 
			+ container_names[container_type] 
			+ ".dbxml/" 
			+ *doc 
			+ "\")";
	}

	if (node_path != NULL)
		query_string += *node_path;

	query_string += ")";
	XmlQueryContext context = m_manager->createQueryContext();

	XmlQueryExpression qe;
	XmlResults results;
	try
	{
		qe = m_manager->prepare(query_string, context);
		results = qe.execute(context);
	}
	catch (XmlException &xe)
	{
		debugOut() << "get_node_element_num: " << query_string << endl;
		debugOut() << "get_node_element_num exception: " << xe.what() << endl;
		throw xe;
	}

	XmlValue value;
	results.next(value);
	if (value.isNumber())
		res = (int)value.asNumber();
	else
		res = 0;

	return res;
}
示例#6
0
/** 
 * @breif  
 * 	get the node content of a document as a string
 * 
 * @Param container_type
 * 	should be value defined in container_index enum
 * @Param doc
 * 	the document name of xml file
 * @Param node_path
 * 	the xpath path of node to be search
 * @Param res
 * 	output parameter, return the string value of results
 *
 * @Returns   
 * 	return no_error for success
 * 	otherwise an XmlException was throwed
 */
BdRetVal bdbXMLInterface::get_node(container_index container_type, 
		const string *doc, 
		const string *node_path, 
		string &res)
{
	string query_string;

	if (m_manager == NULL)
	{
		throw XmlException(XmlException::NULL_POINTER, "m_manager null", __FILE__, __LINE__);
	}


	if (container_type >= CONT_IDX_NUM)
	{
		throw XmlException(XmlException::INVALID_VALUE, "contianer_type", __FILE__, __LINE__);
	}

	if (doc == NULL)
	{
		query_string += "collection('"
			+ container_names[container_type]
			+ ".dbxml')";
	}
	else
	{
		query_string += "doc(\"dbxml:/" 
			+ container_names[container_type] 
			+ ".dbxml/" 
			+ *doc 
			+ "\")";
	}

	if (node_path != NULL)
		query_string += *node_path;

	XmlQueryContext context = m_manager->createQueryContext();


	XmlQueryExpression qe;
	XmlResults results;
	try
	{
		qe = m_manager->prepare(query_string, context);
		results = qe.execute(context);
	}
	catch (XmlException &xe)
	{
		debugOut() << "get node query string: " << query_string << endl;
		debugOut() << "get_node in prepare xml exception: " << xe.what() << endl;
		throw xe;
	}

	res.clear();
	XmlValue value;
	while (results.next(value))
	{
		res = value.asString();
	}

	return no_error;
}