browserutilities/favouritesengine/ClientServer/srvsrc/FavouritesSrvTable.cpp
changeset 0 dd21522fd290
child 36 0ed94ceaa377
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browserutilities/favouritesengine/ClientServer/srvsrc/FavouritesSrvTable.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,887 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*      Implementation of class RFavouritesSrvTable
+*      
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <s32strm.h>
+#include "FavouritesSrvTable.h"
+#include "FavouritesPanic.h"
+#include "FavouritesItemData.h"
+#include "FavouritesFilter.h"
+
+// CONSTANTS
+
+/// Buffer size for formatting SQL query in SetFiltersL().
+const TInt KFavouritesMaxSql = 255;
+
+// Database table names.
+
+/// Favourites table name.
+_LIT( KFavouritesTableName, "Favourites" );
+
+// Database column names.                                       // First in:
+
+/// "Uid" column name.
+_LIT( KFavouritesDbUidColName, "Uid" );                         // 6.6
+/// "Parent folder" column name.
+_LIT( KFavouritesDbParentColName, "Parent" );                   // 6.6
+/// "Type" column name.
+_LIT( KFavouritesDbTypeColName, "Type" );                       // 6.6
+/// "Name" column name.
+_LIT( KFavouritesDbNameColName, "Name" );                       // 6.6
+/// "URL" column name.
+_LIT( KFavouritesDbUrlColName, "Url" );                         // 6.6
+/// "WAP AP ApId" column name.
+_LIT( KFavouritesDbApIdColName, "WapApId" );                    // 6.6
+/// "WAP AP Value Kind" column name.
+_LIT( KFavouritesDbApValueKindColName, "WapApValueKind" );      // 6.6
+/// "Username" column name.
+_LIT( KFavouritesDbUserNameColName, "Username" );               // 6.6
+/// "Password" column name.
+_LIT( KFavouritesDbPasswordColName, "Password" );               // 6.6
+/// "Derived classes' extra data" column name.
+_LIT( KFavouritesDbExtraDataColName, "ExtraData" );             // 6.6
+/// "Factory item" column name.
+_LIT( KFavouritesDbFactoryItemColName, "FactoryItem" );         // 6.6
+/// "Read-only" column name.
+_LIT( KFavouritesDbReadOnlyColName, "ReadOnly" );               // 7.0
+/// "ContextId" column name.
+_LIT( KFavouritesDbContextIdColName, "ContextId" );             // 7.0
+/// "Modified" column name.
+_LIT( KFavouritesDbModifiedColName, "Modified" );               // 8.0
+/// "Preferred Uid" column name.
+_LIT( KFavouritesDbPrefUidColName, "PrefUid" );                 // 9.0
+/// "Derived classes' extra data" column name.
+_LIT( KFavouritesDbBrowserDataColName, "BrowserData" );         // 10.0
+
+_LIT( KFavouritesDbHiddenColName, "Hidden" );                   // 11.0
+// Index column names.
+
+/// "Index by Uid" column name.
+_LIT( KFavouritesDbUidIdxName, "UidIdx" );
+
+// ================= LOCAL FUNCTIONS =======================
+
+/**
+* Append escaped aLiteral to the end of aBuffer. This means appenging aLiteral,
+* with all '-s changed to ''-s.
+* @param aBuffer Buffer to append to.
+* @param aLiteral Literal to append escaped.
+*/
+LOCAL_C void AppendEscaped( TDes& aBuffer, const TDesC& aLiteral )
+    {
+    TInt i;
+    TUint quote('\'');  // TChar gives warnings in THUMB & ARMI
+    for ( i = 0; i < aLiteral.Length(); i++ )
+        {
+        aBuffer.Append( aLiteral[i] );
+        if ( aLiteral[i] == quote )
+            {
+            // Duplicate quote.
+            aBuffer.Append( quote );
+            }
+        }
+    }
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::OpenL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::OpenL
+        (
+        RDbNamedDatabase& aDb,
+        RDbRowSet::TAccess aAccess /*=RDbRowSet::EUpdatable*/
+        )
+    {
+    iFiltering = EFalse;
+    User::LeaveIfError( RDbTable::Open( aDb, KFavouritesTableName, aAccess ) );
+    CleanupClosePushL<RDbTable>( *this );
+    GetColumnNumbersL();
+    CleanupStack::Pop();    // closing this
+    SetIndex( KFavouritesDbUidIdxName );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Close
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::Close()
+    {
+    ClearFilters();
+    RDbTable::Close();
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::InsertLC
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::InsertLC()
+    {
+    RDbTable::InsertL();
+    CleanupStack::PushL( TCleanupItem( StaticCancel, this ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::UpdateLC
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::UpdateLC()
+    {
+    RDbTable::UpdateL();
+    CleanupStack::PushL( TCleanupItem( StaticCancel, this ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::PutL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::PutL( TBool aTouch /*=ETrue*/ )
+    {
+    if ( aTouch )
+        {
+        TTime now;
+        now.UniversalTime();
+        SetModifiedL( now );
+        }
+    RDbTable::PutL();
+    CleanupStack::Pop();    // StaticCancel, pushed by InsertLC or UpdateLC.
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Cancel
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::Cancel()
+    {
+    // Any updates in this method must also be applied StaticCancel!
+    RDbTable::Cancel();
+    CleanupStack::Pop();    // StaticCancel, pushed by InsertLC or UpdateLC.
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetFiltersL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetFiltersL( const TFavouritesFilter& aFilter )
+    {
+    HBufC* buf = HBufC::NewLC( KFavouritesMaxSql );
+    TPtr sql = buf->Des();
+    HBufC* tmpBuf = HBufC::NewLC( KFavouritesMaxSql );
+    TPtr tmpPtr = tmpBuf->Des();
+    _LIT( KNone, "" );
+    _LIT( KAnd, "and" );
+    TPtrC sConn;
+
+    sConn.Set( KNone );
+
+    if ( aFilter.iName )
+        {
+        // "name like 'foo*'"
+        _LIT( KFormat1, "%S like '" );
+        sql.Format( KFormat1, &KFavouritesDbNameColName );
+        AppendEscaped( sql, *aFilter.iName );
+        sql.Append( TChar('\'') );
+        sConn.Set( KAnd );
+        }
+
+    if ( aFilter.iType != CFavouritesItem::ENone )
+        {
+        // "and type = 0"
+        _LIT( KFormat2, " %S %S = %d" );
+        tmpPtr.Format
+            ( KFormat2, &sConn, &KFavouritesDbTypeColName, aFilter.iType );
+        sConn.Set( KAnd );
+        sql.Append( tmpPtr );
+        }
+
+    if ( aFilter.iParentFolder != KFavouritesNullUid )
+        {
+        // "and parent = 7"
+        _LIT( KFormat3, " %S %S = %d" );
+        tmpPtr.Format( KFormat3,
+            &sConn, &KFavouritesDbParentColName, aFilter.iParentFolder );
+        sConn.Set( KAnd );
+        sql.Append( tmpPtr );
+        }
+
+    if ( aFilter.iContextId != KFavouritesNullContextId )
+        {
+        // "and contextid = 7"
+        _LIT( KFormat3, " %S %S = %d" );
+        tmpPtr.Format( KFormat3,
+            &sConn, &KFavouritesDbContextIdColName, aFilter.iContextId );
+        sConn.Set( KAnd );
+        sql.Append( tmpPtr );
+        }
+
+    // Clear old one, if any.
+    ClearFilters();
+
+    if ( sql.Length() > 0 )
+        {
+        // Make new constraint, if there is any filter set.
+        // Otherwise there will be no constraint.
+        User::LeaveIfError
+            ( iFilter.Open( *this, TDbQuery( sql, EDbCompareFolded ) ) );
+        iFiltering = ETrue;
+        }
+
+    CleanupStack::PopAndDestroy( 2 );  // tmpBuf, buf
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::ClearFilters
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::ClearFilters()
+    {
+    if ( iFiltering )
+        {
+        iFilter.Close();
+        iFiltering = EFalse;
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::NextL
+// ---------------------------------------------------------
+//
+TBool RFavouritesSrvTable::NextL()
+    {
+    while ( RDbTable::NextL() )
+        {
+        // Use the filters, if any.
+        if ( !iFiltering || MatchL( iFilter ) )
+            {
+            // We have a matching row.
+            return ETrue;
+            }
+        }
+    // No matching rows were found.
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SeekToUidL
+// ---------------------------------------------------------
+//
+TBool RFavouritesSrvTable::SeekToUidL( TInt aUid )
+    {
+    return SeekL( TDbSeekKey( aUid ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::GotoToUidL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::GotoToUidL( TInt aUid )
+    {
+    if ( !SeekToUidL( aUid ) )
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::ReadItemDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::ReadItemDataL( CFavouritesItemImpl& aItem ) const
+    {
+    // Fill standard attributes.
+    aItem.SetUid( Uid() );
+    // No bookmark can exist with the Null Uid.
+    __ASSERT_DEBUG( aItem.Uid() != KFavouritesNullUid,
+        FavouritesPanic( EFavouritesNullUidInDatabase ) );
+    aItem.SetParentFolder( ParentFolder() );
+    aItem.SetType( Type() );
+    aItem.SetNameL( Name() );
+    HBufC* url = UrlLC();
+    aItem.SetUrlL( *url );
+    CleanupStack::PopAndDestroy();  // url
+    aItem.SetUserNameL( Username() );
+    aItem.SetPasswordL( Password() );
+    aItem.SetWapAp( WapAp() );
+    aItem.SetFactoryItem( FactoryItem() );
+    aItem.SetReadOnly( ReadOnly() );
+    aItem.SetContextId( ContextId() );
+    aItem.SetModified( Modified() );
+    aItem.SetHidden( Hidden() );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Uid
+// ---------------------------------------------------------
+//
+TInt RFavouritesSrvTable::Uid() const
+    {
+    return ColInt( iColNoUid );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::ParentFolder
+// ---------------------------------------------------------
+//
+TInt RFavouritesSrvTable::ParentFolder() const
+    {
+    return ColInt( iColNoParentFolder );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Type
+// ---------------------------------------------------------
+//
+CFavouritesItem::TType RFavouritesSrvTable::Type() const
+    {
+    return STATIC_CAST( CFavouritesItem::TType, ColInt32( iColNoType ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Name
+// ---------------------------------------------------------
+//
+TPtrC RFavouritesSrvTable::Name() const
+    {
+    return ColDes( iColNoName );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::UrlLC
+// ---------------------------------------------------------
+//
+HBufC* RFavouritesSrvTable::UrlLC() const
+    {
+    // URL is long column.
+    RDbColReadStream stream;
+    TInt len = ColLength( iColNoUrl );
+    HBufC* buf = HBufC::NewLC( len );
+    if ( len )
+        {
+        stream.OpenLC( *this, iColNoUrl );
+        TPtr ptr = buf->Des();
+        stream.ReadL( ptr, len );
+        CleanupStack::PopAndDestroy();  // Close stream
+        }
+    return buf;
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::WapAp
+// ---------------------------------------------------------
+//
+TFavouritesWapAp RFavouritesSrvTable::WapAp() const
+    {
+    TFavouritesWapAp wapAp;
+    wapAp.iApId = ColUint32 ( iColNoWapApId );
+    wapAp.iValueKind = STATIC_CAST
+        ( TFavouritesWapAp::TValueKind, ColInt ( iColNoWapApValueKind ) );
+    return wapAp;
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Username
+// ---------------------------------------------------------
+//
+TPtrC RFavouritesSrvTable::Username() const
+    {
+    return ColDes( iColNoUserName );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Password
+// ---------------------------------------------------------
+//
+TPtrC RFavouritesSrvTable::Password() const
+    {
+    return ColDes( iColNoPassword );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::GetExtraDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::GetExtraDataL( MStreamBuf& aSink )
+    {
+    RDbColReadStream rs;
+    rs.OpenLC( *this, iColNoExtraData );
+    RWriteStream ws( &aSink );
+    rs.ReadL( ws );
+    CleanupStack::PopAndDestroy();  // Close rs
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::GetBrowserDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::GetBrowserDataL( MStreamBuf& aSink )
+    {
+    if ( iColNoBrowserData != KDbNullColNo )
+        {
+        RDbColReadStream rs;
+        rs.OpenLC( *this, iColNoBrowserData );
+        RWriteStream ws( &aSink );
+        rs.ReadL( ws );
+        CleanupStack::PopAndDestroy();  // Close rs
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::FactoryItem
+// ---------------------------------------------------------
+//
+TBool RFavouritesSrvTable::FactoryItem() const
+    {
+    return ColInt( iColNoFactoryItem );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::ReadOnly
+// ---------------------------------------------------------
+//
+TBool RFavouritesSrvTable::ReadOnly() const
+    {
+    return ColInt( iColNoReadOnly );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::ContextId
+// ---------------------------------------------------------
+//
+TInt32 RFavouritesSrvTable::ContextId() const
+    {
+    return ColInt32( iColNoContextId );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Modified
+// ---------------------------------------------------------
+//
+TTime RFavouritesSrvTable::Modified() const
+    {
+    TTime modified( 0 );
+    if ( iColNoModified != KDbNullColNo )
+        {
+        modified = ColTime( iColNoModified );
+        }
+    return modified;
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::PreferredUid
+// ---------------------------------------------------------
+//
+TInt RFavouritesSrvTable::PreferredUid() const
+    {
+    TInt preferredUid( KFavouritesNullUid );
+    if ( iColNoPreferredUid != KDbNullColNo )
+        {
+        preferredUid = ColInt( iColNoPreferredUid );
+        }
+    return preferredUid;
+    }
+
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::Hidden
+// ---------------------------------------------------------
+//
+TBool RFavouritesSrvTable::Hidden() const
+    {
+    return ColInt( iColNoHidden );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::WriteItemDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::WriteItemDataL( const CFavouritesItemImpl& aItem )
+    {
+    // Fill standard attributes.
+    __ASSERT_DEBUG( !ReadOnly(), FavouritesPanic( EFavouritesInternal ) );
+    // Uid is *NOT* set. We update the current row.
+    SetParentFolderL( aItem.ParentFolder() );
+    SetTypeL( aItem.Type() );
+    SetNameL( aItem.Name() );
+    SetUrlL( aItem.Url() );
+    SetUsernameL( aItem.UserName() );
+    SetPasswordL( aItem.Password() );
+    SetWapApL( aItem.WapAp() );
+    // Note: read-only flag is *NOT* set. Setting that is accessible via
+    // SetReadOnlyL.
+    // Note: factory item flag is *NOT* set. Setting that is accessible via
+    // SetFactoryItemL.
+    SetContextIdL( aItem.ContextId() );
+    // Note: last modification time is *NOT* set; PutL will do it.
+    // Manual setting (override) is accessible via SetModifiedL.
+    SetHiddenL( aItem.IsHidden() );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetUidL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetUidL( TInt aUid )
+    {
+    SetColL( iColNoUid, aUid );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetParentFolderL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetParentFolderL( TInt aUid )
+    {
+    SetColL( iColNoParentFolder, aUid );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetTypeL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetTypeL( CFavouritesItem::TType aType )
+    {
+    SetColL( iColNoType, STATIC_CAST( TInt, aType ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetNameL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetNameL( const TDesC& aName )
+    {
+    SetColL( iColNoName, aName );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetUrlL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetUrlL( const TDesC& aUrl )
+    {
+    RDbColWriteStream stream;
+    stream.OpenLC( *this, iColNoUrl );
+    stream.WriteL( aUrl, aUrl.Length() );
+    stream.CommitL();
+    CleanupStack::PopAndDestroy();  // stream;
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetWapApL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetWapApL( const TFavouritesWapAp& aWapAp )
+    {
+    SetColL( iColNoWapApId, aWapAp.iApId );
+    SetColL( iColNoWapApValueKind,
+        STATIC_CAST( TInt, aWapAp.iValueKind ) );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetUsernameL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetUsernameL( const TDesC& aUsername )
+    {
+    SetColL( iColNoUserName, aUsername );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetPasswordL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetPasswordL( const TDesC& aPassword )
+    {
+    SetColL( iColNoPassword, aPassword );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetExtraDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetExtraDataL( MStreamBuf& aSource )
+    {
+    RDbColWriteStream ws;
+    ws.OpenLC( *this, iColNoExtraData );
+    RReadStream rs( &aSource );
+    ws.WriteL( rs );
+    ws.CommitL();
+    CleanupStack::PopAndDestroy();  // Close ws
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetBrowserDataL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetBrowserDataL( MStreamBuf& aSource )
+    {
+    if ( iColNoBrowserData != KDbNullColNo )
+        {
+        RDbColWriteStream ws;
+        ws.OpenLC( *this, iColNoBrowserData );
+        RReadStream rs( &aSource );
+        ws.WriteL( rs );
+        ws.CommitL();
+        CleanupStack::PopAndDestroy();  // Close ws
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetFactoryItemL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetFactoryItemL( TBool aFactoryItem )
+    {
+    SetColL( iColNoFactoryItem, aFactoryItem );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetReadOnlyL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetReadOnlyL( TBool aReadOnly )
+    {
+    SetColL( iColNoReadOnly, aReadOnly );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetContextIdL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetContextIdL( TInt32 aContextId )
+    {
+    SetColL( iColNoContextId, aContextId );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetModifiedL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetModifiedL( TTime aModified )
+    {
+    if ( iColNoModified != KDbNullColNo )
+        {
+        SetColL( iColNoModified, aModified );
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetPreferredUidL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetPreferredUidL( TInt aUid )
+    {
+    if ( iColNoPreferredUid != KDbNullColNo )
+        {
+        SetColL( iColNoPreferredUid, aUid );
+        }
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::SetHiddenL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::SetHiddenL( TBool aHidden )
+    {
+    SetColL( iColNoHidden, aHidden );
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::PutWriteLockL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::PutWriteLockL()
+    {
+    // Insert will get write-lock if possible, or leave if not.
+    InsertLC();
+    Cancel();
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::CreateStructureL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::CreateStructureL( RDbNamedDatabase& aDb )
+    {
+    // Create columns.
+    CDbColSet* colset = CDbColSet::NewLC();
+
+    TDbCol col( KFavouritesDbUidColName, EDbColInt32 );
+    col.iAttributes = TDbCol::EAutoIncrement;
+    colset->AddL( col );
+    colset->AddL( TDbCol( KFavouritesDbParentColName, EDbColInt32 ) );
+    colset->AddL( TDbCol( KFavouritesDbTypeColName, EDbColInt32 ) );
+    colset->AddL( TDbCol
+        ( KFavouritesDbNameColName, EDbColText, KFavouritesMaxName ) );
+    colset->AddL( TDbCol
+        ( KFavouritesDbUrlColName, EDbColLongText, KFavouritesMaxUrl ) );
+    colset->AddL( TDbCol( KFavouritesDbApIdColName, EDbColUint32 ) );
+    colset->AddL( TDbCol( KFavouritesDbApValueKindColName, EDbColInt32 ) );
+    colset->AddL( TDbCol
+        ( KFavouritesDbUserNameColName, EDbColText, KFavouritesMaxUserName ) );
+    colset->AddL( TDbCol
+        ( KFavouritesDbPasswordColName, EDbColText, KFavouritesMaxPassword ) );
+    colset->AddL( TDbCol( KFavouritesDbExtraDataColName, EDbColLongBinary ) );
+    colset->AddL( TDbCol( KFavouritesDbFactoryItemColName, EDbColBit ) );
+    colset->AddL( TDbCol( KFavouritesDbReadOnlyColName, EDbColBit ) );
+    colset->AddL( TDbCol( KFavouritesDbContextIdColName, EDbColInt32 ) );
+    colset->AddL( TDbCol( KFavouritesDbModifiedColName, EDbColDateTime ) );
+    colset->AddL( TDbCol( KFavouritesDbPrefUidColName, EDbColInt32 ) );
+    colset->AddL
+        ( TDbCol( KFavouritesDbBrowserDataColName, EDbColLongBinary ) );
+    colset->AddL( TDbCol( KFavouritesDbHiddenColName, EDbColBit ) );
+    User::LeaveIfError
+        ( aDb.CreateTable( KFavouritesTableName, *colset ) );
+    CleanupStack::PopAndDestroy();  // colset
+
+    // Create index by uid.
+    CDbKey* key = CDbKey::NewLC();
+    // Create key on Uid column, ascending order.
+    key->AddL( TDbKeyCol ( KFavouritesDbUidColName ) );
+    User::LeaveIfError( aDb.CreateIndex
+        ( KFavouritesDbUidIdxName, KFavouritesTableName, *key ) );
+    CleanupStack::PopAndDestroy();  // key
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::VerifyStructureL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::VerifyStructureL
+( RDbNamedDatabase& aDb, TBool aUpgrade )
+    {
+    CDbColSet* colset = aDb.ColSetL( KFavouritesTableName );
+    CleanupStack::PushL( colset );
+
+    if (
+        colset->ColNo( KFavouritesDbUidColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbParentColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbTypeColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbNameColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbUrlColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbUserNameColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbPasswordColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbApIdColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbApValueKindColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbExtraDataColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbFactoryItemColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbReadOnlyColName ) == KDbNullColNo ||
+        colset->ColNo( KFavouritesDbContextIdColName ) == KDbNullColNo
+       )
+        {
+        // Mandatory column is missing, this database is corrupt.
+        User::Leave( KErrCorrupt );
+        }
+
+    if ( aUpgrade )
+        {
+        // Check optional columns, upgrade if necessary.
+        // If upgrade is not possible, we don't even check those; as the
+        // database is still functional without them.
+
+        TInt missingCols( EFalse );
+
+        if ( colset->ColNo( KFavouritesDbModifiedColName ) == KDbNullColNo )
+            {
+            // Last modification column is missing.
+            colset->AddL( TDbCol
+                ( KFavouritesDbModifiedColName, EDbColDateTime ) );
+            missingCols = ETrue;
+            }
+
+        if ( colset->ColNo( KFavouritesDbPrefUidColName ) == KDbNullColNo )
+            {
+            // Preferred uid column is missing.
+            colset->AddL( TDbCol( KFavouritesDbPrefUidColName, EDbColInt32 ) );
+            missingCols = ETrue;
+            }
+
+        if ( colset->ColNo( KFavouritesDbBrowserDataColName ) == KDbNullColNo )
+            {
+            // Preferred uid column is missing.
+            colset->AddL
+                ( TDbCol( KFavouritesDbBrowserDataColName, EDbColLongBinary ) );
+            missingCols = ETrue;
+            }
+        if( colset->ColNo( KFavouritesDbHiddenColName)  == KDbNullColNo )
+            {
+            // Preferred uid column is missing.
+            colset->AddL
+                ( TDbCol( KFavouritesDbHiddenColName, EDbColBit ) );
+            missingCols = ETrue;
+            }
+
+        if ( missingCols )
+            {
+            // Some columns are missing, try to add them now.
+            // Upgrade error is ignored, database is still functional (except
+            // of course the missing columns).
+            (void)aDb.AlterTable( KFavouritesTableName, *colset );
+            }
+        }
+
+    CleanupStack::PopAndDestroy();  // colset
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::GetColumnNumbersL
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::GetColumnNumbersL()
+    {
+    CDbColSet* colset = ColSetL();
+    CleanupStack::PushL( colset );
+
+    iColNoUid = colset->ColNo( KFavouritesDbUidColName );
+    iColNoParentFolder = colset->ColNo( KFavouritesDbParentColName );
+    iColNoType = colset->ColNo( KFavouritesDbTypeColName );
+    iColNoName = colset->ColNo( KFavouritesDbNameColName );
+    iColNoUrl = colset->ColNo( KFavouritesDbUrlColName );
+    iColNoUserName = colset->ColNo( KFavouritesDbUserNameColName );
+    iColNoPassword = colset->ColNo( KFavouritesDbPasswordColName );
+    iColNoWapApId = colset->ColNo( KFavouritesDbApIdColName );
+    iColNoWapApValueKind = colset->ColNo( KFavouritesDbApValueKindColName );
+    iColNoExtraData = colset->ColNo( KFavouritesDbExtraDataColName );
+    iColNoFactoryItem = colset->ColNo( KFavouritesDbFactoryItemColName );
+    iColNoReadOnly = colset->ColNo( KFavouritesDbReadOnlyColName );
+    iColNoContextId = colset->ColNo( KFavouritesDbContextIdColName );
+    iColNoModified = colset->ColNo( KFavouritesDbModifiedColName );
+    iColNoPreferredUid = colset->ColNo( KFavouritesDbPrefUidColName );
+    iColNoBrowserData = colset->ColNo( KFavouritesDbBrowserDataColName );
+    iColNoHidden = colset->ColNo( KFavouritesDbHiddenColName );
+
+    CleanupStack::PopAndDestroy();  // colset
+    }
+
+// ---------------------------------------------------------
+// RFavouritesSrvTable::StaticCancel
+// ---------------------------------------------------------
+//
+void RFavouritesSrvTable::StaticCancel( TAny* aTable )
+    {
+    // Same as Cancel; except it does not pop the cleanup item; because
+    // it is called as part of leave processing.
+    // Any updates in this method must also be applied Cancel!
+    RFavouritesSrvTable* table = STATIC_CAST( RFavouritesSrvTable*, aTable );
+    table->RDbTable::Cancel();
+    }
+
+//  End of File