--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/activityfw/activitydatabase/hsactivitydbserver/src/afstorage.cpp Wed Jun 23 18:33:40 2010 +0300
@@ -0,0 +1,505 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+#include "afstorage.h"
+#include "afqueries.h"
+#include "afentry.h"
+#include <bautils.h>
+#include <s32mem.h>
+
+_LIT(KDbName, "activity.db");
+_LIT(KDbDrive, "c:");
+const TInt KMaxPathLength = 256;
+
+// -----------------------------------------------------------------------------
+LOCAL_C void CleanupResetAndDestroy(TAny* item)
+{
+ RPointerArray<CAfEntry> *array = static_cast< RPointerArray<CAfEntry>* >(item);
+ array->ResetAndDestroy();
+ array->Close();
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Constructor for performing 1st stage construction
+ * @param session - initialized session to file system
+ */
+CAfStorage::CAfStorage(RFs& session)
+:
+mFsSession(session)
+{
+ // No implementation required
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Destructor.
+ */
+CAfStorage::~CAfStorage()
+{
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Two-phased constructor.
+ * @param session - initialized session to file system
+ */
+CAfStorage* CAfStorage::NewL(RFs& session)
+{
+ CAfStorage* self = new (ELeave) CAfStorage(session);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self;
+ return self;
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * EPOC default constructor for performing 2nd stage construction
+ */
+void CAfStorage::ConstructL()
+{
+ RBuf path;
+ CleanupClosePushL( path );
+ path.CreateL(KMaxPathLength);
+ User::LeaveIfError(mFsSession.PrivatePath(path ));
+ path.Append(KDbName);
+ path.Insert(0, KDbDrive);
+ BaflUtils::EnsurePathExistsL(mFsSession, path);
+ BaflUtils::FileExists(mFsSession, path) ? OpenDbL(path) : CreateDbL(path);
+ CleanupStack::PopAndDestroy(&path);
+
+ DeleteNonPersistentActivitiesL();
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Create database and its structure
+ * @param databaseFile - database file path
+ */
+void CAfStorage::CreateDbL(const TDesC& databaseFile)
+{
+ mFileStore = CPermanentFileStore::ReplaceL(mFsSession,
+ databaseFile,
+ EFileRead|EFileWrite);
+ mFileStore->SetTypeL(mFileStore->Layout());// Set file store type
+ TStreamId id = mActDb.CreateL(mFileStore);// Create stream object
+ mFileStore->SetRootL(id);// Keep database id as root of store
+ mFileStore->CommitL();// Complete creation by commiting
+ CreateTableL();
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Open database
+ * @param databaseFile - database file path
+ */
+void CAfStorage::OpenDbL(const TDesC& databaseFile)
+{
+ mFileStore = CPermanentFileStore::OpenL(mFsSession,
+ databaseFile,
+ EFileRead|EFileWrite);
+ mFileStore->SetTypeL(mFileStore->Layout()); /* Set file store type*/
+ mActDb.OpenL(mFileStore,mFileStore->Root());
+ CDbTableNames* tables = mActDb.TableNamesL();
+ CleanupStack::PushL(tables);
+ if (0 == tables->Count()) {
+ CreateTableL();
+ }
+ CleanupStack::PopAndDestroy(tables);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Create database structure
+ */
+void CAfStorage::CreateTableL()
+{
+ // Add the columns to column set
+ CDbColSet* actColSet = CDbColSet::NewLC();
+
+ TDbCol appName(KApplicationColumnName, EDbColInt64);
+ appName.iAttributes = TDbCol::ENotNull;
+ actColSet->AddL(appName);
+
+ TDbCol actName(KActivityColumnName, EDbColText16);// Using default length
+ actName.iAttributes = TDbCol::ENotNull;
+ actColSet->AddL(actName);
+
+ TDbCol actFlags(KFlagsColumnName, EDbColInt32);
+ actFlags.iAttributes = TDbCol::ENotNull;
+ actColSet->AddL(actFlags);
+
+ actColSet->AddL(TDbCol(KDataColumnName, EDbColLongBinary));// Stream Data
+
+ // Create the table
+ User::LeaveIfError(mActDb.CreateTable(KActivityTableName,
+ *actColSet));
+
+ CleanupStack::PopAndDestroy(actColSet);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Delete non-persistent activities
+ */
+void CAfStorage::DeleteNonPersistentActivitiesL()
+{
+ HBufC *query(BuildQueryLC(KDeleteNonPersistentActivities(), CAfEntry::Persistent, KNullDesC));
+ User::LeaveIfError(mActDb.Execute(*query));
+ CleanupStack::PopAndDestroy(query);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Register new activity
+ * @param appId - application id
+ * @param actId - activity id
+ * @param flags - activity flags
+ * @param imgSrc - activity thumbnail source
+ * @param privateData - activity private data
+ * @param publicData - activity public data
+ */
+void CAfStorage::AddActivityL(CAfEntry& entry)
+{
+ //verify if row already exists
+ TInt errNo(KErrNone);
+ RDbView view;
+ CleanupClosePushL(view);
+ TRAP( errNo, GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId()));
+ if (KErrNone == errNo) {
+ User::Leave(KErrAlreadyExists);
+ }
+ CleanupStack::PopAndDestroy(&view);
+
+ //write table
+ RDbTable table;
+ CleanupClosePushL(table);
+ User::LeaveIfError(table.Open(mActDb, KActivityTableName, table.EUpdatable));
+ CDbColSet *row = table.ColSetL();
+ CleanupStack::PushL(row);
+
+ table.InsertL();
+ TRAP(errNo,
+ table.SetColL(row->ColNo(KApplicationColumnName), TInt64(entry.ApplicationId()));
+ table.SetColL(row->ColNo(KActivityColumnName), entry.ActivityId());
+ table.SetColL(row->ColNo(KFlagsColumnName), entry.Flags());
+ ExternalizeDataL(table, entry, row->ColNo(KDataColumnName));
+ table.PutL();)
+ if (KErrNone != errNo) {
+ table.Cancel();
+ User::Leave(errNo);
+ }
+ CleanupStack::PopAndDestroy(row);
+ CleanupStack::PopAndDestroy(&table);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Update activity
+ * @param entry - activity data
+ */
+void CAfStorage::UpdateActivityL(CAfEntry& entry)
+{
+ RDbView view;
+ CleanupClosePushL(view);
+ GetActivityForUpdateL(view, entry.ApplicationId(), entry.ActivityId());
+ view.UpdateL();
+ TRAPD(errNo,
+ CDbColSet* colSet = view.ColSetL();
+ CleanupStack::PushL(colSet);
+
+ view.SetColL(colSet->ColNo(KFlagsColumnName), entry.Flags());
+ ExternalizeDataL(view, entry, colSet->ColNo(KDataColumnName));
+
+ view.PutL();
+ if (KErrNone != errNo) {
+ view.Cancel();
+ User::Leave(errNo);
+ }
+ CleanupStack::PopAndDestroy(colSet);)
+
+ if (KErrNone != errNo) {
+ view.Cancel();
+ User::Leave(errNo);
+ }
+ CleanupStack::PopAndDestroy(&view);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Delete activity
+ * @param appId - application id
+ * @param actId - activity id
+ */
+void CAfStorage::DeleteActivityL(CAfEntry& entry)
+{
+ HBufC *query(DeleteRowLC(entry.ApplicationId(), entry.ActivityId()));
+ User::LeaveIfError(mActDb.Execute(*query));
+ CleanupStack::PopAndDestroy(query);
+}
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CAfStorage::DeleteActivitiesL(CAfEntry& entry)
+{
+ HBufC *query(DeleteRowsLC(entry.ApplicationId()));
+ User::LeaveIfError(mActDb.Execute(*query));
+ CleanupStack::PopAndDestroy(query);
+}
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst)
+{
+ ActivitiesL(dst, KSelectRows(), CAfEntry::Public);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Serialize application activity into the buffer
+ * @param dst - destination buffer
+ * @param appId - application id
+ */
+void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst,TInt appId)
+{
+ HBufC *query(SelectRowsLC(appId));
+ ActivitiesL(dst, *query, CAfEntry::Private);
+ CleanupStack::PopAndDestroy(query);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Serialize application activity into the buffer
+ * @param dst - destination entry
+ * @param src - condition pattern
+ */
+void CAfStorage::ActivityL(CAfEntry *&dst, CAfEntry& src)
+{
+ HBufC *query = SelectRowLC(src.ApplicationId(), src.ActivityId());
+ RPointerArray<CAfEntry> array;
+ CleanupStack::PushL(TCleanupItem(CleanupResetAndDestroy,&array));
+ ActivitiesL(array, *query, CAfEntry::Private, 1);
+ if (0 >= array.Count()) {
+ User::Leave(KErrNotFound);
+ }
+ dst = array[0];
+ array.Remove(0);
+ CleanupStack::PopAndDestroy(&array);
+ CleanupStack::PopAndDestroy(query);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Provide initialized file system session
+ * @return file system session
+ */
+RFs& CAfStorage::Fs()
+{
+ return mFsSession;
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Format query to select activity row
+ * @param appId - application id
+ * @param actId - activity id
+ * @return formated sql query
+ */
+HBufC* CAfStorage::SelectRowLC(TInt appId, const TDesC& actId) const
+{
+ return BuildQueryLC(KSelectRow(),appId, actId);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Format query to select activities for application
+ * @param appId - application id
+ * @return formated sql query
+ */
+HBufC* CAfStorage::SelectRowsLC(TInt appId) const
+{
+ return BuildQueryLC(KSelectAppRows(), appId, KNullDesC);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Format query to delete activity
+ * @param appId - application id
+ * @param actId - activity id
+ * @return formated sql query
+ */
+HBufC* CAfStorage::DeleteRowLC(TInt appId, const TDesC& actId) const
+{
+ return BuildQueryLC(KDeleteRow(),appId, actId);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Format query to delete activities for application
+ * @param appId - application id
+ * @return formated sql query
+ */
+HBufC* CAfStorage::DeleteRowsLC(TInt appId) const
+{
+ return BuildQueryLC(KDeleteRows(),appId, KNullDesC);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Format sql query
+ * @format - sql format string
+ * @param appId - application id
+ * @param actId - activity id
+ * @return formated sql query
+ */
+HBufC* CAfStorage::BuildQueryLC(const TDesC& format,
+ TInt appId,
+ const TDesC& actId) const
+{
+ TBuf<16> appName;
+ appName.AppendNum(appId);
+ RBuf actName;
+ CleanupClosePushL(actName);
+ actName.CreateL(actId.Length());
+ actName.Copy(actId);
+ HBufC* query = HBufC::NewL(format.Length() +
+ appName.Length() +
+ actName.Length() );
+ query->Des().AppendFormat(format, &appName, &actName);
+ CleanupStack::PopAndDestroy(&actName);
+ CleanupStack::PushL(query);
+ return query;
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Execute sql query and result serialize into buffer
+ * @param dst - destination result buffer
+ * @param query - sql activity query
+ */
+void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, const TDesC& query, CAfEntry::AccessRights rights, TInt limit)
+{
+ RDbView view;// Create a view on the database
+ CleanupClosePushL(view);
+ User::LeaveIfError(view.Prepare(mActDb, TDbQuery(query), view.EReadOnly));
+ User::LeaveIfError(view.EvaluateAll());
+ ActivitiesL(dst, view, rights, limit);
+ CleanupStack::PopAndDestroy(&view);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Return view deserialisd into entries array
+ * @param dst - destination result
+ * @param query - view
+ * @param rights - acess rights
+ */
+void CAfStorage::ActivitiesL(RPointerArray<CAfEntry>& dst, RDbView& src, CAfEntry::AccessRights rights, TInt limit)
+{
+ CDbColSet* row = src.ColSetL();
+ CleanupStack::PushL(row);
+
+ const TInt flagsOffset(row->ColNo(KFlagsColumnName)),
+ applicationOffset(row->ColNo(KApplicationColumnName)),
+ activityOffset(row->ColNo(KActivityColumnName)),
+ dataOffset(row->ColNo(KDataColumnName));
+
+ RBuf activityName;
+ CleanupClosePushL(activityName);
+
+ for (src.FirstL(); src.AtRow(); src.NextL()) {
+ if(0 < limit && dst.Count() >= limit) {
+ break;
+ }
+ src.GetL();
+ ReadDataL(activityName, src, activityOffset);
+
+ CAfEntry *entry = CAfEntry::NewLC(src.ColInt32(flagsOffset),
+ src.ColInt64(applicationOffset),
+ activityName,
+ KNullDesC,
+ KNullDesC8,
+ KNullDesC8);
+ if (CAfEntry::Public == rights && (entry->Flags() & CAfEntry::Invisible)) {
+ CleanupStack::PopAndDestroy(entry);
+ continue;
+ }
+ InternalizeDataL(*entry, src, dataOffset);
+
+ if (CAfEntry::Public == rights || 0 >= limit) {
+ entry->SetDataL(KNullDesC8(), CAfEntry::Private);
+ }
+ dst.AppendL(entry);
+ CleanupStack::Pop(entry);
+ }
+
+ CleanupStack::PopAndDestroy(&activityName);
+ CleanupStack::PopAndDestroy(row);
+}
+
+// -----------------------------------------------------------------------------
+/**
+ * Get activity for update
+ * @param query - destination query result
+ * @param appId - application id
+ * @param actId - activity id
+ */
+void CAfStorage::GetActivityForUpdateL(RDbView& view, TInt appId, const TDesC& actId)
+{
+ HBufC* query(SelectRowLC(appId, actId));
+ User::LeaveIfError(view.Prepare(mActDb, TDbQuery(*query), view.EUpdatable));
+ CleanupStack::PopAndDestroy(query);
+ User::LeaveIfError(view.EvaluateAll());
+ if (!view.FirstL()) {
+ User::Leave(KErrNotFound);
+ }
+}
+
+// -----------------------------------------------------------------------------
+void CAfStorage::ReadDataL(RBuf& dst, RDbRowSet& src, TInt offset) const
+{
+ const TInt length(src.ColLength(offset));
+ CAfEntry::ReallocL(dst, length);
+ RDbColReadStream srcStream;
+ srcStream.OpenLC(src,offset);
+ srcStream.ReadL(dst, src.ColLength(offset));
+ CleanupStack::PopAndDestroy(&srcStream);
+}
+
+// -----------------------------------------------------------------------------
+void CAfStorage::ExternalizeDataL(RDbRowSet& dst,const CAfEntry &src, TInt offset) const
+{
+ RDbColWriteStream dbStream;
+ CleanupClosePushL(dbStream);
+ dbStream.OpenL(dst, offset);
+ src.ExternalizeDataOnlyL(dbStream);
+ CleanupStack::PopAndDestroy(&dbStream);
+}
+
+// -----------------------------------------------------------------------------
+void CAfStorage::InternalizeDataL(CAfEntry & dst, RDbRowSet& src, TInt offset) const
+{
+ RDbColReadStream dbStream;
+ CleanupClosePushL(dbStream);
+ dbStream.OpenL(src, offset);
+ dst.InternalizeDataOnlyL(dbStream);
+ CleanupStack::PopAndDestroy(&dbStream);
+}