landmarks/locationlandmarks/dbreg/src/EPos_CPosLmDbRegistry.cpp
changeset 0 667063e416a2
child 8 6fcbaa43369c
--- /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
+