srsf/sisrscontrollerplugin/src/sigrammardb.cpp
branchRCL_3
changeset 23 e36f3802f733
equal deleted inserted replaced
22:cad71a31b7fc 23:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2004-2007 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:  This class handles the storage and access of speaker independent
       
    15 *               grammars.  It is also responsible for allocating memory when
       
    16 *               loading grammars into the recognizer.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "sigrammardb.h"
       
    23 #include "rubydebug.h"
       
    24 
       
    25 // ============================ MEMBER FUNCTIONS ===============================
       
    26 
       
    27 // -----------------------------------------------------------------------------
       
    28 // CSIGrammarDB::CSIGrammarDB
       
    29 // C++ default constructor can NOT contain any code, that
       
    30 // might leave.
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CSIGrammarDB::CSIGrammarDB( RDbNamedDatabase& aDatabase, 
       
    34                             RDbs& aDbSession,
       
    35                             TInt aDrive )
       
    36 : CSICommonDB(aDatabase, aDbSession, aDrive )
       
    37     {
       
    38     // Nothing
       
    39     }
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // CSIGrammarDB::ConstructL
       
    43 // Symbian 2nd phase constructor can leave.
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 void CSIGrammarDB::ConstructL()
       
    47     {
       
    48     // Nothing
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CSIGrammarDB::NewL
       
    53 // Two-phased constructor.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CSIGrammarDB* CSIGrammarDB::NewL( RDbNamedDatabase& aDatabase, 
       
    57                                   RDbs& aDbSession,
       
    58                                   TInt aDrive )
       
    59     {
       
    60     RUBY_DEBUG_BLOCK( "CSIGrammarDB::NewL" );
       
    61     
       
    62     CSIGrammarDB* self 
       
    63         = new( ELeave ) CSIGrammarDB( aDatabase, aDbSession, aDrive );
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop( self );	
       
    67     return self;
       
    68     }
       
    69   
       
    70 // -----------------------------------------------------------------------------
       
    71 // CSIGrammarDB::~CSIGrammarDB
       
    72 // Destructor
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 CSIGrammarDB::~CSIGrammarDB()
       
    76     {
       
    77     RUBY_DEBUG0( "CSIGrammarDB::~CSIGrammarDB" );
       
    78 	// Delete all elements of the array before deleting the array
       
    79 	iGrammarArray.ResetAndDestroy();
       
    80 	iGrammarArray.Close();	
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CSIGrammarDB::CreateGrammarL
       
    85 // Creates a new grammar  in the database.
       
    86 // -----------------------------------------------------------------------------
       
    87 //
       
    88 TSIGrammarID CSIGrammarDB::CreateGrammarL( TUid aClientUid )
       
    89     {
       
    90     RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateGrammarL" );
       
    91 
       
    92     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSIGrammar ) ) );
       
    93 	
       
    94 	TSIGrammarID grammarID = STATIC_CAST(TSIGrammarID,CreateNewIDL(KGrammarIdTable, KGrammarIdColumn, aClientUid));
       
    95 	// Construct the table name using the new grammar ID
       
    96 	TBuf<40> KGrammarName( KSIGrammarTable );
       
    97     KGrammarName.AppendNumUC( grammarID );
       
    98     RUBY_DEBUG1( "CSIGrammarDB::CreateGrammarL grammar ID: %i", grammarID );
       
    99 	
       
   100 	// Create a table definition
       
   101 	CDbColSet* columns = CDbColSet::NewLC();
       
   102 	
       
   103 	// add the columns  
       
   104 	// 1) Binary data, 2) binary data size
       
   105 	columns->AddL( TDbCol( KBinaryGrammarColumn, EDbColLongBinary ) );
       
   106 	columns->AddL( TDbCol( KBinaryGrammarColumnSize, EDbColUint32 ) );
       
   107 	
       
   108 	// Create a table
       
   109 	TInt err =iDb.CreateTable( KGrammarName, *columns );
       
   110 	
       
   111 	if ( err != KErrNone )
       
   112 	    {
       
   113 		// Failed to create the table.
       
   114 		// Need to release the new grammar ID and leave.
       
   115 		ReleaseIdL( KGrammarIdTable, KGrammarIdColumn, grammarID );
       
   116 		User::Leave( err );
       
   117 	    }
       
   118 
       
   119 	// Cleanup the column set
       
   120 	CleanupStack::PopAndDestroy( columns );
       
   121 	
       
   122 	// Construct the table name using the provided grammar ID
       
   123 	// Declare a literal string to hold the SQL statement
       
   124 	// SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM  KGrammarName
       
   125  	_LIT(KSQLSelect1,"select  ");	
       
   126 	_LIT(KSQLSelect2," from  ");		
       
   127 	TBuf<120> KSQLStatement;		
       
   128 	KSQLStatement.Append(KSQLSelect1  );	
       
   129 	KSQLStatement.Append(KBinaryGrammarColumn );
       
   130 	KSQLStatement.Append(KNext);
       
   131 	KSQLStatement.Append(KBinaryGrammarColumnSize );	
       
   132 	KSQLStatement.Append(KSQLSelect2  );
       
   133 	KSQLStatement.Append(KGrammarName); 
       
   134 	
       
   135 	// Create a view on the database
       
   136 	RDbView view;
       
   137 	User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   138 	User::LeaveIfError(view.EvaluateAll());
       
   139 	
       
   140 	// Get the structure of rowset
       
   141 	CDbColSet* colSet = view.ColSetL(); 
       
   142  	// Insert a row
       
   143 	view.InsertL();
       
   144 	view.PutL();
       
   145  	// Close the view
       
   146 	view.Close();
       
   147 	delete colSet; 
       
   148 
       
   149 	// Put a empty grammar into the database
       
   150 	CSICompiledGrammar *aSICompiledGrammar=CSICompiledGrammar::NewL(grammarID);
       
   151  	CleanupStack::PushL(aSICompiledGrammar);
       
   152 	UpdateGrammarL(aClientUid,aSICompiledGrammar);
       
   153 	CleanupStack::PopAndDestroy(aSICompiledGrammar);
       
   154 
       
   155     iDbSession.FreeReservedSpace( iDrive );
       
   156 
       
   157  	return grammarID;
       
   158     } 
       
   159 
       
   160 // -----------------------------------------------------------------------------
       
   161 // CSIGrammarDB::UpdateGrammarL
       
   162 // Inserts the externalized SI compiled grammar  into the specified grammar table.
       
   163 // Save the grammar into the database
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CSIGrammarDB::UpdateGrammarL( TUid aClientUid, 
       
   167                                    CSICompiledGrammar *aSICompiledGrammar )
       
   168     {
       
   169 	RUBY_DEBUG_BLOCK( "CSIGrammarDB::UpdateGrammarL" );
       
   170 
       
   171 	// verify ownership 
       
   172 	TSIGrammarID aGrammarID=aSICompiledGrammar->GrammarID();
       
   173 	VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID);
       
   174 	
       
   175 	// Construct the table name using the provided grammar ID
       
   176 	// Declare a literal string to hold the SQL statement
       
   177 	// SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM  KGrammarName
       
   178 	TBuf<40> KGrammarName(KSIGrammarTable);
       
   179     KGrammarName.AppendNumUC(aGrammarID);	
       
   180 	_LIT(KSQLSelect1,"select  ");	
       
   181 	_LIT(KSQLSelect2," from  ");		
       
   182 	TBuf<120> KSQLStatement;		
       
   183 	KSQLStatement.Append(KSQLSelect1  );	
       
   184 	KSQLStatement.Append(KBinaryGrammarColumn );
       
   185 	KSQLStatement.Append(KNext);
       
   186 	KSQLStatement.Append(KBinaryGrammarColumnSize );	
       
   187 	KSQLStatement.Append(KSQLSelect2  );
       
   188 	KSQLStatement.Append(KGrammarName); 
       
   189 	
       
   190 	// Create a view on the database
       
   191 	RDbView view;
       
   192 	User::LeaveIfError( view.Prepare( iDb, TDbQuery( KSQLStatement,EDbCompareNormal ) ) );
       
   193 	User::LeaveIfError( view.EvaluateAll() );
       
   194 	CleanupClosePushL( view );
       
   195 	
       
   196 	// Get the structure of rowset
       
   197 	CDbColSet* colSet = view.ColSetL();
       
   198 	CleanupStack::PushL( colSet );
       
   199 	view.FirstL(); 
       
   200 	view.UpdateL();
       
   201   
       
   202 	// Externalize a compiled grammar
       
   203 	CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   204     CleanupStack::PushL( dataCopyBuffer );              // when the buffer is full
       
   205  	RBufWriteStream stream;
       
   206 	stream.Open( *dataCopyBuffer );
       
   207     CleanupClosePushL( stream );
       
   208 	aSICompiledGrammar->ExternalizeL( stream );
       
   209 	CleanupStack::PopAndDestroy( &stream );
       
   210 	
       
   211 	TPtr8 aWriteBuf( dataCopyBuffer->Ptr( 0 ) );
       
   212 	TInt BufSize = aWriteBuf.Size();
       
   213 	
       
   214 	// add binary buffer by Using the stream  
       
   215 	RDbColWriteStream out;
       
   216 	TDbColNo col = colSet->ColNo( KBinaryGrammarColumn ); // Ordinal position of long column	
       
   217 	out.OpenLC( view, col );
       
   218 	out.WriteL( aWriteBuf );	
       
   219 	out.Close();	
       
   220 	CleanupStack::PopAndDestroy(); // out
       
   221 
       
   222 	// add  size of the buffer
       
   223 	col = colSet->ColNo( KBinaryGrammarColumnSize ); // Ordinal position of  size	
       
   224 	view.SetColL( col, BufSize ); 	
       
   225 	view.PutL();
       
   226  
       
   227 	CleanupStack::PopAndDestroy( dataCopyBuffer );
       
   228 	CleanupStack::PopAndDestroy( colSet );
       
   229 
       
   230 	// close the view
       
   231 	CleanupStack::PopAndDestroy( &view ); // Close view
       
   232     }
       
   233 
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // CSIGrammarDB::FindGrammarL
       
   237 // Find a grammar from loaded grammar array
       
   238 // -----------------------------------------------------------------------------
       
   239 CSICompiledGrammar*  CSIGrammarDB::FindGrammarL(TSIGrammarID aGrammarID) 
       
   240     {
       
   241     RUBY_DEBUG_BLOCK( "CSIGrammarDB::FindGrammarL" );
       
   242     
       
   243     TInt i(0);
       
   244     CSICompiledGrammar* aGrammar=NULL;
       
   245     
       
   246     // Check if grammar already loaded
       
   247     for ( i = 0; i < iGrammarArray.Count(); i++ )
       
   248         {
       
   249         if ( iGrammarArray[i]->GrammarID()==aGrammarID  )
       
   250             { 
       
   251             aGrammar=iGrammarArray[i];
       
   252             break;
       
   253             }		
       
   254         }
       
   255     // Can not found in the loaded grammar array
       
   256     if(i==iGrammarArray.Count())
       
   257         User::Leave(KErrNotFound);
       
   258     
       
   259     return aGrammar;
       
   260     }
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // CSIGrammarDB::GetNewID
       
   264 // Get a new uniq ID 
       
   265 // -----------------------------------------------------------------------------
       
   266 TInt CSIGrammarDB::GetNewID( RArray<TSIRuleID>& aMyIds )
       
   267     {
       
   268     RArray<TSIRuleID> myIDs = aMyIds;
       
   269     TInt Count = myIDs.Count();
       
   270     TInt id = 0;
       
   271     if ( Count == 0 )
       
   272         {
       
   273         id = 1; // empty ,first id will be 1
       
   274         }
       
   275     else
       
   276         { 
       
   277         // Find a unique  ID
       
   278         myIDs.SortUnsigned();
       
   279         id = myIDs[myIDs.Count() - 1] + 1; //by default , the last one 
       
   280         for ( TInt i = 0; i < myIDs.Count(); i++ )
       
   281             {
       
   282             TInt index = i + 1; 
       
   283             TInt s = myIDs[i];
       
   284             if ( s > index )
       
   285                 {
       
   286                 id = index;
       
   287                 break;
       
   288                 }
       
   289             }
       
   290         }
       
   291     return id;
       
   292     }
       
   293 
       
   294 // -----------------------------------------------------------------------------
       
   295 // CSIGrammarDB::CreateRuleL
       
   296 // Creates a new empty rule.
       
   297 // -----------------------------------------------------------------------------
       
   298 void CSIGrammarDB::CreateRuleL( TUid aClientUid, TSIGrammarID aGrammarID, 
       
   299                                 TSIRuleID& aRuleID )
       
   300     {
       
   301     RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateRuleL" );
       
   302 
       
   303     //__UHEAP_MARK;
       
   304     VerifyOwnershipL( aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID );
       
   305     // find the grammar from the database 
       
   306     CSICompiledGrammar* aGrammar = (CSICompiledGrammar*) GrammarL( aGrammarID );
       
   307     CleanupStack::PushL( aGrammar );
       
   308     
       
   309     TInt aID = 0;
       
   310     TInt Count=aGrammar->Count();
       
   311     
       
   312     // existing myRuleVariantID
       
   313     RArray<TSIRuleID> myIDs;
       
   314     myIDs.Reset();
       
   315     for(TInt i = 0; i < Count; i++ )
       
   316         {
       
   317         CSIRule* aRule = &( aGrammar->AtL( i ) );
       
   318         myIDs.Append( aRule->RuleID() );
       
   319         } 
       
   320     
       
   321     // Find a uniq new id 
       
   322     aID=GetNewID( myIDs );
       
   323     myIDs.Close();
       
   324     aRuleID=aID;
       
   325     
       
   326     // add the rule to the grammar	
       
   327     CSIRule* rule = CSIRule::NewL( aRuleID );
       
   328     CleanupStack::PushL( rule );	
       
   329     aGrammar->AddL( rule );
       
   330     CleanupStack::Pop( rule );
       
   331     
       
   332     UpdateGrammarL( aClientUid, aGrammar );
       
   333     CleanupStack::PopAndDestroy( aGrammar );
       
   334     //__UHEAP_MARKEND;
       
   335     } 
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CSIGrammarDB::AddRuleVariantL
       
   339 // Add Rule Variant to the array that hold the grammar array
       
   340 // -----------------------------------------------------------------------------
       
   341 void CSIGrammarDB::AddRuleVariantL(TUid aClientUid,
       
   342 								   TSIGrammarID aGrammarID, 								 
       
   343 								   TSILexiconID aLexiconID,
       
   344 								   const RArray<TSIPronunciationID>& aPronunciationIDs, 								     
       
   345 								   TSIRuleID aRuleID,
       
   346 								   TSIRuleVariantID& aRuleVariantID) 
       
   347     {
       
   348     VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID);
       
   349     
       
   350     CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID);
       
   351     CleanupStack::PushL(aGrammar);
       
   352     
       
   353     CSIRule* aRule=&(aGrammar->RuleL(aRuleID));
       
   354     // existing myRuleVariantID
       
   355     RArray<TSIRuleID> myID;
       
   356     myID.Reset();
       
   357     for( TInt i = 0; i < aRule->Count(); i++ )
       
   358         {
       
   359         CSIRuleVariant* aRuleVariant=&(aRule->AtL(i));
       
   360         myID.Append(aRuleVariant->RuleVariantID());
       
   361         }
       
   362     
       
   363     // Find a uniq new id 
       
   364     aRuleVariantID=STATIC_CAST(TSIRuleVariantID,GetNewID(myID));
       
   365     myID.Close();	
       
   366     
       
   367     // add the rule variant to the rule
       
   368     CSIRuleVariant* ruleVariant = CSIRuleVariant::NewL( aRuleVariantID, aLexiconID );
       
   369     CleanupStack::PushL( ruleVariant );	
       
   370     ruleVariant->SetPronunciationIDsL(aPronunciationIDs);
       
   371     aRule->AddL( ruleVariant );
       
   372     CleanupStack::Pop( ruleVariant );
       
   373     UpdateGrammarL( aClientUid, aGrammar );
       
   374     CleanupStack::PopAndDestroy( aGrammar );	  
       
   375     }
       
   376 
       
   377 // -----------------------------------------------------------------------------
       
   378 // CSIGrammarDB::LoadGrammarL
       
   379 // Loads all rules within the specified grammar into a grammar object, which
       
   380 // is loaded into recognizer during recognition session.
       
   381 // Note : Will leave if already loaded
       
   382 // -----------------------------------------------------------------------------
       
   383 //
       
   384 const CSICompiledGrammar* CSIGrammarDB::LoadGrammarL( TSIGrammarID aGrammarID )
       
   385     {
       
   386     // Construct the table name using the provided grammar ID
       
   387     // Construct the table name using the provided grammar ID
       
   388     // Declare a literal string to hold the SQL statement
       
   389     // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM  KGrammarName
       
   390     TBuf<40> KGrammarName(KSIGrammarTable);
       
   391     KGrammarName.AppendNumUC(aGrammarID);
       
   392     
       
   393     // Create newGrammar object	
       
   394     CSICompiledGrammar* grammar = CSICompiledGrammar::NewLC( aGrammarID );	
       
   395     _LIT(KSQLSelect1,"select  ");	
       
   396     _LIT(KSQLSelect2," from  ");
       
   397     TBuf<120> KSQLStatement;		
       
   398     KSQLStatement.Append(KSQLSelect1  );		
       
   399     KSQLStatement.Append(KBinaryGrammarColumn );
       
   400     KSQLStatement.Append(KNext);
       
   401     KSQLStatement.Append(KBinaryGrammarColumnSize );
       
   402     KSQLStatement.Append(KSQLSelect2  );
       
   403     KSQLStatement.Append(KGrammarName); 
       
   404     
       
   405     // create a view on the database
       
   406     RDbView view;
       
   407     CleanupClosePushL( view );
       
   408     
       
   409     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   410     User::LeaveIfError(view.EvaluateAll());
       
   411     
       
   412     // Get the structure of the rowset 
       
   413     CDbColSet* colSet = view.ColSetL();
       
   414     CleanupStack::PushL( colSet );
       
   415     
       
   416     // iterate across the row set, one row only
       
   417     for (view.FirstL();view.AtRow();view.NextL())
       
   418         {
       
   419         
       
   420         // retrieve the row
       
   421         view.GetL();		
       
   422         
       
   423         // first retrieve the size of binary package 
       
   424         TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column 
       
   425         TInt32 size = view.ColUint32( col);
       
   426         
       
   427         TUint8* buf = new (ELeave) TUint8[size];		
       
   428         CleanupStack::PushL( buf);			
       
   429         TPtr8 readBuf( buf, size, size);
       
   430         CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   431         CleanupStack::PushL(dataCopyBuffer);              // when the buffer is full
       
   432         
       
   433         RBufReadStream stream;
       
   434         CleanupClosePushL( stream );
       
   435         stream.Open(*dataCopyBuffer);
       
   436         
       
   437         // and a stream for long columns
       
   438         RDbColReadStream in;
       
   439         CleanupClosePushL( in );
       
   440         col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column 
       
   441         
       
   442         
       
   443         in.OpenLC(view, col);
       
   444         in.ReadL( readBuf, view.ColLength(col));
       
   445         dataCopyBuffer->InsertL(0,readBuf);
       
   446         grammar->InternalizeL( stream );
       
   447         
       
   448         CleanupStack::PopAndDestroy( col );
       
   449         CleanupStack::PopAndDestroy( &in );
       
   450         CleanupStack::PopAndDestroy( &stream ); 
       
   451         CleanupStack::PopAndDestroy( dataCopyBuffer );
       
   452         CleanupStack::PopAndDestroy( buf );
       
   453         } 
       
   454         
       
   455     CleanupStack::PopAndDestroy( colSet );
       
   456     CleanupStack::PopAndDestroy( &view );
       
   457     
       
   458     // Keep the reference of the grammar object
       
   459     User::LeaveIfError(iGrammarArray.Append(grammar));
       
   460     // Cleanup grammar
       
   461     CleanupStack::Pop(grammar );
       
   462     return grammar;
       
   463     }
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // CSIGrammarDB::GrammarL
       
   467 // Loads all rules within the specified grammar into a grammar object, which
       
   468 // is loaded into recognizer during recognition session.
       
   469 // Note : Will leave if already loaded
       
   470 // -----------------------------------------------------------------------------
       
   471 //
       
   472 const CSICompiledGrammar* CSIGrammarDB::GrammarL( TSIGrammarID aGrammarID )
       
   473     {
       
   474  	  
       
   475     // Construct the table name using the provided grammar ID
       
   476     // Construct the table name using the provided grammar ID
       
   477     // Declare a literal string to hold the SQL statement
       
   478     // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM  KGrammarName
       
   479     TBuf<40> KGrammarName(KSIGrammarTable);
       
   480     KGrammarName.AppendNumUC(aGrammarID);
       
   481     // Create newGrammar object	 
       
   482     CSICompiledGrammar* aGrammar = CSICompiledGrammar::NewLC( aGrammarID );
       
   483     _LIT(KSQLSelect1,"select  ");
       
   484     _LIT(KSQLSelect2," from  ");
       
   485     
       
   486     TBuf<120> KSQLStatement;		
       
   487     KSQLStatement.Append(KSQLSelect1  );		
       
   488     KSQLStatement.Append(KBinaryGrammarColumn );
       
   489     KSQLStatement.Append(KNext);
       
   490     KSQLStatement.Append(KBinaryGrammarColumnSize );
       
   491     KSQLStatement.Append(KSQLSelect2  );
       
   492     KSQLStatement.Append(KGrammarName); 
       
   493     
       
   494     // create a view on the database
       
   495     RDbView view;
       
   496     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   497     
       
   498     User::LeaveIfError(view.EvaluateAll());
       
   499     
       
   500     // Get the structure of the rowset 
       
   501     CDbColSet* colSet = view.ColSetL();
       
   502     
       
   503     // iterate across the row set, one row only
       
   504     for (view.FirstL();view.AtRow();view.NextL())
       
   505         {
       
   506         
       
   507         // retrieve the row
       
   508         view.GetL();
       
   509         
       
   510         // first retrieve the size of binary package 
       
   511         TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column 
       
   512         TInt32 Size = view.ColUint32( col);
       
   513         
       
   514         TUint8* aBuf = new (ELeave) TUint8[Size];		
       
   515         CleanupStack::PushL(aBuf);			
       
   516         TPtr8 aReadBuf(aBuf, Size, Size);
       
   517         CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   518         CleanupStack::PushL(dataCopyBuffer);              // when the buffer is full
       
   519         
       
   520         RBufReadStream stream;
       
   521         stream.Open(*dataCopyBuffer);
       
   522         
       
   523         // and a stream for long columns
       
   524         RDbColReadStream in;
       
   525         col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column 
       
   526         
       
   527         
       
   528         in.OpenLC(view, col);
       
   529         in.ReadL(aReadBuf, view.ColLength(col));
       
   530         dataCopyBuffer->InsertL(0,aReadBuf);
       
   531         aGrammar->InternalizeL( stream );
       
   532         
       
   533         in.Close(); 		
       
   534         CleanupStack::PopAndDestroy(3); // in dataCopyBuffer aBuf
       
   535         }
       
   536     //! clean the memory
       
   537     delete colSet;
       
   538     view.Close();  
       
   539     
       
   540     // Keep the reference of the grammar object
       
   541     // Cleanup grammar
       
   542     CleanupStack::Pop( aGrammar );
       
   543     
       
   544     return aGrammar;
       
   545     }
       
   546 
       
   547 // -----------------------------------------------------------------------------
       
   548 // CSIGrammarDB::CreateIDTableL
       
   549 // Creates a new grammar ID table in the database.
       
   550 // -----------------------------------------------------------------------------
       
   551 //
       
   552 void CSIGrammarDB::CreateIDTableL()
       
   553     {
       
   554     // Invoke function in the base class CSICommonDB.
       
   555     CSICommonDB::CreateIDTableL(KGrammarIdTable, KGrammarIdColumn, KGrammarIndex);
       
   556     }
       
   557 
       
   558 // -----------------------------------------------------------------------------
       
   559 // CSIGrammarDB::GetAllClientGrammarIDsL
       
   560 // This function returns all grammar IDs owned by the specified client.
       
   561 // -----------------------------------------------------------------------------
       
   562 //
       
   563 void CSIGrammarDB::GetAllClientGrammarIDsL( TUid aClientUid,
       
   564                                             RArray<TSIGrammarID>& aGrammarIDs )
       
   565     {
       
   566     RArray<TUint32> ix; 
       
   567     ix.Reset();	
       
   568     GetAllClientIDsL(KGrammarIdTable, KGrammarIdColumn, aClientUid, ix);
       
   569     for(TInt i=0;i<ix.Count();i++) {
       
   570         aGrammarIDs.Append(STATIC_CAST(TSIGrammarID,ix[i]));
       
   571         }
       
   572     ix.Close();
       
   573     }
       
   574 
       
   575 // -----------------------------------------------------------------------------
       
   576 // CSIGrammarDB::GetAllGrammarIDsL
       
   577 // This function returns all grammar IDs in the database.
       
   578 // -----------------------------------------------------------------------------
       
   579 //
       
   580 void CSIGrammarDB::GetAllGrammarIDsL( RArray<TSIGrammarID>& aGrammarIDs )
       
   581     {
       
   582     // This is a hack to get the id aligned to 4-byte boundary,
       
   583     // for some reason this does not happen in winscw build if 
       
   584     // TSIGrammarID is taken from stack.
       
   585     TSIGrammarID* id = new (ELeave) TSIGrammarID;
       
   586     
       
   587     CleanupStack::PushL( id );
       
   588     
       
   589     RArray<TUint32> ix;
       
   590     //! Reset
       
   591     ix.Reset(); 
       
   592     GetAllIDsL(KGrammarIdTable, KGrammarIdColumn,  ix);
       
   593     for(TInt i=0;i<ix.Count();i++) 
       
   594         {
       
   595         *id = STATIC_CAST( TSIGrammarID, ix[i] );
       
   596         aGrammarIDs.Append( *id );
       
   597         }
       
   598     ix.Close();
       
   599     CleanupStack::PopAndDestroy( id );
       
   600     }
       
   601 
       
   602 // -----------------------------------------------------------------------------
       
   603 // CSIGrammarDB::GetAllRuleIDsL
       
   604 // This function returns all rule IDs within the specified grammar.
       
   605 // grammar have to be loaded 
       
   606 // -----------------------------------------------------------------------------
       
   607 //
       
   608 void CSIGrammarDB::GetAllRuleIDsL( TSIGrammarID aGrammarID,
       
   609                                    RArray<TSIRuleID>& aRuleIDs )
       
   610     {
       
   611 	CleanupClosePushL( aRuleIDs );
       
   612 	
       
   613     // Construct the table name using the provided grammar ID
       
   614     TBuf<40> KGrammarName(KSIGrammarTable);
       
   615     KGrammarName.AppendNumUC(aGrammarID);
       
   616     
       
   617     CSICompiledGrammar* newgrammar =( CSICompiledGrammar* )GrammarL( aGrammarID) ;// Load the grammar from database	
       
   618     CleanupStack::PushL(newgrammar);
       
   619     TSIRuleID	RuleId;
       
   620     
       
   621     for (TInt  i=0;i<newgrammar->Count();i++) {
       
   622         CSIRule* aRule=&(newgrammar->AtL(i));
       
   623         RuleId=aRule->RuleID();		
       
   624         User::LeaveIfError(aRuleIDs.Append(RuleId));
       
   625         } 
       
   626     CleanupStack::PopAndDestroy(newgrammar);
       
   627     CleanupStack::Pop();
       
   628     }
       
   629 
       
   630 // -----------------------------------------------------------------------------
       
   631 // CSIGrammarDB::RemoveGrammarL
       
   632 // Deletes a grammar table from the database.
       
   633 // -----------------------------------------------------------------------------
       
   634 //
       
   635 void CSIGrammarDB::RemoveGrammarL( TUid aClientUid,
       
   636                                    TSIGrammarID aGrammarID )
       
   637     {
       
   638     VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID);
       
   639     
       
   640     TInt diskSpace = ( RuleCountL(aGrammarID) * sizeof( CSIRule) ) 
       
   641         + sizeof( CSIGrammar );
       
   642     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) );
       
   643     
       
   644     // Construct the table name using the provided grammar ID
       
   645     TBuf<40> KGrammarName(KSIGrammarTable);
       
   646     KGrammarName.AppendNumUC(aGrammarID);
       
   647     
       
   648     TBuf<50> KSQLStatement;
       
   649     // Declare a literal string to hold the SQL statement
       
   650     // DROP TABLE KGrammarName
       
   651     _LIT(KSQLDelete1, "DROP TABLE ");
       
   652     
       
   653     KSQLStatement = KSQLDelete1;
       
   654     KSQLStatement.Append(KGrammarName);
       
   655     
       
   656     User::LeaveIfError(iDb.Execute(KSQLStatement));
       
   657     
       
   658     // Release the grammar ID
       
   659     ReleaseIdL(KGrammarIdTable, KGrammarIdColumn, aGrammarID);
       
   660     
       
   661     // Cancel free disk space request
       
   662     iDbSession.FreeReservedSpace( iDrive );
       
   663     }
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // CSIGrammarDB::RuleCountL
       
   667 // Returns the number of rules in the specified grammar.
       
   668 // Grammar have to be loaded
       
   669 // -----------------------------------------------------------------------------
       
   670 //
       
   671 TInt CSIGrammarDB::RuleCountL( TSIGrammarID aGrammarID )
       
   672     {
       
   673     // Load a grammar
       
   674     CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID);
       
   675     CleanupStack::PushL(aGrammar);  
       
   676     // Count the number of the rules inside the grammar
       
   677     TInt RuleCount=aGrammar->Count();	 
       
   678     CleanupStack::PopAndDestroy(aGrammar);
       
   679     return RuleCount;
       
   680     }
       
   681 
       
   682 // -----------------------------------------------------------------------------
       
   683 // CSIGrammarDB::RemoveRuleL
       
   684 // Deletes Rule from the database.
       
   685 // Grammar have to be loaded
       
   686 // -----------------------------------------------------------------------------
       
   687 //  
       
   688 void CSIGrammarDB::RemoveRuleL( TUid aClientUid, 
       
   689                                 TSIGrammarID aGrammarID,
       
   690                                 TSIRuleID aRuleID )
       
   691     {
       
   692     VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID);
       
   693     CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID);	 
       
   694     
       
   695     CleanupStack::PushL(aGrammar);  
       
   696     if (aGrammar->Find(aRuleID)==KErrNotFound)
       
   697         {
       
   698         User::Leave(KErrNotFound);
       
   699         }
       
   700     else
       
   701         {
       
   702         aGrammar->DeleteL(aRuleID);
       
   703         }
       
   704     UpdateGrammarL(aClientUid,aGrammar);
       
   705     CleanupStack::PopAndDestroy(aGrammar);
       
   706     }
       
   707 
       
   708 // -----------------------------------------------------------------------------
       
   709 // CSIGrammarDB::IsGrammarLoaded
       
   710 // Checks to see if a valid grammar is loaded into the recognizer.  This is
       
   711 // useful to check if any rules are still loaded after performing UnloadRule().
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 TBool CSIGrammarDB::IsGrammarLoaded()
       
   715     {
       
   716     for ( TInt i = 0; i < iGrammarArray.Count(); i++ )
       
   717         {
       
   718         if ( iGrammarArray[i]->Count() > 0 )
       
   719             {
       
   720             // As long as there is still a rule.
       
   721             return ETrue;
       
   722             }
       
   723         }
       
   724     return EFalse;
       
   725     }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // CSIGrammarDB::IsRuleValidL
       
   729 // Checks if the rule is valid or not.
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 TBool CSIGrammarDB::IsRuleValidL( TSIGrammarID aGrammarID, TSIRuleID aRuleID )
       
   733     {
       
   734     CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID);
       
   735     CleanupStack::PushL(aGrammar);  
       
   736     if (aGrammar->Find(aRuleID)==KErrNotFound)
       
   737         {
       
   738         CleanupStack::PopAndDestroy(aGrammar);
       
   739         return EFalse; 
       
   740         }
       
   741     else {
       
   742         CleanupStack::PopAndDestroy(aGrammar);
       
   743         return ETrue;	
       
   744         }
       
   745     }
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // CSIGrammarDB::ResetAndDestroy
       
   749 // Deallocates the temporary memory containing the grammar object created with
       
   750 // AllRulesL.
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 void CSIGrammarDB::ResetAndDestroy()
       
   754     {
       
   755     iGrammarArray.ResetAndDestroy();
       
   756     }
       
   757 
       
   758 // -----------------------------------------------------------------------------
       
   759 // CSIGrammarDB::UnloadRule
       
   760 // Unloads the specified rule from the specified grammar in temporary memory,
       
   761 // previously loaded with AllRulesL.  The rule in the database remains intact.
       
   762 // -----------------------------------------------------------------------------
       
   763 //
       
   764 void CSIGrammarDB::UnloadRuleL( TSIGrammarID aGrammarID,
       
   765                                 TSIRuleID aRuleID )
       
   766     {
       
   767     CSIGrammar* grammar;
       
   768     
       
   769     for( TInt i = 0; i < iGrammarArray.Count(); i++ )
       
   770         {
       
   771         grammar = iGrammarArray[i];
       
   772         if ( grammar->GrammarID() == aGrammarID )
       
   773             {
       
   774             grammar->DeleteL(aRuleID);
       
   775             return;
       
   776             }
       
   777         }
       
   778     User::Leave(KErrNotFound);
       
   779     }
       
   780 
       
   781 // -----------------------------------------------------------------------------
       
   782 // CSIGrammarDB::UnloadGrammar
       
   783 // Unloads  the specified grammar in temporary memory,
       
   784 // previously loaded with AllRulesL.  The grammar in the database remains intact.
       
   785 // -----------------------------------------------------------------------------
       
   786 //
       
   787 void CSIGrammarDB::UnloadGrammarL( TSIGrammarID aGrammarID)
       
   788     {
       
   789     CSIGrammar* grammar;
       
   790     
       
   791     for( TInt i = 0; i < iGrammarArray.Count(); i++ )
       
   792         {
       
   793         grammar = iGrammarArray[i];
       
   794         if ( grammar->GrammarID() == aGrammarID )
       
   795             {
       
   796             //! delete the object 
       
   797             delete iGrammarArray[i];
       
   798             // remove the pointer
       
   799             iGrammarArray.Remove(i);
       
   800             return;
       
   801             }
       
   802         }
       
   803     User::Leave(KErrNotFound);
       
   804     }
       
   805 
       
   806 //  End of File