home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c031 / 11.ddi / MFC / SAMPLES / TUTORIAL / DATABASE.CP$ / database
Encoding:
Text File  |  1992-01-10  |  7.2 KB  |  314 lines

  1. // database.cpp : Defines the behaviors for the CDataBase class.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and Microsoft
  9. // QuickHelp documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "database.h"
  14. #include <string.h>
  15.  
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char BASED_CODE THIS_FILE[] = __FILE__;
  19. #endif
  20.  
  21. const char szUntitled[] = "Untitled";
  22.  
  23. //////////////////////////////////////////////////////////////////////////
  24. //  CDataBase
  25. //
  26.  
  27. //////////////////////////////////////////////////
  28. //  CDataBase::New
  29. //  Initializes the database.
  30. //
  31. BOOL CDataBase::New()
  32. {
  33.     ASSERT_VALID( this );
  34.     
  35.     // Clean up any old data.
  36.     Terminate();
  37.  
  38.     m_pDataList = new CPersonList;
  39.     
  40.     return ( m_pDataList != NULL );
  41. }
  42.  
  43. //////////////////////////////////////////////////
  44. //  CDataBase::Terminate
  45. //  Cleans up the database.
  46. //
  47. void CDataBase::Terminate()
  48. {
  49.     ASSERT_VALID( this );
  50.     
  51.     if ( m_pDataList != NULL )
  52.         m_pDataList->DeleteAll();
  53.  
  54.     delete m_pDataList;
  55.     delete m_pFindList;
  56.  
  57.     m_pDataList = NULL;
  58.     m_pFindList = NULL;
  59.     
  60.     m_szFileName = szUntitled;
  61.     m_szFileTitle = szUntitled;
  62. }
  63.  
  64. //////////////////////////////////////////////////
  65. //  CDataBase::AddPerson
  66. //  Inserts a person in the appropriate position (alphabetically by last
  67. //  name) in the database.
  68. //
  69. void CDataBase::AddPerson( CPerson* pNewPerson )
  70. {
  71.     ASSERT_VALID( this );
  72.     ASSERT_VALID( pNewPerson );
  73.     ASSERT( pNewPerson != NULL );
  74.     ASSERT( m_pDataList != NULL );
  75.  
  76.     POSITION pos = m_pDataList->GetHeadPosition();
  77.     while ( pos != NULL &&
  78.             _stricmp( ((CPerson*)m_pDataList->GetAt(pos))->GetLastName(),
  79.                     pNewPerson->GetLastName() ) <= 0 )
  80.         m_pDataList->GetNext( pos );
  81.             
  82.     if ( pos == NULL )
  83.         m_pDataList->AddTail( pNewPerson );
  84.     else
  85.         m_pDataList->InsertBefore( pos, pNewPerson );
  86.  
  87.     m_pDataList->SetDirty( TRUE );
  88. }
  89.  
  90. //////////////////////////////////////////////////
  91. //  CDataBase::GetPerson
  92. //  Look up someone by index.
  93. //
  94. CPerson* CDataBase::GetPerson( int nIndex )
  95. {
  96.     ASSERT_VALID( this );
  97.     ASSERT( m_pDataList != NULL );
  98.     
  99.     if ( m_pFindList != NULL )
  100.         return (CPerson*)m_pFindList->GetAt( m_pFindList->FindIndex( nIndex ) );
  101.     else
  102.         return (CPerson*)m_pDataList->GetAt( m_pDataList->FindIndex( nIndex ) );
  103. }
  104.  
  105. //////////////////////////////////////////////////
  106. //  CDatabase::DeletePerson
  107. //  Removes record of person from database.
  108. //
  109. void CDataBase::DeletePerson( int nIndex )
  110. {
  111.     ASSERT_VALID( this );
  112.     ASSERT( m_pDataList != NULL );
  113.     
  114.     POSITION el = m_pDataList->FindIndex( nIndex );
  115.     delete m_pDataList->GetAt( el );
  116.     m_pDataList->RemoveAt( el );
  117.     m_pDataList->SetDirty( TRUE );
  118. }
  119.  
  120. //////////////////////////////////////////////////
  121. //  CDatabase::ReplacePerson
  122. //  Replaces an object in the list with the new object.
  123. //
  124. void CDataBase::ReplacePerson( CPerson* pOldPerson, const CPerson& rNewPerson )
  125. {
  126.     ASSERT_VALID( this );
  127.     
  128.     ASSERT( pOldPerson != NULL );
  129.     ASSERT( m_pDataList != NULL );
  130.  
  131.     // Using the overloaded operator= for CPerson
  132.     *pOldPerson = rNewPerson;
  133.     m_pDataList->SetDirty( TRUE );
  134. }
  135.  
  136. //////////////////////////////////////////////////
  137. //  CDataBase::DoFind
  138. //  Does a FindPerson call, or clears the find data.
  139. //
  140. BOOL CDataBase::DoFind( const char* pszLastName /* = NULL */ )
  141. {
  142.     ASSERT_VALID( this );
  143.     ASSERT( m_pDataList != NULL );
  144.  
  145.     if ( pszLastName == NULL )
  146.     {
  147.         delete m_pFindList;
  148.         m_pFindList = NULL;
  149.         return FALSE;
  150.     }
  151.  
  152.     // The interface should not allow a second find to occur while
  153.     // we already have one.
  154.     ASSERT( m_pFindList == NULL );
  155.     return ( ( m_pFindList = m_pDataList->FindPerson( pszLastName ) ) != NULL );
  156. }
  157.  
  158. //////////////////////////////////////////////////
  159. //  CDataBase::DoOpen
  160. //  Reads a database from the given filename.
  161. //
  162. BOOL CDataBase::DoOpen( const char* pszFileName )
  163. {
  164.     ASSERT_VALID( this );
  165.     ASSERT( pszFileName != NULL );
  166.     
  167.     CFile file( pszFileName, CFile::modeRead );
  168.  
  169.     // read the object data from file
  170.     CPersonList* pNewDataBase = ReadDataBase( &file );
  171.     
  172.     file.Close();
  173.  
  174.     // get rid of current data base if new one is OK
  175.     if ( pNewDataBase != NULL )
  176.     {
  177.         Terminate();
  178.         m_pDataList = pNewDataBase;
  179.         m_pDataList->SetDirty( FALSE );
  180.         
  181.         m_szFileName = pszFileName;
  182.         return TRUE;
  183.     }
  184.     else
  185.         return FALSE;
  186. }
  187.  
  188. //////////////////////////////////////////////////
  189. //  CDataBase::DoSave
  190. //  Saves the database to the given file.
  191. //
  192. BOOL CDataBase::DoSave( const char* pszFileName /* = NULL */ )
  193. {
  194.     ASSERT_VALID( this );
  195.  
  196.     // if we were given a name store it in the object.
  197.     if ( pszFileName != NULL )
  198.         m_szFileName = pszFileName;
  199.  
  200.     CFileStatus status;
  201.     int nAccess = CFile::modeWrite;
  202.  
  203.     // GetStatus will return TRUE if file exists, or FALSE if it doesn't.
  204.     if ( !CFile::GetStatus( m_szFileName, status ) )
  205.         nAccess |= CFile::modeCreate;
  206.     
  207.     CFile file( m_szFileName, nAccess );
  208.  
  209.     // write the data base to a file
  210.     // mark it clean if write is successful
  211.     if ( WriteDataBase( &file ) )
  212.     {
  213.         m_pDataList->SetDirty( FALSE );
  214.         file.Close();
  215.         return TRUE;
  216.     }
  217.     else
  218.     {
  219.         file.Close();
  220.         return FALSE;
  221.     }
  222. }
  223.  
  224. //////////////////////////////////////////////////
  225. //  CDataBase::ReadDataBase
  226. //  Serializes in the database.
  227. //
  228. CPersonList* CDataBase::ReadDataBase( CFile* pFile )
  229. {
  230.     ASSERT_VALID( this );
  231.     CPersonList* pNewDataBase = NULL;
  232.  
  233.     // Create a archive from pFile for reading.
  234.     CArchive archive( pFile, CArchive::load );
  235.  
  236.     // Deserialize the new data base from the archive, or catch the
  237.     // exception.
  238.     TRY
  239.     {
  240.         archive >> pNewDataBase;
  241.     }
  242.     CATCH( CArchiveException, e )
  243.     {
  244. #ifdef _DEBUG
  245.         e->Dump( afxDump );
  246. #endif
  247.         archive.Close();
  248.     
  249.         // If we got part of the database, then delete it.
  250.         if ( pNewDataBase != NULL )
  251.         {
  252.             pNewDataBase->DeleteAll();
  253.             delete pNewDataBase;
  254.         }
  255.  
  256.         // We caught this exception, but we throw it again so our caller can
  257.         // also catch it.
  258.         THROW_LAST();
  259.     }
  260.     END_CATCH
  261.  
  262.     // Exit here if no errors or exceptions.
  263.     archive.Close();
  264.     return pNewDataBase;
  265. }
  266.  
  267. //////////////////////////////////////////////////
  268. //  CDataBase::WriteDataBase
  269. //  Serializes out the data into the given file.
  270. //
  271. BOOL CDataBase::WriteDataBase( CFile* pFile )
  272. {
  273.     ASSERT_VALID( this );
  274.     ASSERT( m_pDataList != NULL );
  275.     
  276.     // Create a archive from theFile for writing
  277.     CArchive archive( pFile, CArchive::store );
  278.  
  279.     // Archive out, or catch the exception.
  280.     TRY
  281.     {
  282.         archive << m_pDataList;
  283.     }
  284.     CATCH( CArchiveException, e )
  285.     {
  286. #ifdef _DEBUG
  287.         e->Dump( afxDump );
  288. #endif
  289.         archive.Close();
  290.  
  291.         // Throw this exception again for the benefit of our caller.
  292.         THROW_LAST();
  293.     }
  294.     END_CATCH
  295.  
  296.     // Exit here if no errors or exceptions.
  297.     archive.Close();
  298.     return TRUE;
  299. }
  300.  
  301. #ifdef _DEBUG
  302. void CDataBase::AssertValid() const
  303. {
  304.     if ( m_pDataList != NULL )
  305.     {
  306.         ASSERT_VALID( m_pDataList );
  307.         if ( m_pFindList != NULL )
  308.             ASSERT_VALID( m_pFindList );
  309.     }
  310.     else
  311.         ASSERT( m_pFindList == NULL );
  312. }
  313. #endif
  314.