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,12 +266,15 @@ int cBlockRecordFile::FindRoomForData( int32 dataSize ) //throw (eArchive)
|
||||||
// first, try the last added to block...
|
// first, try the last added to block...
|
||||||
//
|
//
|
||||||
d.TraceDetail( "Looking for room for %d bytes; first trying mLastAddedTo (%d)\n", dataSize, mLastAddedTo );
|
d.TraceDetail( "Looking for room for %d bytes; first trying mLastAddedTo (%d)\n", dataSize, mLastAddedTo );
|
||||||
|
if( mLastAddedTo >= 0 )
|
||||||
|
{
|
||||||
util_InitBlockArray( mvBlocks[mLastAddedTo] );
|
util_InitBlockArray( mvBlocks[mLastAddedTo] );
|
||||||
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
|
if( mvBlocks[mLastAddedTo].GetAvailableSpace() >= dataSize )
|
||||||
{
|
{
|
||||||
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
|
d.TraceDetail( "---Found room in block %d\n", mLastAddedTo );
|
||||||
return mLastAddedTo;
|
return mLastAddedTo;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// ok, I guess we will have to iterate through all the blocks...
|
// ok, I guess we will have to iterate through all the blocks...
|
||||||
//
|
//
|
||||||
|
|
|
@ -263,6 +263,9 @@ void cDbDataSourceIter::SetFCOData( const iFCO* pFCO ) //throw (eError)
|
||||||
{
|
{
|
||||||
mDbIter.RemoveData();
|
mDbIter.RemoveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pFCO )
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// write the fco's property set to a memory archive...
|
// write the fco's property set to a memory archive...
|
||||||
//
|
//
|
||||||
|
@ -278,6 +281,7 @@ void cDbDataSourceIter::SetFCOData( const iFCO* pFCO ) //throw (eError)
|
||||||
//
|
//
|
||||||
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
|
mDbIter.SetData( arch.GetMemory(), arch.CurrentPos() );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// AddChildArray
|
// AddChildArray
|
||||||
|
|
|
@ -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
|
// pwd
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
else if( verb.compare( _T("pwd") ) == 0 )
|
else if( verb.compare( _T("pwd") ) == 0 )
|
||||||
|
@ -380,11 +478,11 @@ void cDbExplore::Execute( cFCODatabaseFileIter& dbIter )
|
||||||
|
|
||||||
// make sure the file is still valid...
|
// make sure the file is still valid...
|
||||||
//
|
//
|
||||||
/*
|
|
||||||
#ifdef _BLOCKFILE_DEBUG
|
#ifdef _BLOCKFILE_DEBUG
|
||||||
db.AssertAllBlocksValid() ;
|
dbIter.GetDb().AssertAllBlocksValid();
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pIter;
|
delete pIter;
|
||||||
|
|
|
@ -41,268 +41,174 @@
|
||||||
#include "fco/fcoprop.h"
|
#include "fco/fcoprop.h"
|
||||||
#include "fco/fco.h"
|
#include "fco/fco.h"
|
||||||
#include "twtest/test.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;
|
if (iter.SeekTo(filename.c_str()))
|
||||||
TCIN >> noun;
|
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||||
if( noun.compare( _T("!$") ) == 0 )
|
|
||||||
{
|
|
||||||
noun = prevNoun;
|
|
||||||
}
|
|
||||||
prevNoun = noun;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
cFCOName fname(filename);
|
||||||
// TODO -- implement this with the prop displayer as well!
|
|
||||||
//
|
|
||||||
static void PrintFCO( const iFCO* pFCO )
|
|
||||||
{
|
|
||||||
TCOUT.setf(std::ios::left);
|
|
||||||
|
|
||||||
TCOUT << "------- " << pFCO->GetName().AsString() << " -------" << std::endl;
|
if (with_data)
|
||||||
//
|
|
||||||
// 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 ) )
|
iFCO* pFCO = new cFSObject(fname);
|
||||||
{
|
iter.AddFCO(filename,pFCO);
|
||||||
TCOUT << "[";
|
|
||||||
TCOUT.width(2);
|
|
||||||
TCOUT << i << "]" ;
|
|
||||||
TCOUT.width(25);
|
|
||||||
TCOUT << pPropSet->GetPropName(i);
|
|
||||||
TCOUT.width(0);
|
|
||||||
TCOUT << pPropSet->GetPropAt( i )->AsString() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TCOUT << "--------------------------------------------" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TestDbDataSource()
|
|
||||||
{
|
|
||||||
TCERR << std::endl << "TestDbDataSource needs to be redesigned so it doesn't require user interaction" << std::endl;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
cDebug d("TestDbDataSource");
|
|
||||||
cHierDatabase db;
|
|
||||||
|
|
||||||
const TSTRING dbName = _T("tw.db");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
TCOUT << "Object has no data associated with it." << std::endl;
|
iter.AddFCO(filename,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(iter.HasFCOData() == with_data);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
static void AddDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||||
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() ) )
|
|
||||||
{
|
{
|
||||||
|
if (iter.SeekTo(filename.c_str()))
|
||||||
|
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||||
|
|
||||||
|
iter.AddFCO(filename, 0);
|
||||||
iter.AddChildArray();
|
iter.AddChildArray();
|
||||||
|
|
||||||
|
TEST(iter.CanDescend());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
static void RemoveDirectory(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
TCOUT << "Removing the child of " << filename << std::endl;
|
||||||
}
|
if( iter.SeekTo( filename.c_str() ) )
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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
|
//TODO -- check that it has an empty child
|
||||||
iter.DeleteChildArray();
|
iter.RemoveChildArray();
|
||||||
|
iter.RemoveFCO();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
TCOUT << "Unable to find object " << filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//-----------------------------------------------------------------
|
static void RemoveFile(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||||
// rm
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
else if( verb.compare( _T("rm") ) == 0 )
|
|
||||||
{
|
|
||||||
GetNoun(noun);
|
|
||||||
TCOUT << "Removing object " << noun << std::endl;
|
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
|
||||||
{
|
{
|
||||||
|
TCOUT << "Removing object " << filename << std::endl;
|
||||||
|
cFCOName fname(filename);
|
||||||
|
iter.SeekToFCO(fname);
|
||||||
|
|
||||||
if( iter.CanDescend() )
|
if( iter.CanDescend() )
|
||||||
{
|
{
|
||||||
TCOUT << "Can't delete object; it still has children." << std::endl;
|
TCOUT << "Can't delete object; it still has children." << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
iter.RemoveFCOData();
|
||||||
iter.RemoveFCO();
|
iter.RemoveFCO();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
static void ChDir(cDbDataSourceIter& iter, const TSTRING& filename)
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
if( filename.compare( _T("..") ) == 0 )
|
||||||
}
|
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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() )
|
if( iter.AtRoot() )
|
||||||
{
|
TCOUT << "At root already" << std::endl;
|
||||||
TCOUT << "Can't ascend above root." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TCOUT << "Ascending..." << std::endl;
|
TCOUT << "Ascending..." << std::endl;
|
||||||
iter.Ascend();
|
iter.Ascend();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
if( iter.SeekTo( filename.c_str() ) )
|
||||||
{
|
{
|
||||||
if( iter.CanDescend() )
|
if( !iter.CanDescend())
|
||||||
{
|
TCOUT << filename << " has no children; can't descend." << std::endl;
|
||||||
TCOUT << "Descending into " << noun << std::endl;
|
|
||||||
|
TCOUT << "Descending into " << filename << std::endl;
|
||||||
iter.Descend();
|
iter.Descend();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCOUT << noun << " has no children; can't descend." << std::endl;
|
TCOUT << "Unable to find object " << filename << std::endl;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the file is still valid...
|
static void AssertData(cDbDataSourceIter& iter, const TSTRING& filename, bool should_have)
|
||||||
//
|
{
|
||||||
#ifdef _BLOCKFILE_DEBUG
|
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()
|
||||||
|
{
|
||||||
|
cHierDatabase db;
|
||||||
|
db.Open( _T("test.db"), 5, true);
|
||||||
|
cDbDataSourceIter 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();
|
db.AssertAllBlocksValid();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TCOUT << "Exiting..." << std::endl;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( eError& e )
|
|
||||||
{
|
|
||||||
d.TraceError("*** Caught error: %d %s\n", e.GetID(), e.GetMsg().c_str() );
|
|
||||||
TEST(false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -35,137 +35,56 @@
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "core/error.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)
|
||||||
{
|
{
|
||||||
d.TraceDebug( "Processing entry %s\n", iter.GetName() );
|
if (iter.SeekTo(filename.c_str()))
|
||||||
if( iter.CanDescend() )
|
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||||
|
|
||||||
|
iter.CreateEntry(filename);
|
||||||
|
|
||||||
|
if (with_data)
|
||||||
{
|
{
|
||||||
d.TraceDebug( ">>Descending...\n" );
|
iter.SetData( (int8*)g_block_data.c_str(), g_block_data.length() + 1 );
|
||||||
PrintDb(iter, d, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.TraceDebug( "-- Done Processing directory %s\n", iter.GetCwd().c_str() );
|
TEST(iter.HasData() == with_data);
|
||||||
}*/
|
|
||||||
|
|
||||||
static void GetNoun( TSTRING& noun )
|
|
||||||
{
|
|
||||||
static TSTRING prevNoun;
|
|
||||||
TCIN >> noun;
|
|
||||||
if( noun.compare( _T("!$") ) == 0 )
|
|
||||||
{
|
|
||||||
noun = prevNoun;
|
|
||||||
}
|
|
||||||
prevNoun = noun;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
static void AddDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||||
// 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 (iter.SeekTo(filename.c_str()))
|
||||||
|
TCOUT << "Object " << filename << " already exists!" << std::endl;
|
||||||
|
|
||||||
#if 0
|
iter.CreateEntry(filename);
|
||||||
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 )
|
|
||||||
{
|
|
||||||
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();
|
iter.CreateChildArray();
|
||||||
|
|
||||||
|
TEST(iter.CanDescend());
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
static void RemoveDirectory(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
TCOUT << "Removing the child of " << filename << std::endl;
|
||||||
}
|
if( iter.SeekTo( filename.c_str() ) )
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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
|
//TODO -- check that it has an empty child
|
||||||
iter.DeleteChildArray();
|
iter.DeleteChildArray();
|
||||||
|
iter.DeleteEntry();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
TCOUT << "Unable to find object " << filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// rm
|
static void RemoveFile(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||||
//-----------------------------------------------------------------
|
|
||||||
else if( verb.compare( _T("rm") ) == 0 )
|
|
||||||
{
|
{
|
||||||
GetNoun(noun);
|
TCOUT << "Removing object " << filename << std::endl;
|
||||||
TCOUT << "Removing object " << noun << std::endl;
|
if( iter.SeekTo( filename.c_str() ) )
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
|
||||||
{
|
{
|
||||||
if( iter.CanDescend() )
|
if( iter.CanDescend() )
|
||||||
{
|
{
|
||||||
|
@ -173,181 +92,118 @@ void TestHierDatabaseInteractive()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
iter.RemoveData();
|
||||||
iter.DeleteEntry();
|
iter.DeleteEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCOUT << "Unable to find object " << noun << std::endl;
|
TCOUT << "Unable to find object " << filename << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// pwd
|
static void ChDir(cHierDatabase::iterator& iter, const TSTRING& filename)
|
||||||
//-----------------------------------------------------------------
|
|
||||||
else if( verb.compare( _T("pwd") ) == 0 )
|
|
||||||
{
|
{
|
||||||
TCOUT << iter.GetCwd() << std::endl;
|
if( filename.compare( _T("..") ) == 0 )
|
||||||
}
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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() )
|
if( iter.AtRoot() )
|
||||||
{
|
TCOUT << "At root already" << std::endl;
|
||||||
TCOUT << "Can't ascend above root." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TCOUT << "Ascending..." << std::endl;
|
TCOUT << "Ascending..." << std::endl;
|
||||||
iter.Ascend();
|
iter.Ascend();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
if( iter.SeekTo( filename.c_str() ) )
|
||||||
{
|
{
|
||||||
if( iter.CanDescend() )
|
if( !iter.CanDescend())
|
||||||
{
|
TCOUT << filename << " has no children; can't descend." << std::endl;
|
||||||
TCOUT << "Descending into " << noun << std::endl;
|
|
||||||
|
TCOUT << "Descending into " << filename << std::endl;
|
||||||
iter.Descend();
|
iter.Descend();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCOUT << noun << " has no children; can't descend." << std::endl;
|
TCOUT << "Unable to find object " << filename << 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
static void AssertData(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// rm
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
else if( verb.compare( _T("rm") ) == 0 )
|
|
||||||
{
|
{
|
||||||
GetNoun(noun);
|
bool exists = iter.SeekTo( filename.c_str() );
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
TEST(exists == should_have);
|
||||||
{
|
|
||||||
if( iter.CanDescend() )
|
|
||||||
{
|
|
||||||
TCOUT << noun << " doesn't exist; can't delete." << std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TCOUT << "Deleting " << iter.GetName() << std::endl;
|
|
||||||
iter.DeleteEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if (exists)
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// set
|
|
||||||
//-----------------------------------------------------------------
|
|
||||||
else if( verb.compare( _T("set") ) == 0 )
|
|
||||||
{
|
{
|
||||||
GetNoun(noun);
|
bool has_data = iter.HasData();
|
||||||
if( iter.SeekTo( noun.c_str() ) )
|
TEST(has_data == should_have);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if (has_data)
|
||||||
//-----------------------------------------------------------------
|
|
||||||
// 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;
|
int32 dummyLength;
|
||||||
TCOUT << noun << "'s data is: " << (TCHAR*)iter.GetData(dummyLength) << std::endl;
|
TSTRING read_str( (TCHAR*)iter.GetData(dummyLength) );
|
||||||
|
TEST(read_str == g_block_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
static void AssertExists(cHierDatabase::iterator& iter, const TSTRING& filename, bool should_have)
|
||||||
{
|
{
|
||||||
TCOUT << "Can't find object " << noun << std::endl;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the file is still valid...
|
void TestHierDatabaseBasic()
|
||||||
//
|
{
|
||||||
#ifdef _BLOCKFILE_DEBUG
|
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();
|
db.AssertAllBlocksValid();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TCOUT << "Exiting..." << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch( eError& e )
|
|
||||||
{
|
|
||||||
d.TraceError( "Exception caught: %d %s\n", e.GetID(), e.GetMsg().c_str() );
|
|
||||||
TEST( false );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -112,9 +112,9 @@ void TestFSPropDisplayer();
|
||||||
void TestGenre();
|
void TestGenre();
|
||||||
void TestFSDataSourceIter();
|
void TestFSDataSourceIter();
|
||||||
void TestGenerateDb();
|
void TestGenerateDb();
|
||||||
void TestHierDatabaseInteractive();
|
void TestHierDatabaseBasic();
|
||||||
void TestGenreSwitcher();
|
void TestGenreSwitcher();
|
||||||
void TestDbDataSource();
|
void TestDbDataSourceBasic();
|
||||||
void TestGenreSpecList();
|
void TestGenreSpecList();
|
||||||
void TestIntegrityCheck();
|
void TestIntegrityCheck();
|
||||||
void TestFCODatabaseFile();
|
void TestFCODatabaseFile();
|
||||||
|
@ -213,9 +213,9 @@ static void Test(int testID)
|
||||||
case 52: TestGenre(); break;
|
case 52: TestGenre(); break;
|
||||||
case 53: TestFSDataSourceIter(); break;
|
case 53: TestFSDataSourceIter(); break;
|
||||||
//case 54: TestGenerateDb(); break;
|
//case 54: TestGenerateDb(); break;
|
||||||
case 55: TestHierDatabaseInteractive(); break;
|
case 55: TestHierDatabaseBasic(); break;
|
||||||
case 56: TestGenreSwitcher(); break;
|
case 56: TestGenreSwitcher(); break;
|
||||||
case 57: TestDbDataSource(); break;
|
case 57: TestDbDataSourceBasic(); break;
|
||||||
case 58: TestGenreSpecList(); break;
|
case 58: TestGenreSpecList(); break;
|
||||||
//case 59: TestIntegrityCheck(); break;
|
//case 59: TestIntegrityCheck(); break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue