|
/****************************************************************************
|
|
* This file is part of the project AqDatabase.
|
|
* AqDatabase (c) by 2016 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 "createdb.h"
|
|
#include "checkobjects.h"
|
|
#include "createobjects.h"
|
|
#include "type1.h"
|
|
#include "type2.h"
|
|
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/testframework.h>
|
|
|
|
|
|
|
|
#define RUN1_TYPE1_NUM 1000
|
|
#define RUN1_TYPE1_STARTID 10000
|
|
|
|
#define RUN1_TYPE2_NUM 800
|
|
#define RUN1_TYPE2_STARTID 20000
|
|
|
|
|
|
#define RUN2_TYPE1_NUM 700
|
|
#define RUN2_TYPE1_STARTID 30000
|
|
|
|
#define RUN2_TYPE2_NUM 900
|
|
#define RUN2_TYPE2_STARTID 40000
|
|
|
|
|
|
#define RUN3_TYPE1_NUM 400
|
|
#define RUN3_TYPE1_STARTID 50000
|
|
|
|
#define RUN3_TYPE2_NUM 300
|
|
#define RUN3_TYPE2_STARTID 60000
|
|
|
|
|
|
|
|
|
|
int test_rollback_and_add(GWEN_TEST_MODULE *mod)
|
|
{
|
|
AQDB_DB *db=NULL;
|
|
AQDB_ID tableId1;
|
|
AQDB_ID tableId2;
|
|
const char *url;
|
|
const char *dirname;
|
|
const char *fname;
|
|
int rv;
|
|
|
|
/* create database */
|
|
url=GWEN_Test_Module_GetCharParam(mod, "url", NULL);
|
|
dirname=GWEN_Test_Module_GetCharParam(mod, "dirName", NULL);
|
|
fname=GWEN_Test_Module_GetCharParam(mod, "fname", NULL);
|
|
|
|
destroy_database(url, dirname, fname);
|
|
rv=create_database(url, dirname, fname);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Could not create database (%d)", rv);
|
|
return rv;
|
|
}
|
|
|
|
|
|
rv=AQDB_DbFactory(url, &db);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to instantiate db (%d)", rv);
|
|
return rv;
|
|
}
|
|
|
|
AQDB_DB_SetCache(db, 1000, 10*1024*1024);
|
|
|
|
/* open database */
|
|
rv=AQDB_DB_Open(db, AQDB_ACTION_FLAGS_READ | AQDB_ACTION_FLAGS_WRITE);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to open db (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* open table 1 */
|
|
tableId1=0;
|
|
rv=AQDB_DB_OpenTable(db, "type1",
|
|
AQDB_ACTION_FLAGS_READ | AQDB_ACTION_FLAGS_WRITE,
|
|
&tableId1);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to open table for type1 (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* open table 2 */
|
|
tableId2=0;
|
|
rv=AQDB_DB_OpenTable(db, "type2",
|
|
AQDB_ACTION_FLAGS_READ | AQDB_ACTION_FLAGS_WRITE,
|
|
&tableId2);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to open table for type2 (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------- run 1 ----*/
|
|
|
|
/* begin edit session */
|
|
rv=AQDB_DB_BeginEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to begin edit session (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 1 objects */
|
|
rv=create_type1_objects(db, tableId1, RUN1_TYPE1_NUM, RUN1_TYPE1_STARTID); /* create x objects, starting with 2000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type1 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 2 objects */
|
|
rv=create_type2_objects(db, tableId2, RUN1_TYPE2_NUM, RUN1_TYPE2_STARTID); /* create x objects, starting with 7000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type2 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* done editing */
|
|
rv=AQDB_DB_EndEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to end edit session (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
if (1) {
|
|
TYPE1_LIST *tl;
|
|
TYPE1 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type1_List_new();
|
|
rv=read_type1_objects(db, tl, tableId1, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type1 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type1_List_SortById(tl, 1);
|
|
|
|
t=Type1_List_First(tl);
|
|
while (t) {
|
|
rv=check_type1_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type1 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE1_STARTID;
|
|
num=RUN1_TYPE1_NUM;
|
|
t=Type1_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type1 than expected");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type1");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
Type1_List_free(tl);
|
|
}
|
|
|
|
if (1) {
|
|
TYPE2_LIST *tl;
|
|
TYPE2 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type2_List_new();
|
|
rv=read_type2_objects(db, tl, tableId2, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type2 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type2_List_SortById(tl, 1);
|
|
|
|
t=Type2_List_First(tl);
|
|
while (t) {
|
|
rv=check_type2_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type2 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE2_STARTID;
|
|
num=RUN1_TYPE2_NUM;
|
|
t=Type2_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type2 than expected");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
Type2_List_free(tl);
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------- run 2 ----*/
|
|
|
|
/* begin 2nd edit session */
|
|
rv=AQDB_DB_BeginEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to begin edit session (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 1 objects */
|
|
rv=create_type1_objects(db, tableId1, RUN2_TYPE1_NUM, RUN2_TYPE1_STARTID); /* create x objects, starting with 2000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type1 objects (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 2 objects */
|
|
rv=create_type2_objects(db, tableId2, RUN2_TYPE2_NUM, RUN2_TYPE2_STARTID); /* create x objects, starting with 7000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type2 objects (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* done editing */
|
|
rv=AQDB_DB_EndEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to end edit session (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
|
|
if (1) {
|
|
TYPE1_LIST *tl;
|
|
TYPE1 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type1_List_new();
|
|
rv=read_type1_objects(db, tl, tableId1, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type1 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type1_List_SortById(tl, 1);
|
|
|
|
t=Type1_List_First(tl);
|
|
while (t) {
|
|
rv=check_type1_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type1 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE1_STARTID;
|
|
num=RUN1_TYPE1_NUM;
|
|
t=Type1_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type1 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
currentId=RUN2_TYPE1_STARTID;
|
|
num=RUN2_TYPE1_NUM;
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (got %llu, expected %llu) (run2)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type1 than expected (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type1 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
Type1_List_free(tl);
|
|
}
|
|
|
|
if (1) {
|
|
TYPE2_LIST *tl;
|
|
TYPE2 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type2_List_new();
|
|
rv=read_type2_objects(db, tl, tableId2, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type2 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type2_List_SortById(tl, 1);
|
|
|
|
t=Type2_List_First(tl);
|
|
while (t) {
|
|
rv=check_type2_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type2 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE2_STARTID;
|
|
num=RUN1_TYPE2_NUM;
|
|
t=Type2_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
currentId=RUN2_TYPE2_STARTID;
|
|
num=RUN2_TYPE2_NUM;
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu) (run2)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type2 than expected (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
Type2_List_free(tl);
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------- rollback ----*/
|
|
|
|
if (1) {
|
|
AQDB_SESSION_DESCR_LIST *sl;
|
|
AQDB_SESSION_DESCR *sd;
|
|
AQDB_ID sessionId;
|
|
|
|
sl=AQDB_SessionDescr_List_new();
|
|
rv=AQDB_DB_GetRollbackSessions(db, sl);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to get rollback sessions (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
sd=AQDB_SessionDescr_List_Last(sl);
|
|
if (sd==NULL) {
|
|
DBG_ERROR(0, "ERROR: No session descriptor in list");
|
|
AQDB_DB_free(db);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
sessionId=AQDB_SessionDescr_GetSessionId(sd);
|
|
if (sessionId==0) {
|
|
DBG_ERROR(0, "ERROR: Session descriptor has no session id");
|
|
AQDB_DB_free(db);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
#if 0
|
|
DBG_ERROR(0, "Undoing session %llu with %llu additions",
|
|
(unsigned long long) sessionId,
|
|
(unsigned long long) AQDB_SessionDescr_GetAdditions(sd));
|
|
#endif
|
|
/* rollback */
|
|
rv=AQDB_DB_UndoSession(db, sessionId);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Error on rollback (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
AQDB_SessionDescr_List_free(sl);
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------- run 3 ----*/
|
|
|
|
|
|
if (1) {
|
|
TYPE1_LIST *tl;
|
|
TYPE1 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type1_List_new();
|
|
rv=read_type1_objects(db, tl, tableId1, NULL);
|
|
if (rv<0) {
|
|
fprintf(stderr, "ERROR: Unable to read type1 objects (%d) (run3)\n", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type1_List_SortById(tl, 1);
|
|
|
|
t=Type1_List_First(tl);
|
|
while (t) {
|
|
rv=check_type1_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type1 object (%d) (run3)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE1_STARTID;
|
|
num=RUN1_TYPE1_NUM;
|
|
t=Type1_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (%d entries, got %llu, expected %llu) (run3)",
|
|
Type1_List_GetCount(tl),
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
if (t) {
|
|
AQDB_ID idBehind;
|
|
int n=0;
|
|
|
|
idBehind=Type1_GetId(t);
|
|
while (t) {
|
|
n++;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
DBG_ERROR(0, "ERROR: There are %d more objects of type1 than expected (%llu) (run3)",
|
|
n,
|
|
(unsigned long long) idBehind);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
fprintf(stderr, "ERROR: There are too few objects of type1 (run3)\n");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
Type1_List_free(tl);
|
|
}
|
|
|
|
if (1) {
|
|
TYPE2_LIST *tl;
|
|
TYPE2 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type2_List_new();
|
|
rv=read_type2_objects(db, tl, tableId2, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type2 objects (%d) (run3)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type2_List_SortById(tl, 1);
|
|
|
|
t=Type2_List_First(tl);
|
|
while (t) {
|
|
rv=check_type2_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type2 object (%d) (run3)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE2_STARTID;
|
|
num=RUN1_TYPE2_NUM;
|
|
t=Type2_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu) (run3)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type2 than expected (run3)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2 (run3)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
Type2_List_free(tl);
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------- run 3 ----*/
|
|
|
|
/* begin 3nd edit session */
|
|
rv=AQDB_DB_BeginEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to begin edit session (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 1 objects */
|
|
rv=create_type1_objects(db, tableId1, RUN3_TYPE1_NUM, RUN3_TYPE1_STARTID); /* create x objects, starting with 2000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type1 objects (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* create type 2 objects */
|
|
rv=create_type2_objects(db, tableId2, RUN3_TYPE2_NUM, RUN3_TYPE2_STARTID); /* create x objects, starting with 7000 */
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to create type2 objects (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* done editing */
|
|
rv=AQDB_DB_EndEdit(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to end edit session (%d) (run2)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
|
|
if (1) {
|
|
TYPE1_LIST *tl;
|
|
TYPE1 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type1_List_new();
|
|
rv=read_type1_objects(db, tl, tableId1, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type1 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type1_List_SortById(tl, 1);
|
|
|
|
t=Type1_List_First(tl);
|
|
while (t) {
|
|
rv=check_type1_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type1 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE1_STARTID;
|
|
num=RUN1_TYPE1_NUM;
|
|
t=Type1_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type1 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
currentId=RUN3_TYPE1_STARTID;
|
|
num=RUN3_TYPE1_NUM;
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type1_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type1 id (got %llu, expected %llu) (run2)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type1_List_Next(t);
|
|
}
|
|
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type1 than expected (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type1 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
Type1_List_free(tl);
|
|
}
|
|
|
|
if (1) {
|
|
TYPE2_LIST *tl;
|
|
TYPE2 *t;
|
|
AQDB_ID currentId;
|
|
int num;
|
|
|
|
tl=Type2_List_new();
|
|
rv=read_type2_objects(db, tl, tableId2, NULL);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to read type2 objects (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
/* sort list */
|
|
Type2_List_SortById(tl, 1);
|
|
|
|
t=Type2_List_First(tl);
|
|
while (t) {
|
|
rv=check_type2_object(db, t);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Bad result checking type2 object (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return rv;
|
|
}
|
|
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
currentId=RUN1_TYPE2_STARTID;
|
|
num=RUN1_TYPE2_NUM;
|
|
t=Type2_List_First(tl);
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
currentId=RUN3_TYPE2_STARTID;
|
|
num=RUN3_TYPE2_NUM;
|
|
while (t && num) {
|
|
AQDB_ID id;
|
|
|
|
id=Type2_GetId(t);
|
|
if (id!=currentId) {
|
|
DBG_ERROR(0, "ERROR: Unexpected type2 id (got %llu, expected %llu) (run2)",
|
|
(unsigned long long) id,
|
|
(unsigned long long) currentId);
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
currentId++;
|
|
num--;
|
|
t=Type2_List_Next(t);
|
|
}
|
|
|
|
if (t) {
|
|
DBG_ERROR(0, "ERROR: There are more objects of type2 than expected (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
if (num) {
|
|
DBG_ERROR(0, "ERROR: There are too few objects of type2 (run2)");
|
|
return GWEN_ERROR_INTERNAL;
|
|
}
|
|
|
|
Type2_List_free(tl);
|
|
}
|
|
|
|
|
|
|
|
|
|
rv=AQDB_DB_Close(db, 0);
|
|
if (rv<0) {
|
|
DBG_ERROR(0, "ERROR: Unable to close db (%d)", rv);
|
|
AQDB_DB_free(db);
|
|
return 2;
|
|
}
|
|
|
|
AQDB_DB_free(db);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|