StructuralStatsDatabase::StructuralStatsDatabase(DB_ENV *env, Transaction *txn, const std::string &name, const ContainerConfig &config, bool usingCDB) : db_(env, name, "", structural_stats_name, DEFAULT_CONFIG), inMemory_(false) { // child txn is required because of [#16136] -- a DB issue // the requires we close failed transactional opens *after* // a commit or abort (issue is 4.6.x only but safe for 4.7+) TransactionGuard txnGuard; Transaction *child = 0; if (txn != 0 && !usingCDB) { child = txn->createChildInternal(txn->getFlags()); txnGuard = child; } int err = db_.open((child ? child : txn), DB_BTREE, config); txnGuard.commit(); if (err != 0) { if (err == EINVAL) err = ENOENT; // 4.4 will return EINVAL for // non-existent in-memory DBs if (err != ENOENT && txn) txn->abort(); // unconditionally cleanup -- ignore errors db_.close(0); if(err == EEXIST) throw XmlException( XmlException::CONTAINER_EXISTS, db_strerror(err)); throw XmlException(err); // this creates a DB error } }
SyntaxDatabase::SyntaxDatabase(const Syntax *syntax, DB_ENV *env, Transaction *txn, const std::string &name, bool nodesIndexed, const ContainerConfig &flags, bool usingCDB) : syntax_(syntax), environment_(env), containerName_(name), index_(new IndexDatabase(env, name, index_name + syntax->getName(), syntax, DEFAULT_CONFIG)), statistics_(new IndexDatabase(env, name, statistics_name + syntax->getName(), syntax, DEFAULT_CONFIG)) { int err = 0; try { // child txn is required because of [#16136] -- a DB issue // the requires we close failed transactional opens *after* // a commit or abort (issue is 4.6.x only but safe for 4.7+) TransactionGuard txnGuard; Transaction *child = 0; if (txn != 0 && !usingCDB) { child = txn->createChildInternal(txn->getFlags()); txnGuard = child; } // Open the Db objects err = index_->open((child ? child : txn), /*duplicates*/true, nodesIndexed, flags); if(err == 0) err = statistics_->open((child ? child : txn), /*duplicates*/false, nodesIndexed, flags); txnGuard.commit(); } catch (XmlException &xe) { err = xe.getExceptionCode(); } if (err != 0) { if (err == EINVAL) err = ENOENT; // 4.4 will return EINVAL for // non-existent in-memory DBs if (err != ENOENT && txn) txn->abort(); // unconditionally cleanup -- ignore errors try { index_->close(0); } catch (...) {} if(err == EEXIST) throw XmlException( XmlException::CONTAINER_EXISTS, db_strerror(err)); throw XmlException(err); // this creates a DB error } }
Results *QueryExpression::execute(Transaction *txn, Value *contextItem, XmlQueryContext &context, u_int32_t flags) { if (contextItem && (contextItem->getType() == XmlValue::BINARY)) throw XmlException(XmlException::INVALID_VALUE, "XmlQueryExpression::execute: context item cannot be a binary value"); // Count query INCR(Counters::num_queryExec); XmlManager &mgr = ((QueryContext&)context).getManager(); // NOTE: LazyDIResults::next() catches all query exceptions. // If Eager resulst are ever changed to not be implemented in terms // of Lazy results, that code needs to catch exceptions as well // The timer, however, is never used for purely lazy queries, as // there is no control over iteration. if(isUpdating()) { // Auto-transact and execute an updating query TransactionGuard txnGuard; if(txn != 0 || (flags & DBXML_NO_AUTO_COMMIT) == 0) { txn = Transaction::autoTransact(txn, mgr, txnGuard, ((Manager&)mgr).isTransactedEnv(), ((Manager&)mgr).isCDBEnv()); } flags &= ~DBXML_NO_AUTO_COMMIT; { XmlResults res(new LazyDIResults(context, contextItem, *this, txn, flags)); res.hasNext(); // Executes the update } txnGuard.commit(); return new ValueResults(mgr); } Results *ret = new LazyDIResults(context, contextItem, *this, txn, flags & ~DBXML_NO_AUTO_COMMIT); if(context.getEvaluationType() == XmlQueryContext::Eager) { ret = new ValueResults(ret, mgr, txn); } return ret; }