00001 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 00002 // All rights reserved. 00003 // This component and the accompanying materials are made available 00004 // under the terms of "Eclipse Public License v1.0" 00005 // which accompanies this distribution, and is available 00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html". 00007 // 00008 // Initial Contributors: 00009 // Nokia Corporation - initial contribution. 00010 // 00011 // Contributors: 00012 // 00013 // Description: 00014 // This class contains methods to create a database of integers and periodically read /write integers 00015 // from/ to the database. The macro USE_SEMAPHORE is used at various places to show thread synchronization 00016 // using a semaphore. 00017 00018 #include "CDatabase.h" 00019 00020 //Declare a delay of 1000000 microseconds i.e. 1 sec for the periodic functions. 00021 const int KDelay = 1000000; 00022 00023 //The last number in the database. 00024 const int KLastNum = 50; 00025 00029 CDatabase* CDatabase::NewL() 00030 { 00031 CDatabase* self=new(ELeave)CDatabase(); 00032 CleanupStack::PushL(self); 00033 self->ConstructL(); 00034 CleanupStack::Pop(self); 00035 return self; 00036 } 00037 00041 CDatabase::~CDatabase() 00042 { 00043 iFsSession.Close(); //close the file server session. 00044 delete iPeriodic; //delete the periodic object. 00045 delete iConsole; //delete the console. 00046 #ifdef USE_SEMAPHORE 00047 iSemWrite.Close(); 00048 #endif 00049 } 00050 00054 void CDatabase::ConstructL() 00055 { 00056 iPeriodic = CPeriodic::NewL(CActive::EPriorityUserInput); 00057 00058 _LIT(KDbCreateDb,"exampleDatabase.db"); 00059 00060 iFsSession.Connect(); 00061 00062 //The database exampleDatabase.db is created as a permanent file store 00063 //in the app's private directory. 00064 User::LeaveIfError(iFsSession.CreatePrivatePath(RFs::GetSystemDrive())); 00065 00066 User::LeaveIfError(iFsSession.PrivatePath(iDbname)); 00067 iDbname.Append(KDbCreateDb); 00068 00069 #ifdef USE_SEMAPHORE 00070 //Open the global semaphore which was created in CSemaphoreExample. 00071 _LIT(KSemaphoreWrite, "WriteSemaphore"); 00072 User::LeaveIfError(iSemWrite.OpenGlobal(KSemaphoreWrite, EOwnerProcess)); 00073 #endif 00074 } 00075 00079 void CDatabase::CreateDatabaseL() 00080 { 00081 //Construct a file store object - the file to contain the 00082 //database replaces any existing file of the same name. 00083 CFileStore* store = CPermanentFileStore::ReplaceLC(iFsSession, iDbname, EFileRead|EFileWrite); 00084 //Complete file store creation. 00085 store->SetTypeL(store->Layout()); 00086 00087 //Create a database in the store. 00088 TStreamId id= iDatabase.CreateL(store); 00089 00090 //Keep database id as root of store. 00091 store->SetRootL(id); 00092 00093 //Complete database creation by commiting the store. 00094 store->CommitL(); 00095 00096 00097 //Create a table definition. 00098 CDbColSet* columns=CDbColSet::NewLC(); 00099 00100 //Add three columns each containing Int32 values. 00101 _LIT(KCol1, "Number1"); 00102 _LIT(KCol2, "Number2"); 00103 _LIT(KCol3, "Number3"); 00104 columns->AddL(TDbCol(KCol1,EDbColInt32)); 00105 columns->AddL(TDbCol(KCol2,EDbColInt32)); 00106 columns->AddL(TDbCol(KCol3,EDbColInt32)); 00107 00108 00109 //Create the table, table name is "Numbers" and add the columns to it. 00110 _LIT(KTable, "Numbers"); 00111 User::LeaveIfError(iDatabase.CreateTable(KTable,*columns)); 00112 00113 CDbKey* key=CDbKey::NewLC(); 00114 00115 //Add the key columns. 00116 TDbKeyCol number1(KCol1); 00117 key->AddL(number1); 00118 TDbKeyCol number2(KCol2); 00119 key->AddL(number2); 00120 TDbKeyCol number3(KCol3); 00121 key->AddL(number3); 00122 User::LeaveIfError(iDatabase.CreateIndex(KTable,KTable,*key)); 00123 00124 iDatabase.Close(); 00125 //Cleanup the column set. 00126 CleanupStack::PopAndDestroy(key); 00127 CleanupStack::PopAndDestroy(columns); 00128 CleanupStack::PopAndDestroy(store); 00129 } 00130 00135 void CDatabase::WritetoDatabaseL() 00136 { 00137 iPeriodic->Start(0, KDelay, TCallBack(PeriodicWriteL, this)); 00138 CActiveScheduler::Start(); 00139 } 00140 00145 TInt CDatabase::PeriodicWriteL(TAny* aPtr) 00146 { 00147 CDatabase* ptr = static_cast<CDatabase*> (aPtr); 00148 //Invoke the RThread::Resume() function on the consumer thread repeatedly. 00149 ptr->PeriodicWriteFuncL(); 00150 return KErrNone; 00151 } 00152 00157 void CDatabase::PeriodicWriteFuncL() 00158 { 00159 //Declare an integer which is used to fill numbers in the database. 00160 static int num = 0 ; 00161 00162 //Open the file store. 00163 _LIT(KSQLStatement,"select Number1, Number2, Number3 from Numbers order by Number1,Number2,Number3"); 00164 CFileStore* store = CFileStore::OpenLC(iFsSession,iDbname,EFileRead|EFileWrite); 00165 00166 00167 //Open the database from the root stream. 00168 iDatabase.OpenL(store,store->Root()); 00169 00170 //Lock the database before use. 00171 iDatabase.Begin(); 00172 00173 //Create a view on the database view to read/write numbers into it. 00174 RDbView view; 00175 User::LeaveIfError(view.Prepare(iDatabase,TDbQuery(KSQLStatement,EDbCompareNormal))); 00176 User::LeaveIfError(view.EvaluateAll()); 00177 00178 00179 //Insert a new row at the end of the database. 00180 view.InsertL(); 00181 00182 //Fill three coloumns with numbers. 00183 view.SetColL(1, num++); 00184 view.SetColL(2, num++); 00185 view.SetColL(3, num++); 00186 view.PutL(); 00187 00188 //Close the view. 00189 view.Close(); 00190 00191 //Unlock the database after writing. 00192 iDatabase.Commit(); 00193 00194 // close the database. 00195 iDatabase.Close(); 00196 00197 //Do not commit store: database has taken control of commit. 00198 CleanupStack::PopAndDestroy(store); 00199 00200 //Cancel the periodic function once 50 numbers have been written to the database. 00201 if(num > KLastNum ) 00202 { 00203 iPeriodic->Cancel(); 00204 CActiveScheduler::Stop(); 00205 } 00206 00207 #ifdef USE_SEMAPHORE 00208 /*Signal the semaphore and the PeriodicReadFunc() which was 00209 waiting on the semaphore is scheduled to run. 00210 */ 00211 iSemWrite.Signal(); 00212 #endif 00213 } 00214 00220 void CDatabase::ReadfromDatabaseL() 00221 { 00222 _LIT(KTextConsoleTitle, "ReaderThread"); 00223 if(!iConsole) 00224 { 00225 iConsole = Console::NewL(KTextConsoleTitle, TSize(KConsFullScreen,KConsFullScreen)); 00226 _LIT(KReading, "Reading the database.\n"); 00227 iConsole->Printf(KReading); 00228 } 00229 iPeriodic->Start(0, KDelay, TCallBack(PeriodicReadL,this)); 00230 CActiveScheduler::Start(); 00231 } 00232 00237 TInt CDatabase::PeriodicReadL(TAny* aPtr) 00238 { 00239 CDatabase* ptr = static_cast<CDatabase*> (aPtr); 00240 ptr->PeriodicReadFuncL(); 00241 return KErrNone; 00242 } 00243 00248 void CDatabase::PeriodicReadFuncL() 00249 { 00250 #ifdef USE_SEMAPHORE 00251 //Semaphore waits till it gets a signal from the PeriodicWrite() function. 00252 iSemWrite.Wait(); 00253 #endif 00254 00255 CFileStore* store = CFileStore::OpenLC(iFsSession,iDbname,EFileRead); 00256 00257 //Open the database from the root stream. 00258 iDatabase.OpenL(store,store->Root()); 00259 00260 //Lock the database. 00261 iDatabase.Begin(); 00262 00263 //Prepare an SQL query to read three numbers from the database. 00264 _LIT(KSQLStatement,"select Number1,Number2,Number3 from Numbers order by Number1,Number2, Number3"); 00265 00266 //Create a view on the database. 00267 RDbView view; 00268 User::LeaveIfError(view.Prepare(iDatabase,TDbQuery(KSQLStatement,EDbCompareNormal))); 00269 User::LeaveIfError(view.EvaluateAll()); 00270 00271 //Declare integers to iterate through the database rows. 00272 static int count = 0; 00273 TInt iter = 0; 00274 00275 /*Iterate through the database to read only the row which was most recently 00276 written by the PeriodicWriteFunc. 00277 */ 00278 view.FirstL(); 00279 while( iter < count) 00280 { 00281 view.NextL(); 00282 iter++; 00283 } 00284 count ++ ; 00285 00286 //Read the integers from the view and display in console. 00287 view.GetL(); 00288 TInt number1 = view.ColInt(1); 00289 TInt number2 = view.ColInt(2); 00290 TInt number3 = view.ColInt(3); 00291 //Prepare a row formatter to print the numbers to the console. 00292 _LIT(KRowFormatter, "\n reading %d \t%d\t%d"); 00293 00294 iConsole->Printf(KRowFormatter,number1,number2, number3); 00295 00296 //Cancel the periodic function after it has read the last number in the database. 00297 if(number3 >= KLastNum) 00298 { 00299 iPeriodic->Cancel(); 00300 CActiveScheduler::Stop(); 00301 _LIT(KAllRead, "\nAll the numbers in the database have been read\n"); 00302 iConsole->Printf(KAllRead); 00303 _LIT(KExit, "Press a key to exit\n"); 00304 iConsole->Printf(KExit); 00305 iConsole->Getch(); 00306 } 00307 //Close the view. 00308 view.Close(); 00309 00310 //Unlock the database. 00311 iDatabase.Commit(); 00312 00313 iDatabase.Close(); 00314 CleanupStack::PopAndDestroy(store); 00315 }
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.