srsf/nssvasapi/nssvasdb/src/nssvascvasdb.cpp
changeset 13 57b735022c18
parent 1 b13cd05eeb2f
equal deleted inserted replaced
1:b13cd05eeb2f 13:57b735022c18
     1 /*
       
     2 * Copyright (c) 2004-2006 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:  Implementation of VAS database handling
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "nssvascvasdb.h"
       
    20 #include <e32test.h>
       
    21 #include <e32std.h>
       
    22 #include <e32svr.h>
       
    23 #include "rubydebug.h"
       
    24 #include "nssvascoreconstant.h"
       
    25 #include "nssvascrrd.h"
       
    26 
       
    27 #include "nssvasbackupobserver.h"
       
    28 
       
    29 // CONSTANTS
       
    30 
       
    31 // Name of the DB lock mutex
       
    32 _LIT( KLockMutex, "VASDATABASE" );
       
    33 
       
    34 #ifdef _DEBUG
       
    35 // used in UDEB macros only
       
    36 _LIT( KVasDbPanic, "VasCNssVasDb.cpp");
       
    37 #endif // _UDEB
       
    38 
       
    39 // Maximum size of tag array
       
    40 static const TInt KMaxTagArraySize = 50;
       
    41 
       
    42 const TInt KContextListGranularity = 5;
       
    43 
       
    44 const TInt KSqlStatementmaxLength = 120;
       
    45 
       
    46 // MACROS
       
    47 
       
    48 // Complementary macro for TRAPD
       
    49 #define REACT( err, codeblock ) if ( err != KErrNone ) { codeblock; }
       
    50 
       
    51 // ============================ Methods ===============================
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CNssVasDb::NewL
       
    55 // 2-level constructor
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CNssVasDb* CNssVasDb::NewL( CNssContextBuilder& contextBuilder,
       
    59 	                        CNssSpeechItemBuilder& speechItemBuilder )
       
    60     {
       
    61     RUBY_DEBUG_BLOCK( "CNssVasDb::NewL" );
       
    62 
       
    63     CNssVasDb* self = new(ELeave) CNssVasDb( contextBuilder,
       
    64                                              speechItemBuilder );
       
    65     CleanupStack::PushL( self );
       
    66     self->ConstructL();
       
    67     CleanupStack::Pop( self );
       
    68 
       
    69     return self;
       
    70     }
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // CNssVasDb::~CNssVasDb
       
    74 // Standard C++ destructor
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 CNssVasDb::~CNssVasDb()
       
    78     {
       
    79     RUBY_DEBUG0( "CNssVasDb::~CNssVasDb" );
       
    80 
       
    81     if ( iLocked )
       
    82         {
       
    83         RUBY_DEBUG0( "Signalling mutex in CNssVasDb::~CNssVasDb" );
       
    84         iMutex.Signal();
       
    85         }
       
    86     else
       
    87         {
       
    88         RUBY_DEBUG0( "NOT signalling mutex in CNssVasDb::~CNssVasDb iLocked = EFalse" );
       
    89         }
       
    90 
       
    91     if ( iClientHasOpenedDatabase )
       
    92         {
       
    93         CloseDatabase();
       
    94         }
       
    95 
       
    96     iMutex.Close();
       
    97     delete iBackupObserver;
       
    98     iCriticalSection.Close();
       
    99     RUBY_DEBUG0( "CNssVasDb::~CNssVasDb Mutex handle closed" );
       
   100     }
       
   101 	
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CNssVasDb::CNssVasDb
       
   105 // Standard C++ contructor
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 CNssVasDb::CNssVasDb( CNssContextBuilder& aContextBuilder,
       
   109 	                  CNssSpeechItemBuilder& aSpeechItemBuilder )
       
   110 : iClientHasOpenedDatabase( EFalse ),
       
   111   iLocked( EFalse ),
       
   112   iContextBuilder( aContextBuilder ),
       
   113   iSpeechItemBuilder( aSpeechItemBuilder )
       
   114     {
       
   115     // empty
       
   116     }
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // CNssVasDb::ConstructL
       
   120 // Symbian second constructor.
       
   121 // -----------------------------------------------------------------------------
       
   122 //
       
   123 void CNssVasDb::ConstructL()
       
   124     {
       
   125     TInt err = iMutex.OpenGlobal( KLockMutex );
       
   126     if ( err != KErrNone )
       
   127         {
       
   128         RUBY_DEBUG0( "CNssVasDb::ConstructL Creating new global mutex" );
       
   129         iMutex.CreateGlobal( KLockMutex );
       
   130         }
       
   131     else
       
   132         {
       
   133         RUBY_DEBUG0( "CNssVasDb::ConstructL Using existing global mutex" );
       
   134         }
       
   135     iCriticalSection.CreateLocal();
       
   136     iBackupObserver = CNssVasBackupObserver::NewL( *this );
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CNssVasDb::RollbackCleanupFunction
       
   141 // This function is used to form iRollbackCleanupItem. When this item is
       
   142 // popped from the cleanup stack, it makes a rollback on VAS DB.
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 void CNssVasDb::RollbackCleanupFunction( TAny* aArg )
       
   146     {
       
   147     RUBY_DEBUG0( "CNssVasDb::RollbackCleanupFunction" );
       
   148 
       
   149     CNssVasDb* me = (CNssVasDb*)aArg;
       
   150 
       
   151     me->RollbackTransaction();
       
   152     }
       
   153 
       
   154 // -----------------------------------------------------------------------------
       
   155 // CNssVasDb::CreateDatabaseL
       
   156 // Creates a new database.
       
   157 // from a resource file.
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 void CNssVasDb::CreateDatabaseL()
       
   161     {
       
   162     User::LeaveIfError( iDbSession.Connect() );
       
   163     CleanupClosePushL( iDbSession );
       
   164     iDbcreator.CreateVasDatabaseL( iDbSession );
       
   165     CleanupStack::PopAndDestroy( &iDbSession );
       
   166     }
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CNssVasDb::OpenDatabaseL
       
   170 // Opens the database. Reads the path and file name of the database
       
   171 // from a resource file.
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 void CNssVasDb::OpenDatabaseL()
       
   175     {
       
   176     RUBY_DEBUG_BLOCK( "CNssVasDb::OpenDatabaseL" );
       
   177 
       
   178     if ( !iClientHasOpenedDatabase )
       
   179         {
       
   180         RFs fs;
       
   181         User::LeaveIfError( fs.Connect() );
       
   182         CleanupClosePushL ( fs ); // Stack: file session
       
   183 
       
   184         // Open the database
       
   185 	    User::LeaveIfError( iDbSession.Connect() );
       
   186 	    
       
   187         User::LeaveIfError( iDatabase.Open( iDbSession, 
       
   188                             KVasDatabaseName, KVasDatabaseFormatString ) );
       
   189         User::LeaveIfError( fs.CharToDrive( KVasDatabaseDrive, iDrive ) );
       
   190 
       
   191         if ( iDatabase.IsDamaged() )
       
   192             {
       
   193             RUBY_DEBUG0( "CNssVasDb::OpenDatabaseL Recovering" );
       
   194             User::LeaveIfError( iDatabase.Recover() );
       
   195             }
       
   196             
       
   197         CleanupStack::PopAndDestroy( &fs ); 
       
   198 
       
   199 	    iClientHasOpenedDatabase = ETrue;
       
   200         }
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // CNssVasDb::CloseDatabase
       
   205 // Closes the database.
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 TInt CNssVasDb::CloseDatabase()
       
   209     {
       
   210     RUBY_DEBUG0( "CNssVasDb::CloseDatabase" ); 
       
   211   
       
   212     iDatabase.Close();
       
   213     iDbSession.Close();
       
   214     iClientHasOpenedDatabase = EFalse;
       
   215 
       
   216     return KErrNone;
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CNssVasDb::GetModelBankIdLexiconIdL
       
   221 // Returns the model bank ID and the lexicon ID.
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 TBool CNssVasDb::GetModelBankIdLexiconIdL( TUint32& aModelBankId, TUint32& aLexiconId )
       
   225     {
       
   226     TBool ret = EFalse;
       
   227     RDbView view;
       
   228   
       
   229     _LIT( KSQLGetModelBankLexicon, "select modelbankid,lexiconid from contexttable" );
       
   230 
       
   231     User::LeaveIfError( StartTransaction() );
       
   232     CreatePushRollbackItemLC();
       
   233 
       
   234     CleanupClosePushL( view );
       
   235 
       
   236     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( 
       
   237                             KSQLGetModelBankLexicon, EDbCompareNormal ) ) );
       
   238     User::LeaveIfError( view.EvaluateAll() );
       
   239 
       
   240     // There is no ModelbankId or LexiconId 
       
   241     if ( view.IsEmptyL() )
       
   242         {
       
   243         User::Leave( KErrNotFound );
       
   244         }
       
   245     // There is a ModelBankId and a LexiconId 
       
   246     ret = ETrue;
       
   247     view.FirstL();
       
   248     view.GetL();
       
   249 
       
   250     // Get column set
       
   251     CDbColSet* columns = view.ColSetL();
       
   252     // Get column ordinals
       
   253     TDbColNo modelbankid_col = columns->ColNo( KModelBankIdCol );
       
   254     TDbColNo lexiconid_col = columns->ColNo( KLexiconIdCol );
       
   255     // Cleanup column set
       
   256     delete columns;
       
   257 
       
   258     aModelBankId = view.ColUint32( modelbankid_col );
       
   259     aLexiconId   = view.ColUint32( lexiconid_col );
       
   260  
       
   261     // Close view
       
   262     CleanupStack::PopAndDestroy( &view );
       
   263 
       
   264     // Release lock
       
   265     CleanupStack::Pop();  // Rollback cleanup item
       
   266     CommitTransaction( EFalse );
       
   267 
       
   268     return ret;
       
   269     }
       
   270 
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // CNssVasDb::TagExistsL
       
   274 // Checks if a context is empty.
       
   275 // -----------------------------------------------------------------------------
       
   276 //
       
   277 TBool CNssVasDb::TagExistL( TInt aContextId )
       
   278     {
       
   279     RUBY_DEBUG_BLOCK( "CNssVasDb::TagExistL" );
       
   280  
       
   281     TBool   ret( EFalse );
       
   282     RDbView view;
       
   283 
       
   284     CleanupClosePushL(view);
       
   285 
       
   286     _LIT( KSQLGetTags, "select * from tagtable " );
       
   287     _LIT( KSQLWhereContextId, "where contextid=" );
       
   288 
       
   289     iSQLStatement = KSQLGetTags;
       
   290     iSQLStatement.Append( KSQLWhereContextId );
       
   291     iSQLStatement.AppendNumUC( aContextId );
       
   292     
       
   293     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
   294     User::LeaveIfError( view.EvaluateAll() );
       
   295 
       
   296     if ( view.IsEmptyL() )
       
   297         {
       
   298         ret = EFalse;
       
   299         }
       
   300     else
       
   301         {
       
   302         ret = ETrue;
       
   303         }
       
   304 
       
   305     // Close view
       
   306     CleanupStack::PopAndDestroy( &view );
       
   307 
       
   308     return ret;
       
   309     }
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CNssVasDb::TagCountL
       
   313 // Returns the number of tags.
       
   314 // -----------------------------------------------------------------------------
       
   315 //
       
   316 TInt CNssVasDb::TagCountL( TInt aContextId )
       
   317     {
       
   318     RUBY_DEBUG_BLOCK( "CNssVasDb::TagCountL" );
       
   319         
       
   320     RDbView view;
       
   321     TInt    numberOfTags = 0;
       
   322 
       
   323     CleanupClosePushL( view );
       
   324 
       
   325     _LIT( KSQLGetTags, "select * from tagtable " );
       
   326     _LIT( KSQLWhereContextId, "where contextid=" );
       
   327 
       
   328     iSQLStatement = KSQLGetTags;
       
   329     iSQLStatement.Append( KSQLWhereContextId );
       
   330     iSQLStatement.AppendNumUC( aContextId );
       
   331     
       
   332     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
   333     User::LeaveIfError( view.EvaluateAll() );
       
   334 
       
   335     numberOfTags = view.CountL();
       
   336    
       
   337     view.Close();
       
   338     CleanupStack::PopAndDestroy( &view );
       
   339    
       
   340     return numberOfTags;
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CNssVasDb::CommitIfSuccess
       
   345 // Commits or rolls back accoring to success parameter.
       
   346 // -----------------------------------------------------------------------------
       
   347 //
       
   348 void CNssVasDb::CommitIfSuccess( RDbDatabase /*aDatabase*/, TInt aSuccess, TBool aCompactIfCommit )
       
   349     {
       
   350     if ( aSuccess >= 0 )
       
   351         {
       
   352         CommitTransaction( aCompactIfCommit );
       
   353         }
       
   354     else
       
   355         {
       
   356         // Otherwise, roll back the transaction and release the lock.
       
   357         RollbackTransaction();
       
   358         }
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CNssVasDb::SaveContextL
       
   363 // Saves a newly created context. The Context ID is assigned and returned
       
   364 // using the reference parameter.
       
   365 // -----------------------------------------------------------------------------
       
   366 //
       
   367 void CNssVasDb::SaveContextL( CNssContext& aContext, TInt& aContextId )
       
   368     {
       
   369     RUBY_DEBUG_BLOCK( "CNssVasDb::SaveContextL" );
       
   370   
       
   371     if ( !iClientHasOpenedDatabase )
       
   372         {
       
   373         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   374         
       
   375         User::Leave( KErrNotReady );
       
   376         }
       
   377 
       
   378     // Locks the database for the use of this process only
       
   379     TInt error = StartTransaction();
       
   380 
       
   381     if ( error != KErrNone )
       
   382         {
       
   383         RUBY_DEBUG0( "CNssVasDb error: could not lock database." );
       
   384         
       
   385         User::Leave( KErrGeneral );
       
   386         }
       
   387 
       
   388     TRAP( error, SaveContextL( &aContext, aContextId ) );
       
   389     REACT( error, RUBY_DEBUG0( "Context saving failed" ) );
       
   390 
       
   391     if ( error == KErrNone )
       
   392         {
       
   393         TRAP ( error, DoUpdateContextClientDataL( aContext ) );
       
   394         }
       
   395     
       
   396     CommitIfSuccess( iDatabase, error, ETrue );
       
   397     
       
   398     User::LeaveIfError( error );
       
   399     }
       
   400 
       
   401 // -----------------------------------------------------------------------------
       
   402 // CNssVasDb::UpdateContextL
       
   403 // Updates the context to VAS DB.
       
   404 // -----------------------------------------------------------------------------
       
   405 //
       
   406 void CNssVasDb::UpdateContextL( CNssContext& aContext )
       
   407     {
       
   408     RUBY_DEBUG_BLOCK( "CNssVasDb::UpdateContextL" );
       
   409 
       
   410     if ( !iClientHasOpenedDatabase )
       
   411         {
       
   412         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   413         
       
   414         User::Leave( KErrNotReady );
       
   415         }
       
   416 
       
   417     TInt error = StartTransaction();
       
   418 
       
   419     if ( error != KErrNone )
       
   420         {
       
   421         RUBY_DEBUG0( "CNssVasDb error: could not lock database." );
       
   422         
       
   423         User::Leave( KErrGeneral );
       
   424         }
       
   425 
       
   426     TRAP( error, DoUpdateContextL( aContext ) );
       
   427     REACT( error, RUBY_DEBUG0( "Context updating failed" ) );
       
   428 
       
   429     CommitIfSuccess( iDatabase, error, ETrue );
       
   430     
       
   431     User::LeaveIfError( error );
       
   432     }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CNssVasDb::UpdateContextInsideTransactionL
       
   436 // Updates the context to VAS DB.
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 void CNssVasDb::UpdateContextInsideTransactionL( CNssContext& aContext )
       
   440     {
       
   441     RUBY_DEBUG_BLOCK( "CNssVasDb::UpdateContextInsideTransactionL" );
       
   442 
       
   443     if ( !iClientHasOpenedDatabase )
       
   444         {
       
   445         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   446         
       
   447         User::Leave( KErrNotReady );
       
   448         }
       
   449 
       
   450     DoUpdateContextL( aContext );
       
   451     }
       
   452 
       
   453 // -----------------------------------------------------------------------------
       
   454 // CNssVasDb::UpdateContextClientDataL
       
   455 // Updates the client data of the context.
       
   456 // -----------------------------------------------------------------------------
       
   457 //
       
   458 void CNssVasDb::UpdateContextClientDataL( CNssContext& aContext )   
       
   459     {
       
   460     RUBY_DEBUG_BLOCK( "CNssVasDb::UpdateContextClientDataL" );
       
   461 	
       
   462     if ( !iClientHasOpenedDatabase )
       
   463         {
       
   464         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   465         
       
   466         User::Leave( KErrNotReady );
       
   467         }
       
   468 
       
   469     TInt error = StartTransaction();
       
   470 
       
   471     if ( error != KErrNone )
       
   472         {
       
   473         RUBY_DEBUG0( "CNssVasDb error: could not lock database." );
       
   474         
       
   475         User::Leave( KErrGeneral );
       
   476         }
       
   477 
       
   478     TRAP( error, DoUpdateContextClientDataL( aContext ) );
       
   479 
       
   480     CommitIfSuccess( iDatabase, error, ETrue );
       
   481     
       
   482     User::LeaveIfError( error );
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CNssVasDb::GetDefaultModelBankIdL
       
   487 // Usually, all contexts use the same Model Bank. This function
       
   488 // returns the first model bank ID it finds.
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 void CNssVasDb::GetDefaultModelBankIdL( TUint32& aId )
       
   492     {
       
   493     RUBY_DEBUG_BLOCK( "CNssVasDb::GetDefaultModelBankIdL" );
       
   494       
       
   495     _LIT( KSQLGetAll,"select modelbankid from contexttable");
       
   496 
       
   497     iSQLStatement = KSQLGetAll;
       
   498 
       
   499     if ( !iClientHasOpenedDatabase )
       
   500         {
       
   501         User::Leave( KErrDbNotSet );
       
   502         }
       
   503 
       
   504     StartTransaction();
       
   505     CreatePushRollbackItemLC();
       
   506 
       
   507     RDbView view;
       
   508 
       
   509     CleanupClosePushL(view);
       
   510 
       
   511     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
   512     User::LeaveIfError( view.EvaluateAll() );
       
   513 
       
   514     if ( view.IsEmptyL() )
       
   515         {
       
   516 	    User::Leave( KErrNotFound );
       
   517         }
       
   518 
       
   519     // Get column set
       
   520     CDbColSet* columns = view.ColSetL();
       
   521     // Get model bank id column ordinal
       
   522 	TDbColNo modelbankid_col= columns->ColNo( KModelBankIdCol );
       
   523 	delete columns;
       
   524 
       
   525 	view.FirstL();
       
   526     view.GetL(); // Retrieve the current row - actually reads the row from the database.
       
   527 
       
   528     aId = view.ColUint32( modelbankid_col );
       
   529 
       
   530     CleanupStack::PopAndDestroy( &view );// close view
       
   531 
       
   532     // Rollback cleanup
       
   533     CleanupStack::Pop();  // Rollback cleanup item
       
   534     CommitTransaction( EFalse );
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CNssVasDb::ResetModelBankL
       
   539 // Usually, all contexts use the same Model Bank. When the model bank is reseted,
       
   540 // (=speaker independent models are resotred and speaker adaptation is destroyed)
       
   541 // the model bank ID changes for all contexts.
       
   542 // -----------------------------------------------------------------------------
       
   543 //
       
   544 void CNssVasDb::ResetModelBankL( TUint32 aNewId )
       
   545     {
       
   546     RUBY_DEBUG_BLOCK( "CNssVasDb::ResetModelBankL" );
       
   547 
       
   548     _LIT( KSQLUpdateModelbank,"update contexttable set modelbankid=");
       
   549 
       
   550     iSQLStatement = KSQLUpdateModelbank;
       
   551     iSQLStatement.AppendNumUC( aNewId );
       
   552 
       
   553 
       
   554     if ( !iClientHasOpenedDatabase )
       
   555         {
       
   556         User::Leave( KErrDbNotSet );
       
   557         }
       
   558 
       
   559     StartTransaction();
       
   560     CreatePushRollbackItemLC();
       
   561 
       
   562     User::LeaveIfError( iDatabase.Execute( iSQLStatement ) );
       
   563 
       
   564     CleanupStack::Pop();  // Rollback cleanup item
       
   565 
       
   566     User::LeaveIfError( CommitTransaction( ETrue ) );
       
   567     }
       
   568 
       
   569 // -----------------------------------------------------------------------------
       
   570 // CNssVasDb::GetContextByNameL
       
   571 // Reads a context from VAS DB by name.
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 CArrayPtrFlat<CNssContext>* CNssVasDb::GetContextByNameL(const TDesC& aName)
       
   575     {
       
   576 	RUBY_DEBUG_BLOCK("CNssVasDb::GetContextByNameL");
       
   577 
       
   578     _LIT( KSQLGetAll,"select * from contexttable ");
       
   579     _LIT( KSQLWhereName,"where name='");
       
   580     _LIT( KTick,"' ");
       
   581 
       
   582     iSQLStatement = KSQLGetAll;
       
   583     iSQLStatement.Append( KSQLWhereName );
       
   584     iSQLStatement.Append( aName );
       
   585     iSQLStatement.Append( KTick );
       
   586 
       
   587     return GetContextL( iSQLStatement );
       
   588     }
       
   589 
       
   590 // -----------------------------------------------------------------------------
       
   591 // CNssVasDb::GetGlobalContexts
       
   592 // Reads all global contexts from VAS DB.
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 CArrayPtrFlat<CNssContext>* CNssVasDb::GetGlobalContexts()
       
   596     {
       
   597 	RUBY_DEBUG0("CNssVasDb::GetGlobalContexts");
       
   598 	    
       
   599     _LIT( KSQLGetAll,"select * from contexttable ");
       
   600     _LIT( KSQLWhereGlobal,"where global=1");
       
   601 
       
   602     iSQLStatement = KSQLGetAll;
       
   603     iSQLStatement.Append( KSQLWhereGlobal );
       
   604 
       
   605     CArrayPtrFlat<CNssContext>* ret( NULL );
       
   606     TRAPD( error, ret = GetContextL( iSQLStatement ) );
       
   607     if ( error != KErrNone )
       
   608         {
       
   609         return NULL;
       
   610         }
       
   611     return ret;
       
   612     }
       
   613 
       
   614 // -----------------------------------------------------------------------------
       
   615 // CNssVasDb::GetAllContexts
       
   616 // Reads all contexts from VAS DB.
       
   617 // -----------------------------------------------------------------------------
       
   618 //
       
   619 CArrayPtrFlat<CNssContext>* CNssVasDb::GetAllContexts()
       
   620     {   
       
   621     RUBY_DEBUG0("CNssVasDb::GetAllContexts");
       
   622     
       
   623     _LIT( KSQLGetAll,"select * from contexttable ");
       
   624 
       
   625     iSQLStatement = KSQLGetAll;
       
   626 
       
   627     CArrayPtrFlat<CNssContext>* ret( NULL );
       
   628     TRAPD( error, ret = GetContextL( iSQLStatement ) );
       
   629     if ( error != KErrNone )
       
   630         {
       
   631         return NULL;
       
   632         }
       
   633     return ret;
       
   634     }
       
   635 
       
   636 
       
   637 // -----------------------------------------------------------------------------
       
   638 // CNssVasDb::GetContextL
       
   639 // Executes the SQL query. After the query has selected a list of contexts,
       
   640 // these contexts are read from DB to memory.
       
   641 // -----------------------------------------------------------------------------
       
   642 //
       
   643 CArrayPtrFlat<CNssContext>* CNssVasDb::GetContextL(const TDesC& aSQLStatement)
       
   644     {
       
   645     RUBY_DEBUG_BLOCK("CNssVasDb::GetContextL");
       
   646 
       
   647     __ASSERT_DEBUG( aSQLStatement.Left( 6 ).Compare( _L("select") ) == 0,
       
   648                     User::Panic( KVasDbPanic, __LINE__ ) );
       
   649 
       
   650     if ( !iClientHasOpenedDatabase )
       
   651         {
       
   652         User::Leave( KErrDbNotSet );
       
   653         }
       
   654 
       
   655     TInt ret = StartTransaction();
       
   656     RUBY_DEBUG1("Started transaction. Error code [%d]", ret);
       
   657     
       
   658     CreatePushRollbackItemLC();
       
   659     CArrayPtrFlat<CNssContext>* contextList = GetContextInsideTransactionL( aSQLStatement );
       
   660 
       
   661     // Rollback cleanup (just to avoid automatic locking)
       
   662     CleanupStack::Pop();  // Rollback cleanup item 
       
   663     CommitTransaction( EFalse );
       
   664 
       
   665     return contextList;
       
   666     }
       
   667 
       
   668 // -----------------------------------------------------------------------------
       
   669 // CNssVasDb::GetContextInsideTransaction
       
   670 // Reads a context by name. Assumes that a transaction has already been started.
       
   671 // -----------------------------------------------------------------------------
       
   672 //
       
   673 CArrayPtrFlat<CNssContext>* CNssVasDb::GetContextInsideTransactionL( const TDesC& aSQLStatement )
       
   674     {
       
   675     RUBY_DEBUG_BLOCK("CNssVasDb::GetContextInsideTransactionL");
       
   676     RDbView view;
       
   677 
       
   678     CleanupClosePushL(view);
       
   679 
       
   680     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( aSQLStatement, EDbCompareNormal ) ) );
       
   681     RUBY_DEBUG0("CNssVasDb::GetContextInsideTransactionL Prepared query");
       
   682     User::LeaveIfError( view.EvaluateAll() );
       
   683     RUBY_DEBUG0("CNssVasDb::GetContextInsideTransactionL Evaluated query");
       
   684 
       
   685     if ( view.IsEmptyL() )
       
   686         {
       
   687         RUBY_DEBUG0("CNssVasDb::GetContextInsideTransactionL Empty view. Leaving with KErrNotFound");
       
   688 	    User::Leave( KErrNotFound );
       
   689         }
       
   690 
       
   691     CArrayPtrFlat<CNssContext>* contextList = 
       
   692             new (ELeave) CArrayPtrFlat<CNssContext>( KContextListGranularity );
       
   693     CleanupStack::PushL( contextList );
       
   694     CleanupResetAndDestroyPushL( *contextList );
       
   695     RUBY_DEBUG0("CNssVasDb::GetContextInsideTransactionL Before FillContextListArrayL");
       
   696 
       
   697     FillContextListArrayL(view, *contextList);
       
   698    
       
   699     CleanupStack::Pop( contextList ); // ResetAndDestroy
       
   700     CleanupStack::Pop( contextList );  // array itself
       
   701     CleanupStack::PopAndDestroy( &view );// close view
       
   702 
       
   703     return( contextList );
       
   704     }
       
   705 
       
   706 // -----------------------------------------------------------------------------
       
   707 // CNssVasDb::GetTagReferenceList
       
   708 // Fetches tag references for all tags in a context.
       
   709 // -----------------------------------------------------------------------------
       
   710 //
       
   711 TNssTagReferenceListArray* CNssVasDb::GetTagReferenceListL( TInt aContextId )
       
   712     {
       
   713     RUBY_DEBUG_BLOCK( "CNssVasDb::GetTagReferenceListL" );
       
   714     
       
   715     RDbView view;
       
   716     TNssTagReference tagRef;
       
   717 
       
   718     TNssTagReferenceListArray* tagArray = 
       
   719             new (ELeave) TNssTagReferenceListArray( KMaxTagArraySize );
       
   720     CleanupStack::PushL( tagArray );
       
   721 
       
   722     if ( !iClientHasOpenedDatabase )
       
   723         {
       
   724         User::Leave( KErrDbNotSet );
       
   725         }
       
   726 
       
   727     // Start transaction - lock database
       
   728     StartTransaction();
       
   729     CreatePushRollbackItemLC();
       
   730 
       
   731     // Make a query, which lists all tags in the context.
       
   732     // Making a CNssTagReferece only requires tagid and name.
       
   733     _LIT( KSQLGetTag, "select tagid,name from tagtable where contextid=" );
       
   734     iSQLStatement = KSQLGetTag;
       
   735     iSQLStatement.AppendNumUC( aContextId );
       
   736 
       
   737     CleanupClosePushL(view);
       
   738 
       
   739     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
   740     User::LeaveIfError( view.EvaluateAll() );
       
   741 
       
   742     if ( view.IsEmptyL() )
       
   743         {
       
   744 	    User::Leave( KErrNotFound );
       
   745         }
       
   746 
       
   747     // Get column set
       
   748     CDbColSet* columns = view.ColSetL();
       
   749     // Get column ordinals
       
   750     TDbColNo name_col  = columns->ColNo( KNameCol );
       
   751     TDbColNo tagid_col = columns->ColNo( KTagIdCol );
       
   752 
       
   753     delete columns;
       
   754 
       
   755     for( view.FirstL(); view.AtRow(); view.NextL() )
       
   756         {
       
   757         view.GetL();
       
   758 	    tagRef.iTagName = view.ColDes( name_col );
       
   759 	    tagRef.iTagId   = view.ColUint32( tagid_col );
       
   760 	    tagArray->AppendL( tagRef );
       
   761         }
       
   762 
       
   763     // Close view
       
   764     CleanupStack::PopAndDestroy( &view );
       
   765 
       
   766     // Finish transaction - release lock
       
   767     CleanupStack::Pop();  // Rollback cleanup item
       
   768     CommitTransaction( EFalse );
       
   769 
       
   770     // Return result
       
   771     CleanupStack::Pop( tagArray );
       
   772 
       
   773     return( tagArray );
       
   774     }
       
   775 
       
   776 // -----------------------------------------------------------------------------
       
   777 // CNssVasDb::SaveTagL
       
   778 // Saves a newly created tag. When a tag is saved, a Tag ID is assigned to it.
       
   779 // This Tag ID is returned in the reference parameter.
       
   780 // -----------------------------------------------------------------------------
       
   781 //
       
   782 void CNssVasDb::SaveTagL( CNssTag& aTag, TInt& aNewId )
       
   783     {
       
   784     if ( !iClientHasOpenedDatabase )
       
   785         {
       
   786         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   787         
       
   788         User::Leave( KErrNotReady );
       
   789         }
       
   790 
       
   791     // Locks the database for the use of this process only	
       
   792     
       
   793     TInt error = StartTransaction();
       
   794 
       
   795     if ( error != KErrNone )
       
   796         {
       
   797         RUBY_DEBUG0( "CNssVasDb error: could not lock database." );
       
   798         
       
   799         User::Leave( KErrGeneral );
       
   800         }
       
   801 
       
   802     TInt contextId; // Discard context ID 
       
   803     
       
   804     CNssContext* context = static_cast<CNssContext*> ( aTag.Context() );
       
   805     TRAP( error, SaveContextL( context, contextId ) );
       
   806 	
       
   807     if ( error == KErrItemAlreadyExist || error == KErrNone )
       
   808         {
       
   809         TRAP( error, SaveTagL( &aTag, aNewId ) );
       
   810         }
       
   811     else 
       
   812         {
       
   813         RollbackTransaction(); 
       
   814         User::Leave( error );
       
   815         }
       
   816     
       
   817     // Check SavetagL result
       
   818     if ( error != KErrNone )
       
   819         {
       
   820         RollbackTransaction(); 	
       
   821         User::Leave( error );
       
   822         }
       
   823     else
       
   824         {
       
   825         CNssRRD* rrd = static_cast<CNssRRD*>( aTag.RRD() );
       
   826         rrd->SetTagId( aNewId );
       
   827 
       
   828         TRAPD( error, SaveRRDL( rrd ) );
       
   829 	    REACT( error, RUBY_DEBUG0( "RRD saving failed." ) );
       
   830 
       
   831         CommitIfSuccess( iDatabase, error, ETrue );
       
   832         }
       
   833         
       
   834     User::LeaveIfError( error );
       
   835     }
       
   836 
       
   837 // ---------------------------------------------------------
       
   838 // CNssVasDb::SaveTagsL
       
   839 // Saves several tags in one commit.
       
   840 // ---------------------------------------------------------
       
   841 //
       
   842 void CNssVasDb::SaveTagsL( CArrayPtrFlat<CNssTag>* aTagArray, RArray<TInt>& aTagIdArray )
       
   843     {
       
   844     TInt k( 0 );
       
   845     TInt error( KErrNone );
       
   846 
       
   847     if ( !iClientHasOpenedDatabase )
       
   848         {
       
   849         User::Leave( KErrDbNotSet );
       
   850         }
       
   851 
       
   852     // Locks the database for the use of this process only	
       
   853     User::LeaveIfError( StartTransaction() );
       
   854 
       
   855     CreatePushRollbackItemLC(); // Stack: rollback cleanup
       
   856 
       
   857     RArray<TInt> contextIds;
       
   858     CleanupClosePushL( contextIds ); // Stack: rollback cleanup, contextIds
       
   859 
       
   860     for ( k = 0; k < aTagArray->Count(); k++ )
       
   861         {
       
   862         CNssTag* tag = (*aTagArray)[k];
       
   863         CNssContext* context = static_cast<CNssContext*> ( tag->Context() );
       
   864 
       
   865         if ( contextIds.Find( context->ContextId() ) == KErrNotFound )
       
   866             {
       
   867             TInt contextId;
       
   868             TRAP( error, SaveContextL( context, contextId ) );
       
   869 
       
   870             // We accept leaves with error KErrAlreadyExists
       
   871             if ( error != KErrNone && error != KErrAlreadyExists )
       
   872                 {
       
   873                 break;
       
   874                 }
       
   875 
       
   876             contextIds.Append( context->ContextId() );
       
   877             }
       
   878         }
       
   879 
       
   880     // Close context id array
       
   881     CleanupStack::PopAndDestroy( &contextIds ); // Stack: Rollback cleanup
       
   882 
       
   883     // We accept leaves with error KErrAlreadyExists
       
   884     if ( error != KErrNone && error != KErrAlreadyExists )
       
   885         {
       
   886         User::Leave( error );
       
   887         }
       
   888 
       
   889     TInt id;
       
   890     for ( k = 0; k < aTagArray->Count(); k++ )
       
   891         {
       
   892         CNssTag* tag = (*aTagArray)[k];
       
   893 
       
   894         if ( tag->TagId() == KNssVASDbDefaultValue )
       
   895             {
       
   896             SaveTagL( tag, id );
       
   897 
       
   898             CNssRRD* rrd = static_cast<CNssRRD*>( tag->RRD() );
       
   899             rrd->SetTagId( id );
       
   900 
       
   901 	        SaveRRDL( rrd );
       
   902             User::LeaveIfError( aTagIdArray.Append( id ) );
       
   903             }
       
   904         else{
       
   905             UpdateTagInTransactionL( *tag );
       
   906             User::LeaveIfError( aTagIdArray.Append( tag->TagId() ) );
       
   907             }
       
   908         }
       
   909 
       
   910     User::LeaveIfError( CommitTransaction( ETrue ) );
       
   911 
       
   912     // Pop rollback cleanup
       
   913     // (which would have made database rollback, if a leave had happened)
       
   914     CleanupStack::Pop();  // Rollback cleanup item
       
   915     }
       
   916 
       
   917 // ---------------------------------------------------------
       
   918 // CNssVasDb::DeleteTagsL
       
   919 // Deletes several tags in one commit.
       
   920 // ---------------------------------------------------------
       
   921 //
       
   922 void CNssVasDb::DeleteTagsL( const RArray<TUint32>& aTagIdArray )
       
   923     {
       
   924     TInt k( 0 );
       
   925    
       
   926     if ( !iClientHasOpenedDatabase )
       
   927         {
       
   928         User::Leave( KErrDbNotSet );
       
   929         }
       
   930 
       
   931     // Locks the database for the use of this process only	
       
   932     User::LeaveIfError( StartTransaction() );
       
   933 
       
   934     CreatePushRollbackItemLC();
       
   935 
       
   936     for ( k = 0; k < aTagIdArray.Count(); k++ )
       
   937         {
       
   938         DeleteTagInsideTransactionL( aTagIdArray[k] );
       
   939         }
       
   940 
       
   941     User::LeaveIfError( CommitTransaction( ETrue ) );
       
   942 
       
   943     // Pop rollback cleanup
       
   944     // (which would have made database rollback, if a leave had happened)
       
   945     CleanupStack::Pop();  // Rollback cleanup item
       
   946     }
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // CNssVasDb::UpdateTagL
       
   950 // Updates the data of an existing tag.
       
   951 // -----------------------------------------------------------------------------
       
   952 //
       
   953 void CNssVasDb::UpdateTagL( CNssTag& aTag )
       
   954     {
       
   955     RUBY_DEBUG_BLOCK( "CNssVasDb::UpdateTagL" );	
       
   956 
       
   957     if ( !iClientHasOpenedDatabase )
       
   958         {
       
   959         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   960         
       
   961         User::Leave( KErrNotReady );
       
   962         }
       
   963 	
       
   964     // Locks the database for the use of this process only
       
   965     User::LeaveIfError( StartTransaction() );
       
   966 
       
   967     TRAPD( error, UpdateTagInTransactionL( aTag ) );
       
   968 
       
   969     CommitIfSuccess( iDatabase, error, ETrue );
       
   970 
       
   971     User::LeaveIfError( error );
       
   972     }
       
   973 
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // CNssVasDb::UpdateTagRuleIDs
       
   977 // Changes the Rule IDs of some tags. The Rule ID changes, when
       
   978 // and already trained tags is retrained.
       
   979 // -----------------------------------------------------------------------------
       
   980 //
       
   981 void CNssVasDb::UpdateTagRuleIDsL( const RArray<TNssSpeechItem>& aRetrainedTags )
       
   982     {
       
   983     TInt error( KErrNone );
       
   984     if ( !iClientHasOpenedDatabase )
       
   985         {
       
   986         User::Leave( KErrDbNotSet );
       
   987         }
       
   988    
       
   989     _LIT( KSQLUpdateTag,"update tagtable set ");
       
   990     _LIT( KEqual,"=");
       
   991     _LIT( KSQLWhereTagIdIs," where tagid = ");
       
   992 
       
   993     TInt count = aRetrainedTags.Count();
       
   994 
       
   995     if ( count > 0 )
       
   996         {
       
   997         return;
       
   998         }
       
   999 
       
  1000     // Start transaction
       
  1001     User::LeaveIfError( StartTransaction() );
       
  1002     CreatePushRollbackItemLC();
       
  1003 
       
  1004     // Make the changes to Rule IDs
       
  1005     for ( TInt k( 0 ); k < count; k++ )
       
  1006         {
       
  1007         // "update tagtable set "
       
  1008         iSQLStatement = KSQLUpdateTag;
       
  1009 
       
  1010         // "ruleid=1234"
       
  1011         iSQLStatement.Append( KRuleIdCol );
       
  1012         iSQLStatement.Append( KEqual );
       
  1013         iSQLStatement.AppendNumUC( aRetrainedTags[k].iRuleId );
       
  1014 
       
  1015         // " where tagid = 5678"
       
  1016         iSQLStatement.Append( KSQLWhereTagIdIs );
       
  1017         iSQLStatement.AppendNumUC( aRetrainedTags[k].iTagId );
       
  1018 
       
  1019         error =  iDatabase.Execute( iSQLStatement );
       
  1020         if ( error < KErrNone )
       
  1021             {
       
  1022             ReleaseDiskSpace();
       
  1023             User::Leave( error );
       
  1024             }
       
  1025         }
       
  1026 
       
  1027     // Commit transaction
       
  1028     error = CommitTransaction( ETrue );
       
  1029     if ( error )
       
  1030         {
       
  1031         ReleaseDiskSpace();
       
  1032         User::Leave( error );
       
  1033         }
       
  1034 
       
  1035     // Pop rollback cleanup object
       
  1036     CleanupStack::Pop();  // Rollback cleanup item
       
  1037 
       
  1038     ReleaseDiskSpace();    
       
  1039     }
       
  1040 
       
  1041 
       
  1042 // -----------------------------------------------------------------------------
       
  1043 // CNssVasDb::SaveContextL
       
  1044 // Saves a newly created context. When a context is saved, a Context ID is
       
  1045 // assigned to it. This id is returned using the reference parameter.
       
  1046 // -----------------------------------------------------------------------------
       
  1047 //
       
  1048 void CNssVasDb::SaveContextL( CNssContext* aContext, TInt& aContextId )
       
  1049     {
       
  1050     TBuf<KNssVasDbContextName> name;
       
  1051     RDbView view1;
       
  1052 
       
  1053     _LIT( KSQLAdd, "select * from contexttable " );
       
  1054     _LIT( KSQLWhereName, "where name='" );
       
  1055     _LIT( KTick, "' " );
       
  1056 
       
  1057     //Check to see if a context already exist with the new name
       
  1058     iSQLStatement = KSQLAdd;
       
  1059     iSQLStatement.Append( KSQLWhereName );
       
  1060     iSQLStatement.Append( aContext->ContextName() );
       
  1061     iSQLStatement.Append( KTick );
       
  1062 	
       
  1063     CleanupClosePushL( view1 );
       
  1064    
       
  1065     User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );	
       
  1066     User::LeaveIfError( view1.EvaluateAll() );
       
  1067 
       
  1068     if ( !view1.IsEmptyL() ) // context with that name already exist so return status
       
  1069         {  
       
  1070         // Get column set
       
  1071         CDbColSet* columns1 = view1.ColSetL();
       
  1072         TDbColNo contextid_col = columns1->ColNo( KContextIdCol );
       
  1073 
       
  1074 	    delete columns1;
       
  1075 
       
  1076         view1.FirstL();
       
  1077         view1.GetL();
       
  1078 	    //Get the  unique contextid key just generated
       
  1079 	    aContextId = view1.ColUint32(contextid_col);
       
  1080 	    aContext->SetContextId( aContextId );
       
  1081 
       
  1082 	    view1.Close();	  
       
  1083 	    CleanupStack::PopAndDestroy( &view1 );
       
  1084         
       
  1085         User::Leave( KErrAlreadyExists );
       
  1086         }
       
  1087     else{
       
  1088         view1.Close();
       
  1089 	    CleanupStack::PopAndDestroy( &view1 );
       
  1090 	   
       
  1091 	    RDbView view2;
       
  1092 
       
  1093         CleanupClosePushL( view2 );
       
  1094 
       
  1095 	    User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery(KSQLAdd,EDbCompareNormal)));	
       
  1096         User::LeaveIfError( view2.EvaluateAll() );
       
  1097   
       
  1098 	    // Get column set
       
  1099         CDbColSet* columns = view2.ColSetL();
       
  1100         // Get column ordinals
       
  1101         TDbColNo name_col = columns->ColNo( KNameCol );
       
  1102         TDbColNo global_col = columns->ColNo( KGlobalCol );
       
  1103 	    TDbColNo grammarid_col = columns->ColNo( KGrammarIdCol );
       
  1104 	    TDbColNo lexiconid_col = columns->ColNo( KLexiconIdCol );
       
  1105 	    TDbColNo modelbankid_col = columns->ColNo( KModelBankIdCol );
       
  1106 	    TDbColNo contextid_col = columns->ColNo( KContextIdCol );
       
  1107 
       
  1108 	    delete columns;
       
  1109 
       
  1110 	    // Begin process of inserting a row...
       
  1111 	    view2.InsertL();
       
  1112 	    // set column values...
       
  1113 	    view2.SetColL( name_col, aContext->ContextName() );
       
  1114 	    view2.SetColL( global_col, aContext->IsGlobal() );
       
  1115 	    view2.SetColL( lexiconid_col, aContext->LexiconId() );
       
  1116 	    view2.SetColL( grammarid_col, aContext->GrammarId() );
       
  1117 	    view2.SetColL( modelbankid_col, aContext->ModelBankId() );
       
  1118 	
       
  1119 	    // add the row to the table...
       
  1120 	    view2.PutL();
       
  1121 	             
       
  1122 	    view2.GetL();
       
  1123         //Get the  unique contextid key just generated
       
  1124 	    aContextId = view2.ColUint32( contextid_col );
       
  1125 
       
  1126 	    aContext->SetContextId( aContextId );
       
  1127 
       
  1128 	    name = view2.ColDes( name_col );
       
  1129 	  
       
  1130 	    view2.Close();
       
  1131 	    CleanupStack::PopAndDestroy( &view2 );
       
  1132         }
       
  1133     }
       
  1134 
       
  1135 // -----------------------------------------------------------------------------
       
  1136 // CNssVasDb::SaveTagL
       
  1137 // Saves a newly created tag. When a tag is saved, a Tag ID is assigned to it.
       
  1138 // This id is returned using the reference parameter.
       
  1139 // -----------------------------------------------------------------------------
       
  1140 //
       
  1141 void CNssVasDb::SaveTagL( CNssTag* aTag, TInt& aNewId )
       
  1142     {
       
  1143 	RDbView view;
       
  1144  
       
  1145     _LIT( KSQLGet,"select * from tagtable");
       
  1146 	
       
  1147 	CleanupClosePushL(view);
       
  1148 
       
  1149 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery(KSQLGet,EDbCompareNormal)));	
       
  1150 	User::LeaveIfError( view.EvaluateAll());
       
  1151     
       
  1152 	// Get column set
       
  1153     CDbColSet* columns = view.ColSetL();
       
  1154     // Get column ordinals
       
  1155     TDbColNo name_col           = columns->ColNo( KNameCol );
       
  1156 	TDbColNo tagid_col          = columns->ColNo( KTagIdCol );
       
  1157 	TDbColNo contextid_col      = columns->ColNo( KContextIdCol );
       
  1158 	TDbColNo ruleid_col         = columns->ColNo( KRuleIdCol );
       
  1159 
       
  1160 	delete columns;
       
  1161 	  
       
  1162 	// Begin process of inserting a row...
       
  1163 	view.InsertL();
       
  1164 	// set column values...
       
  1165 	
       
  1166 	CNssContext* context = static_cast<CNssContext*> ( aTag->Context() );
       
  1167 	CNssSpeechItem* speechItem = static_cast<CNssSpeechItem*> ( aTag->SpeechItem() );
       
  1168 	
       
  1169 	#ifdef __SIND_EXTENSIONS
       
  1170 	    view.SetColL( name_col, aTag->SpeechItem()->RawText() ); 
       
  1171 	#else
       
  1172 	    view.SetColL( name_col, aTag->SpeechItem()->Text() ); 
       
  1173 	#endif  // __SIND_EXTENSIONS
       
  1174 	view.SetColL( contextid_col, context->ContextId() );
       
  1175 	view.SetColL( ruleid_col, speechItem->RuleID() );
       
  1176 	
       
  1177 	// add the row to the table...
       
  1178 	view.PutL();
       
  1179 
       
  1180     aNewId = view.ColUint32( tagid_col );
       
  1181 
       
  1182 	// finished - so close the view
       
  1183 	view.Close();
       
  1184 	CleanupStack::PopAndDestroy( &view );
       
  1185     }
       
  1186 
       
  1187 
       
  1188 // -----------------------------------------------------------------------------
       
  1189 // CNssVasDb::SaveRRDL
       
  1190 // Reads RRD from DB to memory. Utility function when reading tags.
       
  1191 // -----------------------------------------------------------------------------
       
  1192 //
       
  1193 void CNssVasDb::SaveRRDL( CNssRRD* aRRD )
       
  1194     {
       
  1195     TInt position;
       
  1196 	RDbView view1,view2;
       
  1197    
       
  1198 	_LIT( KSQLAddRRDText, "select * from rrdtexttable");
       
  1199 	_LIT( KSQLAddRRDId,   "select * from rrdinttable");
       
  1200 	
       
  1201     // Save the integer array, if we have one.
       
  1202     if ( aRRD->IntArray() )
       
  1203         {
       
  1204 	    CleanupClosePushL(view1);
       
  1205 	
       
  1206 	    User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( KSQLAddRRDId, EDbCompareNormal ) ) );	
       
  1207 	    User::LeaveIfError( view1.EvaluateAll());
       
  1208 
       
  1209 	    // Get column set	
       
  1210         CDbColSet* columns1 = view1.ColSetL();
       
  1211         // Get column ordinals
       
  1212         TDbColNo tagid_col           = columns1->ColNo( KTagIdCol );
       
  1213 	    TDbColNo rrdint_col          = columns1->ColNo( KRRDIntCol );
       
  1214         TDbColNo rrdposition_col1    = columns1->ColNo( KRRDPositionCol );
       
  1215 
       
  1216 	    delete columns1;
       
  1217 
       
  1218 	    // Begin process of inserting a row...
       
  1219 	    // set column values for id table...
       
  1220         for( position=0; position<aRRD->IntArray()->Count(); position++ )
       
  1221             {
       
  1222 	        view1.InsertL();
       
  1223 	        view1.SetColL( tagid_col,aRRD->TagId() );
       
  1224 	        view1.SetColL(rrdint_col,aRRD->IntArray()->At( position ) );
       
  1225 	        view1.SetColL(rrdposition_col1,position);
       
  1226 	        // add the row to the table...
       
  1227 	        view1.PutL();	   
       
  1228 	        }	
       
  1229 	
       
  1230 	    // finished - so close the view
       
  1231 	    view1.Close(); 	
       
  1232 	    CleanupStack::PopAndDestroy( &view1 );
       
  1233         }
       
  1234 
       
  1235     // Save the text array, if we have one
       
  1236     if ( aRRD->TextArray() )
       
  1237         {
       
  1238 	    CleanupClosePushL( view2 );
       
  1239 
       
  1240         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1241                             TDbQuery( KSQLAddRRDText, EDbCompareNormal ) ) );	
       
  1242 	    User::LeaveIfError( view2.EvaluateAll() );
       
  1243     
       
  1244         // Get column set
       
  1245         CDbColSet* columns2 = view2.ColSetL();
       
  1246         // Get column ordinals
       
  1247         TDbColNo tagid_col2       = columns2->ColNo( KTagIdCol );
       
  1248 	    TDbColNo rrdtext_col2     = columns2->ColNo( KRRDTextCol );
       
  1249         TDbColNo rrdposition_col2 = columns2->ColNo( KRRDPositionCol );
       
  1250 
       
  1251 	    delete columns2;
       
  1252 
       
  1253 	    //set colum values for text table
       
  1254 	    for( position = 0; position < aRRD->TextArray()->Count(); position++ )
       
  1255             {
       
  1256 	        view2.InsertL();
       
  1257 	        view2.SetColL( tagid_col2, aRRD->TagId() );
       
  1258 	        view2.SetColL( rrdtext_col2, aRRD->TextArray()->At( position ) );
       
  1259 	        view2.SetColL( rrdposition_col2, position );
       
  1260 	        view2.PutL();	   
       
  1261             }	
       
  1262 	    // add the row to the table...
       
  1263 	
       
  1264 	    // finished - so close the view
       
  1265 	    view2.Close();  
       
  1266 	    CleanupStack::PopAndDestroy( &view2 );
       
  1267         }
       
  1268     }
       
  1269 
       
  1270 // -----------------------------------------------------------------------------
       
  1271 // CNssVasDb::FillRRDL
       
  1272 // Reads RRD from DB to memory. Utility function when reading tags.
       
  1273 // -----------------------------------------------------------------------------
       
  1274 //
       
  1275 void CNssVasDb::FillRRDL( TUint32 aTagId, CNssRRD& aRRD )
       
  1276     {
       
  1277     RUBY_DEBUG_BLOCK( "CNssVasDb::FillRRDL" );
       
  1278     
       
  1279     TInt position;
       
  1280 	RDbView view1,view2;
       
  1281 
       
  1282 	_LIT( KSQLAddRRDText, "select * from rrdtexttable ");
       
  1283 	_LIT( KSQLAddRRDId,   "select * from rrdinttable ");
       
  1284 	_LIT( KSQLWhereTagId,"where tagid=");
       
  1285 
       
  1286 	iSQLStatement = KSQLAddRRDId;
       
  1287 	iSQLStatement.Append( KSQLWhereTagId );
       
  1288 	iSQLStatement.AppendNumUC( aTagId );
       
  1289 
       
  1290 	CleanupClosePushL(view1);
       
  1291 
       
  1292 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1293 	User::LeaveIfError( view1.EvaluateAll());
       
  1294 
       
  1295 	// Get column set
       
  1296     CDbColSet* columns1 = view1.ColSetL();
       
  1297     // Get column ordinals
       
  1298     TDbColNo tagid_col           = columns1->ColNo( KTagIdCol );
       
  1299 	TDbColNo rrdint_col          = columns1->ColNo( KRRDIntCol );
       
  1300     TDbColNo rrdposition_col1    = columns1->ColNo( KRRDPositionCol );
       
  1301 	// Cleanup column1 set
       
  1302 	delete columns1;
       
  1303 
       
  1304 	// Begin process of inserting a row...
       
  1305 	TInt intarraysize = view1.CountL();
       
  1306     if ( intarraysize > 0 )
       
  1307         {
       
  1308         CArrayFixFlat<TInt>* intArray = new (ELeave) CArrayFixFlat<TInt>(intarraysize);
       
  1309         CleanupStack::PushL( intArray );
       
  1310         intArray->ResizeL( intarraysize );
       
  1311         
       
  1312         // set column values for id table...
       
  1313         for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1314             {
       
  1315             view1.GetL();
       
  1316             aRRD.SetTagId( view1.ColUint32( tagid_col ) );
       
  1317             position = view1.ColUint32( rrdposition_col1 );
       
  1318             if ( position < 0 || position >= intarraysize )
       
  1319                 {
       
  1320                 RUBY_ERROR2("CNssVasDb::FillRRDL position out of bounds. 0 < %i < %i", 
       
  1321                     position, intarraysize );
       
  1322                 User::Leave( KErrCorrupt );
       
  1323                 }
       
  1324             intArray->At( position ) = view1.ColUint32( rrdint_col );
       
  1325             }
       
  1326 
       
  1327         aRRD.SetIntArrayL( intArray );
       
  1328         CleanupStack::Pop( intArray );
       
  1329         intArray->Reset();
       
  1330         delete intArray;
       
  1331         }
       
  1332     
       
  1333 	// finished - so close the view
       
  1334 	view1.Close();
       
  1335 	CleanupStack::PopAndDestroy( &view1 );
       
  1336  
       
  1337 	CleanupClosePushL(view2);
       
  1338 
       
  1339 	iSQLStatement = KSQLAddRRDText;
       
  1340 	iSQLStatement.Append( KSQLWhereTagId );
       
  1341 	iSQLStatement.AppendNumUC( aTagId );
       
  1342     User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1343 	User::LeaveIfError( view2.EvaluateAll() );
       
  1344     
       
  1345     // Get column set
       
  1346     CDbColSet* columns2 = view2.ColSetL();
       
  1347     // Get column ordinals
       
  1348     TDbColNo tagid_col2       = columns2->ColNo( KTagIdCol );
       
  1349 	TDbColNo rrdtext_col2     = columns2->ColNo( KRRDTextCol );
       
  1350     TDbColNo rrdposition_col2 = columns2->ColNo( KRRDPositionCol );
       
  1351    
       
  1352 	delete columns2;
       
  1353     
       
  1354 	TInt textarraysize = view2.CountL();
       
  1355     if ( textarraysize > 0 )
       
  1356         {
       
  1357         CArrayFixFlat<NssRRDText>* textArray = 
       
  1358                     new (ELeave) CArrayFixFlat<NssRRDText>(textarraysize);
       
  1359         CleanupStack::PushL( textArray );
       
  1360         textArray->ResizeL( textarraysize );
       
  1361 
       
  1362         //set colum values for text table
       
  1363         for ( view2.FirstL(); view2.AtRow(); view2.NextL() )
       
  1364             {
       
  1365             view2.GetL();
       
  1366             aRRD.SetTagId( view2.ColUint32( tagid_col2 ) );
       
  1367             position      = view2.ColUint32( rrdposition_col2 );
       
  1368             if ( position < 0 || position >= textarraysize )
       
  1369                 {
       
  1370                 RUBY_ERROR2("CNssVasDb::FillRRDL position out of bounds. 0 < %i < %i", 
       
  1371                     position, textarraysize );
       
  1372                 User::Leave( KErrCorrupt );
       
  1373                 }
       
  1374             textArray->At( position ) = view2.ColDes( rrdtext_col2 );
       
  1375             }	
       
  1376 
       
  1377         aRRD.SetTextArrayL( textArray );
       
  1378         CleanupStack::Pop( textArray );
       
  1379         textArray->Reset();
       
  1380         delete textArray;
       
  1381         }
       
  1382 
       
  1383 	// finished - so close the view
       
  1384 	view2.Close();
       
  1385         
       
  1386     CleanupStack::PopAndDestroy( &view2 );
       
  1387     }
       
  1388 
       
  1389 // -----------------------------------------------------------------------------
       
  1390 // CNssVasDb::GetTagL
       
  1391 // Gets a tag by grammar ID and rule ID.
       
  1392 // -----------------------------------------------------------------------------
       
  1393 //
       
  1394 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TNssGrammarIdRuleId aGrammarIdRuleId )
       
  1395     {
       
  1396 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1397 	CleanupStack::PushL( context );
       
  1398 	RDbView view;
       
  1399 
       
  1400     User::LeaveIfError( StartTransaction() );
       
  1401     CreatePushRollbackItemLC();
       
  1402 
       
  1403 	CleanupClosePushL(view);
       
  1404 
       
  1405 	_LIT( KSQLGetContext, "select * from contexttable where grammarid=");
       
  1406 	iSQLStatement.Copy(KSQLGetContext);
       
  1407 	iSQLStatement.AppendNumUC(aGrammarIdRuleId.iGrammarId);
       
  1408 
       
  1409     TDbQuery dbQuery(iSQLStatement, EDbCompareNormal);
       
  1410 	User::LeaveIfError( view.Prepare( iDatabase, dbQuery ) );
       
  1411 	User::LeaveIfError( view.EvaluateAll() );
       
  1412 
       
  1413 	view.FirstL(); 
       
  1414     FillContextL(view, *context);
       
  1415 
       
  1416 	_LIT( KSQLGetTag, "select * from tagtable where ruleid=");
       
  1417 	_LIT( KSQLAnd," and contextid=");
       
  1418 	iSQLStatement = KSQLGetTag;
       
  1419 	iSQLStatement.AppendNumUC( aGrammarIdRuleId.iRuleId );
       
  1420     iSQLStatement.Append( KSQLAnd );
       
  1421 	iSQLStatement.AppendNumUC( context->ContextId() );
       
  1422 
       
  1423     // Close view
       
  1424     CleanupStack::PopAndDestroy( &view );
       
  1425 
       
  1426     CArrayPtrFlat<CNssTag>* res = GetTagListByQueryL( iSQLStatement );
       
  1427 
       
  1428     // Pop rollback cleanup item
       
  1429     CleanupStack::Pop();  // Rollback cleanup item
       
  1430     CommitTransaction( EFalse );
       
  1431     
       
  1432     CleanupStack::PopAndDestroy( context );
       
  1433 
       
  1434     return( res );
       
  1435     }
       
  1436     
       
  1437 // -----------------------------------------------------------------------------
       
  1438 // CNssVasDb::GetTagsL
       
  1439 // Gets a list of tags by grammar ID and rule ID.
       
  1440 // -----------------------------------------------------------------------------
       
  1441 //
       
  1442 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagsL( TNssGrammarIdRuleIdListArray& aGrammarIdRuleIds )
       
  1443 	{
       
  1444 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1445 	CleanupStack::PushL( context );
       
  1446 	RDbView view;
       
  1447 
       
  1448     User::LeaveIfError( StartTransaction() );
       
  1449     CreatePushRollbackItemLC();
       
  1450 
       
  1451     Mem::FillZ( context,     sizeof(*context)   );
       
  1452 
       
  1453 	CleanupClosePushL(view);
       
  1454 	
       
  1455 	_LIT( KSQLGetContext, "select * from contexttable where ");
       
  1456 	_LIT( KGrammarIdParam, "grammarid=" );
       
  1457 	_LIT( KOr, " OR ");
       
  1458 	iSQLStatement.Copy(KSQLGetContext);
       
  1459 	
       
  1460 	for( TInt i = 0; i < aGrammarIdRuleIds.Count(); i++)
       
  1461 		{
       
  1462 		if( i !=0 )
       
  1463 			{
       
  1464 			iSQLStatement.Append(KOr);
       
  1465 			}
       
  1466 		iSQLStatement.Append(KGrammarIdParam);
       
  1467 		iSQLStatement.AppendNumUC(aGrammarIdRuleIds[i].iGrammarId);
       
  1468 		// same grammar ids usually appear, but that's ok and should not decrease performance
       
  1469 		}
       
  1470 		
       
  1471 	TDbQuery dbQuery(iSQLStatement, EDbCompareNormal);
       
  1472 	User::LeaveIfError( view.Prepare( iDatabase, dbQuery ));
       
  1473 	User::LeaveIfError( view.EvaluateAll());
       
  1474 	
       
  1475 	_LIT( KSQLGetTags, "select * from tagtable where (");
       
  1476 	_LIT( KRuleId, "ruleid=");
       
  1477 	_LIT( KContextId,"contextid=");
       
  1478 	_LIT( KBracketAnd, " AND (");
       
  1479 	_LIT( KBracketOr, ") OR (");
       
  1480 	_LIT( KFinalBracket, ")");
       
  1481 	
       
  1482 	// Get column set
       
  1483     CDbColSet* columns = view.ColSetL();
       
  1484 	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  1485 	TDbColNo grammarid_col= columns->ColNo( KGrammarIdCol );
       
  1486 	delete columns;
       
  1487 	TUint32 currContextId;
       
  1488 	TUint32 currGrammarId;
       
  1489 	TUint32 currRuleId;
       
  1490 	
       
  1491 	iSQLStatement = KSQLGetTags;
       
  1492 	TBool firstPair = ETrue;
       
  1493 	while( view.NextL())
       
  1494 		{
       
  1495 		view.GetL();
       
  1496 		// before each iteration, but first, we add ") OR ("
       
  1497 		if( firstPair )
       
  1498 			{
       
  1499 			firstPair = EFalse;
       
  1500 			}
       
  1501 		else 
       
  1502 			{
       
  1503 			iSQLStatement.Append(KBracketOr);
       
  1504 			}
       
  1505 		currContextId = view.ColUint32( contextid_col );
       
  1506 		currGrammarId = view.ColUint32( grammarid_col );
       
  1507 		iSQLStatement.Append( KContextId );
       
  1508 		iSQLStatement.AppendNumUC( currContextId );
       
  1509 		iSQLStatement.Append( KBracketAnd );
       
  1510 		// we need to find corresponding rule id
       
  1511 		TBool someGrammarFoundAlready = EFalse;
       
  1512 		for( TInt i=0; i<aGrammarIdRuleIds.Count(); i++)
       
  1513 			{
       
  1514 			if( currGrammarId == aGrammarIdRuleIds[i].iGrammarId )
       
  1515 				{
       
  1516 				if( someGrammarFoundAlready )
       
  1517 					{
       
  1518 					iSQLStatement.Append( KOr );
       
  1519 					}
       
  1520 				else 
       
  1521 					{
       
  1522 					someGrammarFoundAlready = ETrue;
       
  1523 					}
       
  1524 				currRuleId = aGrammarIdRuleIds[i].iRuleId;
       
  1525 				iSQLStatement.Append( KRuleId );
       
  1526 				iSQLStatement.AppendNumUC( currRuleId );	
       
  1527 				}
       
  1528 			}  // for
       
  1529 		iSQLStatement.Append(KFinalBracket);  // closing ruleid ORs
       
  1530 		}  // while
       
  1531 	// Close view
       
  1532     CleanupStack::PopAndDestroy( &view );
       
  1533     iSQLStatement.Append( KFinalBracket );
       
  1534     
       
  1535     CArrayPtrFlat<CNssTag>* res = GetTagListByQueryL( iSQLStatement );
       
  1536 
       
  1537     // Pop rollback cleanup item
       
  1538     CleanupStack::Pop();  // Rollback cleanup item
       
  1539     CommitTransaction( EFalse );
       
  1540 
       
  1541     CleanupStack::PopAndDestroy( context );
       
  1542 
       
  1543     return( res );
       
  1544 	}
       
  1545 
       
  1546 // -----------------------------------------------------------------------------
       
  1547 // CNssVasDb::GetTagListByQuery
       
  1548 // Executes the query and reads matches from DB to memory.
       
  1549 // -----------------------------------------------------------------------------
       
  1550 //
       
  1551 // -----------------------------------------------------------------------------
       
  1552 // CNssVasDb::GetTagListByQuery
       
  1553 // Executes the query and reads matches from DB to memory.
       
  1554 // -----------------------------------------------------------------------------
       
  1555 //
       
  1556 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagListByQueryL( const TDesC& aSqlQuery )
       
  1557     {
       
  1558     RUBY_DEBUG_BLOCK( "CNssVasDb::GetTagListByQueryL" );
       
  1559 
       
  1560     __ASSERT_DEBUG( aSqlQuery.Left(6).Compare( _L("select") ) == 0, User::Panic( KVasDbPanic, __LINE__ ) );
       
  1561 
       
  1562 	CNssContext* context = NULL;
       
  1563 	CNssSpeechItem* speechItem = NULL;
       
  1564 	CNssRRD* rrd = NULL;
       
  1565     TInt contextId = -1;
       
  1566 
       
  1567     // 'context' variable is the context of the previous tag.
       
  1568     // When a new tag is read, 'context' is updated only if context changes.
       
  1569     // Set the ID invalid value in order to force the first tag to read a context.
       
  1570     //context.iContextId = (TUint32)-1;
       
  1571     //context->SetContextId( -1 );
       
  1572 
       
  1573 	RDbView view;
       
  1574 	CleanupClosePushL( view );
       
  1575 
       
  1576     CArrayPtrFlat<CNssTag>* tagList = new(ELeave)CArrayPtrFlat<CNssTag>( KMaxTagArraySize );
       
  1577     CleanupStack::PushL( tagList );
       
  1578     CleanupResetAndDestroyPushL( *tagList );
       
  1579 
       
  1580 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( aSqlQuery, EDbCompareNormal ) ) );
       
  1581 	User::LeaveIfError( view.EvaluateAll() );
       
  1582 
       
  1583 	if ( !view.IsEmptyL() )
       
  1584 	    {
       
  1585    	    for (view.FirstL(); view.AtRow(); view.NextL())
       
  1586 	        {
       
  1587 	        context = iContextBuilder.CreateContextL();
       
  1588 	        CleanupStack::PushL( context );
       
  1589 	        
       
  1590 	        speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *context );
       
  1591 	        CleanupStack::PushL( speechItem );
       
  1592 	        
       
  1593             FillSpeechItemL( view, *speechItem, contextId );
       
  1594 
       
  1595             // Get context, if we haven't already done it.
       
  1596             if ( context->ContextId() != (TUint32)contextId )
       
  1597                 {                
       
  1598                 _LIT( KContextQuery, "select * from contexttable where contextid=" );
       
  1599 
       
  1600                 iSQLStatement.Copy( KContextQuery );
       
  1601                 iSQLStatement.AppendNumUC( contextId );
       
  1602 
       
  1603                 CArrayPtrFlat<CNssContext>* contextList = 
       
  1604                             GetContextInsideTransactionL( iSQLStatement );
       
  1605                 CleanupStack::PushL( contextList );
       
  1606 
       
  1607                 User::LeaveIfNull( contextList );
       
  1608 
       
  1609                 if ( contextList->Count() != 1 )
       
  1610                     {
       
  1611                     User::Leave( KErrCorrupt );
       
  1612                     }
       
  1613 
       
  1614                 CleanupStack::Pop( contextList );
       
  1615                 CleanupStack::PopAndDestroy( speechItem );                
       
  1616                 CleanupStack::PopAndDestroy( context );
       
  1617                 
       
  1618                 context = (*contextList)[0];                
       
  1619                 delete contextList;
       
  1620                 
       
  1621                 CleanupStack::PushL( context );
       
  1622                 
       
  1623 	            speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *context );
       
  1624 	            CleanupStack::PushL( speechItem );
       
  1625 	        	        
       
  1626                 FillSpeechItemL( view, *speechItem, contextId );
       
  1627                 }
       
  1628                 
       
  1629             rrd = CNssRRD::NewL();
       
  1630             CleanupStack::PushL( rrd );
       
  1631             
       
  1632             FillRRDL( speechItem->TagId(), *rrd );
       
  1633             
       
  1634             // Append tag to the array 
       
  1635             FillTagListArrayL( *tagList, context, speechItem, rrd );
       
  1636             CleanupStack::PopAndDestroy( rrd );
       
  1637             CleanupStack::PopAndDestroy( speechItem );
       
  1638             CleanupStack::PopAndDestroy( context );
       
  1639             }
       
  1640         }
       
  1641 	else
       
  1642 	    {
       
  1643         User::Leave( KErrNotFound );
       
  1644 	    }
       
  1645 
       
  1646 	CleanupStack::Pop( tagList );  // ResetAndDestroy
       
  1647     CleanupStack::Pop( tagList );  // array itself
       
  1648 	// Finished with the view - so close it.
       
  1649     CleanupStack::PopAndDestroy( &view );
       
  1650 
       
  1651     return tagList;
       
  1652     }
       
  1653     
       
  1654 // -----------------------------------------------------------------------------
       
  1655 // CNssVasDb::GetTagL
       
  1656 // Gets a tag by name.
       
  1657 // -----------------------------------------------------------------------------
       
  1658 //
       
  1659 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL(const TDesC& aName)
       
  1660     {
       
  1661     _LIT( KTick,"' ");
       
  1662 	_LIT( KSQLGetTag, "select * from tagtable where name='");
       
  1663 	
       
  1664 	iSQLStatement = KSQLGetTag;
       
  1665 	iSQLStatement.Append( aName );
       
  1666     iSQLStatement.Append( KTick );
       
  1667 
       
  1668     User::LeaveIfError( StartTransaction() );
       
  1669 
       
  1670     CArrayPtrFlat<CNssTag>* arr = GetTagListByQueryL( iSQLStatement );
       
  1671 
       
  1672     CommitTransaction( EFalse );
       
  1673 
       
  1674     return arr;
       
  1675     }
       
  1676 
       
  1677 // -----------------------------------------------------------------------------
       
  1678 // CNssVasDb::GetTagL
       
  1679 // Gets all tags from a specified context.
       
  1680 // -----------------------------------------------------------------------------
       
  1681 //
       
  1682 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( const CNssContext& aContext)
       
  1683     {
       
  1684     RDbView view;
       
  1685 
       
  1686     User::LeaveIfError( StartTransaction() );
       
  1687     CreatePushRollbackItemLC();
       
  1688 
       
  1689     CleanupClosePushL( view );
       
  1690 
       
  1691 	// Validate the context
       
  1692     _LIT( KSQLGetContext, "select * from contexttable where contextid=");
       
  1693 	iSQLStatement = KSQLGetContext;
       
  1694 	iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  1695 
       
  1696 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1697 	User::LeaveIfError( view.EvaluateAll() );
       
  1698 
       
  1699     if ( view.IsEmptyL() )
       
  1700 	    {
       
  1701         User::Leave( KErrNotFound );
       
  1702 	    }
       
  1703 
       
  1704 	// Finished with the view - so close it.
       
  1705     CleanupStack::PopAndDestroy( &view );
       
  1706 	
       
  1707 	_LIT( KSQLGetTag, "select * from tagtable where contextid=" );
       
  1708 	iSQLStatement.Copy( KSQLGetTag );
       
  1709 	iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  1710 
       
  1711     CArrayPtrFlat<CNssTag>* result = GetTagListByQueryL( iSQLStatement );
       
  1712 
       
  1713     // Transaction finished - free the transaction lock
       
  1714     CleanupStack::Pop();  // Rollback cleanup item
       
  1715     CommitTransaction( EFalse );
       
  1716 
       
  1717     return result;
       
  1718     }
       
  1719 
       
  1720 // -----------------------------------------------------------------------------
       
  1721 // CNssVasDb::GetTagListFromViewL
       
  1722 // Reads the tags from DB to memory and appends them to the array.
       
  1723 // Earlier, the caller has made an SQL query and placed the matches in RDbView.
       
  1724 // -----------------------------------------------------------------------------
       
  1725 //
       
  1726 void CNssVasDb::GetTagListFromViewL( RDbView& aView, CArrayPtrFlat<CNssTag>* aTagList, 
       
  1727                                      CNssContext* aContext )
       
  1728     {
       
  1729     TInt discardable( 0 );
       
  1730 
       
  1731 	for ( aView.FirstL(); aView.AtRow(); aView.NextL() )
       
  1732     	{
       
  1733     	CNssSpeechItem* speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *aContext );
       
  1734     	CleanupStack::PushL( speechItem );
       
  1735     	
       
  1736 	    FillSpeechItemL( aView, *speechItem, discardable );
       
  1737 		CNssRRD* rrd = CNssRRD::NewL();
       
  1738 		CleanupStack::PushL( rrd );
       
  1739 		FillRRDL( speechItem->TagId(), *rrd );
       
  1740 		    
       
  1741 		FillTagListArrayL( *aTagList, aContext, speechItem, rrd );
       
  1742 		
       
  1743 		CleanupStack::PopAndDestroy( rrd );
       
  1744 		CleanupStack::PopAndDestroy( speechItem );
       
  1745 	    }
       
  1746     }
       
  1747 
       
  1748 // -----------------------------------------------------------------------------
       
  1749 // CNssVasDb::DeleteTagL
       
  1750 // Gets a list of tags by RRD data.
       
  1751 // -----------------------------------------------------------------------------
       
  1752 //
       
  1753 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TInt aContextId, TInt aNum, TInt aPosition )
       
  1754     {
       
  1755   	RDbView     view;
       
  1756 	TUint32     tagId;
       
  1757 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1758 	CleanupStack::PushL( context );
       
  1759 
       
  1760     User::LeaveIfError( StartTransaction() );
       
  1761     CreatePushRollbackItemLC();
       
  1762 
       
  1763     CArrayPtrFlat<CNssTag>* tagArray = new(ELeave)CArrayPtrFlat<CNssTag>(1);
       
  1764     CleanupStack::PushL( tagArray );
       
  1765     CleanupResetAndDestroyPushL( *tagArray );
       
  1766 
       
  1767     // Get the context based on ContextId
       
  1768   	CleanupClosePushL(view);
       
  1769 
       
  1770 	_LIT( KSQLGetContext, "select * from contexttable where contextid=" );
       
  1771 	iSQLStatement.Copy( KSQLGetContext );
       
  1772 	iSQLStatement.AppendNumUC( aContextId );
       
  1773 
       
  1774 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1775 	User::LeaveIfError( view.EvaluateAll() );
       
  1776 	view.FirstL();
       
  1777     view.GetL();
       
  1778 	TRAPD( error, FillContextL( view, *context ) );
       
  1779 	// Finished with the view - so close it.
       
  1780 	view.Close();
       
  1781 	CleanupStack::PopAndDestroy( &view );
       
  1782 
       
  1783     // If filling of the context failed, return with Not Found
       
  1784 	if ( error != KErrNone )
       
  1785 	    {
       
  1786         User::Leave( KErrNotFound );
       
  1787         }
       
  1788 
       
  1789     // Get the list of TagId from the RRD table based on Num and Position
       
  1790 	RDbView view1;
       
  1791 	CleanupClosePushL( view1 );
       
  1792 
       
  1793 	_LIT( KSQLGetRRDInt, "select * from rrdinttable where rrdposition=" );
       
  1794 	_LIT( KSQLAndRRDInt, " and rrdint=" );
       
  1795 	iSQLStatement = KSQLGetRRDInt;
       
  1796 	iSQLStatement.AppendNumUC( aPosition );
       
  1797 	iSQLStatement.Append( KSQLAndRRDInt );
       
  1798 	iSQLStatement.AppendNumUC( aNum );
       
  1799 
       
  1800 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1801 	User::LeaveIfError( view1.EvaluateAll() );
       
  1802 	
       
  1803 	if ( view1.IsEmptyL() )
       
  1804 	    {
       
  1805 
       
  1806         User::Leave( KErrNotFound );
       
  1807 	    }
       
  1808 
       
  1809     // Get column set
       
  1810     CDbColSet* columns = view1.ColSetL();
       
  1811     // Get column ordinals
       
  1812     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  1813     // Cleanup column set
       
  1814     delete columns;
       
  1815 
       
  1816     // Select the valid tagId from the list
       
  1817 	for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1818         {   
       
  1819         view1.GetL();
       
  1820         tagId = view1.ColUint32( tagid_col );
       
  1821 
       
  1822         // Get the SpeechItem based on the tagId and ContextId
       
  1823         RDbView view2;
       
  1824 		CleanupClosePushL( view2 );
       
  1825 
       
  1826         _LIT( KSQLGetSpeechItem, "select * from tagtable where tagid=" );
       
  1827         _LIT( KSQLAndContextId," and contextid=" );
       
  1828         iSQLStatement = KSQLGetSpeechItem;
       
  1829         iSQLStatement.AppendNumUC( tagId );
       
  1830 	    iSQLStatement.Append( KSQLAndContextId );
       
  1831         iSQLStatement.AppendNumUC( aContextId );
       
  1832 
       
  1833         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1834                             TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1835         User::LeaveIfError( view2.EvaluateAll() );
       
  1836     
       
  1837         if ( !view2.IsEmptyL() )
       
  1838 	        {
       
  1839             GetTagListFromViewL( view2, tagArray, context );
       
  1840 		    }
       
  1841         view2.Close();
       
  1842         CleanupStack::PopAndDestroy( &view2 );
       
  1843         }
       
  1844 
       
  1845     // close the view 1
       
  1846 	view1.Close();
       
  1847 	CleanupStack::PopAndDestroy( &view1 );
       
  1848 
       
  1849     CleanupStack::Pop( tagArray );  // ResetAndDestroy
       
  1850     CleanupStack::Pop( tagArray );  // array itself
       
  1851 
       
  1852     // Rollback cleanup
       
  1853     CleanupStack::Pop();  // Rollback cleanup item
       
  1854     CommitTransaction( EFalse );
       
  1855     
       
  1856     CleanupStack::PopAndDestroy( context );
       
  1857 
       
  1858     return tagArray;
       
  1859     }
       
  1860 
       
  1861 // -----------------------------------------------------------------------------
       
  1862 // CNssVasDb::DeleteTagL
       
  1863 // Gets a list of tags by RRD data.
       
  1864 // -----------------------------------------------------------------------------
       
  1865 //
       
  1866 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TInt aContextId, 
       
  1867                                             const TDesC& aText, TInt aPosition )
       
  1868     {
       
  1869   	RDbView view;
       
  1870 	TUint32 tagId;
       
  1871 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1872 	CleanupStack::PushL( context );
       
  1873 	
       
  1874     CArrayPtrFlat<CNssTag>* tagArray = new(ELeave)CArrayPtrFlat<CNssTag>(1);
       
  1875     CleanupStack::PushL( tagArray );
       
  1876     CleanupResetAndDestroyPushL( *tagArray );
       
  1877 
       
  1878     User::LeaveIfError( StartTransaction() );
       
  1879     CreatePushRollbackItemLC();
       
  1880 
       
  1881     // Get the context based on ContextId
       
  1882   	CleanupClosePushL( view );
       
  1883 
       
  1884 	_LIT( KSQLGetContext, "select * from contexttable where contextid=" );
       
  1885 	iSQLStatement.Copy( KSQLGetContext );
       
  1886 	iSQLStatement.AppendNumUC( aContextId );
       
  1887 
       
  1888 	User::LeaveIfError( view.Prepare(iDatabase, TDbQuery(iSQLStatement, EDbCompareNormal)));
       
  1889 	User::LeaveIfError( view.EvaluateAll());
       
  1890 	view.FirstL();
       
  1891     view.GetL();
       
  1892 	TRAPD( error, FillContextL( view, *context ) );
       
  1893 	// Finished with the view - so close it.
       
  1894 	view.Close();
       
  1895 	CleanupStack::PopAndDestroy( &view );
       
  1896 
       
  1897     // If filling of the context failed, return with Not Found
       
  1898 	if ( error != KErrNone )
       
  1899 	    {
       
  1900         User::Leave( KErrNotFound );
       
  1901         }
       
  1902 
       
  1903     // Get the list of TagId from the RRD table based on text and Position
       
  1904 	RDbView view1;
       
  1905 	CleanupClosePushL( view1 );
       
  1906 
       
  1907 	_LIT( KSQLGetRRDText, "select * from rrdtexttable where rrdposition=" );
       
  1908 	_LIT( KSQLAndRRDText, " and rrdtext='" );
       
  1909 	_LIT( KSQLTick, "'" );
       
  1910 
       
  1911 	iSQLStatement = KSQLGetRRDText;
       
  1912 	iSQLStatement.AppendNumUC( aPosition );
       
  1913 	iSQLStatement.Append( KSQLAndRRDText );
       
  1914 	iSQLStatement.Append( aText );
       
  1915     iSQLStatement.Append( KSQLTick );
       
  1916 
       
  1917 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1918 	User::LeaveIfError( view1.EvaluateAll() );
       
  1919 	
       
  1920 	if ( view1.IsEmptyL() )
       
  1921 	    {
       
  1922         User::Leave( KErrNotFound );
       
  1923 	    }
       
  1924 
       
  1925     // Get column set
       
  1926     CDbColSet* columns = view1.ColSetL();
       
  1927     // Get column ordinals
       
  1928     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  1929     // Cleanup column set
       
  1930     delete columns;
       
  1931 
       
  1932     // Select the valid tagId from the list
       
  1933 	for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1934 	    {
       
  1935         view1.GetL();
       
  1936         tagId = view1.ColUint32( tagid_col );
       
  1937 
       
  1938         // Get the SpeechItem based on the tagId and ContextId
       
  1939         RDbView view2;
       
  1940 		CleanupClosePushL( view2 );
       
  1941 
       
  1942         _LIT( KSQLGetSpeechItem, "select * from tagtable where tagid=" );
       
  1943         _LIT( KSQLAndContextId, " and contextid=" );
       
  1944         iSQLStatement = KSQLGetSpeechItem;
       
  1945         iSQLStatement.AppendNumUC( tagId );
       
  1946 	    iSQLStatement.Append( KSQLAndContextId );
       
  1947         iSQLStatement.AppendNumUC( aContextId );
       
  1948 
       
  1949         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1950                             TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1951         User::LeaveIfError( view2.EvaluateAll() );
       
  1952 
       
  1953         if ( !view2.IsEmptyL() )
       
  1954 	        {
       
  1955             GetTagListFromViewL( view2, tagArray, context );
       
  1956 		    }
       
  1957         CleanupStack::PopAndDestroy( &view2 );
       
  1958         }
       
  1959     // close the view 1
       
  1960 	CleanupStack::PopAndDestroy( &view1 );
       
  1961 
       
  1962     // Roll back transaction
       
  1963     CleanupStack::Pop();  // Rollback cleanup item
       
  1964     CommitTransaction( EFalse );
       
  1965 
       
  1966     CleanupStack::Pop( tagArray );  // ResetAndDestroyPushL
       
  1967     CleanupStack::Pop( tagArray );  // array itself
       
  1968     CleanupStack::PopAndDestroy( context );
       
  1969 
       
  1970     return tagArray;
       
  1971     }
       
  1972 
       
  1973 // -----------------------------------------------------------------------------
       
  1974 // CNssVasDb::DeleteTagL
       
  1975 // Get a tag by ID.
       
  1976 // -----------------------------------------------------------------------------
       
  1977 //
       
  1978 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TUint32 aTagId )
       
  1979     {
       
  1980 	RDbView view;
       
  1981 
       
  1982     User::LeaveIfError( StartTransaction() );
       
  1983     CreatePushRollbackItemLC();
       
  1984 
       
  1985     CleanupClosePushL( view );
       
  1986 
       
  1987 
       
  1988 	_LIT( KSQLGetTag, "select * from tagtable where tagid=");
       
  1989 
       
  1990 	iSQLStatement = KSQLGetTag;
       
  1991 	iSQLStatement.AppendNumUC( aTagId );
       
  1992 
       
  1993     CArrayPtrFlat<CNssTag>* result = GetTagListByQueryL( iSQLStatement );
       
  1994 
       
  1995     // Close view
       
  1996     CleanupStack::PopAndDestroy( &view );
       
  1997 
       
  1998     // Roll back transaction
       
  1999     CleanupStack::Pop();  // Rollback cleanup item
       
  2000     CommitTransaction( EFalse );
       
  2001 
       
  2002     return( result );
       
  2003     }
       
  2004 
       
  2005 
       
  2006 // -----------------------------------------------------------------------------
       
  2007 // CNssVasDb::DeleteTagL
       
  2008 // Deletes a tag by name
       
  2009 // -----------------------------------------------------------------------------
       
  2010 //
       
  2011 void CNssVasDb::DeleteTagL( const TDesC& aName )
       
  2012     {
       
  2013     if ( !iClientHasOpenedDatabase )
       
  2014         {
       
  2015         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
  2016         
       
  2017         User::Leave( KErrNotReady );
       
  2018         }
       
  2019 
       
  2020     User::LeaveIfError( StartTransaction() );
       
  2021     CreatePushRollbackItemLC();
       
  2022 
       
  2023     TUint32 tagId;
       
  2024     RDbView view;
       
  2025 	
       
  2026     CleanupClosePushL(view);
       
  2027 
       
  2028     _LIT( KTick,"' ");
       
  2029     _LIT( KSQLGetTag, "select * from tagtable where name='");
       
  2030 	
       
  2031     iSQLStatement = KSQLGetTag;
       
  2032     iSQLStatement.Append( aName );
       
  2033     iSQLStatement.Append( KTick );
       
  2034 
       
  2035     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery(iSQLStatement, EDbCompareNormal)));
       
  2036     User::LeaveIfError( view.EvaluateAll());
       
  2037 
       
  2038     // Get column set
       
  2039     CDbColSet* columns = view.ColSetL();
       
  2040     // Get column ordinals
       
  2041     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  2042     // Cleanup column set
       
  2043     delete columns;
       
  2044 
       
  2045     view.FirstL();
       
  2046     view.GetL();
       
  2047     tagId = view.ColUint32( tagid_col );
       
  2048 
       
  2049     // Close view
       
  2050     CleanupStack::PopAndDestroy( &view );
       
  2051 
       
  2052     // Pop rollback item and do commit
       
  2053     CleanupStack::Pop();  // Rollback cleanup item
       
  2054     CommitTransaction( ETrue );
       
  2055 
       
  2056     DeleteTagL( tagId );
       
  2057     }
       
  2058 
       
  2059 // -----------------------------------------------------------------------------
       
  2060 // CNssVasDb::DeleteTagL
       
  2061 // Deletes a tag by ID
       
  2062 // -----------------------------------------------------------------------------
       
  2063 //
       
  2064 void CNssVasDb::DeleteTagL( TUint32 aTagId )
       
  2065     {
       
  2066     if ( !iClientHasOpenedDatabase )
       
  2067         {
       
  2068         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
  2069         
       
  2070         User::Leave( KErrNotReady );
       
  2071         }
       
  2072    
       
  2073     // Lock database
       
  2074     User::LeaveIfError( StartTransaction() );
       
  2075     CreatePushRollbackItemLC();
       
  2076 
       
  2077     DeleteTagInsideTransactionL( aTagId );
       
  2078 
       
  2079     // Commit transaction - unlock databaes
       
  2080     CleanupStack::Pop();  // Rollback cleanup item
       
  2081     CommitTransaction( ETrue );
       
  2082     }
       
  2083 
       
  2084 
       
  2085 // -----------------------------------------------------------------------------
       
  2086 // CNssVasDb::DeleteTagInsideTransactionL
       
  2087 // Deletes the RRD information of a tag.
       
  2088 // -----------------------------------------------------------------------------
       
  2089 //
       
  2090 void CNssVasDb::DeleteTagInsideTransactionL( TUint32 aTagId )
       
  2091     {
       
  2092     TInt error( KErrNone );
       
  2093 
       
  2094     _LIT( KSQLDeleteTag, "delete from tagtable where tagid=");
       
  2095 
       
  2096 	ReserveDiskSpaceL( sizeof(CNssTag) );
       
  2097 
       
  2098     iSQLStatement = KSQLDeleteTag;
       
  2099     iSQLStatement.AppendNumUC(aTagId);
       
  2100 
       
  2101     error = iDatabase.Execute( iSQLStatement );
       
  2102     if ( error < KErrNone )
       
  2103         {
       
  2104         ReleaseDiskSpace();
       
  2105         User::Leave( error );
       
  2106         }
       
  2107 
       
  2108     TRAP( error, DeleteRRDL( aTagId ) );
       
  2109     
       
  2110     ReleaseDiskSpace();
       
  2111     
       
  2112     User::LeaveIfError( error );
       
  2113     }
       
  2114 
       
  2115 
       
  2116 // -----------------------------------------------------------------------------
       
  2117 // CNssVasDb::DeleteRRDL
       
  2118 // Deletes the RRD information of a tag.
       
  2119 // -----------------------------------------------------------------------------
       
  2120 //
       
  2121 void CNssVasDb::DeleteRRDL(TUint32 aTagId)
       
  2122     {
       
  2123     TInt error( KErrNone );
       
  2124     
       
  2125     _LIT( KSQLAddRRDText, "delete from rrdtexttable ");
       
  2126     _LIT( KSQLAddRRDId,   "delete from rrdinttable ");
       
  2127     _LIT( KSQLWhereTagId,"where tagid=");
       
  2128 
       
  2129     iSQLStatement = KSQLAddRRDId;
       
  2130     iSQLStatement.Append( KSQLWhereTagId );
       
  2131     iSQLStatement.AppendNumUC( aTagId );
       
  2132 	
       
  2133     error = iDatabase.Execute( iSQLStatement );
       
  2134    
       
  2135     if ( error < KErrNone && error != KErrNotFound )
       
  2136         {
       
  2137         User::Leave( error );
       
  2138         }
       
  2139 
       
  2140     iSQLStatement = KSQLAddRRDText;
       
  2141     iSQLStatement.Append( KSQLWhereTagId );
       
  2142     iSQLStatement.AppendNumUC( aTagId );
       
  2143 
       
  2144     error = iDatabase.Execute( iSQLStatement );
       
  2145 
       
  2146     if ( error < KErrNone && error != KErrNotFound )
       
  2147         {
       
  2148         User::Leave( error );
       
  2149         }
       
  2150     }
       
  2151 
       
  2152 // -----------------------------------------------------------------------------
       
  2153 // CNssVasDb::DeleteContextL
       
  2154 // Deletes a context.
       
  2155 // -----------------------------------------------------------------------------
       
  2156 //
       
  2157 void CNssVasDb::DeleteContextL( const TDesC& aName )
       
  2158     {
       
  2159     RUBY_DEBUG_BLOCK( "CNssVasDb::DeleteContextL" );
       
  2160     
       
  2161     TInt error( KErrNone );
       
  2162     TUint32 contextId;
       
  2163     TUint32 tagId;
       
  2164     RDbView view1,view2;
       
  2165     
       
  2166     // Begin transaction
       
  2167     User::LeaveIfError( StartTransaction() );
       
  2168     CreatePushRollbackItemLC();
       
  2169     
       
  2170     CleanupClosePushL( view1 );
       
  2171     
       
  2172     // Search the context from DB
       
  2173     _LIT( KTick, "' " );
       
  2174     _LIT( KSQLGetContext, "select * from contexttable where name='" );
       
  2175     
       
  2176     iSQLStatement = KSQLGetContext;
       
  2177     iSQLStatement.Append( aName );
       
  2178     iSQLStatement.Append( KTick );
       
  2179     
       
  2180     User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  2181     User::LeaveIfError( view1.EvaluateAll() );
       
  2182     
       
  2183     // Get column set
       
  2184     CDbColSet* columns1 = view1.ColSetL();
       
  2185     // Get column ordinals
       
  2186     TDbColNo contextid_col= columns1->ColNo( KContextIdCol );
       
  2187     // Cleanup column set
       
  2188     delete columns1;
       
  2189     
       
  2190     view1.FirstL();
       
  2191     
       
  2192     // Doesn't exists, can't delete
       
  2193     if ( !view1.AtRow() )
       
  2194         {
       
  2195         User::Leave( KErrNotFound );
       
  2196         }
       
  2197     
       
  2198     view1.GetL();
       
  2199     contextId = view1.ColUint32( contextid_col );
       
  2200     
       
  2201     view1.DeleteL();
       
  2202     view1.Close();	
       
  2203     CleanupStack::PopAndDestroy( &view1 );
       
  2204     
       
  2205     // Delete all tags, which were in the context.
       
  2206     _LIT( KSQLGetTag, "select * from tagtable where contextid=" );
       
  2207     
       
  2208     iSQLStatement = KSQLGetTag;
       
  2209     iSQLStatement.AppendNumUC( contextId );
       
  2210     
       
  2211     CleanupClosePushL( view2 );
       
  2212     
       
  2213     User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  2214     User::LeaveIfError( view2.EvaluateAll() );
       
  2215     
       
  2216     ReserveDiskSpaceL( (sizeof(CNssTag) * view2.CountL()) + sizeof(CNssContext) );
       
  2217     
       
  2218     view2.FirstL();
       
  2219     
       
  2220     // If this context has any tags, remove the RRD entries from the RRD table.
       
  2221     if ( view2.AtRow() )
       
  2222         {
       
  2223         // Get column set
       
  2224         CDbColSet* columns2 = view2.ColSetL();
       
  2225         
       
  2226         // Get column ordinals
       
  2227         TDbColNo tagid_col = columns2->ColNo( KTagIdCol );
       
  2228         // Cleanup column2 set
       
  2229         delete columns2;
       
  2230         
       
  2231         for ( view2.FirstL(); view2.AtRow(); view2.NextL() )
       
  2232             {
       
  2233             view2.GetL();
       
  2234             tagId = view2.ColUint32( tagid_col );
       
  2235             RUBY_DEBUG0( "CNssVasDb::DeleteContextL deleting RRD" );
       
  2236             // Return value ignored since other tag ids should be iterated through
       
  2237             // even though one RRD deletion fails
       
  2238             TRAP( error, DeleteRRDL( tagId ) );
       
  2239             }
       
  2240         
       
  2241         view2.Close();
       
  2242         }
       
  2243     
       
  2244     // Remove tags from tag table
       
  2245     _LIT( KSQLDeleteTag, "delete from tagtable where contextid=");
       
  2246     iSQLStatement = KSQLDeleteTag;
       
  2247     iSQLStatement.AppendNumUC( contextId );
       
  2248     
       
  2249     error = iDatabase.Execute( iSQLStatement );
       
  2250     
       
  2251     CleanupStack::PopAndDestroy( &view2 );
       
  2252     
       
  2253     if ( error < KErrNone && error != KErrNotFound )
       
  2254         {
       
  2255         ReleaseDiskSpace();
       
  2256         // Roll back transaction
       
  2257         CleanupStack::PopAndDestroy(); // Rollback cleanup item
       
  2258         User::Leave( error );
       
  2259         }
       
  2260    
       
  2261     CleanupStack::Pop();  // Rollback cleanup item
       
  2262     CommitTransaction( ETrue );
       
  2263    
       
  2264     ReleaseDiskSpace();
       
  2265     }
       
  2266 
       
  2267 // -----------------------------------------------------------------------------
       
  2268 // CNssVasDb::UpdateTagInTransactionL
       
  2269 // Updates a tag. Assumes that a transaction has been started earlier.
       
  2270 // -----------------------------------------------------------------------------
       
  2271 //
       
  2272 void CNssVasDb::UpdateTagInTransactionL( CNssTag& aTag )
       
  2273     {
       
  2274     CNssContext* context = static_cast<CNssContext*> ( aTag.Context() );
       
  2275     UpdateContextInsideTransactionL( *context );
       
  2276     CNssSpeechItem* speechItem = static_cast<CNssSpeechItem*>
       
  2277         ( aTag.SpeechItem() );
       
  2278     UpdateSpeechItemL( *speechItem );
       
  2279     CNssRRD* rrd = static_cast<CNssRRD*> ( aTag.RRD() );
       
  2280     UpdateRRDL( *rrd );
       
  2281     }
       
  2282 
       
  2283 // -----------------------------------------------------------------------------
       
  2284 // CNssVasDb::DoUpdateContextL
       
  2285 // Updates an existing context.
       
  2286 // -----------------------------------------------------------------------------
       
  2287 //
       
  2288 void CNssVasDb::DoUpdateContextL( CNssContext& aContext )
       
  2289     {
       
  2290     _LIT( KSQLUpdateContext,"update contexttable set ");
       
  2291     _LIT( KEqual,"=");
       
  2292     _LIT( KCommon,",");
       
  2293     _LIT( KTick,"'");
       
  2294     _LIT( KSQLWhereContextId," where contextid = ");
       
  2295    
       
  2296     iSQLStatement = KSQLUpdateContext;
       
  2297      
       
  2298     iSQLStatement.Append( KNameCol );
       
  2299     iSQLStatement.Append( KEqual );
       
  2300     iSQLStatement.Append( KTick );
       
  2301     iSQLStatement.Append( aContext.ContextName() );
       
  2302     iSQLStatement.Append( KTick );
       
  2303    
       
  2304     iSQLStatement.Append( KCommon );
       
  2305     iSQLStatement.Append( KGlobalCol );
       
  2306     iSQLStatement.Append( KEqual );
       
  2307     iSQLStatement.AppendNumUC( aContext.IsGlobal() );
       
  2308 
       
  2309     iSQLStatement.Append( KCommon );
       
  2310     iSQLStatement.Append( KGrammarIdCol );
       
  2311     iSQLStatement.Append( KEqual );
       
  2312     iSQLStatement.AppendNumUC( aContext.GrammarId() );
       
  2313 
       
  2314     iSQLStatement.Append( KCommon );
       
  2315     iSQLStatement.Append( KLexiconIdCol );
       
  2316     iSQLStatement.Append( KEqual );
       
  2317     iSQLStatement.AppendNumUC( aContext.LexiconId() );
       
  2318 
       
  2319     iSQLStatement.Append( KCommon );
       
  2320     iSQLStatement.Append( KModelBankIdCol );
       
  2321     iSQLStatement.Append( KEqual );
       
  2322     iSQLStatement.AppendNumUC( aContext.ModelBankId() );
       
  2323 
       
  2324     iSQLStatement.Append( KSQLWhereContextId );
       
  2325     iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  2326  
       
  2327     User::LeaveIfError( iDatabase.Execute( iSQLStatement ) );
       
  2328     }
       
  2329 
       
  2330 // -----------------------------------------------------------------------------
       
  2331 // CNssVasDb::DoUpdateUpdateContextClientDataL
       
  2332 // Updates the client data of a context.
       
  2333 // -----------------------------------------------------------------------------
       
  2334 //
       
  2335 void CNssVasDb::DoUpdateContextClientDataL( CNssContext& aContext )
       
  2336     {
       
  2337 	__UHEAP_MARK;
       
  2338 
       
  2339 	// Declare a literal string to hold the SQL statement
       
  2340 	// SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
  2341 
       
  2342 	_LIT( KSQLSelect1, "select clientdata from contexttable where name='" );
       
  2343 
       
  2344 	TBuf<KSqlStatementmaxLength> sqlStatement;
       
  2345 	sqlStatement.Append( KSQLSelect1 );
       
  2346     sqlStatement.Append( aContext.ContextName() );
       
  2347     sqlStatement.Append( '\'' );
       
  2348 
       
  2349 	// create a view on the database
       
  2350 	RDbView view;
       
  2351     CleanupClosePushL( view ); // Stack: view
       
  2352 
       
  2353 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( sqlStatement, EDbCompareNormal ) ) );
       
  2354 	User::LeaveIfError( view.EvaluateAll() );
       
  2355 
       
  2356 	// Get the structure of rowset
       
  2357 	CDbColSet* colSet = view.ColSetL();
       
  2358     CleanupStack::PushL( colSet ); // Stack: view, colset
       
  2359     TInt error( KErrNone );
       
  2360 	
       
  2361 	if( view.FirstL() )
       
  2362 		{
       
  2363 		view.UpdateL();
       
  2364 
       
  2365     
       
  2366 		// add binary buffer by Using the stream  
       
  2367 
       
  2368 		//RDbColWriteStream out;
       
  2369 		TDbColNo col = colSet->ColNo( _L("clientdata") ); // Ordinal position of client data
       
  2370 
       
  2371     	if ( col == KDbNullColNo )
       
  2372         	{
       
  2373         	User::Leave( KErrCorrupt );
       
  2374         	}
       
  2375 
       
  2376     	view.SetColL( col, aContext.ClientData() ); 
       
  2377 	
       
  2378 		view.PutL();
       
  2379 	
       
  2380 		// close the view
       
  2381     	view.Close();
       
  2382 		}
       
  2383 	else 
       
  2384 		{
       
  2385 		error = KErrNotFound;
       
  2386 		}
       
  2387     
       
  2388     CleanupStack::PopAndDestroy( colSet );
       
  2389     CleanupStack::PopAndDestroy( &view );
       
  2390 
       
  2391 	__UHEAP_MARKEND;
       
  2392 
       
  2393     User::LeaveIfError( error );
       
  2394     }
       
  2395 
       
  2396 // -----------------------------------------------------------------------------
       
  2397 // CNssVasDb::UpdateRRDL
       
  2398 // Updates an existing RRD.
       
  2399 // -----------------------------------------------------------------------------
       
  2400 //
       
  2401 void CNssVasDb::UpdateRRDL( CNssRRD& aRRD )
       
  2402     {
       
  2403     TRAPD( error, DeleteRRDL( aRRD.TagId() ) );
       
  2404 
       
  2405     if ( error != KErrNotFound)
       
  2406         {
       
  2407         error = KErrNone;
       
  2408         }
       
  2409 
       
  2410     User::LeaveIfError( error );
       
  2411 
       
  2412     SaveRRDL( &aRRD );
       
  2413     }
       
  2414 
       
  2415 // -----------------------------------------------------------------------------
       
  2416 // CNssVasDb::UpdateSpeechItemL
       
  2417 // Updates an existing speech item.
       
  2418 // -----------------------------------------------------------------------------
       
  2419 //
       
  2420 void CNssVasDb::UpdateSpeechItemL( CNssSpeechItem& aSpeechItem )
       
  2421     {
       
  2422     RDbView view;
       
  2423     CleanupClosePushL( view );
       
  2424  
       
  2425     _LIT( KSQLGet, "select * from tagtable where tagid=" );
       
  2426     
       
  2427     iSQLStatement = KSQLGet;
       
  2428     iSQLStatement.AppendNumUC( aSpeechItem.TagId() );
       
  2429 
       
  2430     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );	
       
  2431     User::LeaveIfError( view.EvaluateAll());
       
  2432     
       
  2433     // Get column set
       
  2434     CDbColSet* columns = view.ColSetL();
       
  2435     // Get column ordinals
       
  2436     TDbColNo name_col= columns->ColNo( KNameCol );
       
  2437 
       
  2438     delete columns;
       
  2439 	  
       
  2440     if ( view.FirstL() )
       
  2441         {
       
  2442         // Begin process of updating a row...
       
  2443         view.UpdateL();
       
  2444         // set column values...
       
  2445 #ifdef __SIND_EXTENSIONS        
       
  2446         view.SetColL( name_col, aSpeechItem.RawText() ); 
       
  2447 #else
       
  2448         view.SetColL( name_col, aSpeechItem.Text() ); 
       
  2449 #endif
       
  2450 
       
  2451         // add the row to the table...
       
  2452         view.PutL();
       
  2453 		
       
  2454         // finished - so close the view
       
  2455         view.Close();
       
  2456 		}
       
  2457     else 
       
  2458         {
       
  2459         User::Leave( KErrNotFound );
       
  2460         }	
       
  2461 	
       
  2462     CleanupStack::PopAndDestroy( &view );
       
  2463     }
       
  2464 
       
  2465 // -----------------------------------------------------------------------------
       
  2466 // CNssVasDb::FillSpeechItemL
       
  2467 // Reads a TNssSpeechItem from DB to memory. Earlier, the caller has run an SQL
       
  2468 // query and specifies the matching context in RDbView.
       
  2469 // -----------------------------------------------------------------------------
       
  2470 //
       
  2471 void CNssVasDb::FillSpeechItemL( RDbView& aView, CNssSpeechItem& aSpeechItem, TInt& aContextId )
       
  2472     {
       
  2473     RUBY_DEBUG_BLOCK( "CNssVasDb::FillSpeechItemL" );
       
  2474 
       
  2475 	if ( aView.IsEmptyL() )
       
  2476 	    {
       
  2477 		User::Leave( KErrNotFound );
       
  2478 	    }
       
  2479 
       
  2480 	// Get column set
       
  2481     CDbColSet* columns = aView.ColSetL();
       
  2482     // Get column ordinals
       
  2483  	TDbColNo tagid_col    = columns->ColNo( KTagIdCol );
       
  2484  	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  2485 	TDbColNo ruleid_col   = columns->ColNo( KRuleIdCol );
       
  2486 	TDbColNo name_col     = columns->ColNo( KNameCol );
       
  2487 
       
  2488     // Cleanup column set
       
  2489     delete columns;
       
  2490 
       
  2491 	// Retrieve the current row
       
  2492 	aView.GetL();
       
  2493 	aSpeechItem.SetTagId( aView.ColUint32( tagid_col ) );
       
  2494 	aSpeechItem.SetRuleID( aView.ColUint32( ruleid_col ) );
       
  2495 	aSpeechItem.SetTextL( aView.ColDes( name_col ) );
       
  2496     aContextId = aView.ColUint32( contextid_col );
       
  2497     }
       
  2498 
       
  2499 
       
  2500 // -----------------------------------------------------------------------------
       
  2501 // CNssVasDb::FillContextL
       
  2502 // Reads a context from DB to memory. Earlier, the caller has run an SQL query
       
  2503 // and specifies the matching context in RDbView.
       
  2504 // -----------------------------------------------------------------------------
       
  2505 //
       
  2506 void CNssVasDb::FillContextL( RDbView& aView, CNssContext& aContext )
       
  2507     {
       
  2508     if ( aView.IsEmptyL() )
       
  2509 	    {
       
  2510 	    User::Leave( KErrNotFound );
       
  2511 	    }
       
  2512 
       
  2513 	// Get column set
       
  2514     CDbColSet* columns = aView.ColSetL();
       
  2515     // Get column ordinals
       
  2516  	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  2517 	TDbColNo name_col = columns->ColNo( KNameCol );
       
  2518     TDbColNo global_col = columns->ColNo( KGlobalCol );
       
  2519 	TDbColNo grammarid_col= columns->ColNo( KGrammarIdCol );
       
  2520 	TDbColNo lexiconid_col= columns->ColNo( KLexiconIdCol );
       
  2521 	TDbColNo modelbankid_col= columns->ColNo( KModelBankIdCol );
       
  2522     // Cleanup column set
       
  2523     delete columns;
       
  2524 
       
  2525 	// Retrieve the current row
       
  2526 	aView.GetL();
       
  2527 	aContext.SetContextId( aView.ColUint32( contextid_col ) );
       
  2528 	aContext.SetGlobal( aView.ColUint32( global_col ) );
       
  2529 	aContext.SetGrammarId( aView.ColUint32( grammarid_col ) );
       
  2530 	aContext.SetLexiconId( aView.ColUint32( lexiconid_col ) );
       
  2531 	aContext.SetModelBankId( aView.ColUint32( modelbankid_col ) );
       
  2532 	aContext.SetNameL( aView.ColDes( name_col ) );
       
  2533     }
       
  2534 
       
  2535 // -----------------------------------------------------------------------------
       
  2536 // CNssVasDb::FillTagListArrayL
       
  2537 // Creates a TNssTag from context, speech item and RRD information.
       
  2538 // Adds a tag to aTagList.
       
  2539 // -----------------------------------------------------------------------------
       
  2540 //
       
  2541 void CNssVasDb::FillTagListArrayL( CArrayPtrFlat<CNssTag>& aTagList, CNssContext* aContext, 
       
  2542                                    CNssSpeechItem* aSpeechItem, CNssRRD* aRRD )
       
  2543     {    
       
  2544     CNssContext* contextCopy = aContext->CopyL();
       
  2545     CNssSpeechItem* speechItenCopy = aSpeechItem->CopyL( contextCopy );
       
  2546     CNssRRD* rrdCopy = aRRD->CopyL();
       
  2547     CNssTag* tag = new (ELeave) CNssTag( contextCopy, rrdCopy, speechItenCopy );
       
  2548     tag->SetTagId( aSpeechItem->TagId() );
       
  2549 	
       
  2550 	aTagList.AppendL( tag );
       
  2551     }
       
  2552 
       
  2553 // -----------------------------------------------------------------------------
       
  2554 // CNssVasDb::FillContextListArrayL
       
  2555 // Utility function to read contexts from DB to memory. Earlier, the caller has
       
  2556 // run an SQL query and the matches are listed in an RDbView.
       
  2557 // -----------------------------------------------------------------------------
       
  2558 //
       
  2559 void CNssVasDb::FillContextListArrayL( RDbView& aView, CArrayPtrFlat<CNssContext>& aContextList )
       
  2560     {
       
  2561     RUBY_DEBUG_BLOCK("CNssVasDb::FillContextListArrayL");
       
  2562 	TInt pos( 0 );
       
  2563 
       
  2564 	// Clear the previous array.
       
  2565 	aContextList.Reset();
       
  2566 
       
  2567     // Get column set
       
  2568     CDbColSet* columns = aView.ColSetL();
       
  2569 
       
  2570     // Get column ordinals
       
  2571     TDbColNo name_col       = columns->ColNo( KNameCol );
       
  2572     TDbColNo global_col     = columns->ColNo( KGlobalCol );
       
  2573 	TDbColNo grammarid_col  = columns->ColNo( KGrammarIdCol );
       
  2574 	TDbColNo lexiconid_col  = columns->ColNo( KLexiconIdCol );
       
  2575 	TDbColNo modelbankid_col= columns->ColNo( KModelBankIdCol );
       
  2576 	TDbColNo contextid_col  = columns->ColNo( KContextIdCol );
       
  2577 
       
  2578     // New in 2.8
       
  2579     TDbColNo clientdata_col = columns->ColNo( KClientDataCol );
       
  2580 
       
  2581 	delete columns;
       
  2582 
       
  2583 	for (aView.FirstL(); aView.AtRow(); aView.NextL())
       
  2584 	    {
       
  2585 	    aView.GetL(); // Retrieve the current row - actually reads the row from the database.
       
  2586        
       
  2587         CNssContext* oneContext = iContextBuilder.CreateContextL();
       
  2588         CleanupStack::PushL( oneContext );
       
  2589        
       
  2590         oneContext->SetNameL( aView.ColDes( name_col ) );
       
  2591         oneContext->SetGlobal( aView.ColUint32( global_col ) );
       
  2592         oneContext->SetContextId( aView.ColUint32( contextid_col ) );
       
  2593         oneContext->SetLexiconId( aView.ColUint32( lexiconid_col ) );
       
  2594         oneContext->SetGrammarId( aView.ColUint32( grammarid_col ) );
       
  2595         oneContext->SetModelBankId( aView.ColUint32( modelbankid_col ) );
       
  2596         oneContext->SetClientData( aView.ColDes8( clientdata_col ) );
       
  2597        
       
  2598 	    // Now add the context object to the list (array) of context.
       
  2599 	    aContextList.InsertL( pos++, oneContext );
       
  2600 	   
       
  2601 	    // Copy has been created in aContextList, no need for pointer anymore
       
  2602 	    CleanupStack::Pop( oneContext );
       
  2603 	    }
       
  2604 }
       
  2605 
       
  2606 // -----------------------------------------------------------------------------
       
  2607 // CNssVasDb::StartTransactionL
       
  2608 // Starts a new transaction.
       
  2609 // -----------------------------------------------------------------------------
       
  2610 //
       
  2611 TInt CNssVasDb::StartTransaction()
       
  2612     {
       
  2613     RUBY_DEBUG0( "CNssVasDb::StartTransaction" );
       
  2614     
       
  2615     if ( !iClientHasOpenedDatabase )
       
  2616         {
       
  2617         RUBY_DEBUG0( "No open DB. E.g. backup/restore in progress" );
       
  2618         return KErrNotReady;
       
  2619         }
       
  2620 
       
  2621     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2622     
       
  2623     iCriticalSection.Wait();
       
  2624     if ( iLocked )
       
  2625         {
       
  2626         // If we already have the lock, no need to take it again
       
  2627         RUBY_DEBUG0( "CNssVasDb::StartTransaction DB is already locked by current process" );
       
  2628         return KErrNone;
       
  2629         }
       
  2630 
       
  2631     // Wait for the mutex so that two processes don't try get the lock simultaneously
       
  2632     RUBY_DEBUG0( "Waiting for mutex in CNssVasDb::StartTransaction" );
       
  2633     iMutex.Wait();
       
  2634     
       
  2635     // check if backup is ongoing
       
  2636 	    
       
  2637     TInt readLockErr = iDatabase.Begin();
       
  2638 
       
  2639     // Mutex should make it sure that we have exclusive lock to Database
       
  2640     // Thus iDatabase.Begin() should succeed every time
       
  2641     __ASSERT_DEBUG( readLockErr == KErrNone, User::Panic( KVasDbPanic, __LINE__ ) );
       
  2642    
       
  2643     if ( readLockErr == KErrNone )
       
  2644         {
       
  2645         iLocked = ETrue;
       
  2646         }
       
  2647 
       
  2648     RUBY_DEBUG0( "CNssVasDb::StartTransaction completed" );        
       
  2649         
       
  2650     return readLockErr;
       
  2651     }
       
  2652 
       
  2653 // -----------------------------------------------------------------------------
       
  2654 // CNssVasDb::CommitTransaction
       
  2655 // Commits changes and releases the lock. If iShouldBeLocked flag is set,
       
  2656 // opens a new tranaction in order to keep the database locked.
       
  2657 // -----------------------------------------------------------------------------
       
  2658 //
       
  2659 TInt CNssVasDb::CommitTransaction( TBool aCompact )
       
  2660     {
       
  2661     RUBY_DEBUG0( "CNssVasDb::CommitTransaction" );
       
  2662 
       
  2663     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2664     //__ASSERT_DEBUG( iLocked, User::Panic( _L("VasCNssVasDb.cpp"), __LINE__ ) );
       
  2665 
       
  2666     TInt ret = KErrNone;
       
  2667 
       
  2668     if ( iLocked )
       
  2669         {
       
  2670         ret = iDatabase.Commit();
       
  2671         
       
  2672         if ( iDatabase.IsDamaged() )
       
  2673             {
       
  2674             RUBY_DEBUG0( "CNssVasDb::CommitTransaction Recovering" );
       
  2675             ret = iDatabase.Recover();
       
  2676             }
       
  2677         
       
  2678         if ( aCompact )
       
  2679             {
       
  2680             RUBY_DEBUG0( "CNssVasDb::CommitTransaction compacting DB" );
       
  2681             iDatabase.Compact(); 
       
  2682             }
       
  2683         
       
  2684         iLocked = EFalse;
       
  2685         
       
  2686         RUBY_DEBUG0( "Signalling mutex in CNssVasDb::CommitTransaction" );
       
  2687         iMutex.Signal();
       
  2688         }
       
  2689     else
       
  2690         {
       
  2691         RUBY_DEBUG0( "ERROR: CNssVasDb::CommitTransaction does nothing, not locked" );
       
  2692         }
       
  2693         
       
  2694     iCriticalSection.Signal();
       
  2695     return( ret );
       
  2696     }
       
  2697 
       
  2698 // -----------------------------------------------------------------------------
       
  2699 // CNssVasDb::RollbackTransaction
       
  2700 // Discards changes and releases the lock.
       
  2701 // -----------------------------------------------------------------------------
       
  2702 //
       
  2703 TInt CNssVasDb::RollbackTransaction()
       
  2704     {
       
  2705     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2706     __ASSERT_DEBUG( iLocked, User::Panic( KVasDbPanic, __LINE__ ) );
       
  2707 
       
  2708     TInt ret = KErrNone;
       
  2709 
       
  2710     iDatabase.Rollback();
       
  2711     
       
  2712     iLocked = EFalse;
       
  2713     
       
  2714     if ( iDatabase.IsDamaged() )
       
  2715         {
       
  2716         RUBY_DEBUG0( "CNssVasDb::RollbackTransaction Recovering" );
       
  2717         ret = iDatabase.Recover();
       
  2718         }
       
  2719 
       
  2720 
       
  2721     RUBY_DEBUG0( "Signalling mutex in CNssVasDb::RollbackTransaction" );
       
  2722     iMutex.Signal();
       
  2723     iCriticalSection.Signal();
       
  2724     
       
  2725     return( ret );
       
  2726     }
       
  2727     
       
  2728 
       
  2729 // -----------------------------------------------------------------------------
       
  2730 // CNssVasDb::LockTransactionsL
       
  2731 // Permit transactions and release database
       
  2732 // -----------------------------------------------------------------------------
       
  2733 //
       
  2734 void CNssVasDb::LockTransactionsL()
       
  2735     {
       
  2736     // lock transactions
       
  2737     RUBY_DEBUG_BLOCK( "CNssVasDb::LockTransactionsL" );
       
  2738     
       
  2739     iCriticalSection.Wait(); // wait until a possible transaction ends
       
  2740             
       
  2741     // release a database
       
  2742     CloseDatabase();
       
  2743     }
       
  2744 
       
  2745 // -----------------------------------------------------------------------------
       
  2746 // CNssVasDb::UnlockTransactionsL
       
  2747 // Allow transactions and reserve database
       
  2748 // -----------------------------------------------------------------------------
       
  2749 //
       
  2750 void CNssVasDb::UnlockTransactionsL()
       
  2751     {
       
  2752     // unlock transactions
       
  2753     RUBY_DEBUG_BLOCK( "CNssVasDb::UnlockTransactionsL" );
       
  2754     OpenDatabaseL(); // open database
       
  2755     
       
  2756     if ( iCriticalSection.IsBlocked() )
       
  2757         {        
       
  2758         iCriticalSection.Signal(); // allow to do transactions
       
  2759         }
       
  2760     }
       
  2761     	
       
  2762 // -----------------------------------------------------------------------------
       
  2763 // CNssVasDb::ReserveDiskSpaceL(
       
  2764 // Reserves disk space. Leaves (KErrDiskFull), if not
       
  2765 // enough space.
       
  2766 // -----------------------------------------------------------------------------
       
  2767 //
       
  2768 void CNssVasDb::ReserveDiskSpaceL( TInt aRequestSize )
       
  2769     {
       
  2770     RUBY_DEBUG_BLOCK( "CNssVasDb::ReserveDiskSpaceL" );
       
  2771 
       
  2772 #ifdef _DEBUG
       
  2773     TInt error = iDbSession.ReserveDriveSpace( iDrive, aRequestSize );
       
  2774     if ( error )
       
  2775         {
       
  2776         RUBY_DEBUG1( "CNssVasDb::ReserveDiskSpaceL fails %d", error );
       
  2777         User::Leave( error );
       
  2778         }
       
  2779 #else
       
  2780     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, aRequestSize ) );
       
  2781 #endif // _DEBUG
       
  2782     }
       
  2783 
       
  2784 
       
  2785 // -----------------------------------------------------------------------------
       
  2786 // CNssVasDb::ReleaseDiskSpace
       
  2787 // Releases the disk space
       
  2788 // -----------------------------------------------------------------------------
       
  2789 //
       
  2790 void CNssVasDb::ReleaseDiskSpace()
       
  2791     {
       
  2792     RUBY_DEBUG0( "CNssVasDb::ReleaseDiskSpace" );
       
  2793     iDbSession.FreeReservedSpace( iDrive );
       
  2794     }
       
  2795 
       
  2796 // -----------------------------------------------------------------------------
       
  2797 // CNssVasDb::CreateRollbackItemLC
       
  2798 // Creates a cleanup item and pushes it to the cleanup stack. In case of a 
       
  2799 // leave, PopAndDestroying this item will call RollbackCleanupFunction
       
  2800 // -----------------------------------------------------------------------------
       
  2801 void CNssVasDb::CreatePushRollbackItemLC() 
       
  2802     {
       
  2803     TCleanupItem item( RollbackCleanupFunction, this );
       
  2804     CleanupStack::PushL( item );
       
  2805     }
       
  2806 
       
  2807 // End of file