void DbXmlUpdateFactory::applyPut(const PendingUpdate &update, DynamicContext *context) { DbXmlUri uri(update.getValue().first()-> asString(context), true); if (uri.isDbXmlScheme()) { const DbXmlNodeImpl *content = (const DbXmlNodeImpl*)update.getTarget().get(); string cname = uri.getContainerName(); string docname = uri.getDocumentName(); DbXmlConfiguration *conf = GET_CONFIGURATION(context); XmlManager &mgr = conf->getManager(); XmlContainer cont = ((Manager&)mgr).getOpenContainer(cname); if (cont.isNull()) { string msg = "Target container for fn:put -- "; msg += cname; msg += " -- must be open"; throw XmlException(XmlException::INVALID_VALUE, msg); } OperationContext &oc = conf->getOperationContext(); XmlDocument doc = mgr.createDocument(); doc.setName(docname); XmlEventReader *reader = (XmlEventReader*)content->getEventReader(context); DBXML_ASSERT(reader); doc.setContentAsEventReader(*reader); XmlUpdateContext uc = mgr.createUpdateContext(); // use internal interface to avoid additional transaction int err = ((Container &)cont).addDocumentInternal(oc.txn(), doc, uc, 0); if (err != 0) throw XmlException(err); } }
BdRetVal bdbXMLInterface::put_stringtodoc(container_index container_type, const char* content, const string& doc_name) { if (m_manager == NULL) { throw XmlException(XmlException::NULL_POINTER, "m_manager", __FILE__, __LINE__); } XmlContainer* container = NULL; container = &m_containers[container_type]; XmlUpdateContext the_context = m_manager->createUpdateContext(); try { XmlDocument the_doc = container->getDocument(doc_name); container->deleteDocument(the_doc, the_context); } catch (XmlException &e) { if (e.getExceptionCode() != XmlException::DOCUMENT_NOT_FOUND) { debugOut() << "xml excepiton" << e.what() << endl; throw XmlException(XmlException::NULL_POINTER, "xml document get error", __FILE__, __LINE__); } } try { container->putDocument(doc_name, content, the_context, 0); } catch (XmlException &e) { debugOut() << "xml exception: " << e.what() << endl; throw XmlException(XmlException::NULL_POINTER, "xml document put content error", __FILE__, __LINE__); } }
void putDocWithMyCompression(XmlManager& mgr, const string& containerName, XmlDocument& xdoc, XmlUpdateContext& uc, XmlCompression& myCompression) { // Define an unique name to use for registering the compression string compressionName = "myCompression"; // Register custom class mgr.registerCompression(compressionName.c_str(), myCompression); // Set the container type as WholedocContainer // and use the custom compression XmlContainerConfig contConf; contConf.setAllowCreate(true); contConf.setContainerType(XmlContainer::WholedocContainer); contConf.setCompressionName(compressionName.c_str()); // Create container XmlContainer cont = mgr.createContainer(containerName, contConf); // Put Document cont.putDocument(xdoc, uc); }
// -------------------------------------------------------------------- static void dict_to_dbxml_proc (map <string,Unit> dict_aa,string containerName) { XmlManager mgr; if (mgr.existsContainer(containerName)) { mgr.removeContainer(containerName); } XmlContainer cont = mgr.createContainer(containerName); XmlUpdateContext uc = mgr.createUpdateContext(); map <string,Unit>:: iterator it = dict_aa.begin (); while (it != dict_aa.end ()) { string key = (*it).first; Unit unit_aa = (*it).second; string row_aa = "<" + key + "><name>" + unit_aa["name"] \ + "</name><population>" + unit_aa["population"] \ + "</population><date_mod>" + unit_aa["date_mod"] \ + "</date_mod></" + key + ">"; cont.putDocument (key,row_aa,uc); it++; } }
BdRetVal bdbXMLInterface::create_doc(container_index container_type, const string &doc_name, const string &root, vector<string>* attr_list, int flag) { if (m_manager == NULL) { throw XmlException(XmlException::NULL_POINTER, "m_manager", __FILE__, __LINE__); } XmlContainer* container = NULL; container = &m_containers[container_type]; XmlUpdateContext the_context = m_manager->createUpdateContext(); try { XmlDocument the_doc = container->getDocument(doc_name); if ((flag & DELET_EXIST) != DELET_EXIST) { throw XmlException(XmlException::NULL_POINTER, "xml document exists", __FILE__, __LINE__); return xml_exception; } else { container->deleteDocument(the_doc, the_context); } } catch (XmlException &e) { if (e.getExceptionCode() != XmlException::DOCUMENT_NOT_FOUND) { debugOut() << "xml excepiton" << e.what() << endl; throw XmlException(XmlException::NULL_POINTER, "xml document get error", __FILE__, __LINE__); } } //创建一个新的document string content = "<?xml version=\"1.0\"?>"; content += "\n<" + root + ">"; if (attr_list != NULL) { for (int i=0; i < attr_list->size(); i++) { content += "\n"; content += (*attr_list)[i]; } } content += "\n</" + root + ">"; try { container->putDocument(doc_name, content, the_context, 0); } catch (XmlException &e) { debugOut() << "xml exception: " << e.what() << endl; throw XmlException(XmlException::NULL_POINTER, "xml document put content error", __FILE__, __LINE__); } }
BdRetVal bdbXMLInterface::delete_doc(container_index container_type, const string &doc_name) { XmlContainer* container = NULL; if (m_manager == NULL) { throw XmlException(XmlException::NULL_POINTER, "n_manager NULL", __FILE__, __LINE__); } container = &m_containers[container_type]; if (container == NULL) { throw XmlException(XmlException::NULL_POINTER, "container NULL", __FILE__, __LINE__); } XmlUpdateContext the_context = m_manager->createUpdateContext(); try{ XmlDocument the_doc = container->getDocument(doc_name); container->deleteDocument(the_doc, the_context); } catch (XmlException &xe) { throw xe; } return no_error; }
string getContent(XmlManager& mgr, const string& containerName, const string& docName) { XmlContainer cont = mgr.openContainer(containerName); string content; cont.getDocument(docName).getContent(content); return content; }
void replaceIndex( XmlContainer &container, const std::string &URI, const std::string &nodeName, const std::string &indexType, XmlTransaction &txn, XmlUpdateContext &uc) { std::cout << "Replacing index on node: " << nodeName << std::endl; try { //Retrieve the XmlIndexSpecification from the container XmlIndexSpecification idxSpec = container.getIndexSpecification( txn ); //Lets see what indexes exist on this container std::string uri, name, index; int count = 0; std::cout << "Before index add." << std::endl; while( idxSpec.next(uri, name, index) ) { // Obtain the value as a string and print it to the console std::cout << "\tFor node '" << name << "', found index: '" << index << "'." << std::endl; count ++; } std::cout << count << " indexes found." << std::endl; //Replace the indexes for the specified node idxSpec.replaceIndex( URI, nodeName, indexType ); //Set the specification back to the container container.setIndexSpecification( txn, idxSpec, uc ); //Look at the indexes again to make sure our replacement took. count = 0; idxSpec.reset(); std::cout << "After index add." << std::endl; while( idxSpec.next(uri, name, index) ) { // Obtain the value as a string and print it to the console std::cout << "\tFor node '" << name << "', found index: '" << index << "'." << std::endl; count ++; } std::cout << count << " indexes found." << std::endl; } //Catches XmlException catch(std::exception &e) { std::cerr << "Index replace failed: \n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } std::cout << "Index replaced successfully." << std::endl; }
void deleteIndex( XmlContainer &container, const std::string &URI, const std::string &nodeName, const std::string &indexType, XmlTransaction &txn, XmlUpdateContext &uc ) { std::cout << "Deleting index type: '" << indexType << "" << " from node: '" << nodeName << "'." << std::endl; try { //Retrieve the XmlIndexSpecification from the container XmlIndexSpecification idxSpec = container.getIndexSpecification( txn ); std::cout << "Before the delete, the following indexes are maintained for the container:" << std::endl; std::string uri, name, index; while( idxSpec.next(uri, name, index) ) { // Obtain the value as a string and print it to the console std::cout << "\tFor node '" << name << "', found index: '" << index << "'." << std::endl; } std::cout << "\n" << std::endl; //Delete the indexes from the specification. idxSpec.deleteIndex( URI, nodeName, indexType ); //Set the specification back to the container container.setIndexSpecification( txn, idxSpec, uc ); //Show the remaining indexes in the container, if any. std::cout << "After the delete, the following indexes exist for the container:" << std::endl; idxSpec.reset(); while( idxSpec.next(uri, name, index) ) { // Obtain the value as a string and print it to the console std::cout << "\tFor node '" << name << "', found index: '" << index << "'." << std::endl; } std::cout << "\n" << std::endl; } //Catches XmlException. catch(std::exception &e) { std::cerr << "Index delete failed: \n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } std::cout << "Index deleted successfully.\n" << std::endl; }
void putDocWithoutDefaultCompression(XmlManager& mgr, const string& containerName, XmlDocument& xdoc, XmlUpdateContext& uc) { // Set the container type as WholedocContainer and turn off // the default compression XmlContainerConfig contConf; contConf.setAllowCreate(true); contConf.setContainerType(XmlContainer::WholedocContainer); contConf.setCompressionName(XmlContainerConfig::NO_COMPRESSION); // Create container XmlContainer cont = mgr.createContainer(containerName, contConf); // Put Document cont.putDocument(xdoc, uc); }
void putDocWithDefaultCompression(XmlManager& mgr, const string& containerName, XmlDocument& xdoc, XmlUpdateContext& uc) { // Set the container type as WholedocContainer and // use the default compression XmlContainerConfig contConf; contConf.setAllowCreate(true); contConf.setContainerType(XmlContainer::WholedocContainer); // The following line is unnecessary because default compression // would take effect if user do not turn off it explicitly. contConf.setCompressionName(XmlContainerConfig::DEFAULT_COMPRESSION); // Create container XmlContainer cont = mgr.createContainer(containerName, contConf); // Put Document cont.putDocument(xdoc, uc); }
void getDetails( XmlTransaction &txn, XmlManager &mgr, const XmlContainer &container, const std::string &query, XmlQueryContext &context ) { //////////////////////////////////////////////////////////////////////// ////// Performs an query (in 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); XmlResults results( mgr.query( txn, fullQuery, context ) ); XmlValue value; std::cout << "\n\tProduct : Price : Inventory Level\n"; while( results.next(value) ) { /// Retrieve the value as a document XmlDocument theDocument = value.asDocument(); /// Obtain information of interest from the document. Note that the // wildcard in the query expression allows us to not worry about what // namespace this document uses. std::string item = getValue( txn, mgr, theDocument, "fn:string(/*/product)", context); std::string price = getValue( txn, mgr, theDocument, "fn:string(/*/inventory/price)", context); std::string inventory = getValue( txn, mgr, theDocument, "fn:string(/*/inventory/inventory)", context); std::cout << "\t" << item << " : " << price << " : " << inventory << std::endl; } std::cout << "\n"; 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); } }
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 ); } }
//Get a document from the container using the document name void doGetDocument( XmlTransaction &txn, XmlContainer &container, const std::string docname) { try { std::cout << "Getting document '" << docname << "' from the container." << std::endl; std::cout << "Return to continue: "; getc(stdin); std::cout << "\n"; //Get the document from the container using the document name XmlDocument theDocument = container.getDocument(txn, docname); std::string content; std::cout << "Document name: " << theDocument.getName() << std::endl; std::cout << theDocument.getContent(content) << std::endl; } //Catches XmlException catch(std::exception &e) { std::cerr << "Get document from container failed.\n"; std::cerr << e.what() << "\n"; txn.abort(); exit( -1 ); } }
int main(int argc, char **argv) { std::string path2DbEnv; std::string theContainer = "namespaceExampleData.dbxml"; for ( int i=1; i<argc; i++ ) { if ( argv[i][0] == '-' ) { switch(argv[i][1]) { case 'h': path2DbEnv = argv[++i]; break; default: usage(); } } } if (! path2DbEnv.length() ) usage(); // 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 (64 MB). The default is quite small u_int32_t envCacheSize = 64*1024*1024; // 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); dberr = dbEnv->open(dbEnv, path2DbEnv.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; } //Have the XmlManager adopt the db environment XmlManager mgr(dbEnv, DBXML_ADOPT_DBENV); //Configure the container to use transactions XmlContainerConfig config; config.setTransactional(true); //Open a container in the db environment XmlContainer container = mgr.openContainer(theContainer, config); //create a transaction XmlTransaction txn = mgr.createTransaction(); //create a context and declare the namespaces XmlQueryContext context = mgr.createQueryContext(); context.setNamespace( "fruits", "http://groceryItem.dbxml/fruits"); context.setNamespace( "vegetables", "http://groceryItem.dbxml/vegetables"); context.setNamespace( "desserts", "http://groceryItem.dbxml/desserts"); //Query for documents by their document names. doContextQuery( txn, mgr, container.getName(), "/*[dbxml:metadata('dbxml:name')='ZuluNut.xml']", context ); doContextQuery( txn, mgr, container.getName(), "/*[dbxml:metadata('dbxml:name')='TrifleOrange.xml']", context ); doContextQuery( txn, mgr, container.getName(), "/*[dbxml:metadata('dbxml:name')='TriCountyProduce.xml']", context ); //Get the document from the container using the document name doGetDocument(txn, container, "ZuluNut.xml"); doGetDocument(txn, container, "TrifleOrange.xml"); doGetDocument(txn, container, "TriCountyProduce.xml"); //commit the transaction txn.commit(); return 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; }
int main(int argc, char **argv) { std::string path2DbEnv; std::string theContainer = "simpleExampleData.dbxml"; for ( int i=1; i<argc; i++ ) { if ( argv[i][0] == '-' ) { switch(argv[i][1]) { case 'h': path2DbEnv = argv[++i]; break; default: usage(); } } } if (! path2DbEnv.length() ) usage(); // 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 (64 MB). The default is quite small u_int32_t envCacheSize = 64*1024*1024; // 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); dberr = dbEnv->open(dbEnv, path2DbEnv.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; } //Have the XmlManager adopt the db environment XmlManager db(dbEnv, DBXML_ADOPT_DBENV); //Configure the container to use transactions XmlContainerConfig config; config.setTransactional(true); //Open a container in the db environment XmlContainer container = db.openContainer(theContainer, config); // Get an XmlUpdateContext. Useful from a performance perspective. XmlUpdateContext updateContext = db.createUpdateContext(); //Get a transaction XmlTransaction txn = db.createTransaction(); std::string document1 = "<aDoc><title>doc1</title><color>green</color></aDoc>"; std::string document2 = "<aDoc><title>doc2</title><color>yellow</color></aDoc>"; //Add the documents XmlDocument myXMLDoc = db.createDocument(); /* Set the XmlDocument to the relevant string and then put it into the container. * Using the flag DBXML_GEN_NAME means that a generated name will be assigned * to the document if it does not have one. An exception will be thrown if * a document is inserted without a name or the DBXML_GEN_NAME flag. */ myXMLDoc.setContent( document1 ); container.putDocument(txn, myXMLDoc, updateContext, DBXML_GEN_NAME); //do it again for the second document myXMLDoc.setContent( document2 ); container.putDocument(txn, myXMLDoc, updateContext, DBXML_GEN_NAME); //Normally we would use a try/catch block to trap any exceptions. // In the catch, we should call txn->abort() to avoid leaving the // database in an indeterminate state in the event of an error. // However, this simple example avoids error handling so as to // highlite basic concepts, so that step if omitted here as well. //Commit the writes. This causes the container write operations // to be saved to the container. txn.commit(); return 0; }
/** * @breif * Put a file to dbxml database, if there already * had the file in db, check the time stamp to decide if * update needed. * * @Param pathname * the path of the file * @Param docname * The doc name in the dbxml database * * @Returns * return no_error for success * otherwise an XmlException was throwed */ BdRetVal bdbXMLInterface::add_files(const string& pathname, const string& docname) { XmlContainer* container = NULL; if (m_manager == NULL) { throw XmlException(XmlException::NULL_POINTER, "n_manager NULL", __FILE__, __LINE__); } debugOut() << "try file: " << pathname << endl; QString q_pathname(pathname.c_str()); for (int i = 0; i < CONT_IDX_NUM; i ++) { QString q_cont_name("database/"); q_cont_name += (container_names[i].c_str()); q_cont_name += "/"; if (q_pathname.contains(q_cont_name, Qt::CaseInsensitive)) { container = &m_containers[i]; } } if (container == NULL) { throw XmlException(XmlException::NULL_POINTER, "container NULL", __FILE__, __LINE__); } XmlUpdateContext the_context = m_manager->createUpdateContext(); try{ XmlDocument the_doc = container->getDocument(docname); // container->deleteDocument(the_doc, the_context); } catch (XmlException &e) { // debugOut() << "open document xml exception: " << e.what() << " file name: " << docname << endl; if (e.getExceptionCode() != XmlException::DOCUMENT_NOT_FOUND) { throw e; } } debugOut() << "putting file: " << pathname << " to container " << container->getName() << " as doc " << docname << endl; try { XmlInputStream *the_stream = m_manager->createLocalFileInputStream(pathname); container->putDocument(docname, the_stream, the_context, 0); } catch (XmlException &e) { debugOut() << "xml exception: " << e.what() << endl; throw e; } return no_error; }