srsf/nssvasapi/nssvasdb/src/nssvascvasdb.cpp
branchRCL_3
changeset 19 e36f3802f733
equal deleted inserted replaced
18:cad71a31b7fc 19:e36f3802f733
       
     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 	CleanupClosePushL( aTagIdArray );
       
   845 
       
   846     TInt k( 0 );
       
   847     TInt error( KErrNone );
       
   848 
       
   849     if ( !iClientHasOpenedDatabase )
       
   850         {
       
   851         User::Leave( KErrDbNotSet );
       
   852         }
       
   853 
       
   854     // Locks the database for the use of this process only	
       
   855     User::LeaveIfError( StartTransaction() );
       
   856 
       
   857     CreatePushRollbackItemLC(); // Stack: rollback cleanup
       
   858 
       
   859     RArray<TInt> contextIds;
       
   860     CleanupClosePushL( contextIds ); // Stack: rollback cleanup, contextIds
       
   861 
       
   862     for ( k = 0; k < aTagArray->Count(); k++ )
       
   863         {
       
   864         CNssTag* tag = (*aTagArray)[k];
       
   865         CNssContext* context = static_cast<CNssContext*> ( tag->Context() );
       
   866 
       
   867         if ( contextIds.Find( context->ContextId() ) == KErrNotFound )
       
   868             {
       
   869             TInt contextId;
       
   870             TRAP( error, SaveContextL( context, contextId ) );
       
   871 
       
   872             // We accept leaves with error KErrAlreadyExists
       
   873             if ( error != KErrNone && error != KErrAlreadyExists )
       
   874                 {
       
   875                 break;
       
   876                 }
       
   877 
       
   878             contextIds.Append( context->ContextId() );
       
   879             }
       
   880         }
       
   881 
       
   882     // Close context id array
       
   883     CleanupStack::PopAndDestroy( &contextIds ); // Stack: Rollback cleanup
       
   884 
       
   885     // We accept leaves with error KErrAlreadyExists
       
   886     if ( error != KErrNone && error != KErrAlreadyExists )
       
   887         {
       
   888         User::Leave( error );
       
   889         }
       
   890 
       
   891     TInt id;
       
   892     for ( k = 0; k < aTagArray->Count(); k++ )
       
   893         {
       
   894         CNssTag* tag = (*aTagArray)[k];
       
   895 
       
   896         if ( tag->TagId() == KNssVASDbDefaultValue )
       
   897             {
       
   898             SaveTagL( tag, id );
       
   899 
       
   900             CNssRRD* rrd = static_cast<CNssRRD*>( tag->RRD() );
       
   901             rrd->SetTagId( id );
       
   902 
       
   903 	        SaveRRDL( rrd );
       
   904             User::LeaveIfError( aTagIdArray.Append( id ) );
       
   905             }
       
   906         else{
       
   907             UpdateTagInTransactionL( *tag );
       
   908             User::LeaveIfError( aTagIdArray.Append( tag->TagId() ) );
       
   909             }
       
   910         }
       
   911 
       
   912     User::LeaveIfError( CommitTransaction( ETrue ) );
       
   913 
       
   914     // Pop rollback cleanup
       
   915     // (which would have made database rollback, if a leave had happened)
       
   916     CleanupStack::Pop();  // Rollback cleanup item
       
   917 	CleanupStack::Pop();
       
   918     }
       
   919 
       
   920 // ---------------------------------------------------------
       
   921 // CNssVasDb::DeleteTagsL
       
   922 // Deletes several tags in one commit.
       
   923 // ---------------------------------------------------------
       
   924 //
       
   925 void CNssVasDb::DeleteTagsL( const RArray<TUint32>& aTagIdArray )
       
   926     {
       
   927     TInt k( 0 );
       
   928    
       
   929     if ( !iClientHasOpenedDatabase )
       
   930         {
       
   931         User::Leave( KErrDbNotSet );
       
   932         }
       
   933 
       
   934     // Locks the database for the use of this process only	
       
   935     User::LeaveIfError( StartTransaction() );
       
   936 
       
   937     CreatePushRollbackItemLC();
       
   938 
       
   939     for ( k = 0; k < aTagIdArray.Count(); k++ )
       
   940         {
       
   941         DeleteTagInsideTransactionL( aTagIdArray[k] );
       
   942         }
       
   943 
       
   944     User::LeaveIfError( CommitTransaction( ETrue ) );
       
   945 
       
   946     // Pop rollback cleanup
       
   947     // (which would have made database rollback, if a leave had happened)
       
   948     CleanupStack::Pop();  // Rollback cleanup item
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // CNssVasDb::UpdateTagL
       
   953 // Updates the data of an existing tag.
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 void CNssVasDb::UpdateTagL( CNssTag& aTag )
       
   957     {
       
   958     RUBY_DEBUG_BLOCK( "CNssVasDb::UpdateTagL" );	
       
   959 
       
   960     if ( !iClientHasOpenedDatabase )
       
   961         {
       
   962         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
   963         
       
   964         User::Leave( KErrNotReady );
       
   965         }
       
   966 	
       
   967     // Locks the database for the use of this process only
       
   968     User::LeaveIfError( StartTransaction() );
       
   969 
       
   970     TRAPD( error, UpdateTagInTransactionL( aTag ) );
       
   971 
       
   972     CommitIfSuccess( iDatabase, error, ETrue );
       
   973 
       
   974     User::LeaveIfError( error );
       
   975     }
       
   976 
       
   977 
       
   978 // -----------------------------------------------------------------------------
       
   979 // CNssVasDb::UpdateTagRuleIDs
       
   980 // Changes the Rule IDs of some tags. The Rule ID changes, when
       
   981 // and already trained tags is retrained.
       
   982 // -----------------------------------------------------------------------------
       
   983 //
       
   984 void CNssVasDb::UpdateTagRuleIDsL( const RArray<TNssSpeechItem>& aRetrainedTags )
       
   985     {
       
   986     TInt error( KErrNone );
       
   987     if ( !iClientHasOpenedDatabase )
       
   988         {
       
   989         User::Leave( KErrDbNotSet );
       
   990         }
       
   991    
       
   992     _LIT( KSQLUpdateTag,"update tagtable set ");
       
   993     _LIT( KEqual,"=");
       
   994     _LIT( KSQLWhereTagIdIs," where tagid = ");
       
   995 
       
   996     TInt count = aRetrainedTags.Count();
       
   997 
       
   998     if ( count > 0 )
       
   999         {
       
  1000         return;
       
  1001         }
       
  1002 
       
  1003     // Start transaction
       
  1004     User::LeaveIfError( StartTransaction() );
       
  1005     CreatePushRollbackItemLC();
       
  1006 
       
  1007     // Make the changes to Rule IDs
       
  1008     for ( TInt k( 0 ); k < count; k++ )
       
  1009         {
       
  1010         // "update tagtable set "
       
  1011         iSQLStatement = KSQLUpdateTag;
       
  1012 
       
  1013         // "ruleid=1234"
       
  1014         iSQLStatement.Append( KRuleIdCol );
       
  1015         iSQLStatement.Append( KEqual );
       
  1016         iSQLStatement.AppendNumUC( aRetrainedTags[k].iRuleId );
       
  1017 
       
  1018         // " where tagid = 5678"
       
  1019         iSQLStatement.Append( KSQLWhereTagIdIs );
       
  1020         iSQLStatement.AppendNumUC( aRetrainedTags[k].iTagId );
       
  1021 
       
  1022         error =  iDatabase.Execute( iSQLStatement );
       
  1023         if ( error < KErrNone )
       
  1024             {
       
  1025             ReleaseDiskSpace();
       
  1026             User::Leave( error );
       
  1027             }
       
  1028         }
       
  1029 
       
  1030     // Commit transaction
       
  1031     error = CommitTransaction( ETrue );
       
  1032     if ( error )
       
  1033         {
       
  1034         ReleaseDiskSpace();
       
  1035         User::Leave( error );
       
  1036         }
       
  1037 
       
  1038     // Pop rollback cleanup object
       
  1039     CleanupStack::Pop();  // Rollback cleanup item
       
  1040 
       
  1041     ReleaseDiskSpace();    
       
  1042     }
       
  1043 
       
  1044 
       
  1045 // -----------------------------------------------------------------------------
       
  1046 // CNssVasDb::SaveContextL
       
  1047 // Saves a newly created context. When a context is saved, a Context ID is
       
  1048 // assigned to it. This id is returned using the reference parameter.
       
  1049 // -----------------------------------------------------------------------------
       
  1050 //
       
  1051 void CNssVasDb::SaveContextL( CNssContext* aContext, TInt& aContextId )
       
  1052     {
       
  1053     TBuf<KNssVasDbContextName> name;
       
  1054     RDbView view1;
       
  1055 
       
  1056     _LIT( KSQLAdd, "select * from contexttable " );
       
  1057     _LIT( KSQLWhereName, "where name='" );
       
  1058     _LIT( KTick, "' " );
       
  1059 
       
  1060     //Check to see if a context already exist with the new name
       
  1061     iSQLStatement = KSQLAdd;
       
  1062     iSQLStatement.Append( KSQLWhereName );
       
  1063     iSQLStatement.Append( aContext->ContextName() );
       
  1064     iSQLStatement.Append( KTick );
       
  1065 	
       
  1066     CleanupClosePushL( view1 );
       
  1067    
       
  1068     User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );	
       
  1069     User::LeaveIfError( view1.EvaluateAll() );
       
  1070 
       
  1071     if ( !view1.IsEmptyL() ) // context with that name already exist so return status
       
  1072         {  
       
  1073         // Get column set
       
  1074         CDbColSet* columns1 = view1.ColSetL();
       
  1075         TDbColNo contextid_col = columns1->ColNo( KContextIdCol );
       
  1076 
       
  1077 	    delete columns1;
       
  1078 
       
  1079         view1.FirstL();
       
  1080         view1.GetL();
       
  1081 	    //Get the  unique contextid key just generated
       
  1082 	    aContextId = view1.ColUint32(contextid_col);
       
  1083 	    aContext->SetContextId( aContextId );
       
  1084 
       
  1085 	    view1.Close();	  
       
  1086 	    CleanupStack::PopAndDestroy( &view1 );
       
  1087         
       
  1088         User::Leave( KErrAlreadyExists );
       
  1089         }
       
  1090     else{
       
  1091         view1.Close();
       
  1092 	    CleanupStack::PopAndDestroy( &view1 );
       
  1093 	   
       
  1094 	    RDbView view2;
       
  1095 
       
  1096         CleanupClosePushL( view2 );
       
  1097 
       
  1098 	    User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery(KSQLAdd,EDbCompareNormal)));	
       
  1099         User::LeaveIfError( view2.EvaluateAll() );
       
  1100   
       
  1101 	    // Get column set
       
  1102         CDbColSet* columns = view2.ColSetL();
       
  1103         // Get column ordinals
       
  1104         TDbColNo name_col = columns->ColNo( KNameCol );
       
  1105         TDbColNo global_col = columns->ColNo( KGlobalCol );
       
  1106 	    TDbColNo grammarid_col = columns->ColNo( KGrammarIdCol );
       
  1107 	    TDbColNo lexiconid_col = columns->ColNo( KLexiconIdCol );
       
  1108 	    TDbColNo modelbankid_col = columns->ColNo( KModelBankIdCol );
       
  1109 	    TDbColNo contextid_col = columns->ColNo( KContextIdCol );
       
  1110 
       
  1111 	    delete columns;
       
  1112 
       
  1113 	    // Begin process of inserting a row...
       
  1114 	    view2.InsertL();
       
  1115 	    // set column values...
       
  1116 	    view2.SetColL( name_col, aContext->ContextName() );
       
  1117 	    view2.SetColL( global_col, aContext->IsGlobal() );
       
  1118 	    view2.SetColL( lexiconid_col, aContext->LexiconId() );
       
  1119 	    view2.SetColL( grammarid_col, aContext->GrammarId() );
       
  1120 	    view2.SetColL( modelbankid_col, aContext->ModelBankId() );
       
  1121 	
       
  1122 	    // add the row to the table...
       
  1123 	    view2.PutL();
       
  1124 	             
       
  1125 	    view2.GetL();
       
  1126         //Get the  unique contextid key just generated
       
  1127 	    aContextId = view2.ColUint32( contextid_col );
       
  1128 
       
  1129 	    aContext->SetContextId( aContextId );
       
  1130 
       
  1131 	    name = view2.ColDes( name_col );
       
  1132 	  
       
  1133 	    view2.Close();
       
  1134 	    CleanupStack::PopAndDestroy( &view2 );
       
  1135         }
       
  1136     }
       
  1137 
       
  1138 // -----------------------------------------------------------------------------
       
  1139 // CNssVasDb::SaveTagL
       
  1140 // Saves a newly created tag. When a tag is saved, a Tag ID is assigned to it.
       
  1141 // This id is returned using the reference parameter.
       
  1142 // -----------------------------------------------------------------------------
       
  1143 //
       
  1144 void CNssVasDb::SaveTagL( CNssTag* aTag, TInt& aNewId )
       
  1145     {
       
  1146 	RDbView view;
       
  1147  
       
  1148     _LIT( KSQLGet,"select * from tagtable");
       
  1149 	
       
  1150 	CleanupClosePushL(view);
       
  1151 
       
  1152 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery(KSQLGet,EDbCompareNormal)));	
       
  1153 	User::LeaveIfError( view.EvaluateAll());
       
  1154     
       
  1155 	// Get column set
       
  1156     CDbColSet* columns = view.ColSetL();
       
  1157     // Get column ordinals
       
  1158     TDbColNo name_col           = columns->ColNo( KNameCol );
       
  1159 	TDbColNo tagid_col          = columns->ColNo( KTagIdCol );
       
  1160 	TDbColNo contextid_col      = columns->ColNo( KContextIdCol );
       
  1161 	TDbColNo ruleid_col         = columns->ColNo( KRuleIdCol );
       
  1162 
       
  1163 	delete columns;
       
  1164 	  
       
  1165 	// Begin process of inserting a row...
       
  1166 	view.InsertL();
       
  1167 	// set column values...
       
  1168 	
       
  1169 	CNssContext* context = static_cast<CNssContext*> ( aTag->Context() );
       
  1170 	CNssSpeechItem* speechItem = static_cast<CNssSpeechItem*> ( aTag->SpeechItem() );
       
  1171 	
       
  1172 	#ifdef __SIND_EXTENSIONS
       
  1173 	    view.SetColL( name_col, aTag->SpeechItem()->RawText() ); 
       
  1174 	#else
       
  1175 	    view.SetColL( name_col, aTag->SpeechItem()->Text() ); 
       
  1176 	#endif  // __SIND_EXTENSIONS
       
  1177 	view.SetColL( contextid_col, context->ContextId() );
       
  1178 	view.SetColL( ruleid_col, speechItem->RuleID() );
       
  1179 	
       
  1180 	// add the row to the table...
       
  1181 	view.PutL();
       
  1182 
       
  1183     aNewId = view.ColUint32( tagid_col );
       
  1184 
       
  1185 	// finished - so close the view
       
  1186 	view.Close();
       
  1187 	CleanupStack::PopAndDestroy( &view );
       
  1188     }
       
  1189 
       
  1190 
       
  1191 // -----------------------------------------------------------------------------
       
  1192 // CNssVasDb::SaveRRDL
       
  1193 // Reads RRD from DB to memory. Utility function when reading tags.
       
  1194 // -----------------------------------------------------------------------------
       
  1195 //
       
  1196 void CNssVasDb::SaveRRDL( CNssRRD* aRRD )
       
  1197     {
       
  1198     TInt position;
       
  1199 	RDbView view1,view2;
       
  1200    
       
  1201 	_LIT( KSQLAddRRDText, "select * from rrdtexttable");
       
  1202 	_LIT( KSQLAddRRDId,   "select * from rrdinttable");
       
  1203 	
       
  1204     // Save the integer array, if we have one.
       
  1205     if ( aRRD->IntArray() )
       
  1206         {
       
  1207 	    CleanupClosePushL(view1);
       
  1208 	
       
  1209 	    User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( KSQLAddRRDId, EDbCompareNormal ) ) );	
       
  1210 	    User::LeaveIfError( view1.EvaluateAll());
       
  1211 
       
  1212 	    // Get column set	
       
  1213         CDbColSet* columns1 = view1.ColSetL();
       
  1214         // Get column ordinals
       
  1215         TDbColNo tagid_col           = columns1->ColNo( KTagIdCol );
       
  1216 	    TDbColNo rrdint_col          = columns1->ColNo( KRRDIntCol );
       
  1217         TDbColNo rrdposition_col1    = columns1->ColNo( KRRDPositionCol );
       
  1218 
       
  1219 	    delete columns1;
       
  1220 
       
  1221 	    // Begin process of inserting a row...
       
  1222 	    // set column values for id table...
       
  1223         for( position=0; position<aRRD->IntArray()->Count(); position++ )
       
  1224             {
       
  1225 	        view1.InsertL();
       
  1226 	        view1.SetColL( tagid_col,aRRD->TagId() );
       
  1227 	        view1.SetColL(rrdint_col,aRRD->IntArray()->At( position ) );
       
  1228 	        view1.SetColL(rrdposition_col1,position);
       
  1229 	        // add the row to the table...
       
  1230 	        view1.PutL();	   
       
  1231 	        }	
       
  1232 	
       
  1233 	    // finished - so close the view
       
  1234 	    view1.Close(); 	
       
  1235 	    CleanupStack::PopAndDestroy( &view1 );
       
  1236         }
       
  1237 
       
  1238     // Save the text array, if we have one
       
  1239     if ( aRRD->TextArray() )
       
  1240         {
       
  1241 	    CleanupClosePushL( view2 );
       
  1242 
       
  1243         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1244                             TDbQuery( KSQLAddRRDText, EDbCompareNormal ) ) );	
       
  1245 	    User::LeaveIfError( view2.EvaluateAll() );
       
  1246     
       
  1247         // Get column set
       
  1248         CDbColSet* columns2 = view2.ColSetL();
       
  1249         // Get column ordinals
       
  1250         TDbColNo tagid_col2       = columns2->ColNo( KTagIdCol );
       
  1251 	    TDbColNo rrdtext_col2     = columns2->ColNo( KRRDTextCol );
       
  1252         TDbColNo rrdposition_col2 = columns2->ColNo( KRRDPositionCol );
       
  1253 
       
  1254 	    delete columns2;
       
  1255 
       
  1256 	    //set colum values for text table
       
  1257 	    for( position = 0; position < aRRD->TextArray()->Count(); position++ )
       
  1258             {
       
  1259 	        view2.InsertL();
       
  1260 	        view2.SetColL( tagid_col2, aRRD->TagId() );
       
  1261 	        view2.SetColL( rrdtext_col2, aRRD->TextArray()->At( position ) );
       
  1262 	        view2.SetColL( rrdposition_col2, position );
       
  1263 	        view2.PutL();	   
       
  1264             }	
       
  1265 	    // add the row to the table...
       
  1266 	
       
  1267 	    // finished - so close the view
       
  1268 	    view2.Close();  
       
  1269 	    CleanupStack::PopAndDestroy( &view2 );
       
  1270         }
       
  1271     }
       
  1272 
       
  1273 // -----------------------------------------------------------------------------
       
  1274 // CNssVasDb::FillRRDL
       
  1275 // Reads RRD from DB to memory. Utility function when reading tags.
       
  1276 // -----------------------------------------------------------------------------
       
  1277 //
       
  1278 void CNssVasDb::FillRRDL( TUint32 aTagId, CNssRRD& aRRD )
       
  1279     {
       
  1280     RUBY_DEBUG_BLOCK( "CNssVasDb::FillRRDL" );
       
  1281     
       
  1282     TInt position;
       
  1283 	RDbView view1,view2;
       
  1284 
       
  1285 	_LIT( KSQLAddRRDText, "select * from rrdtexttable ");
       
  1286 	_LIT( KSQLAddRRDId,   "select * from rrdinttable ");
       
  1287 	_LIT( KSQLWhereTagId,"where tagid=");
       
  1288 
       
  1289 	iSQLStatement = KSQLAddRRDId;
       
  1290 	iSQLStatement.Append( KSQLWhereTagId );
       
  1291 	iSQLStatement.AppendNumUC( aTagId );
       
  1292 
       
  1293 	CleanupClosePushL(view1);
       
  1294 
       
  1295 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1296 	User::LeaveIfError( view1.EvaluateAll());
       
  1297 
       
  1298 	// Get column set
       
  1299     CDbColSet* columns1 = view1.ColSetL();
       
  1300     // Get column ordinals
       
  1301     TDbColNo tagid_col           = columns1->ColNo( KTagIdCol );
       
  1302 	TDbColNo rrdint_col          = columns1->ColNo( KRRDIntCol );
       
  1303     TDbColNo rrdposition_col1    = columns1->ColNo( KRRDPositionCol );
       
  1304 	// Cleanup column1 set
       
  1305 	delete columns1;
       
  1306 
       
  1307 	// Begin process of inserting a row...
       
  1308 	TInt intarraysize = view1.CountL();
       
  1309     if ( intarraysize > 0 )
       
  1310         {
       
  1311         CArrayFixFlat<TInt>* intArray = new (ELeave) CArrayFixFlat<TInt>(intarraysize);
       
  1312         CleanupStack::PushL( intArray );
       
  1313         intArray->ResizeL( intarraysize );
       
  1314         
       
  1315         // set column values for id table...
       
  1316         for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1317             {
       
  1318             view1.GetL();
       
  1319             aRRD.SetTagId( view1.ColUint32( tagid_col ) );
       
  1320             position = view1.ColUint32( rrdposition_col1 );
       
  1321             if ( position < 0 || position >= intarraysize )
       
  1322                 {
       
  1323                 RUBY_ERROR2("CNssVasDb::FillRRDL position out of bounds. 0 < %i < %i", 
       
  1324                     position, intarraysize );
       
  1325                 User::Leave( KErrCorrupt );
       
  1326                 }
       
  1327             intArray->At( position ) = view1.ColUint32( rrdint_col );
       
  1328             }
       
  1329 
       
  1330         aRRD.SetIntArrayL( intArray );
       
  1331         CleanupStack::Pop( intArray );
       
  1332         intArray->Reset();
       
  1333         delete intArray;
       
  1334         }
       
  1335     
       
  1336 	// finished - so close the view
       
  1337 	view1.Close();
       
  1338 	CleanupStack::PopAndDestroy( &view1 );
       
  1339  
       
  1340 	CleanupClosePushL(view2);
       
  1341 
       
  1342 	iSQLStatement = KSQLAddRRDText;
       
  1343 	iSQLStatement.Append( KSQLWhereTagId );
       
  1344 	iSQLStatement.AppendNumUC( aTagId );
       
  1345     User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1346 	User::LeaveIfError( view2.EvaluateAll() );
       
  1347     
       
  1348     // Get column set
       
  1349     CDbColSet* columns2 = view2.ColSetL();
       
  1350     // Get column ordinals
       
  1351     TDbColNo tagid_col2       = columns2->ColNo( KTagIdCol );
       
  1352 	TDbColNo rrdtext_col2     = columns2->ColNo( KRRDTextCol );
       
  1353     TDbColNo rrdposition_col2 = columns2->ColNo( KRRDPositionCol );
       
  1354    
       
  1355 	delete columns2;
       
  1356     
       
  1357 	TInt textarraysize = view2.CountL();
       
  1358     if ( textarraysize > 0 )
       
  1359         {
       
  1360         CArrayFixFlat<NssRRDText>* textArray = 
       
  1361                     new (ELeave) CArrayFixFlat<NssRRDText>(textarraysize);
       
  1362         CleanupStack::PushL( textArray );
       
  1363         textArray->ResizeL( textarraysize );
       
  1364 
       
  1365         //set colum values for text table
       
  1366         for ( view2.FirstL(); view2.AtRow(); view2.NextL() )
       
  1367             {
       
  1368             view2.GetL();
       
  1369             aRRD.SetTagId( view2.ColUint32( tagid_col2 ) );
       
  1370             position      = view2.ColUint32( rrdposition_col2 );
       
  1371             if ( position < 0 || position >= textarraysize )
       
  1372                 {
       
  1373                 RUBY_ERROR2("CNssVasDb::FillRRDL position out of bounds. 0 < %i < %i", 
       
  1374                     position, textarraysize );
       
  1375                 User::Leave( KErrCorrupt );
       
  1376                 }
       
  1377             textArray->At( position ) = view2.ColDes( rrdtext_col2 );
       
  1378             }	
       
  1379 
       
  1380         aRRD.SetTextArrayL( textArray );
       
  1381         CleanupStack::Pop( textArray );
       
  1382         textArray->Reset();
       
  1383         delete textArray;
       
  1384         }
       
  1385 
       
  1386 	// finished - so close the view
       
  1387 	view2.Close();
       
  1388         
       
  1389     CleanupStack::PopAndDestroy( &view2 );
       
  1390     }
       
  1391 
       
  1392 // -----------------------------------------------------------------------------
       
  1393 // CNssVasDb::GetTagL
       
  1394 // Gets a tag by grammar ID and rule ID.
       
  1395 // -----------------------------------------------------------------------------
       
  1396 //
       
  1397 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TNssGrammarIdRuleId aGrammarIdRuleId )
       
  1398     {
       
  1399 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1400 	CleanupStack::PushL( context );
       
  1401 	RDbView view;
       
  1402 
       
  1403     User::LeaveIfError( StartTransaction() );
       
  1404     CreatePushRollbackItemLC();
       
  1405 
       
  1406 	CleanupClosePushL(view);
       
  1407 
       
  1408 	_LIT( KSQLGetContext, "select * from contexttable where grammarid=");
       
  1409 	iSQLStatement.Copy(KSQLGetContext);
       
  1410 	iSQLStatement.AppendNumUC(aGrammarIdRuleId.iGrammarId);
       
  1411 
       
  1412     TDbQuery dbQuery(iSQLStatement, EDbCompareNormal);
       
  1413 	User::LeaveIfError( view.Prepare( iDatabase, dbQuery ) );
       
  1414 	User::LeaveIfError( view.EvaluateAll() );
       
  1415 
       
  1416 	view.FirstL(); 
       
  1417     FillContextL(view, *context);
       
  1418 
       
  1419 	_LIT( KSQLGetTag, "select * from tagtable where ruleid=");
       
  1420 	_LIT( KSQLAnd," and contextid=");
       
  1421 	iSQLStatement = KSQLGetTag;
       
  1422 	iSQLStatement.AppendNumUC( aGrammarIdRuleId.iRuleId );
       
  1423     iSQLStatement.Append( KSQLAnd );
       
  1424 	iSQLStatement.AppendNumUC( context->ContextId() );
       
  1425 
       
  1426     // Close view
       
  1427     CleanupStack::PopAndDestroy( &view );
       
  1428 
       
  1429     CArrayPtrFlat<CNssTag>* res = GetTagListByQueryL( iSQLStatement );
       
  1430 
       
  1431     // Pop rollback cleanup item
       
  1432     CleanupStack::Pop();  // Rollback cleanup item
       
  1433     CommitTransaction( EFalse );
       
  1434     
       
  1435     CleanupStack::PopAndDestroy( context );
       
  1436 
       
  1437     return( res );
       
  1438     }
       
  1439     
       
  1440 // -----------------------------------------------------------------------------
       
  1441 // CNssVasDb::GetTagsL
       
  1442 // Gets a list of tags by grammar ID and rule ID.
       
  1443 // -----------------------------------------------------------------------------
       
  1444 //
       
  1445 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagsL( TNssGrammarIdRuleIdListArray& aGrammarIdRuleIds )
       
  1446 	{
       
  1447 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1448 	CleanupStack::PushL( context );
       
  1449 	RDbView view;
       
  1450 
       
  1451     User::LeaveIfError( StartTransaction() );
       
  1452     CreatePushRollbackItemLC();
       
  1453 
       
  1454     Mem::FillZ( context,     sizeof(*context)   );
       
  1455 
       
  1456 	CleanupClosePushL(view);
       
  1457 	
       
  1458 	_LIT( KSQLGetContext, "select * from contexttable where ");
       
  1459 	_LIT( KGrammarIdParam, "grammarid=" );
       
  1460 	_LIT( KOr, " OR ");
       
  1461 	iSQLStatement.Copy(KSQLGetContext);
       
  1462 	
       
  1463 	for( TInt i = 0; i < aGrammarIdRuleIds.Count(); i++)
       
  1464 		{
       
  1465 		if( i !=0 )
       
  1466 			{
       
  1467 			iSQLStatement.Append(KOr);
       
  1468 			}
       
  1469 		iSQLStatement.Append(KGrammarIdParam);
       
  1470 		iSQLStatement.AppendNumUC(aGrammarIdRuleIds[i].iGrammarId);
       
  1471 		// same grammar ids usually appear, but that's ok and should not decrease performance
       
  1472 		}
       
  1473 		
       
  1474 	TDbQuery dbQuery(iSQLStatement, EDbCompareNormal);
       
  1475 	User::LeaveIfError( view.Prepare( iDatabase, dbQuery ));
       
  1476 	User::LeaveIfError( view.EvaluateAll());
       
  1477 	
       
  1478 	_LIT( KSQLGetTags, "select * from tagtable where (");
       
  1479 	_LIT( KRuleId, "ruleid=");
       
  1480 	_LIT( KContextId,"contextid=");
       
  1481 	_LIT( KBracketAnd, " AND (");
       
  1482 	_LIT( KBracketOr, ") OR (");
       
  1483 	_LIT( KFinalBracket, ")");
       
  1484 	
       
  1485 	// Get column set
       
  1486     CDbColSet* columns = view.ColSetL();
       
  1487 	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  1488 	TDbColNo grammarid_col= columns->ColNo( KGrammarIdCol );
       
  1489 	delete columns;
       
  1490 	TUint32 currContextId;
       
  1491 	TUint32 currGrammarId;
       
  1492 	TUint32 currRuleId;
       
  1493 	
       
  1494 	iSQLStatement = KSQLGetTags;
       
  1495 	TBool firstPair = ETrue;
       
  1496 	while( view.NextL())
       
  1497 		{
       
  1498 		view.GetL();
       
  1499 		// before each iteration, but first, we add ") OR ("
       
  1500 		if( firstPair )
       
  1501 			{
       
  1502 			firstPair = EFalse;
       
  1503 			}
       
  1504 		else 
       
  1505 			{
       
  1506 			iSQLStatement.Append(KBracketOr);
       
  1507 			}
       
  1508 		currContextId = view.ColUint32( contextid_col );
       
  1509 		currGrammarId = view.ColUint32( grammarid_col );
       
  1510 		iSQLStatement.Append( KContextId );
       
  1511 		iSQLStatement.AppendNumUC( currContextId );
       
  1512 		iSQLStatement.Append( KBracketAnd );
       
  1513 		// we need to find corresponding rule id
       
  1514 		TBool someGrammarFoundAlready = EFalse;
       
  1515 		for( TInt i=0; i<aGrammarIdRuleIds.Count(); i++)
       
  1516 			{
       
  1517 			if( currGrammarId == aGrammarIdRuleIds[i].iGrammarId )
       
  1518 				{
       
  1519 				if( someGrammarFoundAlready )
       
  1520 					{
       
  1521 					iSQLStatement.Append( KOr );
       
  1522 					}
       
  1523 				else 
       
  1524 					{
       
  1525 					someGrammarFoundAlready = ETrue;
       
  1526 					}
       
  1527 				currRuleId = aGrammarIdRuleIds[i].iRuleId;
       
  1528 				iSQLStatement.Append( KRuleId );
       
  1529 				iSQLStatement.AppendNumUC( currRuleId );	
       
  1530 				}
       
  1531 			}  // for
       
  1532 		iSQLStatement.Append(KFinalBracket);  // closing ruleid ORs
       
  1533 		}  // while
       
  1534 	// Close view
       
  1535     CleanupStack::PopAndDestroy( &view );
       
  1536     iSQLStatement.Append( KFinalBracket );
       
  1537     
       
  1538     CArrayPtrFlat<CNssTag>* res = GetTagListByQueryL( iSQLStatement );
       
  1539 
       
  1540     // Pop rollback cleanup item
       
  1541     CleanupStack::Pop();  // Rollback cleanup item
       
  1542     CommitTransaction( EFalse );
       
  1543 
       
  1544     CleanupStack::PopAndDestroy( context );
       
  1545 
       
  1546     return( res );
       
  1547 	}
       
  1548 
       
  1549 // -----------------------------------------------------------------------------
       
  1550 // CNssVasDb::GetTagListByQuery
       
  1551 // Executes the query and reads matches from DB to memory.
       
  1552 // -----------------------------------------------------------------------------
       
  1553 //
       
  1554 // -----------------------------------------------------------------------------
       
  1555 // CNssVasDb::GetTagListByQuery
       
  1556 // Executes the query and reads matches from DB to memory.
       
  1557 // -----------------------------------------------------------------------------
       
  1558 //
       
  1559 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagListByQueryL( const TDesC& aSqlQuery )
       
  1560     {
       
  1561     RUBY_DEBUG_BLOCK( "CNssVasDb::GetTagListByQueryL" );
       
  1562 
       
  1563     __ASSERT_DEBUG( aSqlQuery.Left(6).Compare( _L("select") ) == 0, User::Panic( KVasDbPanic, __LINE__ ) );
       
  1564 
       
  1565 	CNssContext* context = NULL;
       
  1566 	CNssSpeechItem* speechItem = NULL;
       
  1567 	CNssRRD* rrd = NULL;
       
  1568     TInt contextId = -1;
       
  1569 
       
  1570     // 'context' variable is the context of the previous tag.
       
  1571     // When a new tag is read, 'context' is updated only if context changes.
       
  1572     // Set the ID invalid value in order to force the first tag to read a context.
       
  1573     //context.iContextId = (TUint32)-1;
       
  1574     //context->SetContextId( -1 );
       
  1575 
       
  1576 	RDbView view;
       
  1577 	CleanupClosePushL( view );
       
  1578 
       
  1579     CArrayPtrFlat<CNssTag>* tagList = new(ELeave)CArrayPtrFlat<CNssTag>( KMaxTagArraySize );
       
  1580     CleanupStack::PushL( tagList );
       
  1581     CleanupResetAndDestroyPushL( *tagList );
       
  1582 
       
  1583 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( aSqlQuery, EDbCompareNormal ) ) );
       
  1584 	User::LeaveIfError( view.EvaluateAll() );
       
  1585 
       
  1586 	if ( !view.IsEmptyL() )
       
  1587 	    {
       
  1588    	    for (view.FirstL(); view.AtRow(); view.NextL())
       
  1589 	        {
       
  1590 	        context = iContextBuilder.CreateContextL();
       
  1591 	        CleanupStack::PushL( context );
       
  1592 	        
       
  1593 	        speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *context );
       
  1594 	        CleanupStack::PushL( speechItem );
       
  1595 	        
       
  1596             FillSpeechItemL( view, *speechItem, contextId );
       
  1597 
       
  1598             // Get context, if we haven't already done it.
       
  1599             if ( context->ContextId() != (TUint32)contextId )
       
  1600                 {                
       
  1601                 _LIT( KContextQuery, "select * from contexttable where contextid=" );
       
  1602 
       
  1603                 iSQLStatement.Copy( KContextQuery );
       
  1604                 iSQLStatement.AppendNumUC( contextId );
       
  1605 
       
  1606                 CArrayPtrFlat<CNssContext>* contextList = 
       
  1607                             GetContextInsideTransactionL( iSQLStatement );
       
  1608                 CleanupStack::PushL( contextList );
       
  1609 
       
  1610                 User::LeaveIfNull( contextList );
       
  1611 
       
  1612                 if ( contextList->Count() != 1 )
       
  1613                     {
       
  1614                     User::Leave( KErrCorrupt );
       
  1615                     }
       
  1616 
       
  1617                 CleanupStack::Pop( contextList );
       
  1618                 CleanupStack::PopAndDestroy( speechItem );                
       
  1619                 CleanupStack::PopAndDestroy( context );
       
  1620                 
       
  1621                 context = (*contextList)[0];                
       
  1622                 delete contextList;
       
  1623                 
       
  1624                 CleanupStack::PushL( context );
       
  1625                 
       
  1626 	            speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *context );
       
  1627 	            CleanupStack::PushL( speechItem );
       
  1628 	        	        
       
  1629                 FillSpeechItemL( view, *speechItem, contextId );
       
  1630                 }
       
  1631                 
       
  1632             rrd = CNssRRD::NewL();
       
  1633             CleanupStack::PushL( rrd );
       
  1634             
       
  1635             FillRRDL( speechItem->TagId(), *rrd );
       
  1636             
       
  1637             // Append tag to the array 
       
  1638             FillTagListArrayL( *tagList, context, speechItem, rrd );
       
  1639             CleanupStack::PopAndDestroy( rrd );
       
  1640             CleanupStack::PopAndDestroy( speechItem );
       
  1641             CleanupStack::PopAndDestroy( context );
       
  1642             }
       
  1643         }
       
  1644 	else
       
  1645 	    {
       
  1646         User::Leave( KErrNotFound );
       
  1647 	    }
       
  1648 
       
  1649 	CleanupStack::Pop( tagList );  // ResetAndDestroy
       
  1650     CleanupStack::Pop( tagList );  // array itself
       
  1651 	// Finished with the view - so close it.
       
  1652     CleanupStack::PopAndDestroy( &view );
       
  1653 
       
  1654     return tagList;
       
  1655     }
       
  1656     
       
  1657 // -----------------------------------------------------------------------------
       
  1658 // CNssVasDb::GetTagL
       
  1659 // Gets a tag by name.
       
  1660 // -----------------------------------------------------------------------------
       
  1661 //
       
  1662 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL(const TDesC& aName)
       
  1663     {
       
  1664     _LIT( KTick,"' ");
       
  1665 	_LIT( KSQLGetTag, "select * from tagtable where name='");
       
  1666 	
       
  1667 	iSQLStatement = KSQLGetTag;
       
  1668 	iSQLStatement.Append( aName );
       
  1669     iSQLStatement.Append( KTick );
       
  1670 
       
  1671     User::LeaveIfError( StartTransaction() );
       
  1672 
       
  1673     CArrayPtrFlat<CNssTag>* arr = GetTagListByQueryL( iSQLStatement );
       
  1674 
       
  1675     CommitTransaction( EFalse );
       
  1676 
       
  1677     return arr;
       
  1678     }
       
  1679 
       
  1680 // -----------------------------------------------------------------------------
       
  1681 // CNssVasDb::GetTagL
       
  1682 // Gets all tags from a specified context.
       
  1683 // -----------------------------------------------------------------------------
       
  1684 //
       
  1685 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( const CNssContext& aContext)
       
  1686     {
       
  1687     RDbView view;
       
  1688 
       
  1689     User::LeaveIfError( StartTransaction() );
       
  1690     CreatePushRollbackItemLC();
       
  1691 
       
  1692     CleanupClosePushL( view );
       
  1693 
       
  1694 	// Validate the context
       
  1695     _LIT( KSQLGetContext, "select * from contexttable where contextid=");
       
  1696 	iSQLStatement = KSQLGetContext;
       
  1697 	iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  1698 
       
  1699 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1700 	User::LeaveIfError( view.EvaluateAll() );
       
  1701 
       
  1702     if ( view.IsEmptyL() )
       
  1703 	    {
       
  1704         User::Leave( KErrNotFound );
       
  1705 	    }
       
  1706 
       
  1707 	// Finished with the view - so close it.
       
  1708     CleanupStack::PopAndDestroy( &view );
       
  1709 	
       
  1710 	_LIT( KSQLGetTag, "select * from tagtable where contextid=" );
       
  1711 	iSQLStatement.Copy( KSQLGetTag );
       
  1712 	iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  1713 
       
  1714     CArrayPtrFlat<CNssTag>* result = GetTagListByQueryL( iSQLStatement );
       
  1715 
       
  1716     // Transaction finished - free the transaction lock
       
  1717     CleanupStack::Pop();  // Rollback cleanup item
       
  1718     CommitTransaction( EFalse );
       
  1719 
       
  1720     return result;
       
  1721     }
       
  1722 
       
  1723 // -----------------------------------------------------------------------------
       
  1724 // CNssVasDb::GetTagListFromViewL
       
  1725 // Reads the tags from DB to memory and appends them to the array.
       
  1726 // Earlier, the caller has made an SQL query and placed the matches in RDbView.
       
  1727 // -----------------------------------------------------------------------------
       
  1728 //
       
  1729 void CNssVasDb::GetTagListFromViewL( RDbView& aView, CArrayPtrFlat<CNssTag>* aTagList, 
       
  1730                                      CNssContext* aContext )
       
  1731     {
       
  1732     TInt discardable( 0 );
       
  1733 
       
  1734 	for ( aView.FirstL(); aView.AtRow(); aView.NextL() )
       
  1735     	{
       
  1736     	CNssSpeechItem* speechItem = iSpeechItemBuilder.CreateEmptySpeechItemL( *aContext );
       
  1737     	CleanupStack::PushL( speechItem );
       
  1738     	
       
  1739 	    FillSpeechItemL( aView, *speechItem, discardable );
       
  1740 		CNssRRD* rrd = CNssRRD::NewL();
       
  1741 		CleanupStack::PushL( rrd );
       
  1742 		FillRRDL( speechItem->TagId(), *rrd );
       
  1743 		    
       
  1744 		FillTagListArrayL( *aTagList, aContext, speechItem, rrd );
       
  1745 		
       
  1746 		CleanupStack::PopAndDestroy( rrd );
       
  1747 		CleanupStack::PopAndDestroy( speechItem );
       
  1748 	    }
       
  1749     }
       
  1750 
       
  1751 // -----------------------------------------------------------------------------
       
  1752 // CNssVasDb::DeleteTagL
       
  1753 // Gets a list of tags by RRD data.
       
  1754 // -----------------------------------------------------------------------------
       
  1755 //
       
  1756 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TInt aContextId, TInt aNum, TInt aPosition )
       
  1757     {
       
  1758   	RDbView     view;
       
  1759 	TUint32     tagId;
       
  1760 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1761 	CleanupStack::PushL( context );
       
  1762 
       
  1763     User::LeaveIfError( StartTransaction() );
       
  1764     CreatePushRollbackItemLC();
       
  1765 
       
  1766     CArrayPtrFlat<CNssTag>* tagArray = new(ELeave)CArrayPtrFlat<CNssTag>(1);
       
  1767     CleanupStack::PushL( tagArray );
       
  1768     CleanupResetAndDestroyPushL( *tagArray );
       
  1769 
       
  1770     // Get the context based on ContextId
       
  1771   	CleanupClosePushL(view);
       
  1772 
       
  1773 	_LIT( KSQLGetContext, "select * from contexttable where contextid=" );
       
  1774 	iSQLStatement.Copy( KSQLGetContext );
       
  1775 	iSQLStatement.AppendNumUC( aContextId );
       
  1776 
       
  1777 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1778 	User::LeaveIfError( view.EvaluateAll() );
       
  1779 	view.FirstL();
       
  1780     view.GetL();
       
  1781 	TRAPD( error, FillContextL( view, *context ) );
       
  1782 	// Finished with the view - so close it.
       
  1783 	view.Close();
       
  1784 	CleanupStack::PopAndDestroy( &view );
       
  1785 
       
  1786     // If filling of the context failed, return with Not Found
       
  1787 	if ( error != KErrNone )
       
  1788 	    {
       
  1789         User::Leave( KErrNotFound );
       
  1790         }
       
  1791 
       
  1792     // Get the list of TagId from the RRD table based on Num and Position
       
  1793 	RDbView view1;
       
  1794 	CleanupClosePushL( view1 );
       
  1795 
       
  1796 	_LIT( KSQLGetRRDInt, "select * from rrdinttable where rrdposition=" );
       
  1797 	_LIT( KSQLAndRRDInt, " and rrdint=" );
       
  1798 	iSQLStatement = KSQLGetRRDInt;
       
  1799 	iSQLStatement.AppendNumUC( aPosition );
       
  1800 	iSQLStatement.Append( KSQLAndRRDInt );
       
  1801 	iSQLStatement.AppendNumUC( aNum );
       
  1802 
       
  1803 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1804 	User::LeaveIfError( view1.EvaluateAll() );
       
  1805 	
       
  1806 	if ( view1.IsEmptyL() )
       
  1807 	    {
       
  1808 
       
  1809         User::Leave( KErrNotFound );
       
  1810 	    }
       
  1811 
       
  1812     // Get column set
       
  1813     CDbColSet* columns = view1.ColSetL();
       
  1814     // Get column ordinals
       
  1815     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  1816     // Cleanup column set
       
  1817     delete columns;
       
  1818 
       
  1819     // Select the valid tagId from the list
       
  1820 	for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1821         {   
       
  1822         view1.GetL();
       
  1823         tagId = view1.ColUint32( tagid_col );
       
  1824 
       
  1825         // Get the SpeechItem based on the tagId and ContextId
       
  1826         RDbView view2;
       
  1827 		CleanupClosePushL( view2 );
       
  1828 
       
  1829         _LIT( KSQLGetSpeechItem, "select * from tagtable where tagid=" );
       
  1830         _LIT( KSQLAndContextId," and contextid=" );
       
  1831         iSQLStatement = KSQLGetSpeechItem;
       
  1832         iSQLStatement.AppendNumUC( tagId );
       
  1833 	    iSQLStatement.Append( KSQLAndContextId );
       
  1834         iSQLStatement.AppendNumUC( aContextId );
       
  1835 
       
  1836         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1837                             TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1838         User::LeaveIfError( view2.EvaluateAll() );
       
  1839     
       
  1840         if ( !view2.IsEmptyL() )
       
  1841 	        {
       
  1842             GetTagListFromViewL( view2, tagArray, context );
       
  1843 		    }
       
  1844         view2.Close();
       
  1845         CleanupStack::PopAndDestroy( &view2 );
       
  1846         }
       
  1847 
       
  1848     // close the view 1
       
  1849 	view1.Close();
       
  1850 	CleanupStack::PopAndDestroy( &view1 );
       
  1851 
       
  1852     CleanupStack::Pop( tagArray );  // ResetAndDestroy
       
  1853     CleanupStack::Pop( tagArray );  // array itself
       
  1854 
       
  1855     // Rollback cleanup
       
  1856     CleanupStack::Pop();  // Rollback cleanup item
       
  1857     CommitTransaction( EFalse );
       
  1858     
       
  1859     CleanupStack::PopAndDestroy( context );
       
  1860 
       
  1861     return tagArray;
       
  1862     }
       
  1863 
       
  1864 // -----------------------------------------------------------------------------
       
  1865 // CNssVasDb::DeleteTagL
       
  1866 // Gets a list of tags by RRD data.
       
  1867 // -----------------------------------------------------------------------------
       
  1868 //
       
  1869 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TInt aContextId, 
       
  1870                                             const TDesC& aText, TInt aPosition )
       
  1871     {
       
  1872   	RDbView view;
       
  1873 	TUint32 tagId;
       
  1874 	CNssContext* context = iContextBuilder.CreateContextL();
       
  1875 	CleanupStack::PushL( context );
       
  1876 	
       
  1877     CArrayPtrFlat<CNssTag>* tagArray = new(ELeave)CArrayPtrFlat<CNssTag>(1);
       
  1878     CleanupStack::PushL( tagArray );
       
  1879     CleanupResetAndDestroyPushL( *tagArray );
       
  1880 
       
  1881     User::LeaveIfError( StartTransaction() );
       
  1882     CreatePushRollbackItemLC();
       
  1883 
       
  1884     // Get the context based on ContextId
       
  1885   	CleanupClosePushL( view );
       
  1886 
       
  1887 	_LIT( KSQLGetContext, "select * from contexttable where contextid=" );
       
  1888 	iSQLStatement.Copy( KSQLGetContext );
       
  1889 	iSQLStatement.AppendNumUC( aContextId );
       
  1890 
       
  1891 	User::LeaveIfError( view.Prepare(iDatabase, TDbQuery(iSQLStatement, EDbCompareNormal)));
       
  1892 	User::LeaveIfError( view.EvaluateAll());
       
  1893 	view.FirstL();
       
  1894     view.GetL();
       
  1895 	TRAPD( error, FillContextL( view, *context ) );
       
  1896 	// Finished with the view - so close it.
       
  1897 	view.Close();
       
  1898 	CleanupStack::PopAndDestroy( &view );
       
  1899 
       
  1900     // If filling of the context failed, return with Not Found
       
  1901 	if ( error != KErrNone )
       
  1902 	    {
       
  1903         User::Leave( KErrNotFound );
       
  1904         }
       
  1905 
       
  1906     // Get the list of TagId from the RRD table based on text and Position
       
  1907 	RDbView view1;
       
  1908 	CleanupClosePushL( view1 );
       
  1909 
       
  1910 	_LIT( KSQLGetRRDText, "select * from rrdtexttable where rrdposition=" );
       
  1911 	_LIT( KSQLAndRRDText, " and rrdtext='" );
       
  1912 	_LIT( KSQLTick, "'" );
       
  1913 
       
  1914 	iSQLStatement = KSQLGetRRDText;
       
  1915 	iSQLStatement.AppendNumUC( aPosition );
       
  1916 	iSQLStatement.Append( KSQLAndRRDText );
       
  1917 	iSQLStatement.Append( aText );
       
  1918     iSQLStatement.Append( KSQLTick );
       
  1919 
       
  1920 	User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1921 	User::LeaveIfError( view1.EvaluateAll() );
       
  1922 	
       
  1923 	if ( view1.IsEmptyL() )
       
  1924 	    {
       
  1925         User::Leave( KErrNotFound );
       
  1926 	    }
       
  1927 
       
  1928     // Get column set
       
  1929     CDbColSet* columns = view1.ColSetL();
       
  1930     // Get column ordinals
       
  1931     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  1932     // Cleanup column set
       
  1933     delete columns;
       
  1934 
       
  1935     // Select the valid tagId from the list
       
  1936 	for ( view1.FirstL(); view1.AtRow(); view1.NextL() )
       
  1937 	    {
       
  1938         view1.GetL();
       
  1939         tagId = view1.ColUint32( tagid_col );
       
  1940 
       
  1941         // Get the SpeechItem based on the tagId and ContextId
       
  1942         RDbView view2;
       
  1943 		CleanupClosePushL( view2 );
       
  1944 
       
  1945         _LIT( KSQLGetSpeechItem, "select * from tagtable where tagid=" );
       
  1946         _LIT( KSQLAndContextId, " and contextid=" );
       
  1947         iSQLStatement = KSQLGetSpeechItem;
       
  1948         iSQLStatement.AppendNumUC( tagId );
       
  1949 	    iSQLStatement.Append( KSQLAndContextId );
       
  1950         iSQLStatement.AppendNumUC( aContextId );
       
  1951 
       
  1952         User::LeaveIfError( view2.Prepare( iDatabase, 
       
  1953                             TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  1954         User::LeaveIfError( view2.EvaluateAll() );
       
  1955 
       
  1956         if ( !view2.IsEmptyL() )
       
  1957 	        {
       
  1958             GetTagListFromViewL( view2, tagArray, context );
       
  1959 		    }
       
  1960         CleanupStack::PopAndDestroy( &view2 );
       
  1961         }
       
  1962     // close the view 1
       
  1963 	CleanupStack::PopAndDestroy( &view1 );
       
  1964 
       
  1965     // Roll back transaction
       
  1966     CleanupStack::Pop();  // Rollback cleanup item
       
  1967     CommitTransaction( EFalse );
       
  1968 
       
  1969     CleanupStack::Pop( tagArray );  // ResetAndDestroyPushL
       
  1970     CleanupStack::Pop( tagArray );  // array itself
       
  1971     CleanupStack::PopAndDestroy( context );
       
  1972 
       
  1973     return tagArray;
       
  1974     }
       
  1975 
       
  1976 // -----------------------------------------------------------------------------
       
  1977 // CNssVasDb::DeleteTagL
       
  1978 // Get a tag by ID.
       
  1979 // -----------------------------------------------------------------------------
       
  1980 //
       
  1981 CArrayPtrFlat<CNssTag>* CNssVasDb::GetTagL( TUint32 aTagId )
       
  1982     {
       
  1983 	RDbView view;
       
  1984 
       
  1985     User::LeaveIfError( StartTransaction() );
       
  1986     CreatePushRollbackItemLC();
       
  1987 
       
  1988     CleanupClosePushL( view );
       
  1989 
       
  1990 
       
  1991 	_LIT( KSQLGetTag, "select * from tagtable where tagid=");
       
  1992 
       
  1993 	iSQLStatement = KSQLGetTag;
       
  1994 	iSQLStatement.AppendNumUC( aTagId );
       
  1995 
       
  1996     CArrayPtrFlat<CNssTag>* result = GetTagListByQueryL( iSQLStatement );
       
  1997 
       
  1998     // Close view
       
  1999     CleanupStack::PopAndDestroy( &view );
       
  2000 
       
  2001     // Roll back transaction
       
  2002     CleanupStack::Pop();  // Rollback cleanup item
       
  2003     CommitTransaction( EFalse );
       
  2004 
       
  2005     return( result );
       
  2006     }
       
  2007 
       
  2008 
       
  2009 // -----------------------------------------------------------------------------
       
  2010 // CNssVasDb::DeleteTagL
       
  2011 // Deletes a tag by name
       
  2012 // -----------------------------------------------------------------------------
       
  2013 //
       
  2014 void CNssVasDb::DeleteTagL( const TDesC& aName )
       
  2015     {
       
  2016     if ( !iClientHasOpenedDatabase )
       
  2017         {
       
  2018         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
  2019         
       
  2020         User::Leave( KErrNotReady );
       
  2021         }
       
  2022 
       
  2023     User::LeaveIfError( StartTransaction() );
       
  2024     CreatePushRollbackItemLC();
       
  2025 
       
  2026     TUint32 tagId;
       
  2027     RDbView view;
       
  2028 	
       
  2029     CleanupClosePushL(view);
       
  2030 
       
  2031     _LIT( KTick,"' ");
       
  2032     _LIT( KSQLGetTag, "select * from tagtable where name='");
       
  2033 	
       
  2034     iSQLStatement = KSQLGetTag;
       
  2035     iSQLStatement.Append( aName );
       
  2036     iSQLStatement.Append( KTick );
       
  2037 
       
  2038     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery(iSQLStatement, EDbCompareNormal)));
       
  2039     User::LeaveIfError( view.EvaluateAll());
       
  2040 
       
  2041     // Get column set
       
  2042     CDbColSet* columns = view.ColSetL();
       
  2043     // Get column ordinals
       
  2044     TDbColNo tagid_col= columns->ColNo( KTagIdCol );
       
  2045     // Cleanup column set
       
  2046     delete columns;
       
  2047 
       
  2048     view.FirstL();
       
  2049     view.GetL();
       
  2050     tagId = view.ColUint32( tagid_col );
       
  2051 
       
  2052     // Close view
       
  2053     CleanupStack::PopAndDestroy( &view );
       
  2054 
       
  2055     // Pop rollback item and do commit
       
  2056     CleanupStack::Pop();  // Rollback cleanup item
       
  2057     CommitTransaction( ETrue );
       
  2058 
       
  2059     DeleteTagL( tagId );
       
  2060     }
       
  2061 
       
  2062 // -----------------------------------------------------------------------------
       
  2063 // CNssVasDb::DeleteTagL
       
  2064 // Deletes a tag by ID
       
  2065 // -----------------------------------------------------------------------------
       
  2066 //
       
  2067 void CNssVasDb::DeleteTagL( TUint32 aTagId )
       
  2068     {
       
  2069     if ( !iClientHasOpenedDatabase )
       
  2070         {
       
  2071         RUBY_DEBUG0( "CNssVasDb error: database not opened." );
       
  2072         
       
  2073         User::Leave( KErrNotReady );
       
  2074         }
       
  2075    
       
  2076     // Lock database
       
  2077     User::LeaveIfError( StartTransaction() );
       
  2078     CreatePushRollbackItemLC();
       
  2079 
       
  2080     DeleteTagInsideTransactionL( aTagId );
       
  2081 
       
  2082     // Commit transaction - unlock databaes
       
  2083     CleanupStack::Pop();  // Rollback cleanup item
       
  2084     CommitTransaction( ETrue );
       
  2085     }
       
  2086 
       
  2087 
       
  2088 // -----------------------------------------------------------------------------
       
  2089 // CNssVasDb::DeleteTagInsideTransactionL
       
  2090 // Deletes the RRD information of a tag.
       
  2091 // -----------------------------------------------------------------------------
       
  2092 //
       
  2093 void CNssVasDb::DeleteTagInsideTransactionL( TUint32 aTagId )
       
  2094     {
       
  2095     TInt error( KErrNone );
       
  2096 
       
  2097     _LIT( KSQLDeleteTag, "delete from tagtable where tagid=");
       
  2098 
       
  2099 	ReserveDiskSpaceL( sizeof(CNssTag) );
       
  2100 
       
  2101     iSQLStatement = KSQLDeleteTag;
       
  2102     iSQLStatement.AppendNumUC(aTagId);
       
  2103 
       
  2104     error = iDatabase.Execute( iSQLStatement );
       
  2105     if ( error < KErrNone )
       
  2106         {
       
  2107         ReleaseDiskSpace();
       
  2108         User::Leave( error );
       
  2109         }
       
  2110 
       
  2111     TRAP( error, DeleteRRDL( aTagId ) );
       
  2112     
       
  2113     ReleaseDiskSpace();
       
  2114     
       
  2115     User::LeaveIfError( error );
       
  2116     }
       
  2117 
       
  2118 
       
  2119 // -----------------------------------------------------------------------------
       
  2120 // CNssVasDb::DeleteRRDL
       
  2121 // Deletes the RRD information of a tag.
       
  2122 // -----------------------------------------------------------------------------
       
  2123 //
       
  2124 void CNssVasDb::DeleteRRDL(TUint32 aTagId)
       
  2125     {
       
  2126     TInt error( KErrNone );
       
  2127     
       
  2128     _LIT( KSQLAddRRDText, "delete from rrdtexttable ");
       
  2129     _LIT( KSQLAddRRDId,   "delete from rrdinttable ");
       
  2130     _LIT( KSQLWhereTagId,"where tagid=");
       
  2131 
       
  2132     iSQLStatement = KSQLAddRRDId;
       
  2133     iSQLStatement.Append( KSQLWhereTagId );
       
  2134     iSQLStatement.AppendNumUC( aTagId );
       
  2135 	
       
  2136     error = iDatabase.Execute( iSQLStatement );
       
  2137    
       
  2138     if ( error < KErrNone && error != KErrNotFound )
       
  2139         {
       
  2140         User::Leave( error );
       
  2141         }
       
  2142 
       
  2143     iSQLStatement = KSQLAddRRDText;
       
  2144     iSQLStatement.Append( KSQLWhereTagId );
       
  2145     iSQLStatement.AppendNumUC( aTagId );
       
  2146 
       
  2147     error = iDatabase.Execute( iSQLStatement );
       
  2148 
       
  2149     if ( error < KErrNone && error != KErrNotFound )
       
  2150         {
       
  2151         User::Leave( error );
       
  2152         }
       
  2153     }
       
  2154 
       
  2155 // -----------------------------------------------------------------------------
       
  2156 // CNssVasDb::DeleteContextL
       
  2157 // Deletes a context.
       
  2158 // -----------------------------------------------------------------------------
       
  2159 //
       
  2160 void CNssVasDb::DeleteContextL( const TDesC& aName )
       
  2161     {
       
  2162     RUBY_DEBUG_BLOCK( "CNssVasDb::DeleteContextL" );
       
  2163     
       
  2164     TInt error( KErrNone );
       
  2165     TUint32 contextId;
       
  2166     TUint32 tagId;
       
  2167     RDbView view1,view2;
       
  2168     
       
  2169     // Begin transaction
       
  2170     User::LeaveIfError( StartTransaction() );
       
  2171     CreatePushRollbackItemLC();
       
  2172     
       
  2173     CleanupClosePushL( view1 );
       
  2174     
       
  2175     // Search the context from DB
       
  2176     _LIT( KTick, "' " );
       
  2177     _LIT( KSQLGetContext, "select * from contexttable where name='" );
       
  2178     
       
  2179     iSQLStatement = KSQLGetContext;
       
  2180     iSQLStatement.Append( aName );
       
  2181     iSQLStatement.Append( KTick );
       
  2182     
       
  2183     User::LeaveIfError( view1.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  2184     User::LeaveIfError( view1.EvaluateAll() );
       
  2185     
       
  2186     // Get column set
       
  2187     CDbColSet* columns1 = view1.ColSetL();
       
  2188     // Get column ordinals
       
  2189     TDbColNo contextid_col= columns1->ColNo( KContextIdCol );
       
  2190     // Cleanup column set
       
  2191     delete columns1;
       
  2192     
       
  2193     view1.FirstL();
       
  2194     
       
  2195     // Doesn't exists, can't delete
       
  2196     if ( !view1.AtRow() )
       
  2197         {
       
  2198         User::Leave( KErrNotFound );
       
  2199         }
       
  2200     
       
  2201     view1.GetL();
       
  2202     contextId = view1.ColUint32( contextid_col );
       
  2203     
       
  2204     view1.DeleteL();
       
  2205     view1.Close();	
       
  2206     CleanupStack::PopAndDestroy( &view1 );
       
  2207     
       
  2208     // Delete all tags, which were in the context.
       
  2209     _LIT( KSQLGetTag, "select * from tagtable where contextid=" );
       
  2210     
       
  2211     iSQLStatement = KSQLGetTag;
       
  2212     iSQLStatement.AppendNumUC( contextId );
       
  2213     
       
  2214     CleanupClosePushL( view2 );
       
  2215     
       
  2216     User::LeaveIfError( view2.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );
       
  2217     User::LeaveIfError( view2.EvaluateAll() );
       
  2218     
       
  2219     ReserveDiskSpaceL( (sizeof(CNssTag) * view2.CountL()) + sizeof(CNssContext) );
       
  2220     
       
  2221     view2.FirstL();
       
  2222     
       
  2223     // If this context has any tags, remove the RRD entries from the RRD table.
       
  2224     if ( view2.AtRow() )
       
  2225         {
       
  2226         // Get column set
       
  2227         CDbColSet* columns2 = view2.ColSetL();
       
  2228         
       
  2229         // Get column ordinals
       
  2230         TDbColNo tagid_col = columns2->ColNo( KTagIdCol );
       
  2231         // Cleanup column2 set
       
  2232         delete columns2;
       
  2233         
       
  2234         for ( view2.FirstL(); view2.AtRow(); view2.NextL() )
       
  2235             {
       
  2236             view2.GetL();
       
  2237             tagId = view2.ColUint32( tagid_col );
       
  2238             RUBY_DEBUG0( "CNssVasDb::DeleteContextL deleting RRD" );
       
  2239             // Return value ignored since other tag ids should be iterated through
       
  2240             // even though one RRD deletion fails
       
  2241             TRAP( error, DeleteRRDL( tagId ) );
       
  2242             }
       
  2243         
       
  2244         view2.Close();
       
  2245         }
       
  2246     
       
  2247     // Remove tags from tag table
       
  2248     _LIT( KSQLDeleteTag, "delete from tagtable where contextid=");
       
  2249     iSQLStatement = KSQLDeleteTag;
       
  2250     iSQLStatement.AppendNumUC( contextId );
       
  2251     
       
  2252     error = iDatabase.Execute( iSQLStatement );
       
  2253     
       
  2254     CleanupStack::PopAndDestroy( &view2 );
       
  2255     
       
  2256     if ( error < KErrNone && error != KErrNotFound )
       
  2257         {
       
  2258         ReleaseDiskSpace();
       
  2259         // Roll back transaction
       
  2260         CleanupStack::PopAndDestroy(); // Rollback cleanup item
       
  2261         User::Leave( error );
       
  2262         }
       
  2263    
       
  2264     CleanupStack::Pop();  // Rollback cleanup item
       
  2265     CommitTransaction( ETrue );
       
  2266    
       
  2267     ReleaseDiskSpace();
       
  2268     }
       
  2269 
       
  2270 // -----------------------------------------------------------------------------
       
  2271 // CNssVasDb::UpdateTagInTransactionL
       
  2272 // Updates a tag. Assumes that a transaction has been started earlier.
       
  2273 // -----------------------------------------------------------------------------
       
  2274 //
       
  2275 void CNssVasDb::UpdateTagInTransactionL( CNssTag& aTag )
       
  2276     {
       
  2277     CNssContext* context = static_cast<CNssContext*> ( aTag.Context() );
       
  2278     UpdateContextInsideTransactionL( *context );
       
  2279     CNssSpeechItem* speechItem = static_cast<CNssSpeechItem*>
       
  2280         ( aTag.SpeechItem() );
       
  2281     UpdateSpeechItemL( *speechItem );
       
  2282     CNssRRD* rrd = static_cast<CNssRRD*> ( aTag.RRD() );
       
  2283     UpdateRRDL( *rrd );
       
  2284     }
       
  2285 
       
  2286 // -----------------------------------------------------------------------------
       
  2287 // CNssVasDb::DoUpdateContextL
       
  2288 // Updates an existing context.
       
  2289 // -----------------------------------------------------------------------------
       
  2290 //
       
  2291 void CNssVasDb::DoUpdateContextL( CNssContext& aContext )
       
  2292     {
       
  2293     _LIT( KSQLUpdateContext,"update contexttable set ");
       
  2294     _LIT( KEqual,"=");
       
  2295     _LIT( KCommon,",");
       
  2296     _LIT( KTick,"'");
       
  2297     _LIT( KSQLWhereContextId," where contextid = ");
       
  2298    
       
  2299     iSQLStatement = KSQLUpdateContext;
       
  2300      
       
  2301     iSQLStatement.Append( KNameCol );
       
  2302     iSQLStatement.Append( KEqual );
       
  2303     iSQLStatement.Append( KTick );
       
  2304     iSQLStatement.Append( aContext.ContextName() );
       
  2305     iSQLStatement.Append( KTick );
       
  2306    
       
  2307     iSQLStatement.Append( KCommon );
       
  2308     iSQLStatement.Append( KGlobalCol );
       
  2309     iSQLStatement.Append( KEqual );
       
  2310     iSQLStatement.AppendNumUC( aContext.IsGlobal() );
       
  2311 
       
  2312     iSQLStatement.Append( KCommon );
       
  2313     iSQLStatement.Append( KGrammarIdCol );
       
  2314     iSQLStatement.Append( KEqual );
       
  2315     iSQLStatement.AppendNumUC( aContext.GrammarId() );
       
  2316 
       
  2317     iSQLStatement.Append( KCommon );
       
  2318     iSQLStatement.Append( KLexiconIdCol );
       
  2319     iSQLStatement.Append( KEqual );
       
  2320     iSQLStatement.AppendNumUC( aContext.LexiconId() );
       
  2321 
       
  2322     iSQLStatement.Append( KCommon );
       
  2323     iSQLStatement.Append( KModelBankIdCol );
       
  2324     iSQLStatement.Append( KEqual );
       
  2325     iSQLStatement.AppendNumUC( aContext.ModelBankId() );
       
  2326 
       
  2327     iSQLStatement.Append( KSQLWhereContextId );
       
  2328     iSQLStatement.AppendNumUC( aContext.ContextId() );
       
  2329  
       
  2330     User::LeaveIfError( iDatabase.Execute( iSQLStatement ) );
       
  2331     }
       
  2332 
       
  2333 // -----------------------------------------------------------------------------
       
  2334 // CNssVasDb::DoUpdateUpdateContextClientDataL
       
  2335 // Updates the client data of a context.
       
  2336 // -----------------------------------------------------------------------------
       
  2337 //
       
  2338 void CNssVasDb::DoUpdateContextClientDataL( CNssContext& aContext )
       
  2339     {
       
  2340 	__UHEAP_MARK;
       
  2341 
       
  2342 	// Declare a literal string to hold the SQL statement
       
  2343 	// SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
  2344 
       
  2345 	_LIT( KSQLSelect1, "select clientdata from contexttable where name='" );
       
  2346 
       
  2347 	TBuf<KSqlStatementmaxLength> sqlStatement;
       
  2348 	sqlStatement.Append( KSQLSelect1 );
       
  2349     sqlStatement.Append( aContext.ContextName() );
       
  2350     sqlStatement.Append( '\'' );
       
  2351 
       
  2352 	// create a view on the database
       
  2353 	RDbView view;
       
  2354     CleanupClosePushL( view ); // Stack: view
       
  2355 
       
  2356 	User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( sqlStatement, EDbCompareNormal ) ) );
       
  2357 	User::LeaveIfError( view.EvaluateAll() );
       
  2358 
       
  2359 	// Get the structure of rowset
       
  2360 	CDbColSet* colSet = view.ColSetL();
       
  2361     CleanupStack::PushL( colSet ); // Stack: view, colset
       
  2362     TInt error( KErrNone );
       
  2363 	
       
  2364 	if( view.FirstL() )
       
  2365 		{
       
  2366 		view.UpdateL();
       
  2367 
       
  2368     
       
  2369 		// add binary buffer by Using the stream  
       
  2370 
       
  2371 		//RDbColWriteStream out;
       
  2372 		TDbColNo col = colSet->ColNo( _L("clientdata") ); // Ordinal position of client data
       
  2373 
       
  2374     	if ( col == KDbNullColNo )
       
  2375         	{
       
  2376         	User::Leave( KErrCorrupt );
       
  2377         	}
       
  2378 
       
  2379     	view.SetColL( col, aContext.ClientData() ); 
       
  2380 	
       
  2381 		view.PutL();
       
  2382 	
       
  2383 		// close the view
       
  2384     	view.Close();
       
  2385 		}
       
  2386 	else 
       
  2387 		{
       
  2388 		error = KErrNotFound;
       
  2389 		}
       
  2390     
       
  2391     CleanupStack::PopAndDestroy( colSet );
       
  2392     CleanupStack::PopAndDestroy( &view );
       
  2393 
       
  2394 	__UHEAP_MARKEND;
       
  2395 
       
  2396     User::LeaveIfError( error );
       
  2397     }
       
  2398 
       
  2399 // -----------------------------------------------------------------------------
       
  2400 // CNssVasDb::UpdateRRDL
       
  2401 // Updates an existing RRD.
       
  2402 // -----------------------------------------------------------------------------
       
  2403 //
       
  2404 void CNssVasDb::UpdateRRDL( CNssRRD& aRRD )
       
  2405     {
       
  2406     TRAPD( error, DeleteRRDL( aRRD.TagId() ) );
       
  2407 
       
  2408     if ( error != KErrNotFound)
       
  2409         {
       
  2410         error = KErrNone;
       
  2411         }
       
  2412 
       
  2413     User::LeaveIfError( error );
       
  2414 
       
  2415     SaveRRDL( &aRRD );
       
  2416     }
       
  2417 
       
  2418 // -----------------------------------------------------------------------------
       
  2419 // CNssVasDb::UpdateSpeechItemL
       
  2420 // Updates an existing speech item.
       
  2421 // -----------------------------------------------------------------------------
       
  2422 //
       
  2423 void CNssVasDb::UpdateSpeechItemL( CNssSpeechItem& aSpeechItem )
       
  2424     {
       
  2425     RDbView view;
       
  2426     CleanupClosePushL( view );
       
  2427  
       
  2428     _LIT( KSQLGet, "select * from tagtable where tagid=" );
       
  2429     
       
  2430     iSQLStatement = KSQLGet;
       
  2431     iSQLStatement.AppendNumUC( aSpeechItem.TagId() );
       
  2432 
       
  2433     User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( iSQLStatement, EDbCompareNormal ) ) );	
       
  2434     User::LeaveIfError( view.EvaluateAll());
       
  2435     
       
  2436     // Get column set
       
  2437     CDbColSet* columns = view.ColSetL();
       
  2438     // Get column ordinals
       
  2439     TDbColNo name_col= columns->ColNo( KNameCol );
       
  2440 
       
  2441     delete columns;
       
  2442 	  
       
  2443     if ( view.FirstL() )
       
  2444         {
       
  2445         // Begin process of updating a row...
       
  2446         view.UpdateL();
       
  2447         // set column values...
       
  2448 #ifdef __SIND_EXTENSIONS        
       
  2449         view.SetColL( name_col, aSpeechItem.RawText() ); 
       
  2450 #else
       
  2451         view.SetColL( name_col, aSpeechItem.Text() ); 
       
  2452 #endif
       
  2453 
       
  2454         // add the row to the table...
       
  2455         view.PutL();
       
  2456 		
       
  2457         // finished - so close the view
       
  2458         view.Close();
       
  2459 		}
       
  2460     else 
       
  2461         {
       
  2462         User::Leave( KErrNotFound );
       
  2463         }	
       
  2464 	
       
  2465     CleanupStack::PopAndDestroy( &view );
       
  2466     }
       
  2467 
       
  2468 // -----------------------------------------------------------------------------
       
  2469 // CNssVasDb::FillSpeechItemL
       
  2470 // Reads a TNssSpeechItem from DB to memory. Earlier, the caller has run an SQL
       
  2471 // query and specifies the matching context in RDbView.
       
  2472 // -----------------------------------------------------------------------------
       
  2473 //
       
  2474 void CNssVasDb::FillSpeechItemL( RDbView& aView, CNssSpeechItem& aSpeechItem, TInt& aContextId )
       
  2475     {
       
  2476     RUBY_DEBUG_BLOCK( "CNssVasDb::FillSpeechItemL" );
       
  2477 
       
  2478 	if ( aView.IsEmptyL() )
       
  2479 	    {
       
  2480 		User::Leave( KErrNotFound );
       
  2481 	    }
       
  2482 
       
  2483 	// Get column set
       
  2484     CDbColSet* columns = aView.ColSetL();
       
  2485     // Get column ordinals
       
  2486  	TDbColNo tagid_col    = columns->ColNo( KTagIdCol );
       
  2487  	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  2488 	TDbColNo ruleid_col   = columns->ColNo( KRuleIdCol );
       
  2489 	TDbColNo name_col     = columns->ColNo( KNameCol );
       
  2490 
       
  2491     // Cleanup column set
       
  2492     delete columns;
       
  2493 
       
  2494 	// Retrieve the current row
       
  2495 	aView.GetL();
       
  2496 	aSpeechItem.SetTagId( aView.ColUint32( tagid_col ) );
       
  2497 	aSpeechItem.SetRuleID( aView.ColUint32( ruleid_col ) );
       
  2498 	aSpeechItem.SetTextL( aView.ColDes( name_col ) );
       
  2499     aContextId = aView.ColUint32( contextid_col );
       
  2500     }
       
  2501 
       
  2502 
       
  2503 // -----------------------------------------------------------------------------
       
  2504 // CNssVasDb::FillContextL
       
  2505 // Reads a context from DB to memory. Earlier, the caller has run an SQL query
       
  2506 // and specifies the matching context in RDbView.
       
  2507 // -----------------------------------------------------------------------------
       
  2508 //
       
  2509 void CNssVasDb::FillContextL( RDbView& aView, CNssContext& aContext )
       
  2510     {
       
  2511     if ( aView.IsEmptyL() )
       
  2512 	    {
       
  2513 	    User::Leave( KErrNotFound );
       
  2514 	    }
       
  2515 
       
  2516 	// Get column set
       
  2517     CDbColSet* columns = aView.ColSetL();
       
  2518     // Get column ordinals
       
  2519  	TDbColNo contextid_col= columns->ColNo( KContextIdCol );
       
  2520 	TDbColNo name_col = columns->ColNo( KNameCol );
       
  2521     TDbColNo global_col = columns->ColNo( KGlobalCol );
       
  2522 	TDbColNo grammarid_col= columns->ColNo( KGrammarIdCol );
       
  2523 	TDbColNo lexiconid_col= columns->ColNo( KLexiconIdCol );
       
  2524 	TDbColNo modelbankid_col= columns->ColNo( KModelBankIdCol );
       
  2525     // Cleanup column set
       
  2526     delete columns;
       
  2527 
       
  2528 	// Retrieve the current row
       
  2529 	aView.GetL();
       
  2530 	aContext.SetContextId( aView.ColUint32( contextid_col ) );
       
  2531 	aContext.SetGlobal( aView.ColUint32( global_col ) );
       
  2532 	aContext.SetGrammarId( aView.ColUint32( grammarid_col ) );
       
  2533 	aContext.SetLexiconId( aView.ColUint32( lexiconid_col ) );
       
  2534 	aContext.SetModelBankId( aView.ColUint32( modelbankid_col ) );
       
  2535 	aContext.SetNameL( aView.ColDes( name_col ) );
       
  2536     }
       
  2537 
       
  2538 // -----------------------------------------------------------------------------
       
  2539 // CNssVasDb::FillTagListArrayL
       
  2540 // Creates a TNssTag from context, speech item and RRD information.
       
  2541 // Adds a tag to aTagList.
       
  2542 // -----------------------------------------------------------------------------
       
  2543 //
       
  2544 void CNssVasDb::FillTagListArrayL( CArrayPtrFlat<CNssTag>& aTagList, CNssContext* aContext, 
       
  2545                                    CNssSpeechItem* aSpeechItem, CNssRRD* aRRD )
       
  2546     {    
       
  2547     CNssContext* contextCopy = aContext->CopyL();
       
  2548     CNssSpeechItem* speechItenCopy = aSpeechItem->CopyL( contextCopy );
       
  2549     CNssRRD* rrdCopy = aRRD->CopyL();
       
  2550     CNssTag* tag = new (ELeave) CNssTag( contextCopy, rrdCopy, speechItenCopy );
       
  2551     tag->SetTagId( aSpeechItem->TagId() );
       
  2552 	
       
  2553 	aTagList.AppendL( tag );
       
  2554     }
       
  2555 
       
  2556 // -----------------------------------------------------------------------------
       
  2557 // CNssVasDb::FillContextListArrayL
       
  2558 // Utility function to read contexts from DB to memory. Earlier, the caller has
       
  2559 // run an SQL query and the matches are listed in an RDbView.
       
  2560 // -----------------------------------------------------------------------------
       
  2561 //
       
  2562 void CNssVasDb::FillContextListArrayL( RDbView& aView, CArrayPtrFlat<CNssContext>& aContextList )
       
  2563     {
       
  2564     RUBY_DEBUG_BLOCK("CNssVasDb::FillContextListArrayL");
       
  2565 	TInt pos( 0 );
       
  2566 
       
  2567 	// Clear the previous array.
       
  2568 	aContextList.Reset();
       
  2569 
       
  2570     // Get column set
       
  2571     CDbColSet* columns = aView.ColSetL();
       
  2572 
       
  2573     // Get column ordinals
       
  2574     TDbColNo name_col       = columns->ColNo( KNameCol );
       
  2575     TDbColNo global_col     = columns->ColNo( KGlobalCol );
       
  2576 	TDbColNo grammarid_col  = columns->ColNo( KGrammarIdCol );
       
  2577 	TDbColNo lexiconid_col  = columns->ColNo( KLexiconIdCol );
       
  2578 	TDbColNo modelbankid_col= columns->ColNo( KModelBankIdCol );
       
  2579 	TDbColNo contextid_col  = columns->ColNo( KContextIdCol );
       
  2580 
       
  2581     // New in 2.8
       
  2582     TDbColNo clientdata_col = columns->ColNo( KClientDataCol );
       
  2583 
       
  2584 	delete columns;
       
  2585 
       
  2586 	for (aView.FirstL(); aView.AtRow(); aView.NextL())
       
  2587 	    {
       
  2588 	    aView.GetL(); // Retrieve the current row - actually reads the row from the database.
       
  2589        
       
  2590         CNssContext* oneContext = iContextBuilder.CreateContextL();
       
  2591         CleanupStack::PushL( oneContext );
       
  2592        
       
  2593         oneContext->SetNameL( aView.ColDes( name_col ) );
       
  2594         oneContext->SetGlobal( aView.ColUint32( global_col ) );
       
  2595         oneContext->SetContextId( aView.ColUint32( contextid_col ) );
       
  2596         oneContext->SetLexiconId( aView.ColUint32( lexiconid_col ) );
       
  2597         oneContext->SetGrammarId( aView.ColUint32( grammarid_col ) );
       
  2598         oneContext->SetModelBankId( aView.ColUint32( modelbankid_col ) );
       
  2599         oneContext->SetClientData( aView.ColDes8( clientdata_col ) );
       
  2600        
       
  2601 	    // Now add the context object to the list (array) of context.
       
  2602 	    aContextList.InsertL( pos++, oneContext );
       
  2603 	   
       
  2604 	    // Copy has been created in aContextList, no need for pointer anymore
       
  2605 	    CleanupStack::Pop( oneContext );
       
  2606 	    }
       
  2607 }
       
  2608 
       
  2609 // -----------------------------------------------------------------------------
       
  2610 // CNssVasDb::StartTransactionL
       
  2611 // Starts a new transaction.
       
  2612 // -----------------------------------------------------------------------------
       
  2613 //
       
  2614 TInt CNssVasDb::StartTransaction()
       
  2615     {
       
  2616     RUBY_DEBUG0( "CNssVasDb::StartTransaction" );
       
  2617     
       
  2618     if ( !iClientHasOpenedDatabase )
       
  2619         {
       
  2620         RUBY_DEBUG0( "No open DB. E.g. backup/restore in progress" );
       
  2621         return KErrNotReady;
       
  2622         }
       
  2623 
       
  2624     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2625     
       
  2626     iCriticalSection.Wait();
       
  2627     if ( iLocked )
       
  2628         {
       
  2629         // If we already have the lock, no need to take it again
       
  2630         RUBY_DEBUG0( "CNssVasDb::StartTransaction DB is already locked by current process" );
       
  2631         return KErrNone;
       
  2632         }
       
  2633 
       
  2634     // Wait for the mutex so that two processes don't try get the lock simultaneously
       
  2635     RUBY_DEBUG0( "Waiting for mutex in CNssVasDb::StartTransaction" );
       
  2636     iMutex.Wait();
       
  2637     
       
  2638     // check if backup is ongoing
       
  2639 	    
       
  2640     TInt readLockErr = iDatabase.Begin();
       
  2641 
       
  2642     // Mutex should make it sure that we have exclusive lock to Database
       
  2643     // Thus iDatabase.Begin() should succeed every time
       
  2644     __ASSERT_DEBUG( readLockErr == KErrNone, User::Panic( KVasDbPanic, __LINE__ ) );
       
  2645    
       
  2646     if ( readLockErr == KErrNone )
       
  2647         {
       
  2648         iLocked = ETrue;
       
  2649         }
       
  2650 
       
  2651     RUBY_DEBUG0( "CNssVasDb::StartTransaction completed" );        
       
  2652         
       
  2653     return readLockErr;
       
  2654     }
       
  2655 
       
  2656 // -----------------------------------------------------------------------------
       
  2657 // CNssVasDb::CommitTransaction
       
  2658 // Commits changes and releases the lock. If iShouldBeLocked flag is set,
       
  2659 // opens a new tranaction in order to keep the database locked.
       
  2660 // -----------------------------------------------------------------------------
       
  2661 //
       
  2662 TInt CNssVasDb::CommitTransaction( TBool aCompact )
       
  2663     {
       
  2664     RUBY_DEBUG0( "CNssVasDb::CommitTransaction" );
       
  2665 
       
  2666     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2667     //__ASSERT_DEBUG( iLocked, User::Panic( _L("VasCNssVasDb.cpp"), __LINE__ ) );
       
  2668 
       
  2669     TInt ret = KErrNone;
       
  2670 
       
  2671     if ( iLocked )
       
  2672         {
       
  2673         ret = iDatabase.Commit();
       
  2674         
       
  2675         if ( iDatabase.IsDamaged() )
       
  2676             {
       
  2677             RUBY_DEBUG0( "CNssVasDb::CommitTransaction Recovering" );
       
  2678             ret = iDatabase.Recover();
       
  2679             }
       
  2680         
       
  2681         if ( aCompact )
       
  2682             {
       
  2683             RUBY_DEBUG0( "CNssVasDb::CommitTransaction compacting DB" );
       
  2684             iDatabase.Compact(); 
       
  2685             }
       
  2686         
       
  2687         iLocked = EFalse;
       
  2688         
       
  2689         RUBY_DEBUG0( "Signalling mutex in CNssVasDb::CommitTransaction" );
       
  2690         iMutex.Signal();
       
  2691         }
       
  2692     else
       
  2693         {
       
  2694         RUBY_DEBUG0( "ERROR: CNssVasDb::CommitTransaction does nothing, not locked" );
       
  2695         }
       
  2696         
       
  2697     iCriticalSection.Signal();
       
  2698     return( ret );
       
  2699     }
       
  2700 
       
  2701 // -----------------------------------------------------------------------------
       
  2702 // CNssVasDb::RollbackTransaction
       
  2703 // Discards changes and releases the lock.
       
  2704 // -----------------------------------------------------------------------------
       
  2705 //
       
  2706 TInt CNssVasDb::RollbackTransaction()
       
  2707     {
       
  2708     __ASSERT_DEBUG( iLocked == iDatabase.InTransaction(), User::Panic( KVasDbPanic, __LINE__ ) );
       
  2709     __ASSERT_DEBUG( iLocked, User::Panic( KVasDbPanic, __LINE__ ) );
       
  2710 
       
  2711     TInt ret = KErrNone;
       
  2712 
       
  2713     iDatabase.Rollback();
       
  2714     
       
  2715     iLocked = EFalse;
       
  2716     
       
  2717     if ( iDatabase.IsDamaged() )
       
  2718         {
       
  2719         RUBY_DEBUG0( "CNssVasDb::RollbackTransaction Recovering" );
       
  2720         ret = iDatabase.Recover();
       
  2721         }
       
  2722 
       
  2723 
       
  2724     RUBY_DEBUG0( "Signalling mutex in CNssVasDb::RollbackTransaction" );
       
  2725     iMutex.Signal();
       
  2726     iCriticalSection.Signal();
       
  2727     
       
  2728     return( ret );
       
  2729     }
       
  2730     
       
  2731 
       
  2732 // -----------------------------------------------------------------------------
       
  2733 // CNssVasDb::LockTransactionsL
       
  2734 // Permit transactions and release database
       
  2735 // -----------------------------------------------------------------------------
       
  2736 //
       
  2737 void CNssVasDb::LockTransactionsL()
       
  2738     {
       
  2739     // lock transactions
       
  2740     RUBY_DEBUG_BLOCK( "CNssVasDb::LockTransactionsL" );
       
  2741     
       
  2742     iCriticalSection.Wait(); // wait until a possible transaction ends
       
  2743             
       
  2744     // release a database
       
  2745     CloseDatabase();
       
  2746     }
       
  2747 
       
  2748 // -----------------------------------------------------------------------------
       
  2749 // CNssVasDb::UnlockTransactionsL
       
  2750 // Allow transactions and reserve database
       
  2751 // -----------------------------------------------------------------------------
       
  2752 //
       
  2753 void CNssVasDb::UnlockTransactionsL()
       
  2754     {
       
  2755     // unlock transactions
       
  2756     RUBY_DEBUG_BLOCK( "CNssVasDb::UnlockTransactionsL" );
       
  2757     OpenDatabaseL(); // open database
       
  2758     
       
  2759     if ( iCriticalSection.IsBlocked() )
       
  2760         {        
       
  2761         iCriticalSection.Signal(); // allow to do transactions
       
  2762         }
       
  2763     }
       
  2764     	
       
  2765 // -----------------------------------------------------------------------------
       
  2766 // CNssVasDb::ReserveDiskSpaceL(
       
  2767 // Reserves disk space. Leaves (KErrDiskFull), if not
       
  2768 // enough space.
       
  2769 // -----------------------------------------------------------------------------
       
  2770 //
       
  2771 void CNssVasDb::ReserveDiskSpaceL( TInt aRequestSize )
       
  2772     {
       
  2773     RUBY_DEBUG_BLOCK( "CNssVasDb::ReserveDiskSpaceL" );
       
  2774 
       
  2775 #ifdef _DEBUG
       
  2776     TInt error = iDbSession.ReserveDriveSpace( iDrive, aRequestSize );
       
  2777     if ( error )
       
  2778         {
       
  2779         RUBY_DEBUG1( "CNssVasDb::ReserveDiskSpaceL fails %d", error );
       
  2780         User::Leave( error );
       
  2781         }
       
  2782 #else
       
  2783     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, aRequestSize ) );
       
  2784 #endif // _DEBUG
       
  2785     }
       
  2786 
       
  2787 
       
  2788 // -----------------------------------------------------------------------------
       
  2789 // CNssVasDb::ReleaseDiskSpace
       
  2790 // Releases the disk space
       
  2791 // -----------------------------------------------------------------------------
       
  2792 //
       
  2793 void CNssVasDb::ReleaseDiskSpace()
       
  2794     {
       
  2795     RUBY_DEBUG0( "CNssVasDb::ReleaseDiskSpace" );
       
  2796     iDbSession.FreeReservedSpace( iDrive );
       
  2797     }
       
  2798 
       
  2799 // -----------------------------------------------------------------------------
       
  2800 // CNssVasDb::CreateRollbackItemLC
       
  2801 // Creates a cleanup item and pushes it to the cleanup stack. In case of a 
       
  2802 // leave, PopAndDestroying this item will call RollbackCleanupFunction
       
  2803 // -----------------------------------------------------------------------------
       
  2804 void CNssVasDb::CreatePushRollbackItemLC() 
       
  2805     {
       
  2806     TCleanupItem item( RollbackCleanupFunction, this );
       
  2807     CleanupStack::PushL( item );
       
  2808     }
       
  2809 
       
  2810 // End of file