activityfw/activitydatabase/hsactivitydbserver/src/afstorage.cpp
changeset 102 8b8b34fa9751
parent 100 0920c6a9b6c8
child 106 e78d6e055a5b
equal deleted inserted replaced
100:0920c6a9b6c8 102:8b8b34fa9751
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 #include "afstorage.h"
       
    18 #include "afqueries.h"
       
    19 #include "afentry.h"
       
    20 #include <bautils.h>
       
    21 #include <s32mem.h>
       
    22 
       
    23 _LIT(KDbName, "activity.db");
       
    24 _LIT(KDbDrive, "c:");
       
    25 const TInt KMaxPathLength = 256;
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 LOCAL_C void CleanupResetAndDestroy(TAny*  item)
       
    29 {
       
    30     RPointerArray<CAfEntry> *array = static_cast< RPointerArray<CAfEntry>* >(item);
       
    31     array->ResetAndDestroy();
       
    32     array->Close();
       
    33 }
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 /**
       
    37  * Constructor for performing 1st stage construction
       
    38  * @param session - initialized session to file system
       
    39  */
       
    40 CAfStorage::CAfStorage(RFs& session)
       
    41 :
       
    42 mFsSession(session)
       
    43 {
       
    44     // No implementation required
       
    45 }
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 /**
       
    49  * Destructor.
       
    50  */
       
    51 CAfStorage::~CAfStorage()
       
    52 {
       
    53 }
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 /**
       
    57  * Two-phased constructor.
       
    58  * @param session - initialized session to file system
       
    59  */
       
    60 CAfStorage* CAfStorage::NewL(RFs& session)
       
    61 {
       
    62     CAfStorage* self = new (ELeave) CAfStorage(session);
       
    63     CleanupStack::PushL(self);
       
    64     self->ConstructL();
       
    65     CleanupStack::Pop(); // self;
       
    66     return self;
       
    67 }
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 /**
       
    71  * EPOC default constructor for performing 2nd stage construction
       
    72  */
       
    73 void CAfStorage::ConstructL()
       
    74 {
       
    75     RBuf path;
       
    76     CleanupClosePushL( path );
       
    77     path.CreateL(KMaxPathLength);
       
    78     User::LeaveIfError(mFsSession.PrivatePath(path ));
       
    79     path.Append(KDbName);
       
    80     path.Insert(0, KDbDrive);
       
    81     BaflUtils::EnsurePathExistsL(mFsSession, path);
       
    82     BaflUtils::FileExists(mFsSession, path) ? OpenDbL(path) : CreateDbL(path);
       
    83     CleanupStack::PopAndDestroy(&path);
       
    84 
       
    85     DeleteNonPersistentActivitiesL();
       
    86 }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 /**
       
    90  * Create database and its structure
       
    91  * @param databaseFile - database file path
       
    92  */
       
    93 void CAfStorage::CreateDbL(const TDesC& databaseFile)
       
    94 {
       
    95     mFileStore = CPermanentFileStore::ReplaceL(mFsSession,
       
    96                                                databaseFile,
       
    97                                                EFileRead|EFileWrite);
       
    98     mFileStore->SetTypeL(mFileStore->Layout());// Set file store type
       
    99     TStreamId id = mActDb.CreateL(mFileStore);// Create stream object
       
   100     mFileStore->SetRootL(id);// Keep database id as root of store
       
   101     mFileStore->CommitL();// Complete creation by commiting
       
   102     CreateTableL();
       
   103 }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 /**
       
   107  * Open database
       
   108  * @param databaseFile - database file path
       
   109  */
       
   110 void CAfStorage::OpenDbL(const TDesC& databaseFile)
       
   111 {
       
   112     mFileStore = CPermanentFileStore::OpenL(mFsSession,
       
   113                                             databaseFile,
       
   114                                             EFileRead|EFileWrite);
       
   115     mFileStore->SetTypeL(mFileStore->Layout()); /* Set file store type*/
       
   116     mActDb.OpenL(mFileStore,mFileStore->Root());
       
   117     CDbTableNames* tables = mActDb.TableNamesL();
       
   118     CleanupStack::PushL(tables);
       
   119     if (0 == tables->Count()) {
       
   120         CreateTableL();
       
   121     }
       
   122     CleanupStack::PopAndDestroy(tables);
       
   123 }
       
   124 
       
   125 // -----------------------------------------------------------------------------
       
   126 /**
       
   127  * Create database structure
       
   128  */
       
   129 void CAfStorage::CreateTableL()
       
   130 {
       
   131     // Add the columns to column set
       
   132     CDbColSet* actColSet = CDbColSet::NewLC();
       
   133 
       
   134     TDbCol appName(KApplicationColumnName, EDbColInt64);
       
   135     appName.iAttributes = TDbCol::ENotNull;
       
   136     actColSet->AddL(appName);
       
   137 
       
   138     TDbCol actName(KActivityColumnName, EDbColText16);// Using default length
       
   139     actName.iAttributes = TDbCol::ENotNull;
       
   140     actColSet->AddL(actName);
       
   141 
       
   142     TDbCol actFlags(KFlagsColumnName, EDbColInt32);
       
   143     actFlags.iAttributes = TDbCol::ENotNull;
       
   144     actColSet->AddL(actFlags);
       
   145 
       
   146     actColSet->AddL(TDbCol(KDataColumnName, EDbColLongBinary));// Stream Data
       
   147 
       
   148     // Create the table
       
   149     User::LeaveIfError(mActDb.CreateTable(KActivityTableName,
       
   150                                          *actColSet));
       
   151 
       
   152     CleanupStack::PopAndDestroy(actColSet);
       
   153 }
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 /**
       
   157  * Delete non-persistent activities
       
   158  */
       
   159 void CAfStorage::DeleteNonPersistentActivitiesL()
       
   160 {
       
   161     HBufC *query(BuildQueryLC(KDeleteNonPersistentActivities(), CAfEntry::Persistent, KNullDesC));
       
   162     User::LeaveIfError(mActDb.Execute(*query));
       
   163     CleanupStack::PopAndDestroy(query);
       
   164 }
       
   165 
       
   166 // -----------------------------------------------------------------------------
       
   167 /**
       
   168  * Register new activity
       
   169  * @param appId - application id
       
   170  * @param actId - activity id
       
   171  * @param flags - activity flags
       
   172  * @param imgSrc - activity thumbnail source
       
   173  * @param privateData - activity private data
       
   174  * @param publicData - activity public data
       
   175  */
       
   176 void CAfStorage::AddActivityL(CAfEntry& entry)
       
   177 {
       
   178     //verify if row already exists
       
   179     TInt errNo(KErrNone);
       
   180     RDbView view;
       
   181     CleanupClosePushL(view);
       
   182     TRAP( errNo, GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId()));
       
   183     if (KErrNone == errNo) {
       
   184         User::Leave(KErrAlreadyExists);
       
   185     }
       
   186     CleanupStack::PopAndDestroy(&view);
       
   187 
       
   188     //write table
       
   189     RDbTable table;
       
   190     CleanupClosePushL(table);
       
   191     User::LeaveIfError(table.Open(mActDb, KActivityTableName, table.EUpdatable));
       
   192     CDbColSet *row = table.ColSetL();
       
   193     CleanupStack::PushL(row);
       
   194 
       
   195     table.InsertL();
       
   196     TRAP(errNo,
       
   197     table.SetColL(row->ColNo(KApplicationColumnName), TInt64(entry.ApplicationId()));
       
   198     table.SetColL(row->ColNo(KActivityColumnName), entry.ActivityId());
       
   199     table.SetColL(row->ColNo(KFlagsColumnName), entry.Flags());
       
   200     ExternalizeDataL(table, entry, row->ColNo(KDataColumnName));
       
   201     table.PutL();)
       
   202     if (KErrNone != errNo) {
       
   203         table.Cancel();
       
   204         User::Leave(errNo);
       
   205     }
       
   206     CleanupStack::PopAndDestroy(row);
       
   207     CleanupStack::PopAndDestroy(&table);
       
   208 }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 /**
       
   212  * Update activity
       
   213  * @param entry - activity data
       
   214  */
       
   215 void CAfStorage::UpdateActivityL(CAfEntry& entry)
       
   216 {
       
   217     RDbView view;
       
   218     CleanupClosePushL(view);
       
   219     GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId());
       
   220     view.UpdateL();
       
   221     TRAPD(errNo,
       
   222     CDbColSet* colSet = view.ColSetL();
       
   223     CleanupStack::PushL(colSet);
       
   224 
       
   225     view.SetColL(colSet->ColNo(KFlagsColumnName), entry.Flags());
       
   226     ExternalizeDataL(view, entry, colSet->ColNo(KDataColumnName));
       
   227 
       
   228     view.PutL();
       
   229     if (KErrNone != errNo) {
       
   230         view.Cancel();
       
   231         User::Leave(errNo);
       
   232     }
       
   233     CleanupStack::PopAndDestroy(colSet);)
       
   234 
       
   235     if (KErrNone != errNo) {
       
   236         view.Cancel();
       
   237         User::Leave(errNo);
       
   238     }
       
   239     CleanupStack::PopAndDestroy(&view);
       
   240 }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 /**
       
   244  * Delete activity
       
   245  * @param appId - application id
       
   246  * @param actId - activity id
       
   247  */
       
   248 void CAfStorage::DeleteActivityL(CAfEntry& entry)
       
   249 {
       
   250     HBufC *query(DeleteRowLC(entry.ApplicationId(), entry.ActivityId()));
       
   251     User::LeaveIfError(mActDb.Execute(*query));
       
   252     CleanupStack::PopAndDestroy(query);
       
   253 }
       
   254 
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CAfStorage::DeleteActivitiesL(CAfEntry& entry)
       
   260 {
       
   261     HBufC *query(DeleteRowsLC(entry.ApplicationId()));
       
   262     User::LeaveIfError(mActDb.Execute(*query));
       
   263     CleanupStack::PopAndDestroy(query);
       
   264 }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst)
       
   271 {
       
   272     ActivitiesL(dst, KSelectRows(), CAfEntry::Public);
       
   273 }
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 /**
       
   277  * Serialize application activity into the buffer
       
   278  * @param dst - destination buffer
       
   279  * @param appId - application id
       
   280  */
       
   281 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst,TInt appId)
       
   282 {
       
   283     HBufC *query(SelectRowsLC(appId));
       
   284     ActivitiesL(dst, *query, CAfEntry::Private);
       
   285     CleanupStack::PopAndDestroy(query);
       
   286 }
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 /**
       
   290  * Serialize application activity into the buffer
       
   291  * @param dst - destination entry
       
   292  * @param src - condition pattern
       
   293  */
       
   294 void CAfStorage::ActivityL(CAfEntry *&dst, CAfEntry& src)
       
   295 {
       
   296     HBufC *query = SelectRowLC(src.ApplicationId(), src.ActivityId());
       
   297     RPointerArray<CAfEntry> array;
       
   298     CleanupStack::PushL(TCleanupItem(CleanupResetAndDestroy,&array));
       
   299     ActivitiesL(array, *query, CAfEntry::Private, 1);
       
   300     if (0 >= array.Count()) {
       
   301         User::Leave(KErrNotFound);
       
   302     }
       
   303     dst = array[0];
       
   304     array.Remove(0);
       
   305     CleanupStack::PopAndDestroy(&array);
       
   306     CleanupStack::PopAndDestroy(query);
       
   307 }
       
   308 
       
   309 // -----------------------------------------------------------------------------
       
   310 /**
       
   311  * Provide initialized file system session
       
   312  * @return file system session
       
   313  */
       
   314 RFs& CAfStorage::Fs()
       
   315 {
       
   316     return mFsSession;
       
   317 }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 /**
       
   321  * Format query to select activity row
       
   322  * @param appId - application id
       
   323  * @param actId - activity id
       
   324  * @return formated sql query
       
   325  */
       
   326 HBufC* CAfStorage::SelectRowLC(TInt appId, const TDesC& actId) const
       
   327 {
       
   328     return BuildQueryLC(KSelectRow(),appId, actId);
       
   329 }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 /**
       
   333  * Format query to select activities for application
       
   334  * @param appId - application id
       
   335  * @return formated sql query
       
   336  */
       
   337 HBufC* CAfStorage::SelectRowsLC(TInt appId) const
       
   338 {
       
   339     return BuildQueryLC(KSelectAppRows(), appId, KNullDesC);
       
   340 }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 /**
       
   344  * Format query to delete activity
       
   345  * @param appId - application id
       
   346  * @param actId - activity id
       
   347  * @return formated sql query
       
   348  */
       
   349 HBufC* CAfStorage::DeleteRowLC(TInt appId, const TDesC& actId) const
       
   350 {
       
   351     return BuildQueryLC(KDeleteRow(),appId, actId);
       
   352 }
       
   353 
       
   354 // -----------------------------------------------------------------------------
       
   355 /**
       
   356  * Format query to delete activities for application
       
   357  * @param appId - application id
       
   358  * @return formated sql query
       
   359  */
       
   360 HBufC* CAfStorage::DeleteRowsLC(TInt appId) const
       
   361 {
       
   362     return BuildQueryLC(KDeleteRows(),appId, KNullDesC);
       
   363 }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 /**
       
   367  * Format sql query
       
   368  * @format - sql format string
       
   369  * @param appId - application id
       
   370  * @param actId - activity id
       
   371  * @return formated sql query
       
   372  */
       
   373 HBufC* CAfStorage::BuildQueryLC(const TDesC& format,
       
   374                                       TInt appId,
       
   375                                       const TDesC& actId) const
       
   376 {
       
   377     TBuf<16> appName;
       
   378     appName.AppendNum(appId);
       
   379     RBuf actName;
       
   380     CleanupClosePushL(actName);
       
   381     actName.CreateL(actId.Length());
       
   382     actName.Copy(actId);
       
   383     HBufC* query = HBufC::NewL(format.Length() +
       
   384                                appName.Length() +
       
   385                                actName.Length() );
       
   386     query->Des().AppendFormat(format, &appName, &actName);
       
   387     CleanupStack::PopAndDestroy(&actName);
       
   388     CleanupStack::PushL(query);
       
   389     return query;
       
   390 }
       
   391 
       
   392 // -----------------------------------------------------------------------------
       
   393 /**
       
   394  * Execute sql query and result serialize into buffer
       
   395  * @param dst - destination result buffer
       
   396  * @param query - sql activity query
       
   397  */
       
   398 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, const TDesC& query, CAfEntry::AccessRights rights, TInt limit)
       
   399 {
       
   400     RDbView view;// Create a view on the database
       
   401     CleanupClosePushL(view);
       
   402     User::LeaveIfError(view.Prepare(mActDb, TDbQuery(query), view.EReadOnly));
       
   403     User::LeaveIfError(view.EvaluateAll());
       
   404     ActivitiesL(dst, view, rights, limit);
       
   405     CleanupStack::PopAndDestroy(&view);
       
   406 }
       
   407 
       
   408 // -----------------------------------------------------------------------------
       
   409 /**
       
   410  * Return view deserialisd into entries array
       
   411  * @param dst - destination result
       
   412  * @param query - view
       
   413  * @param rights - acess rights
       
   414  */
       
   415 void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, RDbView& src, CAfEntry::AccessRights rights, TInt limit)
       
   416 {
       
   417     CDbColSet* row = src.ColSetL();
       
   418     CleanupStack::PushL(row);
       
   419 
       
   420     const TInt flagsOffset(row->ColNo(KFlagsColumnName)),
       
   421                applicationOffset(row->ColNo(KApplicationColumnName)),
       
   422                activityOffset(row->ColNo(KActivityColumnName)),
       
   423                dataOffset(row->ColNo(KDataColumnName));
       
   424 
       
   425     RBuf activityName;
       
   426     CleanupClosePushL(activityName);
       
   427 
       
   428     for (src.FirstL(); src.AtRow(); src.NextL()) {
       
   429         if(0 < limit && dst.Count() >= limit) {
       
   430             break;
       
   431         }
       
   432         src.GetL();
       
   433         ReadDataL(activityName, src, activityOffset);
       
   434 
       
   435         CAfEntry *entry = CAfEntry::NewLC(src.ColInt32(flagsOffset),
       
   436                                           src.ColInt64(applicationOffset),
       
   437                                           activityName,
       
   438                                           KNullDesC,
       
   439                                           KNullDesC8,
       
   440                                           KNullDesC8);
       
   441         if (CAfEntry::Public == rights && (entry->Flags() & CAfEntry::Invisible)) {
       
   442             CleanupStack::PopAndDestroy(entry);
       
   443             continue;
       
   444         }
       
   445         InternalizeDataL(*entry, src, dataOffset);
       
   446         
       
   447         if (CAfEntry::Public == rights || 0 >= limit) {
       
   448             entry->SetDataL(KNullDesC8(), CAfEntry::Private);
       
   449         }
       
   450         dst.AppendL(entry);
       
   451         CleanupStack::Pop(entry);
       
   452     }
       
   453 
       
   454     CleanupStack::PopAndDestroy(&activityName);
       
   455     CleanupStack::PopAndDestroy(row);
       
   456 }
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 /**
       
   460  * Get activity for update
       
   461  * @param query - destination query result
       
   462  * @param appId - application id
       
   463  * @param actId - activity id
       
   464  */
       
   465 void CAfStorage::GetActivityForUpdateL(RDbView& view, TInt appId, const TDesC& actId)
       
   466 {
       
   467     HBufC* query(SelectRowLC(appId, actId));
       
   468     User::LeaveIfError(view.Prepare(mActDb, TDbQuery(*query), view.EUpdatable));
       
   469     CleanupStack::PopAndDestroy(query);
       
   470     User::LeaveIfError(view.EvaluateAll());
       
   471     if (!view.FirstL()) {
       
   472         User::Leave(KErrNotFound);
       
   473     }
       
   474 }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 void CAfStorage::ReadDataL(RBuf& dst, RDbRowSet& src, TInt offset) const
       
   478 {
       
   479     const TInt length(src.ColLength(offset));
       
   480     CAfEntry::ReallocL(dst, length);
       
   481     RDbColReadStream srcStream;
       
   482     srcStream.OpenLC(src,offset);
       
   483     srcStream.ReadL(dst, src.ColLength(offset));
       
   484     CleanupStack::PopAndDestroy(&srcStream);
       
   485 }
       
   486 
       
   487 // -----------------------------------------------------------------------------
       
   488 void CAfStorage::ExternalizeDataL(RDbRowSet& dst,const CAfEntry &src, TInt offset) const
       
   489 {
       
   490     RDbColWriteStream dbStream;
       
   491     CleanupClosePushL(dbStream);
       
   492     dbStream.OpenL(dst, offset);
       
   493     src.ExternalizeDataOnlyL(dbStream);
       
   494     CleanupStack::PopAndDestroy(&dbStream);
       
   495 }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 void CAfStorage::InternalizeDataL(CAfEntry & dst, RDbRowSet& src, TInt offset) const
       
   499 {
       
   500     RDbColReadStream dbStream;
       
   501     CleanupClosePushL(dbStream);
       
   502     dbStream.OpenL(src, offset);
       
   503     dst.InternalizeDataOnlyL(dbStream);
       
   504     CleanupStack::PopAndDestroy(&dbStream);
       
   505 }