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(); }
MgByteReader* MgResourceDefinitionManager::GetResource( MgResourceIdentifier* resource, const MgDataBindingInfo* dataBindingInfo) { assert(NULL != resource); Ptr<MgByteReader> byteReader; MG_RESOURCE_SERVICE_TRY() // Get the resource. XmlDocument xmlDoc = GetDocument(*resource); string document; xmlDoc.getContent(document); // Bind the data if required. if (NULL != dataBindingInfo) { // Substitute all the tags if necessary. XmlValue tagValue; if (xmlDoc.getMetaData(MgResourceInfo::sm_metadataUri, MgResourceInfo::sm_metadataNames[MgResourceInfo::Tags], tagValue)) { STRING resourceTags; MgUtil::MultiByteToWideChar(tagValue.asString(), resourceTags); // If there is no resource tag, then just do the substitution for // the login username and password. MgTagManager tagManager(resourceTags); tagManager.SubstituteTags(*dataBindingInfo, document); } } // Create a byte reader. Ptr<MgByteSource> byteSource = new MgByteSource( (unsigned char*)document.c_str(), (INT32)document.length()); byteSource->SetMimeType(MgMimeType::Xml); byteReader = byteSource->GetReader(); MG_RESOURCE_CONTAINER_CATCH_AND_THROW(L"MgResourceDefinitionManager.GetResource") return SAFE_ADDREF((MgByteReader*)byteReader); }
void doQuery( XmlTransaction &txn, XmlManager &db, const XmlContainer &container, const std::string &query ) { //////////////////////////////////////////////////////////////////////// ////// Performs a simple query (no context) against the /////// ////// provided container. /////// //////////////////////////////////////////////////////////////////////// ///// some defensive code eliminated for clarity // // Perform the query. Result type is by default Result Document std::string fullQuery = "collection('" + container.getName() + "')" + query; try { std::cout << "Exercising query '" << fullQuery << "' " << std::endl; std::cout << "Return to continue: "; getc(stdin); XmlQueryContext context = db.createQueryContext(); XmlResults results( db.query( txn, fullQuery, context) ); XmlValue value; while( results.next(value) ) { // Obtain the value as a string and print it to stdout std::cout << value.asString() << std::endl; } std::cout << (unsigned int) results.size() << " objects returned for expression '" << fullQuery << "'\n" << std::endl; } catch(XmlException &e) { std::cerr << "Query " << fullQuery << " failed\n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } catch(std::exception &e) { std::cerr << "Query " << fullQuery << " failed\n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } }
void doContextQuery( XmlTransaction &txn, XmlManager &mgr, const std::string cname, const std::string &query, XmlQueryContext &context ) { //////////////////////////////////////////////////////////////////////// ////// Performs a simple query (with context) against the /////// ////// provided container. /////// //////////////////////////////////////////////////////////////////////// ///// some defensive code eliminated for clarity // // Perform the query. Result type is by default Result Document std::string fullQuery = "collection('" + cname + "')" + query; try { std::cout << "Exercising query '" << fullQuery << "' " << std::endl; std::cout << "Return to continue: "; getc(stdin); std::cout << "\n"; XmlResults results( mgr.query(txn, fullQuery, context ) ); XmlValue value; while(results.next(value)) { // Get the document's name and print it to the console XmlDocument theDocument = value.asDocument(); std::cout << "Document name: " << theDocument.getName() << std::endl; std::cout << value.asString() << std::endl; } std::cout << (unsigned int)results.size() << " objects returned for expression '" << fullQuery << "'\n" << std::endl; } //Catches XmlException catch(std::exception &e) { std::cerr << "Query " << fullQuery << " failed\n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } }
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; }
void AddDocumentCommand::execute(Args &args, Environment &env) { if ((args.size() < 3) || (args.size() > 4)){ throw CommandException("Wrong number of arguments"); } env.testContainer(); env.deleteResults(); if ((args.size() == 4) && (args[3] == "q")) { if(env.txn()) { XmlTransaction myTxn = env.childTransaction(); env.results() = new XmlResults( env.db().query(myTxn, args[2], env.context())); XmlValue value; while(env.results()->next(value)) { string v = value.asString(); string name = env.container()-> putDocument(myTxn, args[1], v, env.uc(), DBXML_GEN_NAME); if(env.verbose()) cout << "Document added, name = " << name << endl; } myTxn.commit(); } else { env.results() = new XmlResults(env.db().query(args[2], env.context())); XmlValue value; while(env.results()->next(value)) { string v = value.asString(); string name = env.container()-> putDocument(args[1], v, env.uc(), DBXML_GEN_NAME); if(env.verbose()) cout << "Document added, name = " << name << endl; } } } else { // by string or by file bool byString = true; if (args.size() == 4 && args[3] == "f") byString = false; XmlDocument doc = env.db().createDocument(); doc.setName(args[1]); if (byString) doc.setContent(args[2]); else { XmlInputStream *is = env.db().createLocalFileInputStream(args[2]); doc.setContentAsXmlInputStream(is); } if(env.txn()) { XmlTransaction myTxn = env.childTransaction(); env.container()->putDocument(myTxn, doc, env.uc()); myTxn.commit(); } else { env.container()->putDocument(doc, env.uc()); } // put doc content in last results XmlResults res = env.db().createResults(); res.add(XmlValue(doc)); env.results() = new XmlResults(res); if(env.verbose()) cout << "Document added, name = " << args[1] << endl; } }
/** * @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; }
/////////////////////////////////////////////////////////////////////////////// /// \brief /// Packages the specified resource. /// void MgLibraryResourceContentManager::PackageResource(MgResourceIdentifier& resource, MgResourcePackageMaker& packageMaker) { ACE_ASSERT(resource.IsFolder()); MG_RESOURCE_SERVICE_TRY() string resourcePathname; MgUtil::WideCharToMultiByte(resource.ToString(), resourcePathname); // Set up an XQuery. XmlManager& xmlMan = m_container.getManager(); XmlQueryContext queryContext = xmlMan.createQueryContext(); string query; if (m_repositoryMan.m_currUserIsAdmin) { queryContext.setEvaluationType(XmlQueryContext::Lazy); query = "collection('"; } else { queryContext.setEvaluationType(XmlQueryContext::Eager); query = "for $i in collection('"; } query += m_container.getName(); query += "')"; query += "/*[starts-with(dbxml:metadata('dbxml:name'),'"; query += resourcePathname; if (m_repositoryMan.m_currUserIsAdmin) { query += "')]"; } else { query += "')] order by dbxml:metadata('dbxml:name', $i) return $i"; } // Execute the XQuery. XmlResults results = IsTransacted() ? xmlMan.query(GetXmlTxn(), query, queryContext, 0) : xmlMan.query(query, queryContext, 0); MgLibraryRepositoryManager& libraryRepositoryMan = (MgLibraryRepositoryManager&)m_repositoryMan; MgResourceDataFileManager* dataFileMan = libraryRepositoryMan.GetResourceDataFileManager(); ACE_ASSERT(NULL != dataFileMan); MgResourceDataStreamManager* dataStreamMan = libraryRepositoryMan.GetResourceDataStreamManager(); ACE_ASSERT(NULL != dataStreamMan); // Get the resources MgResourceIdentifier currResource; XmlValue xmlValue; while (results.next(xmlValue)) { // Note that the permission checks were already done at the time we // packaged the resource headers. const XmlDocument& xmlDoc = xmlValue.asDocument(); currResource.SetResource(MgUtil::MultiByteToWideChar(xmlDoc.getName())); // Package the resource content. if (!packageMaker.PackageResourceContent(currResource, xmlDoc)) { // The current user has no read permission to this resource. continue; } // Skip packaging resource data if there is no resource tag. XmlValue tagValue; if (!xmlDoc.getMetaData(MgResourceInfo::sm_metadataUri, MgResourceInfo::sm_metadataNames[MgResourceInfo::Tags], tagValue)) { continue; } STRING resourceTags; MgUtil::MultiByteToWideChar(tagValue.asString(), resourceTags); // Get the file path if it exists. MgTagManager tagMan(resourceTags); STRING filePath; MgTagInfo filePathTag; if (tagMan.GetTag(MgResourceTag::DataFilePath, filePathTag, false)) { filePath = dataFileMan->GetResourceDataFilePath(); filePath += filePathTag.GetAttribute(MgTagInfo::TokenValue); filePath += L"/"; } // Enumerate the resource data. MgTagMap& tagMap = tagMan.GetTagMap(); for (MgTagMap::const_iterator i = tagMap.begin(); i != tagMap.end(); ++i) { CREFSTRING dataName = (*i).first; // Skip the reserved tags. if (tagMan.IsReservedTag(dataName)) { continue; } // Get the resource data. const MgTagInfo& tagInfo = (*i).second; CREFSTRING mimeType = tagInfo.GetAttribute(MgTagInfo::MimeType); CREFSTRING dataType = tagInfo.GetAttribute(MgTagInfo::StorageType); Ptr<MgByteReader> byteReader; if (MgResourceDataType::File == dataType) { ACE_ASSERT(!filePath.empty()); STRING pathname = filePath; pathname += dataName; byteReader = dataFileMan->GetResourceData(pathname, mimeType); } else if (MgResourceDataType::Stream == dataType) { string dataKey; MgUtil::WideCharToMultiByte( tagInfo.GetAttribute(MgTagInfo::TokenValue), dataKey); byteReader = dataStreamMan->GetResourceData(dataKey, dataName, mimeType); } else if (MgResourceDataType::String == dataType) { string data; MgUtil::WideCharToMultiByte( tagInfo.GetAttribute(MgTagInfo::TokenValue), data); Ptr<MgByteSource> byteSource = new MgByteSource( (BYTE_ARRAY_IN)data.c_str(), (INT32)data.length()); byteSource->SetMimeType(mimeType); byteReader = byteSource->GetReader(); } else { throw new MgInvalidResourceDataTypeException( L"MgLibraryResourceContentManager.PackageResource", __LINE__, __WFILE__, NULL, L"", NULL); } // Package the resource data. packageMaker.PackageResourceData(currResource, byteReader, dataName, dataType); } } MG_RESOURCE_SERVICE_CATCH_AND_THROW(L"MgLibraryResourceContentManager.PackageResource") }