Redo hierdatabase & dbdatasource unit tests so they do something useful; add sanity checks to cBlockRecordFile::FindRoomForData and cDbDataSourceIter::SetFCOData, the need for these was exposed by the new tests. Also update debug-only DB Explore mode with a few more commands
This commit is contained in:
parent
fdb25ca903
commit
5a425591ce
|
@ -266,11 +266,14 @@ int cBlockRecordFile::FindRoomForData( int32 dataSize ) //throw (eArchive)
|
|||
// first, try the last added to block...
|
||||
//
|
||||
d.TraceDetail( "Looking for room for %d bytes; first trying mLastAddedTo (%d)\n", dataSize, mLastAddedTo );
|
||||
util_InitBlockArray( mvBlocks[mLastAddedTo] );
|
||||
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
|
||||
if( mLastAddedTo >= 0 )
|
||||
{
|
||||
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
|
||||
return mLastAddedTo;
|
||||
util_InitBlockArray( mvBlocks[mLastAddedTo] );
|
||||
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
|
||||
{
|
||||
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
|
||||
return mLastAddedTo;
|
||||
}
|
||||
}
|
||||
//
|
||||
// ok, I guess we will have to iterate through all the blocks...
|
||||
|
|
|
@ -263,20 +263,24 @@ void cDbDataSourceIter::SetFCOData( const iFCO* pFCO ) //throw (eError)
|
|||
{
|
||||
mDbIter.RemoveData();
|
||||
}
|
||||
//
|
||||
// write the fco's property set to a memory archive...
|
||||
//
|
||||
// TODO -- does this need to be static?
|
||||
static cMemoryArchive arch;
|
||||
arch.Seek ( 0, cBidirArchive::BEGINNING );
|
||||
cSerializerImpl ser (arch, cSerializerImpl::S_WRITE);
|
||||
ser.Init();
|
||||
ser.WriteObject ( pFCO->GetPropSet() );
|
||||
ser.Finit();
|
||||
//
|
||||
// write this to the archive...
|
||||
//
|
||||
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
|
||||
|
||||
if( pFCO )
|
||||
{
|
||||
//
|
||||
// write the fco's property set to a memory archive...
|
||||
//
|
||||
// TODO -- does this need to be static?
|
||||
static cMemoryArchive arch;
|
||||
arch.Seek ( 0, cBidirArchive::BEGINNING );
|
||||
cSerializerImpl ser (arch, cSerializerImpl::S_WRITE);
|
||||
ser.Init();
|
||||
ser.WriteObject ( pFCO->GetPropSet() );
|
||||
ser.Finit();
|
||||
//
|
||||
// write this to the archive...
|
||||
//
|
||||
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -250,6 +250,104 @@ void cDbExplore::Execute( cFCODatabaseFileIter& dbIter )
|
|||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mkdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mkdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making a child of " << noun << std::endl;
|
||||
if( pIter->SeekTo( noun.c_str() ) )
|
||||
{
|
||||
pIter->AddChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mk
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mk") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making object " << noun << std::endl;
|
||||
if( pIter->SeekTo( noun.c_str() ) )
|
||||
{
|
||||
TCOUT << "Error: object already exists!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
pIter->AddFCO( noun, 0 ); // add a null fco for now
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rmdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rmdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing the child of " << noun << std::endl;
|
||||
if( pIter->SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( pIter->CanRemoveChildArray() )
|
||||
{
|
||||
pIter->RemoveChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rm
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rm") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing object " << noun << std::endl;
|
||||
if( pIter->SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( pIter->CanDescend() )
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
pIter->RemoveFCO();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
else if( verb.compare( _T("rmdata") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing object data " << noun << std::endl;
|
||||
if( pIter->SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( pIter->CanDescend() )
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
pIter->RemoveFCOData();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// pwd
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("pwd") ) == 0 )
|
||||
|
@ -380,11 +478,11 @@ void cDbExplore::Execute( cFCODatabaseFileIter& dbIter )
|
|||
|
||||
// make sure the file is still valid...
|
||||
//
|
||||
/*
|
||||
|
||||
#ifdef _BLOCKFILE_DEBUG
|
||||
db.AssertAllBlocksValid() ;
|
||||
dbIter.GetDb().AssertAllBlocksValid();
|
||||
#endif
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
delete pIter;
|
||||
|
|
|
@ -41,268 +41,174 @@
|
|||
#include "fco/fcoprop.h"
|
||||
#include "fco/fco.h"
|
||||
#include "twtest/test.h"
|
||||
#include "fs/fsobject.h"
|
||||
|
||||
static void GetNoun( TSTRING& noun )
|
||||
static void AddFile(cDbDataSourceIter& iter, const TSTRING& filename, bool with_data=false)
|
||||
{
|
||||
static TSTRING prevNoun;
|
||||
TCIN >> noun;
|
||||
if( noun.compare( _T("!$") ) == 0 )
|
||||
if (iter.SeekTo(filename.c_str()))
|
||||
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||
|
||||
cFCOName fname(filename);
|
||||
|
||||
if (with_data)
|
||||
{
|
||||
noun = prevNoun;
|
||||
iFCO* pFCO = new cFSObject(fname);
|
||||
iter.AddFCO(filename,pFCO);
|
||||
}
|
||||
prevNoun = noun;
|
||||
else
|
||||
{
|
||||
iter.AddFCO(filename,0);
|
||||
}
|
||||
|
||||
TEST(iter.HasFCOData() == with_data);
|
||||
}
|
||||
|
||||
//
|
||||
// TODO -- implement this with the prop displayer as well!
|
||||
//
|
||||
static void PrintFCO( const iFCO* pFCO )
|
||||
static void AddDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||
{
|
||||
TCOUT.setf(std::ios::left);
|
||||
|
||||
TCOUT << "------- " << pFCO->GetName().AsString() << " -------" << std::endl;
|
||||
//
|
||||
// iterate over all of the properties
|
||||
//
|
||||
const iFCOPropSet* pPropSet = pFCO->GetPropSet();
|
||||
cFCOPropVector v = pPropSet->GetValidVector();
|
||||
for( int i=0; i < pPropSet->GetNumProps(); i++ )
|
||||
{
|
||||
if( v.ContainsItem( i ) )
|
||||
if (iter.SeekTo(filename.c_str()))
|
||||
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||
|
||||
iter.AddFCO(filename, 0);
|
||||
iter.AddChildArray();
|
||||
|
||||
TEST(iter.CanDescend());
|
||||
}
|
||||
|
||||
static void RemoveDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||
{
|
||||
TCOUT << "Removing the child of " << filename << std::endl;
|
||||
if( iter.SeekTo( filename.c_str() ) )
|
||||
{
|
||||
//TODO -- check that it has an empty child
|
||||
iter.RemoveChildArray();
|
||||
iter.RemoveFCO();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveFile(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||
{
|
||||
TCOUT << "Removing object " << filename << std::endl;
|
||||
cFCOName fname(filename);
|
||||
iter.SeekToFCO(fname);
|
||||
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.RemoveFCOData();
|
||||
iter.RemoveFCO();
|
||||
}
|
||||
}
|
||||
|
||||
static void ChDir(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||
{
|
||||
if( filename.compare( _T("..") ) == 0 )
|
||||
{
|
||||
if( iter.AtRoot() )
|
||||
TCOUT << "At root already" << std::endl;
|
||||
|
||||
TCOUT << "Ascending..." << std::endl;
|
||||
iter.Ascend();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iter.SeekTo( filename.c_str() ) )
|
||||
{
|
||||
TCOUT << "[";
|
||||
TCOUT.width(2);
|
||||
TCOUT << i << "]" ;
|
||||
TCOUT.width(25);
|
||||
TCOUT << pPropSet->GetPropName(i);
|
||||
TCOUT.width(0);
|
||||
TCOUT << pPropSet->GetPropAt( i )->AsString() << std::endl;
|
||||
if( !iter.CanDescend())
|
||||
TCOUT << filename << " has no children; can't descend." << std::endl;
|
||||
|
||||
TCOUT << "Descending into " << filename << std::endl;
|
||||
iter.Descend();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
TCOUT << "--------------------------------------------" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void TestDbDataSource()
|
||||
static void AssertData(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
TEST(exists == should_have);
|
||||
|
||||
if (exists)
|
||||
{
|
||||
bool has_data = iter.HasFCOData();
|
||||
TEST(has_data == should_have);
|
||||
|
||||
if (has_data)
|
||||
{
|
||||
iFCO* pFCO = iter.CreateFCO();
|
||||
TEST(pFCO);
|
||||
TCOUT << "Roundtrip FCOName = " << pFCO->GetName().AsString() << std::endl;
|
||||
TSTRING expected = filename + "/";
|
||||
TEST(pFCO->GetName().AsString() == expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AssertExists(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
TEST(exists == should_have);
|
||||
}
|
||||
|
||||
static void AssertChildren(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
|
||||
if (exists)
|
||||
{
|
||||
bool has_children = iter.CanDescend();
|
||||
TEST(has_children == should_have);
|
||||
}
|
||||
}
|
||||
|
||||
void TestDbDataSourceBasic()
|
||||
{
|
||||
TCERR << std::endl << "TestDbDataSource needs to be redesigned so it doesn't require user interaction" << std::endl;
|
||||
|
||||
#if 0
|
||||
cDebug d("TestDbDataSource");
|
||||
cHierDatabase db;
|
||||
db.Open( _T("test.db"), 5, true);
|
||||
cDbDataSourceIter iter(&db);
|
||||
|
||||
const TSTRING dbName = _T("tw.db");
|
||||
AddFile(iter, "file1", true);
|
||||
AddFile(iter, "file2", false);
|
||||
AddFile(iter, "file3", false);
|
||||
|
||||
AddDirectory(iter, "dir1");
|
||||
AddDirectory(iter, "dir2");
|
||||
AddDirectory(iter, "dir3");
|
||||
|
||||
AssertData(iter, "file1", true);
|
||||
|
||||
ChDir(iter, "dir1");
|
||||
AddFile(iter, "dir1_file1");
|
||||
ChDir(iter, "..");
|
||||
|
||||
RemoveFile(iter, "file1");
|
||||
RemoveFile(iter, "file2");
|
||||
|
||||
AssertExists(iter, "file1", false);
|
||||
AssertExists(iter, "file2", false);
|
||||
AssertExists(iter, "file3", true);
|
||||
|
||||
RemoveDirectory(iter, "dir2");
|
||||
|
||||
AssertExists(iter, "dir1", true);
|
||||
AssertExists(iter, "dir2", false);
|
||||
AssertExists(iter, "dir3", true);
|
||||
|
||||
AssertChildren(iter, "dir1", true);
|
||||
AssertChildren(iter, "dir3", true);
|
||||
AssertChildren(iter, "file3", false);
|
||||
|
||||
try
|
||||
{
|
||||
// TODO -- get the case sensitiveness and delimiting char out of the factory instead of iFSServices
|
||||
//
|
||||
TCOUT << _T("Opening database ") << dbName << std::endl;
|
||||
db.Open( dbName, 5, false );
|
||||
cDbDataSourceIter iter( &db );
|
||||
|
||||
////////////////////////////
|
||||
// the main event loop...
|
||||
////////////////////////////
|
||||
while( true )
|
||||
{
|
||||
TSTRING verb, noun;
|
||||
TCOUT << _T(">>");
|
||||
TCIN >> verb;
|
||||
//
|
||||
// ok, now we switch on the command...
|
||||
//
|
||||
//-----------------------------------------------------------------
|
||||
// quit
|
||||
//-----------------------------------------------------------------
|
||||
if( verb.compare( _T("quit") ) == 0 )
|
||||
{
|
||||
// the quit command...
|
||||
break;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// print
|
||||
//-----------------------------------------------------------------
|
||||
if( verb.compare( _T("print") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.HasFCOData() )
|
||||
{
|
||||
iFCO* pFCO = iter.CreateFCO();
|
||||
PrintFCO( pFCO );
|
||||
pFCO->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Object has no data associated with it." << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mkdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mkdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making a child of " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
iter.AddChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mk
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mk") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making object " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
TCOUT << "Error: object already exists!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.AddFCO( noun, 0 ); // add a null fco for now
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rmdir
|
||||
//-----------------------------------------------------------------
|
||||
// TODO -- still needs to be implemented in the iterator class!
|
||||
//
|
||||
/*
|
||||
else if( verb.compare( _T("rmdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing the child of " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
//TODO -- check that it has an empty child
|
||||
iter.DeleteChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//-----------------------------------------------------------------
|
||||
// rm
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rm") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing object " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.RemoveFCO();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// pwd
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("pwd") ) == 0 )
|
||||
{
|
||||
TCOUT << iter.GetParentName().AsString() << std::endl;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// ls
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("ls") ) == 0 )
|
||||
{
|
||||
int cnt = 0;
|
||||
for( iter.SeekBegin(); ! iter.Done(); iter.Next(), cnt++ )
|
||||
{
|
||||
TCOUT << "[" << cnt ;
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "]*\t" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "]\t" ;
|
||||
}
|
||||
TCOUT << iter.GetShortName() << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// cd
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("cd") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( noun.compare( _T("..") ) == 0 )
|
||||
{
|
||||
if( iter.AtRoot() )
|
||||
{
|
||||
TCOUT << "Can't ascend above root." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Ascending..." << std::endl;
|
||||
iter.Ascend();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Descending into " << noun << std::endl;
|
||||
iter.Descend();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << noun << " has no children; can't descend." << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the file is still valid...
|
||||
//
|
||||
#ifdef _BLOCKFILE_DEBUG
|
||||
db.AssertAllBlocksValid() ;
|
||||
#endif
|
||||
}
|
||||
|
||||
TCOUT << "Exiting..." << std::endl;
|
||||
|
||||
|
||||
}
|
||||
catch( eError& e )
|
||||
{
|
||||
d.TraceError("*** Caught error: %d %s\n", e.GetID(), e.GetMsg().c_str() );
|
||||
TEST(false);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
db.AssertAllBlocksValid();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -35,319 +35,175 @@
|
|||
#include "test.h"
|
||||
#include "core/error.h"
|
||||
|
||||
/*static void PrintDb( cHierDatabase::iterator iter, cDebug d, bool bFirst = true )
|
||||
{
|
||||
if( ! bFirst )
|
||||
{
|
||||
iter.Descend();
|
||||
}
|
||||
d.TraceDebug( "-- Processing directory %s\n", iter.GetCwd().c_str() );
|
||||
|
||||
for( iter.SeekBegin(); ! iter.Done(); iter.Next() )
|
||||
|
||||
static const TSTRING g_block_data = "Hello World Hello World Hello World Hello World";
|
||||
|
||||
|
||||
static void AddFile(cHierDatabase::iterator& iter, const TSTRING& filename, bool with_data=false)
|
||||
{
|
||||
if (iter.SeekTo(filename.c_str()))
|
||||
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||
|
||||
iter.CreateEntry(filename);
|
||||
|
||||
if (with_data)
|
||||
{
|
||||
iter.SetData( (int8*)g_block_data.c_str(), g_block_data.length() + 1 );
|
||||
}
|
||||
|
||||
TEST(iter.HasData() == with_data);
|
||||
}
|
||||
|
||||
static void AddDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||
{
|
||||
if (iter.SeekTo(filename.c_str()))
|
||||
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||
|
||||
iter.CreateEntry(filename);
|
||||
iter.CreateChildArray();
|
||||
|
||||
TEST(iter.CanDescend());
|
||||
}
|
||||
|
||||
static void RemoveDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||
{
|
||||
TCOUT << "Removing the child of " << filename << std::endl;
|
||||
if( iter.SeekTo( filename.c_str() ) )
|
||||
{
|
||||
//TODO -- check that it has an empty child
|
||||
iter.DeleteChildArray();
|
||||
iter.DeleteEntry();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveFile(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||
{
|
||||
TCOUT << "Removing object " << filename << std::endl;
|
||||
if( iter.SeekTo( filename.c_str() ) )
|
||||
{
|
||||
d.TraceDebug( "Processing entry %s\n", iter.GetName() );
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
d.TraceDebug( ">>Descending...\n" );
|
||||
PrintDb(iter, d, false);
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
d.TraceDebug( "-- Done Processing directory %s\n", iter.GetCwd().c_str() );
|
||||
}*/
|
||||
|
||||
static void GetNoun( TSTRING& noun )
|
||||
{
|
||||
static TSTRING prevNoun;
|
||||
TCIN >> noun;
|
||||
if( noun.compare( _T("!$") ) == 0 )
|
||||
{
|
||||
noun = prevNoun;
|
||||
}
|
||||
prevNoun = noun;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TestHierDatabaseInteractive -- this provides an interactive interface to
|
||||
// the database
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void TestHierDatabaseInteractive()
|
||||
{
|
||||
TCERR << std::endl << "TestHierDatabaseInteractive needs to be redesigned (& renamed) to not require user interaction" << std::endl;
|
||||
|
||||
#if 0
|
||||
cDebug d( "TestHierDatabaseInteractive" );
|
||||
try
|
||||
{
|
||||
cHierDatabase db;
|
||||
//db.Open( _T("c:/tmp/tw.hdb"), 5, true);
|
||||
db.Open( _T("tw.db"), 5, false);
|
||||
cHierDatabase::iterator iter(&db);
|
||||
|
||||
while( true )
|
||||
else
|
||||
{
|
||||
TSTRING verb, noun;
|
||||
TCOUT << _T(">>");
|
||||
TCIN >> verb;
|
||||
//
|
||||
// ok, now we switch on the command...
|
||||
//
|
||||
//-----------------------------------------------------------------
|
||||
// quit
|
||||
//-----------------------------------------------------------------
|
||||
if( verb.compare( _T("quit") ) == 0 )
|
||||
{
|
||||
// the quit command...
|
||||
break;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// print
|
||||
//-----------------------------------------------------------------
|
||||
if( verb.compare( _T("print") ) == 0 )
|
||||
{
|
||||
// the print command...
|
||||
ASSERT( false );
|
||||
// TODO -- Implement this!
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mkdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mkdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making a child of " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
iter.CreateChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// mk
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("mk") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Making object " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
TCOUT << "Error: object already exists!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.CreateEntry( noun );
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rmdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rmdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing the child of " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
//TODO -- check that it has an empty child
|
||||
iter.DeleteChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rm
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rm") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
TCOUT << "Removing object " << noun << std::endl;
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter.DeleteEntry();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// pwd
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("pwd") ) == 0 )
|
||||
{
|
||||
TCOUT << iter.GetCwd() << std::endl;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// ls
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("ls") ) == 0 )
|
||||
{
|
||||
int cnt = 0;
|
||||
for( iter.SeekBegin(); ! iter.Done(); iter.Next(), cnt++ )
|
||||
{
|
||||
TCOUT << "[" << cnt ;
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "]*\t" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "]\t" ;
|
||||
}
|
||||
TCOUT << iter.GetName() << std::endl;
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// cd
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("cd") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( noun.compare( _T("..") ) == 0 )
|
||||
{
|
||||
if( iter.AtRoot() )
|
||||
{
|
||||
TCOUT << "Can't ascend above root." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Ascending..." << std::endl;
|
||||
iter.Ascend();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Descending into " << noun << std::endl;
|
||||
iter.Descend();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << noun << " has no children; can't descend." << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << noun << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rmdir
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rmdir") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << "Deleting child of " << iter.GetName() << std::endl;
|
||||
iter.DeleteChildArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << noun << " has no child; can't delete." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// rm
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("rm") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.CanDescend() )
|
||||
{
|
||||
TCOUT << noun << " doesn't exist; can't delete." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Deleting " << iter.GetName() << std::endl;
|
||||
iter.DeleteEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// set
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("set") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( iter.HasData() )
|
||||
{
|
||||
iter.RemoveData();
|
||||
}
|
||||
TSTRING data;
|
||||
TCIN >> data;
|
||||
iter.SetData( (int8*)data.c_str(), data.length() + 1 );
|
||||
TCOUT << "Setting " << noun << "'s data to " << data << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Can't find object " << noun << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// get
|
||||
//-----------------------------------------------------------------
|
||||
else if( verb.compare( _T("get") ) == 0 )
|
||||
{
|
||||
GetNoun(noun);
|
||||
if( iter.SeekTo( noun.c_str() ) )
|
||||
{
|
||||
if( ! iter.HasData() )
|
||||
{
|
||||
TCOUT << "Object has no data!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 dummyLength;
|
||||
TCOUT << noun << "'s data is: " << (TCHAR*)iter.GetData(dummyLength) << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Can't find object " << noun << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// make sure the file is still valid...
|
||||
//
|
||||
#ifdef _BLOCKFILE_DEBUG
|
||||
db.AssertAllBlocksValid() ;
|
||||
#endif
|
||||
iter.RemoveData();
|
||||
iter.DeleteEntry();
|
||||
}
|
||||
|
||||
TCOUT << "Exiting..." << std::endl;
|
||||
|
||||
}
|
||||
catch( eError& e )
|
||||
else
|
||||
{
|
||||
d.TraceError( "Exception caught: %d %s\n", e.GetID(), e.GetMsg().c_str() );
|
||||
TEST( false );
|
||||
TCOUT << "Unable to find object " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void ChDir(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||
{
|
||||
if( filename.compare( _T("..") ) == 0 )
|
||||
{
|
||||
if( iter.AtRoot() )
|
||||
TCOUT << "At root already" << std::endl;
|
||||
|
||||
TCOUT << "Ascending..." << std::endl;
|
||||
iter.Ascend();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iter.SeekTo( filename.c_str() ) )
|
||||
{
|
||||
if( !iter.CanDescend())
|
||||
TCOUT << filename << " has no children; can't descend." << std::endl;
|
||||
|
||||
TCOUT << "Descending into " << filename << std::endl;
|
||||
iter.Descend();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCOUT << "Unable to find object " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AssertData(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
TEST(exists == should_have);
|
||||
|
||||
if (exists)
|
||||
{
|
||||
bool has_data = iter.HasData();
|
||||
TEST(has_data == should_have);
|
||||
|
||||
if (has_data)
|
||||
{
|
||||
int32 dummyLength;
|
||||
TSTRING read_str( (TCHAR*)iter.GetData(dummyLength) );
|
||||
TEST(read_str == g_block_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AssertExists(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
TEST(exists == should_have);
|
||||
}
|
||||
|
||||
static void AssertChildren(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
|
||||
{
|
||||
bool exists = iter.SeekTo( filename.c_str() );
|
||||
|
||||
if (exists)
|
||||
{
|
||||
bool has_children = iter.CanDescend();
|
||||
TEST(has_children == should_have);
|
||||
}
|
||||
}
|
||||
|
||||
void TestHierDatabaseBasic()
|
||||
{
|
||||
cHierDatabase db;
|
||||
db.Open( _T("test.db"), 5, true);
|
||||
cHierDatabase::iterator iter(&db);
|
||||
|
||||
AddFile(iter, "file1", true);
|
||||
AddFile(iter, "file2", false);
|
||||
AddFile(iter, "file3", false);
|
||||
|
||||
AddDirectory(iter, "dir1");
|
||||
AddDirectory(iter, "dir2");
|
||||
AddDirectory(iter, "dir3");
|
||||
|
||||
AssertData(iter, "file1", true);
|
||||
|
||||
ChDir(iter, "dir1");
|
||||
AddFile(iter, "dir1_file1");
|
||||
ChDir(iter, "..");
|
||||
|
||||
RemoveFile(iter, "file1");
|
||||
RemoveFile(iter, "file2");
|
||||
|
||||
AssertExists(iter, "file1", false);
|
||||
AssertExists(iter, "file2", false);
|
||||
AssertExists(iter, "file3", true);
|
||||
|
||||
RemoveDirectory(iter, "dir2");
|
||||
|
||||
AssertExists(iter, "dir1", true);
|
||||
AssertExists(iter, "dir2", false);
|
||||
AssertExists(iter, "dir3", true);
|
||||
|
||||
AssertChildren(iter, "dir1", true);
|
||||
AssertChildren(iter, "dir3", true);
|
||||
AssertChildren(iter, "file3", false);
|
||||
|
||||
#ifdef DEBUG
|
||||
db.AssertAllBlocksValid();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ void TestFSPropDisplayer();
|
|||
void TestGenre();
|
||||
void TestFSDataSourceIter();
|
||||
void TestGenerateDb();
|
||||
void TestHierDatabaseInteractive();
|
||||
void TestHierDatabaseBasic();
|
||||
void TestGenreSwitcher();
|
||||
void TestDbDataSource();
|
||||
void TestDbDataSourceBasic();
|
||||
void TestGenreSpecList();
|
||||
void TestIntegrityCheck();
|
||||
void TestFCODatabaseFile();
|
||||
|
@ -213,9 +213,9 @@ static void Test(int testID)
|
|||
case 52: TestGenre(); break;
|
||||
case 53: TestFSDataSourceIter(); break;
|
||||
//case 54: TestGenerateDb(); break;
|
||||
case 55: TestHierDatabaseInteractive(); break;
|
||||
case 55: TestHierDatabaseBasic(); break;
|
||||
case 56: TestGenreSwitcher(); break;
|
||||
case 57: TestDbDataSource(); break;
|
||||
case 57: TestDbDataSourceBasic(); break;
|
||||
case 58: TestGenreSpecList(); break;
|
||||
//case 59: TestIntegrityCheck(); break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue