Projekt

Allgemein

Profil

Herunterladen (10,8 KB) Statistiken
| Zweig: | Markierung: | Revision:
/****************************************************************************
* This file is part of the project AqFinance.
* AqFinance (c) by 2009 Martin Preuss, all rights reserved.
*
* The license for this file can be found in the file COPYING which you
* should have received along with this file.
****************************************************************************/


#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


#include "rollback_p.h"
#include "dbdir_l.h"
#include "table_l.h"
#include <aqdatabase/aqdb_db_be.h>
#include <aqdatabase/aqdb_object_be.h>
#include <aqdatabase/aqdb_sessionlog.h>
#include <aqdatabase/aqdb_sessiondescr.h>

#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/directory.h>
#include <gwenhywfar/idlist64.h>




int GWENHYWFAR_CB AQDB_DbDir_GetRollbackSessions(AQDB_DB *db,
uint32_t aflags,
AQDB_SESSION_DESCR_LIST *sl) {
AQDB_ID qid=0;
int rv;
AQDB_ID oids[16];
int len;
char qexpr[256];

snprintf(qexpr, sizeof(qexpr)-1, "$type==%d", AQDB_SessionLogType_EndEdit);

/* query */
rv=AQDB_DB_QuerySubmit(db,
AQDB_DB_DIR_TID_ROLLBACKLOG,
0,
qexpr,
0, /* query flags */
&qid);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

/* browse all objects */
len=16;
rv=AQDB_DB_QueryGetFirst(db, qid, oids, &len);
while(rv==0) {
int i;

for (i=0; i<len; i++) {
AQDB_OBJECT *o=NULL;
AQDB_SESSION_LOG *sessionLog=NULL;
const void *p;
uint32_t l;

rv=AQDB_DB_ReadObject(db,
AQDB_DB_DIR_TID_ROLLBACKLOG,
oids[i],
&o);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading object %d (%d)", oids[i], rv);
AQDB_DB_QueryClose(db, qid);
return rv;
}

/* get session log */
rv=AQDB_SessionLog_fromObject(o, &sessionLog);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading session log from object %d (%d)", oids[i], rv);
AQDB_Object_free(o);
AQDB_DB_QueryClose(db, qid);
return rv;
}
AQDB_Object_free(o);

/* get session description */
p=AQDB_SessionLog_GetDataPtr(sessionLog);
l=AQDB_SessionLog_GetDataLen(sessionLog);

if (p && l) {
AQDB_SESSION_DESCR *sd=NULL;
int cnt;

cnt=AQDB_DbDir_GetColumnCount(db, AQDB_DB_DIR_TID_ROLLBACKLOG);
if (cnt<1) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", cnt);
AQDB_SessionLog_free(sessionLog);
AQDB_DB_QueryClose(db, qid);
return cnt;
}

/* read session descriptor object from session log */
o=AQDB_DbDir_Object_fromBuffer(AQDB_DB_DIR_TID_ROLLBACKLOG, oids[i], cnt, p, l);
if (o==NULL) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading session description object %d (%d)", oids[i], rv);
AQDB_SessionLog_free(sessionLog);
AQDB_DB_QueryClose(db, qid);
return rv;
}

/* read session descriptor from object */
rv=AQDB_SessionDescr_fromObject(o, &sd);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading session description from object %d (%d)", oids[i], rv);
AQDB_Object_free(o);
AQDB_SessionLog_free(sessionLog);
AQDB_DB_QueryClose(db, qid);
return rv;
}
AQDB_Object_free(o);

/* add session description */
AQDB_SessionDescr_List_Add(sd, sl);
}
AQDB_SessionLog_free(sessionLog);
} /* for */

len=16;
rv=AQDB_DB_QueryGetNext(db, qid, oids, &len);
}

AQDB_DB_QueryClose(db, qid);
if (rv<0) {
if (rv!=GWEN_ERROR_NOT_FOUND) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}

return 0;
}



int AQDB_DbDir__GetSessionObjectIds(AQDB_DB *db, AQDB_ID sid, GWEN_IDLIST64 *idlist) {
AQDB_ID qid=0;
int rv;
AQDB_ID oids[16];
int len;
char qexpr[256];

snprintf(qexpr, sizeof(qexpr)-1, "$sessionid>=%lu", (unsigned long) sid);

/* query */
rv=AQDB_DB_QuerySubmit(db,
AQDB_DB_DIR_TID_ROLLBACKLOG,
0,
qexpr,
0, /* query flags */
&qid);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

/* append all object ids */
len=16;
rv=AQDB_DB_QueryGetFirst(db, qid, oids, &len);
while(rv==0) {
int i;

for (i=0; i<len; i++)
GWEN_IdList64_AddId(idlist, oids[i]);

len=16;
rv=AQDB_DB_QueryGetNext(db, qid, oids, &len);
}

AQDB_DB_QueryClose(db, qid);
if (rv<0) {
if (rv!=GWEN_ERROR_NOT_FOUND) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}

return 0;
}



int AQDB_DbDir__WriteObjectFromLog(AQDB_DB *db, const AQDB_SESSION_LOG *sl) {
AQDB_DBDIR_TABLE *table=NULL;
AQDB_ID tid=0;
AQDB_ID oid=0;
int rv;
const void *p;
uint32_t l;

/* get current table id */
rv=AQDB_DbDir_FindTableByName(db, AQDB_SessionLog_GetTableName(sl), &table);
if (rv>=0)
tid=AQDB_DbDir_Table_GetId(table);
else if (rv<0) {
if (rv==GWEN_ERROR_NOT_FOUND) {
/* name not in list, open the table */
rv=AQDB_DB_OpenTable(db, AQDB_SessionLog_GetTableName(sl),
AQDB_ACTION_FLAGS_READ | AQDB_ACTION_FLAGS_WRITE,
&tid);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
else {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}

/* get object id */
oid=AQDB_SessionLog_GetObjectId(sl);

/* get data */
p=AQDB_SessionLog_GetDataPtr(sl);
l=AQDB_SessionLog_GetDataLen(sl);

if (p && l) {
AQDB_OBJECT *o=NULL;
int cnt;

cnt=AQDB_DbDir_GetColumnCount(db, tid);
if (cnt<1) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", cnt);
return cnt;
}

/* read object from session log */
o=AQDB_DbDir_Object_fromBuffer(tid, oid, cnt, p, l);
if (o==NULL) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading object %d (%d)", oid, rv);
return rv;
}

/* write object to DB */
rv=AQDB_DbDir_ReallyWriteObject(db, o);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
AQDB_Object_free(o);
return rv;
}
AQDB_Object_free(o);
}
else {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

return 0;
}



int AQDB_DbDir__DeleteObjectFromLog(AQDB_DB *db, const AQDB_SESSION_LOG *sl) {
AQDB_DBDIR_TABLE *table=NULL;
AQDB_ID tid=0;
AQDB_ID oid=0;
int rv;

/* get current table id */
rv=AQDB_DbDir_FindTableByName(db, AQDB_SessionLog_GetTableName(sl), &table);
if (rv>=0) {
tid=AQDB_DbDir_Table_GetId(table);
}
else if (rv<0) {
if (rv==GWEN_ERROR_NOT_FOUND) {
/* name not in list, open the table */
rv=AQDB_DB_OpenTable(db, AQDB_SessionLog_GetTableName(sl),
AQDB_ACTION_FLAGS_READ | AQDB_ACTION_FLAGS_WRITE,
&tid);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}
else {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}
}

/* get object id */
oid=AQDB_SessionLog_GetObjectId(sl);

/* delete object from DB */
rv=AQDB_DbDir_ReallyDeleteObject(db, tid, oid);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

return 0;
}



int AQDB_DbDir__UndoSession(AQDB_DB *db, AQDB_ID sid, GWEN_IDLIST64 *idlist) {
GWEN_IDLIST64_ITERATOR *it;
uint64_t id;

it=GWEN_IdList64_Iterator_new(idlist);
id=GWEN_IdList64_Iterator_GetFirstId(it);
while(id!=0) {
AQDB_OBJECT *o=NULL;
AQDB_SESSION_LOG *sessionLog=NULL;
int rv;

rv=AQDB_DbDir_ReallyReadObject(db, AQDB_DB_DIR_TID_ROLLBACKLOG, id, &o);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading object %lu (%d)", (unsigned long) id, rv);
GWEN_IdList64_Iterator_free(it);
return rv;
}

/* get session log */
rv=AQDB_SessionLog_fromObject(o, &sessionLog);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "Error reading session log from object %lu (%d)", (unsigned long) id, rv);
AQDB_Object_free(o);
GWEN_IdList64_Iterator_free(it);
return rv;
}
AQDB_Object_free(o);

switch(AQDB_SessionLog_GetType(sessionLog)) {
case AQDB_SessionLogType_BeginEdit:
case AQDB_SessionLogType_EndEdit:
break;

case AQDB_SessionLogType_AddObject:
/* add given object */
rv=AQDB_DbDir__WriteObjectFromLog(db, sessionLog);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
GWEN_IdList64_Iterator_free(it);
return rv;
}
break;

case AQDB_SessionLogType_DelObject:
/* remove given object */
rv=AQDB_DbDir__DeleteObjectFromLog(db, sessionLog);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
GWEN_IdList64_Iterator_free(it);
return rv;
}
break;

case AQDB_SessionLogType_ChgObject:
/* modify given object */
rv=AQDB_DbDir__WriteObjectFromLog(db, sessionLog);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
GWEN_IdList64_Iterator_free(it);
return rv;
}
break;
} /* switch */

AQDB_SessionLog_free(sessionLog);

/* delete log entry */
/* DBG_ERROR(0, "Deleting log entry %lu", (unsigned long int) id); */
rv=AQDB_DbDir_ReallyDeleteObject(db, AQDB_DB_DIR_TID_ROLLBACKLOG, id);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
GWEN_IdList64_Iterator_free(it);
return rv;
}

id=GWEN_IdList64_Iterator_GetNextId(it);
}
GWEN_IdList64_Iterator_free(it);

return 0;
}



int AQDB_DbDir_UndoSessionForUser(AQDB_DB *db, AQDB_ID sid, const char *userName) {
GWEN_IDLIST64 *idlist;
int rv;

rv=AQDB_DbDir_BeginEdit(db, AQDB_DB_DIR_SESSION_FLAGS_ROLLBACK, userName);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

idlist=GWEN_IdList64_newWithSteps(AQDB_DBDIR_IDLIST_ENTRIES);
rv=AQDB_DbDir__GetSessionObjectIds(db, sid, idlist);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
AQDB_DB_EndEdit(db, AQDB_ACTION_FLAGS_ABORT);
GWEN_IdList64_free(idlist);
return rv;
}

/* reverse-sort the list */
rv=GWEN_IdList64_ReverseSort(idlist);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
AQDB_DB_EndEdit(db, AQDB_ACTION_FLAGS_ABORT);
GWEN_IdList64_free(idlist);
return rv;
}

/* now undo the session */
rv=AQDB_DbDir__UndoSession(db, sid, idlist);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
AQDB_DB_EndEdit(db, AQDB_ACTION_FLAGS_ABORT);
GWEN_IdList64_free(idlist);
return rv;
}
GWEN_IdList64_free(idlist);

rv=AQDB_DB_EndEdit(db, 0);
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
AQDB_DB_EndEdit(db, AQDB_ACTION_FLAGS_ABORT);
return rv;
}

return 0;
}



int GWENHYWFAR_CB AQDB_DbDir_UndoSession(AQDB_DB *db, AQDB_ID sid) {
int rv;

rv=AQDB_DbDir_UndoSessionForUser(db, sid, "unknown");
if (rv<0) {
DBG_INFO(AQDB_LOGDOMAIN, "here (%d)", rv);
return rv;
}

return 0;
}










(9-9/14)