--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/landmarks/locationlandmarks/dbreg/src/EPos_CPosLmDbRegistry.cpp Tue Feb 02 01:06:48 2010 +0200
@@ -0,0 +1,540 @@
+/*
+* Copyright (c) 2005 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: Registry for storing landmark database information.
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include <d32dbms.h>
+#include <EPos_Landmarks.h>
+#include <epos_poslmdatabaseutility.h>
+#include <EPos_TPosLmDatabaseSettings.h>
+#include "EPos_CPosLmDbRegistry.h"
+#include "EPos_PosDbRegistryConstants.h"
+#include "EPos_CPosLmDatabaseIterator.h"
+
+//CONSTANTS
+const TInt KPosLmSqlStatementMaxLen = 256;
+
+//If a URI including the sql statement exceed KPosLmSqlStatementMaxLen
+//a panic will be raised. The sql statement used in the function
+//FindLongEntryL excluding the URI is approx. 55 characters. Creating a
+//sql statement with a URI of max 180 characters will therefor not exceed
+//KPosLmSqlStatementMaxLen.
+const TInt KPosLmSqlStatementUriMaxLen = 180;
+
+struct TDeleteFile
+ {
+ RFs* iFs;
+ TPtrC iFilename;
+ };
+
+// ==================== LOCAL FUNCTIONS ====================
+
+// ---------------------------------------------------------
+// Deletes the database if anything goes
+// wrong during database construction.
+// ---------------------------------------------------------
+//
+void DeleteFileCleanupItem(TAny* aParam)
+ {
+ TDeleteFile* obj = reinterpret_cast<TDeleteFile*>(aParam);
+ obj->iFs->Delete(obj->iFilename);
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::CPosLmDbRegistry
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPosLmDbRegistry::CPosLmDbRegistry()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPosLmDbRegistry::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CPosLmDbRegistry* CPosLmDbRegistry::NewL()
+ {
+ CPosLmDbRegistry* self = new (ELeave) CPosLmDbRegistry;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// Destructor
+EXPORT_C CPosLmDbRegistry::~CPosLmDbRegistry()
+ {
+ iDb.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::CreateL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::CreateL(
+ RFs& aFileSession,
+ const TDesC& aFileName)
+ {
+ User::LeaveIfError(iDb.Create(aFileSession, aFileName));
+
+ TDeleteFile* del = new (ELeave) TDeleteFile;
+ CleanupStack::PushL(del);
+ del->iFs = &aFileSession;
+ del->iFilename.Set(aFileName);
+
+ CleanupStack::PushL(TCleanupItem(DeleteFileCleanupItem, del));
+ CleanupClosePushL(iDb);
+
+ //Create the database table
+ CDbColSet* columns = CDbColSet::NewLC();
+
+ columns->AddL(TDbCol(KPosLmProtocolCol, EDbColText, KProtocolMaxLength));
+ columns->AddL(TDbCol(KPosLmFileNameCol, EDbColLongText));
+ columns->AddL(TDbCol(KPosLmSettingsCol, EDbColLongText));
+ User::LeaveIfError(iDb.CreateTable(KPosLmDbRegistryTable, *columns));
+
+ CleanupStack::PopAndDestroy(columns);
+
+ //Create index on the protocol field
+ _LIT(KPosSqlCreateIndex, "CREATE INDEX %S ON %S (%S)");
+
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+ sql->Des().Format(KPosSqlCreateIndex, &KPosLmDbRegIndex,
+ &KPosLmDbRegistryTable, &KPosLmProtocolCol);
+ User::LeaveIfError(iDb.Execute(*sql));
+ CleanupStack::PopAndDestroy(sql);
+
+ CleanupStack::Pop(&iDb);
+ CleanupStack::Pop(); //DeleteFileCleanupItem
+ CleanupStack::PopAndDestroy(del);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::Open
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CPosLmDbRegistry::Open(
+ RFs& aFileSession,
+ const TDesC& aFileName)
+ {
+ return iDb.Open(aFileSession, aFileName);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::RegisterDatabaseL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::RegisterDatabaseL(
+ const TDesC& aDatabaseUri,
+ const TPosLmDatabaseSettings& aSettings)
+ {
+ RecoverIfNeededL();
+
+ HBufC* embeddedUri =
+ PosLmDatabaseUtility::EmbedSingleQuoteCharactersLC(aDatabaseUri);
+
+ RDbView view;
+ CleanupClosePushL(view);
+
+ if (FindEntryL(view, *embeddedUri))
+ {
+ User::Leave(KErrAlreadyExists);
+ }
+
+ CleanupStack::PopAndDestroy(2, embeddedUri); //&view
+
+ _LIT(KPosLmSqlRegisterDb, "SELECT %S, %S, %S FROM %S");
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+ sql->Des().Format(KPosLmSqlRegisterDb, &KPosLmProtocolCol,
+ &KPosLmFileNameCol, &KPosLmSettingsCol, &KPosLmDbRegistryTable);
+
+ CleanupClosePushL(view);
+ User::LeaveIfError(view.Prepare(iDb, TDbQuery(*sql),
+ TDbWindow::EUnlimited, RDbView::EInsertOnly));
+
+ CDbColSet* colset = view.ColSetL();
+ CleanupStack::PushL(colset);
+
+ view.InsertL();
+ view.SetColL(
+ colset->ColNo(KPosLmProtocolCol), ExtractProtocol(aDatabaseUri));
+
+ RDbColWriteStream out;
+ out.OpenLC(view, colset->ColNo(KPosLmFileNameCol));
+ out.WriteL(ExtractFileName(aDatabaseUri));
+ CleanupStack::Pop(&out);
+ out.Close(); // This line must exist in order for
+ // the item to be written to db.
+
+ TPckgC<TPosLmDatabaseSettings> settingsPckg(aSettings);
+ out.OpenLC(view, colset->ColNo(KPosLmSettingsCol));
+ out.WriteL(settingsPckg);
+ CleanupStack::Pop(&out);
+ out.Close(); // This line must exist in order for
+ // the item to be written to db.
+
+ view.PutL();
+ // CleanupStack::PopAndDestroy(3, sql); //view, colset
+
+ // CleanupStack::PopAndDestroy(colset);
+ CleanupStack::Pop(colset);
+ delete colset;
+ CleanupStack::PopAndDestroy(&view);
+ CleanupStack::PopAndDestroy(sql);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::UnregisterDatabaseL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::UnregisterDatabaseL(
+ const TDesC& aDatabaseUri)
+ {
+ RecoverIfNeededL();
+
+ HBufC* embeddedUri =
+ PosLmDatabaseUtility::EmbedSingleQuoteCharactersLC(aDatabaseUri);
+
+ _LIT(KPosLmSqlUnregisterDb,
+ "Delete FROM %S WHERE %S = '%S' AND %S = '%S'");
+
+ //If the URI length is less than KPosLmSqlStatementUriMaxLen
+ //proceed as usual, i.e. create a sql delete statement to unregister
+ //the URI. However, URIs that exceed KPosLmSqlStatementUriMaxLen has
+ //to be handled differently, see the else block.
+ if (embeddedUri->Length() < KPosLmSqlStatementUriMaxLen)
+ {
+ TPtrC protPtr = ExtractProtocol(*embeddedUri);
+ TPtrC namePtr = ExtractFileName(*embeddedUri);
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+
+ sql->Des().Format(KPosLmSqlUnregisterDb, &KPosLmDbRegistryTable,
+ &KPosLmProtocolCol, &protPtr, &KPosLmFileNameCol, &namePtr);
+
+ User::LeaveIfError(iDb.Execute(*sql));
+ CleanupStack::PopAndDestroy(sql);
+ }
+ else
+ {
+ //Handle long URIs.
+ RDbView view;
+ CleanupClosePushL(view);
+
+ if (FindLongEntryL(view, *embeddedUri))
+ {
+ view.DeleteL();
+ }
+
+ CleanupStack::PopAndDestroy(&view);
+ }
+ CleanupStack::PopAndDestroy(embeddedUri);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::UnregisterAllL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::UnregisterAllL(
+ const TDesC& aProtocol)
+ {
+ RecoverIfNeededL();
+
+ _LIT(KPosLmSqlUnregisterAll, "Delete FROM %S WHERE %S = '%S'");
+
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+ sql->Des().Format(KPosLmSqlUnregisterAll, &KPosLmDbRegistryTable,
+ &KPosLmProtocolCol, &aProtocol);
+
+ User::LeaveIfError(iDb.Execute(*sql));
+ CleanupStack::PopAndDestroy(sql);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ReadDatabaseSettingsL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::ReadDatabaseSettingsL(
+ const TDesC& aDatabaseUri,
+ TPosLmDatabaseSettings& aSettings)
+ {
+ RecoverIfNeededL();
+
+ HBufC* embeddedUri =
+ PosLmDatabaseUtility::EmbedSingleQuoteCharactersLC(aDatabaseUri);
+
+ RDbView view;
+ CleanupClosePushL(view);
+ if (!FindEntryL(view, *embeddedUri))
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ CDbColSet* colset = view.ColSetL();
+ CleanupStack::PushL(colset);
+
+ view.GetL();
+ TPckg<TPosLmDatabaseSettings> dbPckg(aSettings);
+
+ RDbColReadStream in;
+ in.OpenLC(view, colset->ColNo(KPosLmSettingsCol));
+ in.ReadL(dbPckg);
+ in.Close();
+
+ CleanupStack::PopAndDestroy(4, embeddedUri); //&view, colset, &in
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ModifyDatabaseSettingsL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CPosLmDbRegistry::ModifyDatabaseSettingsL(
+ const TDesC& aDatabaseUri,
+ const TPosLmDatabaseSettings& aSettings)
+ {
+ RecoverIfNeededL();
+
+ HBufC* embeddedUri =
+ PosLmDatabaseUtility::EmbedSingleQuoteCharactersLC(aDatabaseUri);
+
+ RDbView view;
+ CleanupClosePushL(view);
+ if (!FindEntryL(view, *embeddedUri))
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ view.UpdateL();
+
+ CDbColSet* colset = view.ColSetL();
+ CleanupStack::PushL(colset);
+
+ TPckg<TPosLmDatabaseSettings> settingsPckg(aSettings);
+ RDbColWriteStream out;
+ out.OpenLC(view, colset->ColNo(KPosLmSettingsCol));
+ out.WriteL(settingsPckg);
+ CleanupStack::Pop(&out);
+ out.Close();
+
+ view.PutL();
+
+ CleanupStack::PopAndDestroy(3, embeddedUri); //&view, colset
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ListDatabasesL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CPosLmDatabaseIterator* CPosLmDbRegistry::ListDatabasesL(
+ const TDesC& aProtocol)
+ {
+ RecoverIfNeededL();
+
+ _LIT(KPosLmSqlListDb, "SELECT * FROM %S WHERE %S = '%S'");
+
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+ sql->Des().Format(KPosLmSqlListDb,
+ &KPosLmDbRegistryTable, &KPosLmProtocolCol, &aProtocol);
+
+ RDbView view;
+ CleanupClosePushL(view);
+ User::LeaveIfError(view.Prepare(
+ iDb, TDbQuery(*sql), TDbWindow::EUnlimited));
+ User::LeaveIfError(view.EvaluateAll());
+
+ CPosLmDatabaseIterator* iter = CPosLmDatabaseIterator::NewL(view);
+ CleanupStack::Pop(&view);
+ CleanupStack::PopAndDestroy(sql);
+
+ return iter;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::Compact
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CPosLmDbRegistry::Compact()
+ {
+ return iDb.Compact();
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ExtractProtocol
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC CPosLmDbRegistry::ExtractProtocol(
+ const TDesC& aDatabaseUri)
+ {
+ TInt pos = aDatabaseUri.Find(KProtocol);
+ if (pos == KErrNotFound)
+ {
+ return TPtrC();
+ }
+ return aDatabaseUri.Left(pos);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::ExtractFileName
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC CPosLmDbRegistry::ExtractFileName(
+ const TDesC& aDatabaseUri)
+ {
+ TInt pos = aDatabaseUri.Find(KProtocol);
+ if (pos == KErrNotFound)
+ {
+ return TPtrC();
+ }
+ return aDatabaseUri.Right(aDatabaseUri.Length() -
+ pos - KProtocol().Length());
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::FindEntryL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmDbRegistry::FindEntryL(
+ RDbView& aView,
+ const TDesC& aDatabaseUri)
+ {
+ if (aDatabaseUri.Length() < KPosLmSqlStatementUriMaxLen)
+ {
+ _LIT(KPosLmSqlSelectSettings,
+ "SELECT %S FROM %S WHERE %S = '%S' AND %S = '%S'");
+
+ TPtrC protPtr = ExtractProtocol(aDatabaseUri);
+ TPtrC namePtr = ExtractFileName(aDatabaseUri);
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+
+ sql->Des().Format(KPosLmSqlSelectSettings, &KPosLmSettingsCol,
+ &KPosLmDbRegistryTable, &KPosLmProtocolCol, &protPtr,
+ &KPosLmFileNameCol, &namePtr);
+
+ User::LeaveIfError(aView.Prepare(iDb, TDbQuery(*sql),
+ TDbWindow::EUnlimited));
+ User::LeaveIfError(aView.EvaluateAll());
+
+ CleanupStack::PopAndDestroy(sql);
+ return aView.NextL();
+ }
+
+ return FindLongEntryL(aView, aDatabaseUri);
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::FindLongEntryL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CPosLmDbRegistry::FindLongEntryL(
+ RDbView& aView,
+ const TDesC& aDatabaseUri)
+ {
+ _LIT(KPosLmSqlSelectSettingsLike,
+ "SELECT %S, %S FROM %S WHERE %S = '%S' AND %S LIKE '%S*'");
+
+ HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen);
+
+ TPtrC protPtr = ExtractProtocol(aDatabaseUri);
+ TPtrC namePtr = ExtractFileName(aDatabaseUri);
+ TPtrC leftPart(namePtr.Left(KPosLmSqlStatementUriMaxLen));
+
+ sql->Des().Format(KPosLmSqlSelectSettingsLike,
+ &KPosLmSettingsCol, &KPosLmFileNameCol,
+ &KPosLmDbRegistryTable, &KPosLmProtocolCol, &protPtr,
+ &KPosLmFileNameCol, &leftPart);
+
+ //Find all entries that match the supplied URI,
+ User::LeaveIfError(
+ aView.Prepare(iDb, TDbQuery(*sql), TDbWindow::EUnlimited));
+ User::LeaveIfError(aView.EvaluateAll());
+
+ //Check for exact matches.
+ TBool found(EFalse);
+ while (!found && aView.NextL())
+ {
+ aView.GetL();
+
+ CDbColSet* colset = aView.ColSetL();
+ CleanupStack::PushL(colset);
+
+ TDbColNo colNo = colset->ColNo(KPosLmFileNameCol);
+ TInt nameLength = aView.ColLength(colNo);
+
+ CleanupStack::PopAndDestroy(colset);
+
+ HBufC* name = HBufC::NewLC(nameLength);
+ TPtr ptr = name->Des();
+
+ RDbColReadStream in;
+ in.OpenLC(aView, colNo);
+ in.ReadL(ptr, nameLength);
+ CleanupStack::Pop(&in);
+ in.Close();
+
+ if (ptr == namePtr)
+ {
+ found = ETrue;
+ }
+ CleanupStack::PopAndDestroy(name);
+ }
+
+ CleanupStack::PopAndDestroy(sql);
+ return found;
+ }
+
+// -----------------------------------------------------------------------------
+// CPosLmDbRegistry::RecoverIfNeededL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CPosLmDbRegistry::RecoverIfNeededL()
+ {
+ if (iDb.IsDamaged())
+ {
+ User::LeaveIfError(iDb.Recover());
+ }
+ }
+
+// End of File
+