examples/SFExamples/Files/StoreDatabase/src/StoreDatabaseAppUi.cpp

00001 /*
00002  * Copyright (c) 2002-2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003  *    
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *    
00007  *  * Redistributions of source code must retain the above copyright notice, this
00008  *    list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright notice,
00010  *    this list of conditions and the following disclaimer in the documentation
00011  *    and/or other materials provided with the distribution.
00012  *  * Neither the name of Nokia Corporation nor the names of its contributors
00013  *    may be used to endorse or promote products derived from this software
00014  *    without specific prior written permission.
00015  *    
00016  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021  *    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  *    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023  *    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024  *    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *    
00027  *    Description:  
00028  */  
00029 
00030 // INCLUDES
00031 #include <f32file.h>
00032 #include <s32file.h>
00033 #include <d32dbms.h>
00034 #include <bautils.h>
00035 #include <eikmenub.h>
00036 
00037 #include <StoreDatabase.rsg>
00038 
00039 #include "StoreDatabaseAppUi.h"
00040 #include "StoreDatabaseMainView.h"
00041 #include "employee.h"
00042 #include "StoreDatabase.hrh"
00043 
00044 // CONSTANTS
00045 _LIT(KFileName,      "c:\\data\\employee.db");
00046 
00047 _LIT(KEmployeesTable, "EmployeesTable");
00048 _LIT(KEmployeesIndex, "EmployeesIndex");
00049 
00050 _LIT(KIdentifier,    "Identifier");
00051 _LIT(KName,          "Name");
00052 _LIT(KPhoneNumber,   "PhoneNumber");
00053 
00054 const TInt KIdentifierIdx  = 1;
00055 const TInt KNameIdx        = 2;
00056 const TInt KPhoneNumberIdx = 3;
00057 
00058 const TInt KMaxBuffer      = 100;
00059 
00060 _LIT(KName1,        "John Doe");
00061 _LIT(KPhoneNumber1, "+1-222-333-4444");
00062 
00063 _LIT(KName2,        "Jane Roe");
00064 _LIT(KPhoneNumber2, "+1-234-567-8900");
00065 
00066 const TChar KEndOfLine = '\f';
00067 
00068 
00069 // MEMBER FUNCTIONS
00070 
00071 // --------------------------------------------------------------------------
00072 // Constructor
00073 // --------------------------------------------------------------------------
00074 void CStoreDatabaseAppUi::ConstructL()
00075         {
00076 
00077 
00078         BaseConstructL(EAknEnableSkin);
00079         
00080         iMainView = CStoreDatabaseMainView::NewL(ClientRect());
00081         iStatus = EStatusUninitialized;
00082         BaflUtils::EnsurePathExistsL(iCoeEnv->FsSession(), KFileName);
00083         }
00084         
00085 // --------------------------------------------------------------------------
00086 // Destructor
00087 // --------------------------------------------------------------------------
00088 CStoreDatabaseAppUi::~CStoreDatabaseAppUi()
00089     {
00090     if (iMainView)
00091         {
00092         delete iMainView;
00093         iMainView = NULL;
00094         }
00095     
00096     iDatabase.Close();
00097     delete iFileStore;
00098     iArray.ResetAndDestroy();
00099     }
00100 
00101 // --------------------------------------------------------------------------
00102 // Handles user command.
00103 // --------------------------------------------------------------------------
00104 void CStoreDatabaseAppUi::HandleCommandL(TInt aCommand)
00105         {
00106         switch ( aCommand )
00107                 {
00108                 // For S60, we need to handle this event, which is normally
00109                 // an event from the right soft key.
00110                 case EAknSoftkeyExit:
00111                 case EEikCmdExit:
00112                         {
00113                         Exit();
00114                         break;
00115                         }
00116                 
00117                 case EStoreDatabaseCreateDb:
00118                         {
00119                         DoCreateDbL();                  
00120                         break;
00121                         }
00122                         
00123                 case EStoreDatabaseAddDataToDb:
00124                         {
00125                         DoAddDataToDbL();       
00126                         break;
00127                         }
00128                         
00129                 case EStoreDatabaseReadDataFromDb:
00130                         {
00131                         DoReadDataFromDbL();
00132                         break;
00133                         }
00134                         
00135                 case EStoreDatabaseDeleteDataFromDb:
00136                         {
00137                         // Delete all data from the database.
00138                         DoDeleteDataFromDbL();
00139                         break;
00140                         }
00141                 
00142                 default:
00143                         // Do nothing
00144                         break;
00145                 }
00146         }
00147 
00148 
00149 
00150 // --------------------------------------------------------------------------
00151 // Handles screen resolution/size changes.
00152 // --------------------------------------------------------------------------
00153 void CStoreDatabaseAppUi::HandleResourceChangeL(TInt aType)
00154         {
00155         CAknAppUi::HandleResourceChangeL(aType);
00156         iMainView->SetRect(ClientRect());
00157         }
00158 
00159 void CStoreDatabaseAppUi::DoCreateDbL()
00160         {
00161         CreateDatabaseL(iCoeEnv->FsSession(), KFileName);
00162         CreateTableL(iDatabase);
00163         CreateIndexL(iDatabase);
00164         iStatus = EStatusCreated;
00165         
00166         // Display message on the main view.
00167         HBufC* message = iCoeEnv->AllocReadResourceLC(
00168                         R_STOREDATABASE_DBCREATED);
00169         iMainView->SetTextL(*message);
00170         CleanupStack::PopAndDestroy(message);
00171         }
00172 
00173 void CStoreDatabaseAppUi::DoAddDataToDbL()
00174         {
00175         // Display a warning when the database has not been created.
00176         if (EStatusUninitialized == iStatus)
00177                 {
00178                 iEikonEnv->InfoWinL(R_STOREDATABASE_CAPTION, 
00179                                 R_STOREDATABASE_UNINITIALIZED);
00180                 return;
00181                 }
00182         
00183         // If the data has been added, then just return.
00184         if (EStatusAdded == iStatus)
00185                 {
00186                 return;
00187                 }
00188         
00189         // Create a new instance of CEmployee.
00190         CEmployee* employee = new (ELeave) CEmployee();
00191         CleanupStack::PushL(employee);
00192         
00193         // Add the first employee.
00194         employee->SetName(KName1);
00195         employee->SetPhoneNumber(KPhoneNumber1);
00196         AddEmployeeToDatabaseUsingSqlL(iDatabase, *employee);
00197         
00198         //
00199         // Alternatively, we can add using this statement.
00200         // The statement below uses RDbView to add to the database,
00201         // instead of using SQL statement.
00202         //
00203         // -> AddEmployeeToDatabaseL(iDatabase, *employee);
00204         
00205         // Add the second employee.
00206         employee->SetName(KName2);
00207         employee->SetPhoneNumber(KPhoneNumber2);
00208         AddEmployeeToDatabaseUsingSqlL(iDatabase, *employee);
00209         
00210         CleanupStack::PopAndDestroy(employee);
00211         iStatus = EStatusAdded;
00212         
00213         // Display message on the main view.
00214         HBufC* message = iCoeEnv->AllocReadResourceLC(
00215                         R_STOREDATABASE_DBADDED);
00216         iMainView->SetTextL(*message);
00217         CleanupStack::PopAndDestroy(message);
00218         }
00219 
00220 void CStoreDatabaseAppUi::DoReadDataFromDbL()
00221         {
00222         // Display a warning if the database has not been created yet.
00223         if (iStatus == EStatusUninitialized)
00224                 {
00225                 iEikonEnv->InfoWinL(R_STOREDATABASE_CAPTION,
00226                                 R_STOREDATABASE_UNINITIALIZED);
00227                 return;
00228                 }
00229         
00230         // Reset the array and read all employees from the database.
00231         iArray.ResetAndDestroy();
00232         ReadEmployeesFromDatabaseL(iDatabase);
00233 
00234         // Display all the employees on the main view.
00235         RBuf buffer;
00236         buffer.CreateL(KMaxBuffer * iArray.Count());
00237         CleanupClosePushL(buffer);
00238         for (TInt i = 0; i < iArray.Count(); i++)
00239                 {
00240                 const CEmployee* employee = iArray[i];
00241                 buffer.AppendNum(employee->Identifier());
00242                 buffer.Append(KEndOfLine);
00243                 buffer.Append(employee->Name());
00244                 buffer.Append(KEndOfLine);
00245                 buffer.Append(employee->PhoneNumber());
00246                 buffer.Append(KEndOfLine);
00247                 buffer.Append(KEndOfLine);
00248                 }
00249         iMainView->SetTextL(buffer);
00250         
00251         CleanupStack::PopAndDestroy(&buffer);
00252         }
00253 
00254 void CStoreDatabaseAppUi::DoDeleteDataFromDbL()
00255         {
00256         // Display a warning if the database has not been created yet.
00257         if (iStatus == EStatusUninitialized)
00258                 {
00259                 iEikonEnv->InfoWinL(R_STOREDATABASE_CAPTION,
00260                                 R_STOREDATABASE_UNINITIALIZED);
00261                 return;
00262                 }
00263         
00264         //
00265         // Delete all employees from the database.
00266         //
00267         DeleteEmployeeFromDatabaseL(iDatabase, KName1);
00268         DeleteEmployeeFromDatabaseL(iDatabase, KName2);
00269         iStatus = EStatusCreated;
00270                 
00271         // Display message on the main view.
00272         HBufC* message = iCoeEnv->AllocReadResourceLC(
00273                         R_STOREDATABASE_DBDELETED);
00274         iMainView->SetTextL(*message);
00275         CleanupStack::PopAndDestroy(message);
00276         }
00277 
00278 void CStoreDatabaseAppUi::CreateDatabaseL(RFs& aFs, const TDesC& aFileName)
00279         {
00280         // Create a permanent file store for the database.
00281         delete iFileStore;
00282         iFileStore = 0;
00283         iFileStore = CPermanentFileStore::ReplaceL(
00284                         aFs, aFileName, EFileRead | EFileWrite);
00285         iFileStore->SetTypeL(iFileStore->Layout());
00286         
00287         // Create a database in the store.
00288         iDatabase.Close();
00289         TStreamId id = iDatabase.CreateL(iFileStore);
00290         
00291         // Set the root for this store and then commit the change.
00292         iFileStore->SetRootL(id);
00293         iFileStore->CommitL();
00294         }
00295 
00296 void CStoreDatabaseAppUi::CreateTableL(RDbDatabase& aDatabase)
00297         {
00298         CDbColSet* columns = CDbColSet::NewLC();
00299         
00300         // The first column is an identifier, which is auto-increment.
00301         TDbCol identifier(KIdentifier, EDbColUint32);
00302         identifier.iAttributes = TDbCol::EAutoIncrement;
00303         columns->AddL(identifier);
00304         
00305         // The second column is name.
00306         TDbCol name(KName, EDbColText, KMaxEmployeeName);
00307         name.iAttributes = TDbCol::ENotNull;
00308         columns->AddL(name);
00309         
00310         // The third column is phone number.
00311         columns->AddL(TDbCol(KPhoneNumber, EDbColText, KMaxEmployeeNumber));
00312 
00313         // Create a new table based on the columns definition above.
00314         User::LeaveIfError(aDatabase.CreateTable(KEmployeesTable, *columns));
00315         
00316         CleanupStack::PopAndDestroy(columns);
00317         }
00318 
00319 void CStoreDatabaseAppUi::CreateIndexL(RDbDatabase& aDatabase)
00320         {
00321         // Define a key that uses the name and identifier.
00322         CDbKey* key = CDbKey::NewLC();
00323         key->AddL(TDbKeyCol(KName));
00324         key->AddL(TDbKeyCol(KIdentifier));
00325         
00326         // Create an index on the database.
00327         User::LeaveIfError(aDatabase.CreateIndex(KEmployeesIndex, KEmployeesTable, *key));
00328         
00329         CleanupStack::PopAndDestroy(key);
00330         }
00331 
00332 void CStoreDatabaseAppUi::AddEmployeeToDatabaseL(RDbDatabase& aDatabase,
00333                 const CEmployee& aEmployee)
00334         {
00335         // The SQL statement to select all employees.
00336         _LIT(KSqlStatement, "SELECT * FROM %S");
00337         TBuf<KMaxBuffer> sqlStatement;
00338         sqlStatement.AppendFormat(KSqlStatement, &KEmployeesTable);
00339         
00340         // Create a view based on the SQL statement above.
00341         RDbView view;
00342         User::LeaveIfError(view.Prepare(
00343                         aDatabase, TDbQuery(sqlStatement, EDbCompareFolded)));
00344         CleanupClosePushL(view);
00345         User::LeaveIfError(view.EvaluateAll());
00346         
00347         // Insert a new row.
00348         view.InsertL();
00349         view.SetColL(KNameIdx, aEmployee.Name());
00350         view.SetColL(KPhoneNumberIdx, aEmployee.PhoneNumber());
00351         view.PutL();
00352         
00353         // Free all the resources.
00354         CleanupStack::PopAndDestroy(&view);
00355         }
00356 
00357 void CStoreDatabaseAppUi::AddEmployeeToDatabaseUsingSqlL(RDbDatabase& aDatabase,
00358                 const CEmployee& aEmployee)
00359         {
00360         // The SQL statement to insert an employee.
00361         _LIT(KSqlStatement, "INSERT INTO %S (%S, %S) VALUES ('%S', '%S')");
00362         
00363         TBuf<KMaxBuffer> sqlStatement;
00364         TPtrC name = aEmployee.Name();
00365         TPtrC phoneNumber = aEmployee.PhoneNumber();
00366         sqlStatement.AppendFormat(KSqlStatement, &KEmployeesTable,
00367                         &KName, &KPhoneNumber, &name, &phoneNumber);
00368         
00369         // Execute the SQL statement.
00370         User::LeaveIfError(aDatabase.Execute(sqlStatement, EDbCompareFolded));
00371         }
00372 
00373 void CStoreDatabaseAppUi::ReadEmployeesFromDatabaseL(RDbDatabase& aDatabase)
00374         {
00375         // Prepare and evaluate SQL statement using RDbView.
00376         _LIT(KSqlStatement, "SELECT * FROM %S ORDER BY %S");
00377         TBuf<KMaxBuffer> sqlStatement;
00378         sqlStatement.AppendFormat(KSqlStatement, &KEmployeesTable,
00379                         &KName);
00380         
00381         RDbView view;
00382         User::LeaveIfError(view.Prepare(
00383                         aDatabase, TDbQuery(sqlStatement, EDbCompareFolded)));
00384         CleanupClosePushL(view);
00385         User::LeaveIfError(view.EvaluateAll());
00386         
00387         // Iterate to RDbView from the first row to the last one.
00388         view.FirstL();
00389         while (view.AtRow())
00390                 {
00391                 view.GetL();
00392                 TUint32 identifier = view.ColUint32(KIdentifierIdx);
00393                 TPtrC name = view.ColDes(KNameIdx);
00394                 TPtrC phoneNumber = view.ColDes(KPhoneNumberIdx);
00395                 view.NextL();
00396 
00397                 // Do something with the data here.
00398                 // In this example, we add the data to the array.
00399                 CEmployee* employee = new (ELeave) CEmployee();
00400                 employee->SetIdentifier(identifier);
00401                 employee->SetName(name);
00402                 employee->SetPhoneNumber(phoneNumber);
00403                 iArray.Append(employee);
00404                 }
00405                 
00406         CleanupStack::PopAndDestroy(&view);
00407         }
00408 
00409 void CStoreDatabaseAppUi::DeleteEmployeeFromDatabaseL(RDbDatabase& aDatabase,
00410                 const TDesC& aName)
00411         {
00412         // Prepare and evaluate SQL statement using RDbView.
00413         _LIT(KSqlStatement, "DELETE FROM %S WHERE %S='%S'");
00414         
00415         TBuf<KMaxBuffer> sqlStatement;
00416         sqlStatement.AppendFormat(KSqlStatement, &KEmployeesTable,
00417                         &KName, &aName);
00418         
00419         // Execute the SQL statement.
00420         User::LeaveIfError(aDatabase.Execute(sqlStatement, EDbCompareFolded));
00421         }
00422 
00423 // End of File

Generated by  doxygen 1.6.2