/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
/
/**
* SOURCE: test_persmddobj.cc
*
* MODULE: test for PersMDDObj of mddmgr
*
* PURPOSE:
* creates a persistent collection of objects and iterators and tests
* usage of O2 OIds.
*
* COMMENTS:
* none
*
*/
#include "mymalloc/mymalloc.h"
#define TEST_PROTECTED
#define TEST_PRIVATE
#include
#include
#include "ulongtype.hh"
#include "mddmgr/persmddcoll.hh"
#include "mddmgr/persmddobj.hh"
#include "mddmgr/perstile.hh"
#include "mddmgr/persmddcolliter.hh"
#include "adminif.hh"
#include "databaseif.hh"
#include "transactionif.hh"
#include "oidif.hh"
#include "raslib/rminit.hh"
#include "typefactory.hh"
#include "mddif/dbmddobj.hh"
#include "mddif/dbmddcoll.hh"
#include "mddbasetype.hh"
#include "mdddomaintype.hh"
#include "settype.hh"
/*
Global Variables
*/
extern char* myExecArgv0 = "";
RMINITGLOBALS('C')
static char* O2DBName;
char *collName;
char defaultCollName[]= "ObjsContainer";
OId globalOId1, globalOId2;
OId globalCollOId;
EOId globalEOId[4];
int numObjsCreated;
TransactionIf ta;
int ExitNo;
/*
Functions
*/
int
getOption( )
{
unsigned int result;
cout << endl;
cout << "Choose Option : " << endl;
cout << "-----------------------------------------------------------------"<> result;
return result;
}
// 1 - Create MDD collection
static int createMDDColl( const char* collName, DatabaseIf* db );
// 2 - Populate collection with MDD objects
static void testConstructors( char* cn );
// 3 - Retrieves an MDD collection with name cn and prints contents:
static void testAccessing( char* cn );
// 4 - Retrieves an MDD collection with OId o and prints contents:
static void testAccessing( OId o );
// 5 - Retrieves an MDD object with OId o and prints contents:
static void testAccessingMDDObj( OId o );
// Removes one of the MDD objects in the collection
static void testRemove( );
// 6 - Removes MDD object with OId o in the collection
static void testRemove( OId o );
// 7 - Test PersMDDObj::intersect( ) objects of the collection
static void testSearch( );
// 8 - Test PersMDDColl::getCardinality( )
static void testGetCardinality( char* cn);
// 9 - Scans collection and tests PersMDDObj get functions
static void testGetFunctions( );
//10 - Remove MDD collection given OId
//11 - Insert MDD given OId in a second collection
static void testInsertMDDObjColl( OId o, char* cn );
//12 - Test later insertion of tile in PersMDDObj
static void testLaterInsert( OId o );
//13 - Test removeTile from an MDD obj
static void testRemoveTile( OId o );
// Tries accessing several OIds, including ilegal ones, to test
// several error conditions.
static void testAccessingOId( );
/*************************************************************
* Function name.: int main( int argc, char** argv)
*
* Arguments.....:
* argc: number of arguments given to program
* argv: array of char* with arguments
* Return value..: exit status
* Description...: none
************************************************************/
int
main( int argc, char** argv)
{
// variables representing O2 database, ta and session
DatabaseIf database;
if( argc < 2 ) {
cout << "Usage: test_persmddcoll [collName]" << endl;
return -1;
}
O2DBName = strdup( argv[1] );
if ( argc == 3 ) collName = strdup( argv[2] );
else
collName = defaultCollName;
// don't forget to initialize before using AdminIf!
myExecArgv0 = argv[0];
AdminIf* myAdmin = AdminIf::instance();
// connect to the database
cout << "Connecting to database " << O2DBName
<< "..." << endl;
int errorDBOpen;
try{
errorDBOpen = database.open( O2DBName );
}
catch( ...)
{
cout << "Caught Exception " << endl;
errorDBOpen = -6;
}
if ( errorDBOpen < 0 )
{
cout << "Database doesn't exist. Create it new ... " << endl;
cout << "Creating new database " << O2DBName
<< "..." << endl;
database.create( O2DBName, "TestSMSchema" );
cout << "Connecting to database " << O2DBName
<< "..." << endl;
try{
errorDBOpen = database.open( O2DBName );
}
catch(...)
{
errorDBOpen = -6;
}
}
if ( errorDBOpen < 0 )
{
cout << "Failed at opening newly created database " << errorDBOpen << endl;
cout << "Exiting " << endl;
return errorDBOpen;
}
ta.begin( &database );
cout << endl << "Deleting root object from the database ..." <> c;
if ( c == 'A' || c == 'a' )
{
ta.abort( );
cout <<"End of Transaction Abort..."<> c;
if (c =='y' || c == 'Y' )
{
cout <<"Garbaging ..."<< endl;
ta.begin( &database );
database.garbage( );
ta.commit( );
}
}
cout <<"End of transaction commit... "<getDomain( );
PersMDDObj* MDDObj1 = new PersMDDObj( mType1, tmpInt, O2DBName, oid1 );
uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
PersTile* tile1Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
MDDObj1->insertTile(tile1Obj1);
cout << "tile 2 = nil, 0-400, 22-24 "<< endl;
dom[0].set_interval(0l,400l);
dom[1].set_interval(22l,24l);
uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
PersTile* tile2Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
MDDObj1->insertTile(tile2Obj1);
cout << "tile 3 = nil, 0-600, 10-1000 "<< endl;
dom[0].set_interval(0l,600l);
dom[1].set_interval(10l,1000l);
uLongCells = (char*) mymalloc( dom.cell_count() * ulongTypeObj->getSize() );
PersTile* tile3Obj1 = new PersTile( dom, ulongTypeObj, uLongCells );
MDDObj1->insertTile(tile3Obj1);
cout << "MDDObj1 == isPersistent:" << MDDObj1->isPersistent( )<< ";" <printStatus( );
cout << endl;
objsSet.insert(MDDObj1);
// create MDD Object
cout << "Creating mddObj2 "<< endl;
cout << "tile 1 = nil, 0-19, 20-59, 30-59 "<< endl;
r_Sinterval limits1Obj2(0l,19l);
r_Sinterval limits2Obj2(20l,59l);
r_Sinterval limits3Obj2(30l,59l);
r_Minterval dom2(3);
dom2 << limits1Obj2 << limits2Obj2 << limits3Obj2;
tmpInt = *( ( MDDDomainType* ) mType2 )->getDomain( );
PersMDDObj* MDDObj2 = new PersMDDObj( mType2, tmpInt, O2DBName, oid2 );
boolCells = (char*) mymalloc( dom2.cell_count() * boolTypeObj->getSize() );
PersTile* tile1Obj2 = new PersTile( dom2, boolTypeObj, boolCells);
MDDObj2->insertTile( tile1Obj2 );
cout << "tile 2 = nil, 20-39, 60-79, 60-89 "<< endl;
dom2[0].set_interval(20l,39l);
dom2[1].set_interval(60l,79l);
dom2[2].set_interval(60l,89l);
boolCells = (char*) mymalloc( dom2.cell_count() * boolTypeObj->getSize() );
PersTile* tile2Obj2 = new PersTile( dom2, boolTypeObj, boolCells );
MDDObj2->insertTile(tile2Obj2);
cout << "MDDObj2 == isPersistent:" << MDDObj2->isPersistent( )<< ";" <printStatus( );
cout << endl;
/*
// This program doesn't work if the TA is aborted when OIds are
// allocated, even if all allocated OIds are binded. Question: is it
// because of dangling handles? This little test was done to
// check that.
// This without oids works with ta.abort
// conclusion: the problem with abort is not due to the handles
Handle hd;
d_Ref refObj = MDDObj2->getDBMDDObjId();
hd = refObj.o2_get_handle();
*/
objsSet.insert(MDDObj2);
numObjsCreated = 2;
cout << "Release all " << endl;
( ( PersMDDColl ) objsSet ).releaseAll( );
}
/*************************************************************
* Function......: testAccessing( char* cn )
* testAccessing( OId o )
************************************************************/
static void testAccessing( char* cn )
{
PersMDDObj* accessedObj;
cout << "....testAccessing collection "<< cn << endl;
try{
PersMDDColl objsSet( cn );
// To test PersMDDColl::printStatus( )
// objsSet.printStatus( );
// To test PersMDDObj::printStatus( ), MDDCollIter::createIterator( ) and
// MDDCollIter methods :
cout << "Iterating through the collection with PersMDDCollIter " << endl;
MDDCollIter* objsIt = objsSet.createIterator( );
for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
{
cout << i<<". MDD object in set:" << endl;
accessedObj = (PersMDDObj*) objsIt->getElement();
accessedObj->printStatus();
EOId eoid;
if ( accessedObj->getEOId( &eoid ) ==0 )
cout <<"EOId: " << eoid;
// old version cout <<"EOId: " << eoid.getSystemName( ) << eoid.getBaseName( ) << eoid.getOId( );
cout << endl << endl;
accessedObj->getEOId( &globalEOId[i-1] );
}
delete objsIt;
objsSet.releaseAll( );
}
catch ( r_Error& errObj)
{
cout <<"Error caught ................."<< endl;
}
}
static void testAccessing( OId o )
{
PersMDDObj* accessedObj;
cout << "....testAccessing collection "<< o << endl;
try {
PersMDDColl objsSet( o, O2DBName );
OId o;
if ( objsSet.getOId( &o ) == 0 )
cout <<"getOId " << o << endl;
else
cout <<"Error getOId " << endl;
EOId eo;
if ( objsSet.getEOId( &eo ) == 0 )
cout << "getEOId " << eo <notDone( ); i++, objsIt->advance( ))
{
cout << i<<". MDD object in set:" << endl;
accessedObj = (PersMDDObj*) objsIt->getElement();
accessedObj->printStatus();
EOId eoid;
if ( accessedObj->getEOId( &eoid ) ==0 )
cout <<"EOId: " << eoid ;
// cout <<"EOId: " << eoid.getSystemName( ) << eoid.getBaseName() << eoid.getOId( );
cout << endl << endl;
accessedObj->getEOId( &globalEOId[i-1] );
}
delete objsIt;
objsSet.releaseAll( );
}
catch ( r_Error& errObj)
{
cout <<"Error caught ................."<< endl;
}
}
/*************************************************************
* Function......: testAccessingMDDObj(OId o )
* testAccessingOId( )
*
************************************************************/
static void testAccessingMDDObj(OId o)
{
PersMDDObj *mObj;
cout << "....testAccessingMDDObj"<printStatus( );
delete mObj;
}
catch (...)
{
cout <<" Object not found..." << endl;
}
}
static void testAccessingOId()
{
PersMDDObj *mObj1, *mObj2, *mObj;
Handle hdObj;
int result;
OId o(70000);
OId o1(5010);
OId o2(0);
OId o3(5);
cout << "....testAccessingOId"<printStatus( );
cout << "Not used OId " << endl;
cout << "getType " << o1.getType( O2DBName ) << endl;
cout << "Nonexistent OId " << endl;
cout << "getType " << o.getType( O2DBName ) << endl;
// mObj2 = new PersMDDObj( O2DBName, globalOId2);
// mObj2->printStatus( );
cout <<"Loading PersMDDObjs from OIds " << endl;
mObj1 = new PersMDDObj( O2DBName, globalOId1);
mObj1->printStatus( );
mObj2 = new PersMDDObj( O2DBName, globalOId2);
mObj2->printStatus( );
delete mObj1;
delete mObj2;
for ( int i = 0; i < numObjsCreated; i++ )
{
cout << "Reading with " << i+1<< ".th EOId " ;
cout << globalEOId[i];
// cout << globalEOId[i].getSystemName( );
// cout << " ; "<< globalEOId[i].getBaseName( ) << ";" << globalEOId[i].getOId( );
cout << endl;
// result = o2_externalNameGetObject( &globalEOId[i], &hdObj );
result = globalEOId[i].getObject( &hdObj );
if ( result == 0 )
{
DBMDDObjId obj1(hdObj);
mObj = new PersMDDObj(obj1);
mObj->printStatus( );
}
else
cout << "No such object!!" << endl;
// o2_unref_handle( );
delete mObj;
}
}
/*************************************************************
* Function......: testLaterInsert()
*
************************************************************/
static void testLaterInsert( OId o )
{
PersMDDObj* accessedObj;
cout << "....testLaterInsert"<printStatus( );
cout << endl << "Inserting new Tile ..."<< endl;
PersTile *t, *t2, *t3;
switch( accessedObj->getDimension( ) )
{
case 2 :
t2 = new PersTile( r_Minterval("[40:60,80:1200]"),
accessedObj->getCellType( ) );
t = t2;
break;
case 3 :
t3 = new PersTile(r_Minterval("[40:60,80:100,0:20]"),
accessedObj->getCellType( ) );
t = t3;
break;
default:
cout << "Error Dimensionality not expected" << endl;
break;
}
accessedObj->insertTile(t);
cout << " New status after insertion:" << endl;
accessedObj->printStatus();
cout << endl << endl;
delete accessedObj;
}
/*************************************************************
* Function......: testSearch()
*
************************************************************/
static void testSearch()
{
MDDObj* accessedObj;
cout << "....testSearch"<notDone( ); i++, objsIt->advance( ))
{
accessedObj = objsIt->getElement();
cout << "Accessed Object " << endl;
accessedObj->printStatus( );
cout << endl;
if (i == 1 || i == 2)
{
r_Minterval searchInt1(2);
r_Minterval searchInt2(3);
vector< Tile* >* entriesList;
cout << " -- " << i << ". MDD object in list. Search for:";
switch (i) {
case 1: searchInt1[0].set_interval(10l,20l);
searchInt1[1].set_interval(10l,30l);
cout << " 10-20, 10-30" << endl;
entriesList = accessedObj->intersect(searchInt1);
break;
case 2: searchInt2[0].set_interval(10l,20l);
searchInt2[1].set_interval(10l,30l);
searchInt2[2].set_interval(40l,50l);
cout << " 10-20, 10-30, 40-50" <intersect(searchInt2);
break;
default: break;
}
cout << " -- Search result: " << endl;
vector::iterator entryIt = entriesList->begin();
while (entryIt != entriesList->end())
{
// (*entryIt)->printStatus();
r_Minterval tileInterval = (*entryIt)->getDomain();
int dimensionality = tileInterval.dimension();
cout << " PersTile printStatus";
cout << " domain == " << dimensionality << ": ";
for (int i = 0; i printStatus( );
}
catch (...)
{
cout <<" Object not found..." << endl;
return;
}
vector* tiles = mObj->getTiles( );
if ( tiles->size( ) == 0 )
{
cout <<"MDD object has no tiles !! "<< endl;
return;
}
else
{
int ix = tiles->size( )/2;
cout << "Removing "<< ix <<". tile from MDD Obj "<< endl;
cout << "Tile Description: " << (*tiles)[ix]->getDomain( ) << endl;
PersTile* t = (PersTile*) (*tiles)[ix];
mObj->removeTile( (*tiles)[ix] );
delete tiles;
delete mObj;
}
}
/*************************************************************
* Function......: testGetCardinality( const char* cn )
* testGetFunctions()
*
************************************************************/
static void testGetCardinality( char* cn )
{
cout << "....testGetCardinality( "<< cn << " )" << endl;
try{
PersMDDColl objsSet( cn );
cout<< "Cardinality of collection " << objsSet.getCardinality( ) <* entriesList;
for( int i = 1 ; objsIt->notDone( ); i++, objsIt->advance( ))
{
r_Minterval currDom;
r_Minterval defDom;
cout << " " << i << ". Object" << endl;
accessedObj = (PersMDDObj*) objsIt->getElement();
defDom = accessedObj->getDefinitionDomain( );
cout << " GetDefinitionDomain result: ";
defDom.print_status( );
cout << endl;
currDom = accessedObj->getCurrentDomain( );
cout << " GetCurrentDomain result: ";
currDom.print_status( );
cout << endl;
entriesList = accessedObj->getTiles( );
cout << " -- GetTiles result: " << endl;
vector::iterator entryIt = entriesList->begin();
while (entryIt != entriesList->end())
{
// (*entryIt)->printStatus();
r_Minterval tileInterval = (*entryIt)->getDomain();
int dimensionality = tileInterval.dimension();
cout << " PersTile ";
cout << " domain == " << dimensionality << ": ";
for (int i = 0; i notDone( ) && i < 2; i++, objsIt->advance( ))
{
accessedObj = (PersMDDObj*) objsIt->getElement();
}
cout << "Delete of objsIt:" << endl;
delete objsIt;
cout << "Finished Delete of objsIt." << endl;
cout << "Remove accessedObj:" << endl;
objsSet.remove( accessedObj );
cout << "Finished Remove accessedObj." << endl;
}
static void testRemove( OId o )
{
cout << "....testRemove( OId == " << o <<" ) "<< endl;
PersMDDColl objsSet(collName);
objsSet.remove( o, O2DBName );
}
/*************************************************************
* Function......: createMDDColl( )
************************************************************/
static int
createMDDColl( const char* collName, DatabaseIf* db )
{
MDDDomainType* mType1 = 0;
MDDDomainType* mType2 = 0;
MDDType* mt = 0;
CollectionType* collType1 = 0;
const BaseType* ulongTypeObj = TypeFactory::mapType("ULong");
const MDDDomainType* cmType1 =
( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType2D" );
const MDDDomainType* cmType2 =
( MDDDomainType* ) TypeFactory::mapMDDType( "TestSMDomainType3D" );
const CollectionType* collType =
(CollectionType*)TypeFactory::mapSetType( "ObjsContainerType" );
if( !cmType1 || !cmType2 || !collType )
{
char name1[] = "TestSMDomainType2D";
char name2[] = "TestSMDomainType3D";
r_Sinterval limits1Obj1(0l,1000l);
r_Sinterval limits2Obj1(0l,800l);
r_Minterval dom1(2);
dom1 << limits1Obj1 << limits2Obj1;
cout << "MDD Type 1 , domain "<< dom1 << endl;
cout << " tile 1 = nil, 0-19, 20-59, 30-59 "<< endl;
r_Sinterval limits1Obj2(0l,19l);
r_Sinterval limits2Obj2(20l,59l);
r_Sinterval limits3Obj2(30l,59l);
r_Minterval dom2(3);
dom2 << limits1Obj2 << limits2Obj2 << limits3Obj2;
cout << "MDD Type 2 , domain "<< dom2 << endl;
// MDDDomainType* mType1 =
mType1 =
new MDDDomainType((char*) name1, ( BaseType* ) ulongTypeObj, dom1 );
// MDDDomainType* mType2 =
mType2 =
new MDDDomainType((char*) name2, ( BaseType* ) ulongTypeObj, dom2 );
cout << "MDD Type1 == ";
mType1->print_status( cout );
cout << endl;
cout << "MDD Type2 == ";
mType2->print_status( cout );
cout << endl;
TypeFactory::addMDDType( mType1 );
TypeFactory::addMDDType( mType2 );
if ( !collType )
{
cout << "Collection type newly created " << endl;
// MDDType* mt = new MDDType( );
mt = new MDDType( );
cout << "MDDtype created "<< endl;
collType1 = new SetType( "ObjsContainerType", mType1 );
cout << "Set Type created ... ";
collType = collType1;
TypeFactory::addSetType( (SetType*) collType );
cout <<" and added "<< endl;
}
}
//ta.commit( );
//ta.begin( );
cout << "Creating root collection" << endl;
// cout << " &database = " << long( db ) << endl;
OId oColl;
if( OId::allocateMDDCollOId( &oColl ) == 0 )
cout <<"Successfully allocated OId for collection " << oColl << endl;
else
cout <<"Error allocating OId for collection " << endl;
globalCollOId = oColl;
PersMDDColl* col;
try {
// CollectionType* ct = TypeFactory::mapSetType( "ObjsContainerType" );
col = PersMDDColl::createRoot( collName, oColl, collType, db );
}
catch (...)
{
cout <<"Error caught ................."<< endl;
return -1;
}
cout << "Committing TA ..."<< endl;
ta.commit( );
/*
cout <<"Freeing types ... "<< endl;
// if ( mType1 ) delete mType1;
cout << "Type 1 freed . "<< endl;
// if ( mType2 ) delete mType2;
cout << "Type 2 freed . "<< endl;
// if ( mt ) delete mt;
cout << "Type mt freed . "<< endl;
// if ( collType1 ) delete collType1;
cout << "Types collType1 freed . "<< endl;
*/
if ( col ) delete col;
cout << "Col freed . "<< endl;
ta.begin( db );
return 0;
}