BerkeleyDBXML-0.6.2: Database/Berkeley/dbxml_helper.cpp
#include "dbxml_helper.h"
#include "XmlManager.hpp"
#include "XmlException.hpp"
#include <string.h>
using namespace DbXml;
using namespace std;
#define UNWRAP_DBTXN_() \
if (dbtxnp == NULL) \
dbtxn = NULL; \
else { \
dbtxn = *dbtxnp; \
if (dbtxn == NULL) return -20883; /* Haskell binding-specific error code */ \
}
#define UNWRAP_DBTXN() \
DbTxn* dbtxn; \
UNWRAP_DBTXN_()
XmlManagerInfo::XmlManagerInfo()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &attr);
}
XmlManagerInfo::~XmlManagerInfo()
{
while (queryExpressions.begin() != queryExpressions.end())
delete *queryExpressions.begin();
}
XmlQueryExpressionInfo::XmlQueryExpressionInfo(
DbXml::XmlQueryExpression qe,
XmlManagerInfo* mi)
: qe(qe), mi(mi)
{
pthread_mutex_lock(&mi->mutex);
try {
mi->queryExpressions.insert(this);
pthread_mutex_unlock(&mi->mutex);
}
catch (...) {
pthread_mutex_unlock(&mi->mutex);
throw;
}
}
XmlQueryExpressionInfo::~XmlQueryExpressionInfo()
{
pthread_mutex_lock(&mi->mutex);
try {
std::set<XmlQueryExpressionInfo*>::iterator it = mi->queryExpressions.find(this);
if (it != mi->queryExpressions.end())
mi->queryExpressions.erase(it);
pthread_mutex_unlock(&mi->mutex);
}
catch (...) {
pthread_mutex_unlock(&mi->mutex);
throw;
}
}
static int asInt(XmlException& exc)
{
int dbE = exc.getDbErrno();
if (dbE < 0)
dbE = -dbE;
return (exc.getExceptionCode() + 1) * 100000 + dbE;
}
int _xmlManager(DbEnv* dbenv, u_int32_t flags, XmlManagerInfo** mgr)
{
*mgr = new XmlManagerInfo;
try {
(*mgr)->mgr = XmlManager(dbenv, flags);
return 0;
}
catch (XmlException& exc) {
delete *mgr;
*mgr = NULL;
return asInt(exc);
}
}
void _xmlManager_close(XmlManagerInfo* mgr)
{
delete mgr;
}
int _xmlManager_openContainer(XmlManagerInfo* mgr, const char* name, u_int32_t flags,
int cType, int mode, DbXml::XmlContainer*** container)
{
try {
DbXml::XmlContainer c = mgr->mgr.openContainer(name, flags,
cType == 0 ? XmlContainer::NodeContainer : XmlContainer::WholedocContainer,
mode);
*container = new DbXml::XmlContainer*;
**container = new DbXml::XmlContainer(c);
return 0;
}
catch (XmlException& exc) {
*container = NULL;
return asInt(exc);
}
}
void _xmlContainer_delete(DbXml::XmlContainer** cont)
{
delete *cont;
delete cont;
}
void _xmlContainer_close(DbXml::XmlContainer** cont)
{
delete *cont;
*cont = NULL;
}
int _xmlManager_createTransaction(XmlManagerInfo* mgr, u_int32_t flags, DbXml::XmlTransaction** trans)
{
try {
XmlTransaction t = mgr->mgr.createTransaction(flags);
*trans = new XmlTransaction(t);
return 0;
}
catch (XmlException& exc) {
*trans = NULL;
return asInt(exc);
}
}
int _xmlManager_createTransaction_DbTxn(XmlManagerInfo* mgr, DbTxn** dbtxnp, DbXml::XmlTransaction** trans)
{
UNWRAP_DBTXN();
try {
void detach_DbTxn(DbTxn** dbtxnp); // Defined in Berkeley DB
detach_DbTxn(dbtxnp); // Detach the DbTxn so that Berkeley DB doesn't
// try to clean it up by running DbTxn_abort in
// its finalizer.
XmlTransaction t = mgr->mgr.createTransaction(dbtxn);
*trans = new XmlTransaction(t);
return 0;
}
catch (XmlException& exc) {
*trans = NULL;
return asInt(exc);
}
}
void _xmlTransaction_delete(DbXml::XmlTransaction* trans)
{
delete trans;
}
int _xmlTransaction_commit(DbXml::XmlTransaction* trans)
{
try {
trans->commit();
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlTransaction_abort(DbXml::XmlTransaction* trans)
{
try {
trans->abort();
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlContainer_getDocument(DbXml::XmlContainer** cont, DbXml::XmlTransaction* trans,
const char* key, u_int32_t flags, DbXml::XmlDocument** doc)
{
try {
XmlDocument d;
if (trans != NULL)
d = (*cont)->getDocument(*trans, key, flags);
else
d = (*cont)->getDocument(key, flags);
*doc = new XmlDocument(d);
return 0;
}
catch (XmlException& exc) {
*doc = NULL;
return asInt(exc);
}
}
char* _xmlContainer_getName(DbXml::XmlContainer** cont)
{
string s = (*cont)->getName();
char* str = new char[s.length()+1];
strcpy(str, s.c_str());
return str;
}
void _deleteString(char* str)
{
delete[] str;
}
void _xmlDocument_delete(DbXml::XmlDocument* doc)
{
delete doc;
}
int _xmlDocument_getContent(DbXml::XmlDocument* doc, char** str, int* length)
{
string s;
try {
doc->getContent(s);
}
catch (XmlException& exc) {
*str = NULL;
return asInt(exc);
}
*length = (int)s.length();
*str = new char[s.length()+1];
strcpy(*str, s.c_str());
return 0;
}
int _xmlManager_createQueryContext(XmlManagerInfo* mgr, int rt, int ev, DbXml::XmlQueryContext** ctx)
{
try {
XmlQueryContext c = mgr->mgr.createQueryContext(
XmlQueryContext::LiveValues,
ev == 0 ? XmlQueryContext::Eager : XmlQueryContext::Lazy);
*ctx = new XmlQueryContext(c);
return 0;
}
catch (XmlException& exc) {
*ctx = NULL;
return asInt(exc);
}
}
void _xmlQueryContext_delete(DbXml::XmlQueryContext* ctx)
{
delete ctx;
}
void _xmlResults_delete(DbXml::XmlResults* res)
{
delete res;
}
int _xmlResults_hasNext(DbXml::XmlResults* res, int* answer)
{
try {
*answer = res->hasNext();
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlResults_nextDocument(DbXml::XmlResults* res, DbXml::XmlDocument** doc)
{
*doc = new XmlDocument;
try {
if (!res->next(**doc)) {
delete *doc;
*doc = NULL;
}
return 0;
}
catch (XmlException& exc) {
delete *doc;
*doc = NULL;
return asInt(exc);
}
}
int _xmlResults_nextValue(DbXml::XmlResults* res, DbXml::XmlValue** val)
{
*val = new XmlValue;
try {
if (!res->next(**val)) {
delete *val;
*val = NULL;
}
return 0;
}
catch (XmlException& exc) {
delete *val;
*val = NULL;
return asInt(exc);
}
}
int _xmlManager_query(XmlManagerInfo* mgr, DbXml::XmlTransaction* trans,
const char* query, DbXml::XmlQueryContext* ctx, u_int32_t flags, DbXml::XmlResults** res)
{
try {
XmlResults r;
if (trans != NULL)
r = mgr->mgr.query(*trans, query, *ctx, flags);
else
r = mgr->mgr.query(query, *ctx, flags);
*res = new XmlResults(r);
return 0;
}
catch (XmlException& exc) {
*res = NULL;
return asInt(exc);
}
}
void _xmlQueryExpression_delete(XmlQueryExpressionInfo* exp)
{
delete exp;
}
int _xmlManager_prepare(XmlManagerInfo* mgr, DbXml::XmlTransaction* trans,
const char* query, DbXml::XmlQueryContext* ctx, XmlQueryExpressionInfo** exp)
{
try {
XmlQueryExpression e;
if (trans != NULL)
e = mgr->mgr.prepare(*trans, query, *ctx);
else
e = mgr->mgr.prepare(query, *ctx);
*exp = new XmlQueryExpressionInfo(e, mgr);
return 0;
}
catch (XmlException& exc) {
*exp = NULL;
return asInt(exc);
}
}
int _xmlQueryContext_setDefaultCollection(DbXml::XmlQueryContext* ctx, const char* coll)
{
try {
ctx->setDefaultCollection(coll);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlQueryContext_setVariableValue(DbXml::XmlQueryContext* ctx, const char* name, DbXml::XmlValue* value)
{
try {
ctx->setVariableValue(name, *value);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
void _xmlValue_delete(DbXml::XmlValue* val)
{
delete val;
}
DbXml::XmlValue* _xmlNone()
{
return new XmlValue;
}
DbXml::XmlValue* _xmlString(const char* text)
{
return new XmlValue(text);
}
DbXml::XmlValue* _xmlBool(int value)
{
return new XmlValue((bool)value);
}
DbXml::XmlValue* _xmlDouble(double value)
{
return new XmlValue(value);
}
int _xmlValue_asString(DbXml::XmlValue* value, char** str)
{
string s;
try {
s = value->asString();
}
catch (XmlException& exc) {
*str = NULL;
return asInt(exc);
}
*str = new char[s.length()+1];
strcpy(*str, s.c_str());
return 0;
}
int _xmlQueryExpression_execute(XmlQueryExpressionInfo* exp, DbXml::XmlTransaction* trans,
DbXml::XmlValue* contextItem, DbXml::XmlQueryContext* qctx, u_int32_t flags, DbXml::XmlResults** res)
{
try {
XmlResults r;
if (trans != NULL && contextItem != NULL)
r = exp->qe.execute(*trans, *contextItem, *qctx, flags);
else
if (trans != NULL && contextItem == NULL)
r = exp->qe.execute(*trans, *qctx, flags);
else
if (trans == NULL && contextItem != NULL)
r = exp->qe.execute(*contextItem, *qctx, flags);
else
r = exp->qe.execute(*qctx, flags);
*res = new XmlResults(r);
return 0;
}
catch (XmlException& exc) {
*res = NULL;
return asInt(exc);
}
}
int _xmlManager_createDocument(XmlManagerInfo* mgr, DbXml::XmlDocument** doc)
{
try {
XmlDocument d = mgr->mgr.createDocument();
*doc = new XmlDocument(d);
return 0;
}
catch (XmlException& exc) {
*doc = NULL;
return asInt(exc);
}
}
int _xmlDocument_getName(DbXml::XmlDocument* doc, char** name)
{
string s;
try {
s = doc->getName();
}
catch (XmlException& exc) {
*name = NULL;
return asInt(exc);
}
*name = new char[s.length()+1];
strcpy(*name, s.c_str());
return 0;
}
int _xmlDocument_setName(DbXml::XmlDocument* doc, const char* name)
{
try {
doc->setName(name);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
void _xmlUpdateContext_delete(DbXml::XmlUpdateContext* ctx)
{
delete ctx;
}
int _xmlManager_createUpdateContext(XmlManagerInfo* mgr, DbXml::XmlUpdateContext** ctx)
{
try {
XmlUpdateContext c = mgr->mgr.createUpdateContext();
*ctx = new XmlUpdateContext(c);
return 0;
}
catch (XmlException& exc) {
*ctx = NULL;
return asInt(exc);
}
}
int _xmlDocument_setContent(DbXml::XmlDocument* doc, const char* text, unsigned int length)
{
try {
doc->setContent(string(text, length));
return 0;
}
catch (XmlException& exc) {
*doc = NULL;
return asInt(exc);
}
}
int _xmlContainer_updateDocument(DbXml::XmlContainer** cont, DbXml::XmlTransaction* trans,
DbXml::XmlDocument* doc, DbXml::XmlUpdateContext* uctx)
{
try {
if (trans != NULL)
(*cont)->updateDocument(*trans, *doc, *uctx);
else
(*cont)->updateDocument(*doc, *uctx);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlContainer_putDocument(DbXml::XmlContainer** cont, DbXml::XmlTransaction* trans,
DbXml::XmlDocument* doc, DbXml::XmlUpdateContext* uctx, u_int32_t flags)
{
try {
if (trans != NULL)
(*cont)->putDocument(*trans, *doc, *uctx, flags);
else
(*cont)->putDocument(*doc, *uctx, flags);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}
int _xmlContainer_deleteDocument(DbXml::XmlContainer** cont, DbXml::XmlTransaction* trans,
DbXml::XmlDocument* doc, DbXml::XmlUpdateContext* uctx)
{
try {
if (trans != NULL)
(*cont)->deleteDocument(*trans, *doc, *uctx);
else
(*cont)->deleteDocument(*doc, *uctx);
return 0;
}
catch (XmlException& exc) {
return asInt(exc);
}
}