cHierDatabaseIter::cHierDatabaseIter( cHierDatabase* pDb ) //throw(eArchive)
:   mpDb    ( pDb ),
    mCurPath( )
{
    ASSERT( pDb != 0);
    mCurPath.SetCaseSensitive   ( mpDb->IsCaseSensitive() );
    mCurPath.SetDelimiter       ( mpDb->GetDelimitingChar() );
    //
    // load in the root array...
    //
    SeekToRoot();
}
///////////////////////////////////////////////////////////////////////////////
// SeekToDirectory
///////////////////////////////////////////////////////////////////////////////
bool cDbDataSourceIter::SeekToDirectory( const cFCOName& parentName, bool bCreate )
{
	cDebug d( "cDbDataSourceIter::SeekToDirectory" );
	//
	// the first task is to ascend until we are in a directory that we can descend into to 
	// reach parentName...
	//
	cFCOName curParent = GetParentName();
	d.TraceDebug( _T("Entering... Seeking to %s (cwd = %s)\n"), parentName.AsString().c_str(), curParent.AsString().c_str() );
	int ascendCount ;
	switch( curParent.GetRelationship( parentName ) )
	{
		case cFCOName::REL_BELOW:
			//
			// we must ascend...
			//
			ascendCount = curParent.GetSize() - parentName.GetSize();
			d.TraceDetail( _T("\tAscending %d times...\n"), ascendCount );
			ASSERT( ascendCount > 0 );
			for( ; ascendCount > 0; ascendCount-- )
				Ascend();
			break;
		case cFCOName::REL_ABOVE:
			//
			// we are above the needed directory; nothing else to do here...
			//
			d.TraceDetail( _T("\tAbove; not ascending...\n") );
			break;
		case cFCOName::REL_EQUAL:
			//
			// we need to do nothing else here...
			//
			d.TraceDetail( _T("\tEqual; doing nothing...\n") );
			SeekBegin();
			return true;
		case cFCOName::REL_UNRELATED:
			//
			// we have to go all the way to the root...
			//
			d.TraceDetail( _T("\tUnrelated; seeking to root...\n") );
			SeekToRoot();
			break;
		default:
			// unreachable
			ASSERT( false );
			return false;
	}

	curParent = GetParentName();
	if( parentName.GetSize() == curParent.GetSize() )
		return true;
	//
	// now we will descend to the parent directory we are interested in...
	//
	cFCOName::iterator i(parentName);
	i.SeekTo( curParent.GetSize() );
	for(; (! i.Done()); i.Next() )
	{
		if( ! mDbIter.SeekTo( i.GetName() ) )
		{
			// this needs to be created!
			if( bCreate )
				mDbIter.CreateEntry( i.GetName() );
			else
				return false;
		}
		//
		// create the child array and descend
		//
		if( ! mDbIter.CanDescend() )
		{
			if( bCreate )
				mDbIter.CreateChildArray();
			else
				return false;
		}
		mDbIter.Descend();
	}
	return true;
}