metadataengine/server/src/mdssqlfindoperation.cpp
changeset 0 c53acadfccc6
child 15 3cebc1a84278
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2005-2009 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:  Manages object search from database using SQL,*
       
    15 */
       
    16 
       
    17 #include "mdssqlfindoperation.h"
       
    18 
       
    19 #include "mdcresult.h"
       
    20 #include "mdcitem.h"
       
    21 #include "mdcserializationbuffer.h"
       
    22 #include "mdsfindsequence.h"
       
    23 #include "mdsobjectdef.h"
       
    24 #include "mdsnamespacedef.h"
       
    25 #include "mdspropertydef.h"
       
    26 #include "mdsfindsqlclause.h"
       
    27 #include "mdsserver.h"
       
    28 #include "mdsdbconnectionpool.h"
       
    29 #include "mdeinternalerror.h"
       
    30 
       
    31 const TInt KMaxResultSize = 1024*256; // 256 KiB
       
    32 
       
    33 CMdSSqlFindOperation* CMdSSqlFindOperation::NewL(
       
    34     CMdSFindSequence& aFind,
       
    35     TUint aSetSize
       
    36     )
       
    37     {
       
    38     CMdSSqlFindOperation* that = CMdSSqlFindOperation::NewLC(
       
    39         aFind, aSetSize );
       
    40     CleanupStack::Pop( that );
       
    41     return that;
       
    42     }
       
    43 
       
    44 CMdSSqlFindOperation* CMdSSqlFindOperation::NewLC(    
       
    45     CMdSFindSequence& aFind,
       
    46     TUint aSetSize
       
    47     )
       
    48     {
       
    49     CMdSSqlFindOperation* that = new (ELeave) CMdSSqlFindOperation(        
       
    50         aFind, 
       
    51         aSetSize
       
    52         );
       
    53     CleanupStack::PushL( that );
       
    54     that->ConstructL();
       
    55     return that;
       
    56     }
       
    57 
       
    58 CMdSSqlFindOperation::CMdSSqlFindOperation(    
       
    59     CMdSFindSequence& aFind,
       
    60     TUint aSetSize
       
    61     )
       
    62     : iResultMode( EQueryResultModeFirst ), iResultRow(NULL),
       
    63     iResultRows(), iResultCount( 0 ), iResults( NULL ), iFind ( aFind ),
       
    64     iState( EStateIdle ), iSetSize( aSetSize ), iLimit( 0 ), 
       
    65     iLimitCounter( 0 ), iMemoryLimit( 0 ), 
       
    66     iHarvestingPrioritizationCount( 0 )
       
    67     {
       
    68     }
       
    69 
       
    70 void CMdSSqlFindOperation::ConstructL()
       
    71     {    
       
    72 	iFindClause = CMdSFindSqlClause::NewL( const_cast<CMdsSchema&>(iFind.Schema()) );	
       
    73     }
       
    74 
       
    75 
       
    76 CMdSSqlFindOperation::~CMdSSqlFindOperation()
       
    77     {
       
    78 	ConsumeRows();
       
    79     iResultRows.Close();
       
    80 
       
    81     iResultIds.Close();
       
    82 
       
    83     // doesn't own result row
       
    84     iResultRow = NULL;
       
    85 
       
    86     iQueryId.Close();
       
    87 
       
    88    	delete iResults;
       
    89    	delete iFindClause;
       
    90     }
       
    91 
       
    92 TInt CMdSSqlFindOperation::ExecuteL()
       
    93     {
       
    94     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
    95 
       
    96     iResultRow = &iFindClause->ResultRow();
       
    97     iQueryType = iFindClause->QueryType();
       
    98     iResultMode = iFindClause->ResultMode();
       
    99 
       
   100 	if( EQueryResultModeFirst >= iResultMode || EQueryResultModeLast <= iResultMode )
       
   101 		{
       
   102 #ifdef _DEBUG
       
   103 		User::Panic( _L("MdSFOExe") , KErrMdEUnknownQueryResultMode );
       
   104 #endif
       
   105 
       
   106 		User::Leave( KErrMdEUnknownQueryResultMode );
       
   107 		}
       
   108 
       
   109    	iFind.SetResultMode( iQueryType == EQueryTypeObject && iResultMode == EQueryResultModeItem );
       
   110         
       
   111    	connection.ExecuteQueryL( iFindClause->AsTextL(), iQueryId, iFindClause->Variables() );
       
   112 
       
   113     iState = EStateRunning;
       
   114 
       
   115 	iSetCounter = 0;
       
   116 	iMemoryLimit = 0;
       
   117 	iHarvestingPrioritizationCount = 0;
       
   118 
       
   119     return FetchResultsL();
       
   120     }
       
   121 
       
   122 TInt CMdSSqlFindOperation::ContinueL()
       
   123     {
       
   124     // Continue query: fetch next row
       
   125     iSetCounter = 0;
       
   126     iState = EStateRunning;
       
   127 
       
   128     return FetchResultsL();
       
   129     }
       
   130 
       
   131 TInt CMdSSqlFindOperation::FetchResultsL()
       
   132     {
       
   133 	iMemoryLimit += EstimateBaseResultSize();
       
   134 	
       
   135 	if( !iResultRow )
       
   136 		{
       
   137 #ifdef _DEBUG
       
   138 		User::Panic( _L("MdSFOFe1") , KErrCorrupt );
       
   139 #endif
       
   140 
       
   141 		User::Leave( KErrCorrupt );
       
   142 		}
       
   143 
       
   144     CMdSSqLiteConnection& connection = MMdSDbConnectionPool::GetDefaultDBL();
       
   145 
       
   146     while( ETrue )
       
   147         {
       
   148         RRowData* resultRow = new (ELeave) RRowData();        
       
   149         CleanupStack::PushL( resultRow );
       
   150         CleanupClosePushL( *resultRow );
       
   151 
       
   152         resultRow->AppendColumnTypesL( *iResultRow );
       
   153 
       
   154         // fetch next DB row
       
   155         if ( !connection.NextRowL( iQueryId, *resultRow ) )
       
   156             {
       
   157             CleanupStack::PopAndDestroy( 2, resultRow ); // close and delete resultRow separately
       
   158             resultRow = NULL;
       
   159 
       
   160            	TRAPD( err, AddToContainerL() );
       
   161 
       
   162            	if( KErrNone != err )
       
   163            		{
       
   164            		iResults = NULL;
       
   165            		ConsumeRows();
       
   166            		}
       
   167 
       
   168            	connection.Terminate( iQueryId );
       
   169             iState = EStateDead;
       
   170             return KErrNone;
       
   171             }
       
   172 
       
   173         iMemoryLimit += EstimateResultRowSizeL( *resultRow );
       
   174 
       
   175 		// Check if maximum memory limit is reached or 
       
   176 		// set/limit counter is more than maximum set/limit size. 
       
   177 		if( KMaxResultSize <= iMemoryLimit )
       
   178 			{
       
   179 			// Store all previus items to result buffer.
       
   180 
       
   181            	TRAPD( err, AddToContainerL() );
       
   182 
       
   183            	if( KErrNone != err )
       
   184            		{
       
   185            		iResults = NULL;
       
   186            		ConsumeRows();
       
   187            		}
       
   188 
       
   189 			// add estimated size to next result set
       
   190 	        iMemoryLimit = EstimateResultRowSizeL( *resultRow );
       
   191 
       
   192 			if( EQueryResultModeItem == iResultMode || EQueryResultModeDistinctValues == iResultMode )
       
   193 				{
       
   194 				// add result row to result rows pointer array
       
   195 	           	iResultRows.AppendL( resultRow );
       
   196 				
       
   197 				iSetCounter++;
       
   198 	           	
       
   199 				// pop result row from cleanup stack twice
       
   200 				CleanupStack::Pop( 2, resultRow );
       
   201 				}
       
   202 			else
       
   203 				{
       
   204 				if( EQueryResultModeId == iResultMode )
       
   205 					{					
       
   206 					TItemId itemId = 0;
       
   207 					resultRow->Column( 0 ).Get( itemId );
       
   208 					iResultIds.AppendL( itemId );
       
   209 
       
   210 					iSetCounter++;
       
   211 					}
       
   212 				else
       
   213 					{
       
   214 					TUint32 count;
       
   215 					resultRow->Column( 0 ).Get( count );
       
   216 					iResultCount += count;
       
   217 					}
       
   218 
       
   219 				// pop and destroy result row from cleanup stack twice
       
   220 				CleanupStack::PopAndDestroy( 2, resultRow );
       
   221 				}
       
   222 
       
   223 
       
   224 			resultRow = NULL;
       
   225 
       
   226            	++iLimitCounter;
       
   227                 
       
   228             iState = EStateIdle;
       
   229             connection.EnableTransaction( EFalse, iQueryId );
       
   230             return KFindSetReady;
       
   231 			}
       
   232 		else
       
   233 			{
       
   234 			if( EQueryResultModeItem == iResultMode || EQueryResultModeDistinctValues == iResultMode )
       
   235 				{
       
   236 				// add result row to result rows pointer array
       
   237 	           	iResultRows.AppendL( resultRow );
       
   238 
       
   239 				iSetCounter++;
       
   240 
       
   241 				// pop result row from cleanup stack twice
       
   242 				CleanupStack::Pop( 2, resultRow );
       
   243 				}
       
   244 			else 
       
   245 				{
       
   246 				if( EQueryResultModeId == iResultMode )
       
   247 					{					
       
   248 					TItemId itemId = 0;
       
   249 					resultRow->Column( 0 ).Get( itemId );
       
   250 					iResultIds.AppendL( itemId ); 
       
   251 
       
   252 					iSetCounter++;
       
   253 					}
       
   254 				else
       
   255 					{
       
   256 					TUint32 count;
       
   257 					resultRow->Column( 0 ).Get( count );
       
   258 					iResultCount += count;
       
   259 					}
       
   260 
       
   261 				// pop and destroy result row from cleanup stack twice
       
   262 				CleanupStack::PopAndDestroy( 2, resultRow );
       
   263 				}
       
   264 
       
   265 			resultRow = NULL;
       
   266 
       
   267 			++iLimitCounter;
       
   268 			}
       
   269 
       
   270         // check for different exit conditions
       
   271         if ( iState == EStateRunning )
       
   272             {
       
   273             if ( iLimitCounter >= iLimit )
       
   274                 {
       
   275 	           	TRAPD( err, AddToContainerL() );
       
   276 
       
   277 	           	if( KErrNone != err )
       
   278 	           		{
       
   279 	           		iResults = NULL;
       
   280 	           		ConsumeRows();
       
   281 	           		}
       
   282 
       
   283 	           	connection.Terminate( iQueryId );
       
   284                 iState = EStateDead;
       
   285                 return KErrNone;
       
   286                 }
       
   287             else if( iSetCounter >= iSetSize )
       
   288                 {
       
   289 	           	TRAPD( err, AddToContainerL() );
       
   290 
       
   291 	           	if( KErrNone != err )
       
   292 	           		{
       
   293 	           		iResults = NULL;
       
   294 	           		ConsumeRows();
       
   295 	           		}
       
   296 
       
   297                 iState = EStateIdle;
       
   298                 connection.EnableTransaction( EFalse, iQueryId );
       
   299                 return KFindSetReady;
       
   300                 }
       
   301             }
       
   302         else if ( iState == EStateStop )
       
   303             {
       
   304             // stop instructed
       
   305             connection.Terminate( iQueryId );
       
   306             iState = EStateDead;
       
   307             return KErrCancel;
       
   308             }
       
   309         else 
       
   310             {
       
   311 #ifdef _DEBUG
       
   312 	    	User::Panic( _L("MdSFOFe2") , KErrCorrupt );
       
   313 #endif
       
   314 	    	User::Leave( KErrCorrupt );
       
   315             }
       
   316         }
       
   317     }
       
   318 
       
   319 TInt CMdSSqlFindOperation::EstimateBaseResultSize()
       
   320 	{
       
   321 	switch( iResultMode )
       
   322 		{
       
   323 		case EQueryResultModeItem:
       
   324 			return sizeof(TMdCItems);
       
   325 
       
   326 		case EQueryResultModeId:
       
   327 			return sizeof(TMdCItemIds);
       
   328 
       
   329 		case EQueryResultModeCount:
       
   330 			return sizeof(TMdCItemCounts);
       
   331 
       
   332 		case EQueryResultModeDistinctValues:
       
   333 			return sizeof(TMdCItemIds);
       
   334 
       
   335 		// should never happen
       
   336 		default:
       
   337 #ifdef _DEBUG
       
   338 			User::Panic( _L( "MdSFOEBS" ), KErrMdEUnknownQueryResultMode );
       
   339 #endif
       
   340 			return 0;
       
   341 		}
       
   342 	}
       
   343 
       
   344 TInt CMdSSqlFindOperation::EstimateResultRowSizeL( RRowData& aRow )
       
   345 	{
       
   346 	if( iResultMode == EQueryResultModeId )
       
   347 		{
       
   348 		return CMdCSerializationBuffer::KRequiredSizeForTItemId;
       
   349 		}
       
   350 	else if( iResultMode == EQueryResultModeCount )
       
   351 		{
       
   352 		return 0;
       
   353 		}
       
   354 	else if( iResultMode == EQueryResultModeDistinctValues )
       
   355 		{
       
   356 		if( iFindClause->PropertyFilters().Count() != 1 )
       
   357 			{
       
   358 			User::Leave( KErrCorrupt );
       
   359 			}
       
   360 
       
   361 		const RPointerArray<CMdsPropertyDef>& propertyFilters = iFindClause->PropertyFilters();
       
   362 
       
   363 		TInt rowSize = 0;
       
   364 		if( propertyFilters[0]->GetType() == EPropertyText )
       
   365 	    	{
       
   366 	    	if ( !aRow.Column( 0 ).IsNull() )
       
   367 	    		{
       
   368 				// Required size for text property
       
   369 				TPtrC16 value = TPtr16((TUint16*)0, 0);
       
   370 				aRow.Column( 0 ).Get( value );
       
   371 				rowSize += CMdCSerializationBuffer::RequiredSize( value );
       
   372 	    		}	    		
       
   373 	    	}
       
   374 	    else
       
   375 	    	{
       
   376 #ifdef _DEBUG
       
   377 	    	User::Panic( _L("MdSFOEs1") , KErrMdEUnknownPropertyType );
       
   378 #endif
       
   379 	    	User::Leave( KErrMdEUnknownPropertyType );
       
   380 	    	}
       
   381 	    	
       
   382 	    return rowSize;
       
   383 		}
       
   384 
       
   385 	switch( iQueryType )
       
   386 		{
       
   387 		case EQueryTypeObject:
       
   388 			{
       
   389 			TInt rowSize = sizeof(TMdCObject);
       
   390 
       
   391 			const TInt KUriColumn = 7;
       
   392 
       
   393 			TPtrC16 uri = TPtr16((TUint16*)0, 0);
       
   394 			
       
   395 			// Required size for object URI
       
   396 			if (!aRow.Column( KUriColumn ).IsNull())
       
   397 				{
       
   398 				aRow.Column( KUriColumn ).Get( uri );
       
   399 				rowSize += CMdCSerializationBuffer::RequiredSize( uri );
       
   400 				}
       
   401 
       
   402 			if( iFindClause->NoObjectLocking() && iFindClause->ObjectDef() && iFindClause->ObjectDef()->GetId() != KBaseObjectDefId )
       
   403 				{
       
   404 				// check if object is placeholder and add it to count of harvester 
       
   405 				// prioritization URIs
       
   406 				const TInt KFlagsColumn = 2;
       
   407 				TUint32 flags = 0;
       
   408 				aRow.Column( KFlagsColumn ).Get( flags );
       
   409 				if( flags & EMdEObjectFlagPlaceholder )
       
   410 					{
       
   411 					if( iFind.Server().ReserveSpaceHarvestingPrioritizationUri( uri ) )
       
   412 						{
       
   413 						iHarvestingPrioritizationCount++;
       
   414 						}
       
   415 					}
       
   416 				}
       
   417 
       
   418 			// Required size for properties
       
   419 			CMdsObjectDef* objectDef = iFindClause->ObjectDef();
       
   420 
       
   421 			if( !objectDef )
       
   422 				{
       
   423 #ifdef _DEBUG
       
   424 				User::Panic( _L("MdSFOEs2") , KErrMdEUnknownObjectDef );
       
   425 #endif
       
   426 				User::Leave( KErrMdEUnknownObjectDef );
       
   427 				}
       
   428 
       
   429 			const RPointerArray<CMdsPropertyDef>& propertyFilters = iFindClause->PropertyFilters();
       
   430 
       
   431 			// no property filterss
       
   432 			if( propertyFilters.Count() <= 0 )
       
   433 				{
       
   434 				const TInt count = objectDef->GetAllPropertiesCount();
       
   435 
       
   436 				// space for every property, even if it's "null"
       
   437 				rowSize += count * sizeof(TMdCProperty);
       
   438 
       
   439 				for( TInt i = 0; i < count; i++ )
       
   440 					{
       
   441 					const CMdsObjectDef::TMdsColumnOrder& propertyColumn = 
       
   442 						objectDef->GetPropertyColumnL( i );
       
   443 
       
   444 					TColumn& column = aRow.Column( propertyColumn.iColumnId );
       
   445 
       
   446 					if( column.IsNull() )
       
   447 						{
       
   448 						continue;
       
   449 						}
       
   450 
       
   451 					if( propertyColumn.iPropertyDef.GetType() == EPropertyText )
       
   452 				    	{
       
   453 						// Required size for text in text property
       
   454 						TPtrC16 value = TPtr16((TUint16*)0, 0);
       
   455 						column.Get( value );
       
   456 						rowSize += CMdCSerializationBuffer::RequiredSize( value );
       
   457 				    	}
       
   458 					}
       
   459 				}
       
   460 			// property filters
       
   461 			else
       
   462 				{
       
   463 				const TInt count = propertyFilters.Count();
       
   464 
       
   465 				// space for every property, even if it's "null"
       
   466 				rowSize += count * sizeof(TMdCProperty);
       
   467 
       
   468 				for( TInt i = 0; i < count; i++ )
       
   469 					{
       
   470 					CMdsPropertyDef* propDef = propertyFilters[i];
       
   471 
       
   472 					if( !propDef )
       
   473 						{
       
   474 #ifdef _DEBUG
       
   475 						User::Panic( _L("MdSFOEs3") , KErrMdEUnknownPropertyDef );
       
   476 #endif						
       
   477 						User::Leave( KErrMdEUnknownPropertyDef );
       
   478 						}
       
   479 
       
   480 					TColumn& column = aRow.Column( KBaseObjectBasicValueColumnOffset + i );
       
   481 
       
   482 					if( column.IsNull() )
       
   483 						{
       
   484 						continue;
       
   485 						}
       
   486 
       
   487 					if( propDef->GetType() == EPropertyText )
       
   488 				    	{
       
   489 						// Required size for text in text property
       
   490 						TPtrC16 value = TPtr16((TUint16*)0, 0);
       
   491 						column.Get( value );
       
   492 						rowSize += CMdCSerializationBuffer::RequiredSize( value );
       
   493 				    	}
       
   494 					}
       
   495 				}
       
   496 
       
   497 			if( FindCriteria().IncludesFreetexts() )
       
   498 				{
       
   499 				// In result row the second lastest column is free text count
       
   500 				const TInt freeTextCountColumn = aRow.Size() - 2;
       
   501 
       
   502 				// Get free text count
       
   503 				TUint32 freeTextCount = 0;
       
   504 				aRow.Column( freeTextCountColumn ).Get( freeTextCount );
       
   505 
       
   506 				if( freeTextCount > 0 )
       
   507 					{
       
   508 					// In result row last column is total free text length
       
   509 					const TInt totalFreeTextsLengthColumn = aRow.Size() - 1;
       
   510 
       
   511 					// Get total free text length.
       
   512 					TUint32 totalFreeTextsLength = 0;
       
   513 					aRow.Column( totalFreeTextsLengthColumn ).Get( totalFreeTextsLength );
       
   514 
       
   515 					// Required size for free texts.
       
   516 					// For every free text length (TUint16) 
       
   517 					rowSize += freeTextCount * ( CMdCSerializationBuffer::KRequiredSizeForEmptyText );
       
   518 					// and total free text length * TUint16
       
   519 					rowSize += totalFreeTextsLength * sizeof( TUint16 );
       
   520 					}
       
   521 				}
       
   522 
       
   523 			return rowSize;
       
   524 			}
       
   525 
       
   526 		case EQueryTypeRelation:
       
   527 			return sizeof(TMdCRelation);
       
   528 
       
   529 		case EQueryTypeEvent:
       
   530 			{
       
   531 			TInt rowSize = sizeof(TMdCEvent);
       
   532 
       
   533 			// Required size for source and participant texts
       
   534 			TPtrC16 source = TPtr16((TUint16*)0, 0);
       
   535 			aRow.Column( 4 ).Get( source );
       
   536 			rowSize += CMdCSerializationBuffer::RequiredSize( source );
       
   537 
       
   538 			TPtrC16 participant = TPtr16((TUint16*)0, 0);
       
   539 			aRow.Column( 5 ).Get( participant );
       
   540 			rowSize += CMdCSerializationBuffer::RequiredSize( participant );
       
   541 
       
   542 			return rowSize;
       
   543 			}
       
   544 
       
   545 		default:
       
   546 #ifdef _DEBUG
       
   547 			User::Panic( _L( "MdSFOEs4" ), KErrMdEUnknownQueryResultMode );
       
   548 #endif
       
   549 			return 0;
       
   550 		}
       
   551 	}
       
   552 
       
   553 TInt CMdSSqlFindOperation::State()
       
   554     {
       
   555     return iState;
       
   556     }
       
   557 
       
   558 void CMdSSqlFindOperation::Cancel()
       
   559     {
       
   560     if ( iState == EStateRunning )
       
   561         {
       
   562         iState = EStateStop;
       
   563         }
       
   564     }
       
   565 
       
   566 RPointerArray<HBufC>& CMdSSqlFindOperation::QueryFreeText()
       
   567 	{
       
   568 	return iFindClause->QueryFreeText();
       
   569 	}
       
   570 
       
   571 
       
   572 CMdSFindSqlClause& CMdSSqlFindOperation::FindCriteria()
       
   573     {
       
   574     return *iFindClause;
       
   575     }
       
   576 
       
   577 CMdCSerializationBuffer* CMdSSqlFindOperation::Results()
       
   578 	{
       
   579 	CMdCSerializationBuffer* results = iResults;
       
   580 	iResults = NULL;
       
   581 	return results;
       
   582 	}
       
   583 
       
   584 void CMdSSqlFindOperation::SetLimit(TUint32 aLimit)
       
   585 	{
       
   586 	iLimit = aLimit;
       
   587 	}
       
   588 
       
   589 void CMdSSqlFindOperation::SetOffset(TUint32 aOffset)
       
   590 	{
       
   591 	iOffset = aOffset;
       
   592 	}
       
   593 
       
   594 TMdCOffset CMdSSqlFindOperation::AddItemToContainerL( RRowData &aRow, TMdCOffset aFreespaceOffset )
       
   595     {
       
   596     switch( iQueryType )  
       
   597         {
       
   598         case EQueryTypeObject:
       
   599             {
       
   600             aFreespaceOffset = AddObjectToContainerL( aRow, aFreespaceOffset );
       
   601             break;
       
   602             }
       
   603         case EQueryTypeEvent:
       
   604             {
       
   605             TMdCEvent event;
       
   606             TPtrC16 source = TPtr16( ( TUint16* )0, 0 );      //KNullPtr16;
       
   607             TPtrC16 participant = TPtr16( ( TUint16* )0, 0 ); //KNullPtr16;
       
   608 
       
   609             aRow.Column( 0 ).Get( event.iId );
       
   610             aRow.Column( 1 ).Get( event.iObjectId );
       
   611             aRow.Column( 2 ).Get( event.iDefId );
       
   612             aRow.Column( 3 ).Get( event.iTime );
       
   613             aRow.Column( 4 ).Get( source );
       
   614             aRow.Column( 5 ).Get( participant );
       
   615 
       
   616             const TMdCOffset eventOffset = iResults->Position();
       
   617             
       
   618             if ( source.Length() > 0 )
       
   619             	{
       
   620             	event.iSourceText.iPtr.iCount = source.Length();
       
   621             	event.iSourceText.iPtr.iOffset = aFreespaceOffset;
       
   622             	iResults->PositionL( aFreespaceOffset );
       
   623             	aFreespaceOffset = iResults->InsertL( source );
       
   624             	}
       
   625             else
       
   626             	{
       
   627             	event.iSourceText.iPtr.iCount = 0;
       
   628             	event.iSourceText.iPtr.iOffset = KNoOffset;
       
   629             	}
       
   630 
       
   631             if ( participant.Length() > 0 )
       
   632             	{
       
   633             	event.iParticipantText.iPtr.iCount = participant.Length();
       
   634             	event.iParticipantText.iPtr.iOffset = aFreespaceOffset;
       
   635             	iResults->PositionL( aFreespaceOffset );
       
   636                 aFreespaceOffset = iResults->InsertL( participant );
       
   637             	}
       
   638             else
       
   639             	{
       
   640             	event.iParticipantText.iPtr.iCount = 0;
       
   641             	event.iParticipantText.iPtr.iOffset = KNoOffset;
       
   642             	}
       
   643             
       
   644             iResults->PositionL( eventOffset );
       
   645             event.SerializeL( *iResults );
       
   646             break;
       
   647             }
       
   648         case EQueryTypeRelation:
       
   649             {
       
   650             TMdCRelation relation;
       
   651             TUint32 flags           ( 0 );
       
   652 
       
   653             aRow.Column( 0 ).Get( relation.iId );
       
   654             aRow.Column( 1 ).Get( flags );
       
   655             aRow.Column( 2 ).Get( relation.iDefId );
       
   656             aRow.Column( 3 ).Get( relation.iLeftObjectId );
       
   657             aRow.Column( 4 ).Get( relation.iRightObjectId );
       
   658             aRow.Column( 5 ).Get( relation.iParameter );
       
   659             aRow.Column( 6 ).Get( relation.iGuidHigh );
       
   660             aRow.Column( 7 ).Get( relation.iGuidLow );
       
   661             aRow.Column( 8 ).Get( relation.iLastModifiedDate );
       
   662 
       
   663             relation.SerializeL( *iResults );
       
   664             break;
       
   665             }
       
   666         // Unknown query type
       
   667         default:
       
   668             {
       
   669 #ifdef _DEBUG
       
   670 			User::Panic( _L("MdSFOAd1") , KErrMdEUnknownQueryType );
       
   671 #endif
       
   672             User::Leave( KErrMdEUnknownQueryType );
       
   673             }
       
   674         }
       
   675     return aFreespaceOffset;
       
   676     }
       
   677 
       
   678 void CMdSSqlFindOperation::AddIdToContainerL( TItemId aId )
       
   679     {
       
   680     switch( iQueryType )  
       
   681         {
       
   682         case EQueryTypeObject:
       
   683         case EQueryTypeEvent:
       
   684         case EQueryTypeRelation:
       
   685             {
       
   686             iResults->InsertL( aId );
       
   687             break;
       
   688             }
       
   689         default:
       
   690             {
       
   691 #ifdef _DEBUG
       
   692 			User::Panic( _L("MdSFOAd2") , KErrMdEUnknownQueryType );
       
   693 #endif
       
   694             User::Leave( KErrMdEUnknownQueryType );
       
   695             }
       
   696         }
       
   697     }
       
   698 
       
   699 void CMdSSqlFindOperation::CreateItemL()
       
   700     {
       
   701     TMdCItems items;
       
   702     items.iNamespaceDefId = iFindClause->NamespaceDef()->GetId();
       
   703     items.iObjects.iPtr.iCount = 0;
       
   704     items.iObjects.iPtr.iOffset = KNoOffset;
       
   705     items.iRelations.iPtr.iCount = 0;
       
   706     items.iRelations.iPtr.iOffset = KNoOffset;
       
   707     items.iEvents.iPtr.iCount = 0;
       
   708     items.iEvents.iPtr.iOffset = KNoOffset;
       
   709 
       
   710     // move after main header
       
   711     iResults->PositionL( sizeof(TMdCItems) );
       
   712 
       
   713     TUint32 count = iResultRows.Count();
       
   714     TMdCOffset freetextOffset = KNoOffset;
       
   715     switch( iQueryType )
       
   716         {
       
   717         case EQueryTypeObject:
       
   718             {
       
   719             // add objects header
       
   720             items.iObjects.iPtr.iCount = count;
       
   721             items.iObjects.iPtr.iOffset = iResults->Position();
       
   722             freetextOffset = items.iObjects.iPtr.iOffset + count * sizeof(TMdCObject);
       
   723             
       
   724             // initializate server's harvesting prioritization buffer
       
   725         	if( iHarvestingPrioritizationCount > 0 )
       
   726         		{
       
   727         		iFind.Server().StartAddingHarvestingPrioritizationUrisL();
       
   728         		}		
       
   729 
       
   730             break;
       
   731             }
       
   732         case EQueryTypeEvent:
       
   733             {
       
   734             // add objects header
       
   735             items.iEvents.iPtr.iCount = count;
       
   736             items.iEvents.iPtr.iOffset = iResults->Position();
       
   737             freetextOffset = items.iEvents.iPtr.iOffset + count * sizeof(TMdCEvent);
       
   738             break;
       
   739             }
       
   740         case EQueryTypeRelation:
       
   741             {
       
   742             // add objects header
       
   743             items.iRelations.iPtr.iCount = count;
       
   744             items.iRelations.iPtr.iOffset = iResults->Position();
       
   745             freetextOffset = items.iRelations.iPtr.iOffset + count * sizeof(TMdCRelation);
       
   746             break;
       
   747             }
       
   748         default:
       
   749             {
       
   750 #ifdef _DEBUG
       
   751 			User::Panic( _L("MdSFOCr1") , KErrMdEUnknownQueryType );
       
   752 #endif
       
   753 			User::Leave( KErrMdEUnknownQueryType );
       
   754             }
       
   755         }
       
   756 
       
   757   	iResults->PositionL( KNoOffset );
       
   758 	items.SerializeL( *iResults );
       
   759 
       
   760     //Set offset to objects/events/relations
       
   761     for( TInt i = 0; i < count; i++ )
       
   762         {
       
   763         switch ( iQueryType )
       
   764         	{
       
   765 			case EQueryTypeObject:
       
   766 	        	{
       
   767 	            iResults->PositionL( items.iObjects.iPtr.iOffset
       
   768 	            		+ i * sizeof(TMdCObject) );
       
   769 	            freetextOffset = AddItemToContainerL( *iResultRows[i], freetextOffset );
       
   770 	            break;
       
   771 	            }
       
   772 	        case EQueryTypeEvent:
       
   773 	        	{
       
   774 	            iResults->PositionL( items.iEvents.iPtr.iOffset
       
   775 	            		+ i * sizeof(TMdCEvent) );
       
   776 	            freetextOffset = AddItemToContainerL( *iResultRows[i], freetextOffset );
       
   777 	            break;
       
   778 	            }
       
   779 	        case EQueryTypeRelation:
       
   780 	        	{
       
   781 	            iResults->PositionL( items.iRelations.iPtr.iOffset
       
   782 	            		+ i * sizeof(TMdCRelation) );
       
   783 	            freetextOffset = AddItemToContainerL( *iResultRows[i], freetextOffset );
       
   784 			    break;
       
   785 	            }
       
   786 	        default:
       
   787 	        	{
       
   788 #ifdef _DEBUG
       
   789 	        	User::Panic( _L("MdSFOCr2") , KErrMdEUnknownQueryType );
       
   790 #endif
       
   791 	        	User::Leave( KErrMdEUnknownQueryType );
       
   792 	        	}
       
   793         	}
       
   794         }
       
   795     }
       
   796 
       
   797 void CMdSSqlFindOperation::CreateCountL()
       
   798     {
       
   799     TMdCItemCounts itemCounts;
       
   800     itemCounts.iNamespaceDefId = iFindClause->NamespaceDef()->GetId();
       
   801     itemCounts.iObjects = 0;
       
   802     itemCounts.iEvents = 0;
       
   803     itemCounts.iRelations = 0;
       
   804 
       
   805     switch( iQueryType )
       
   806         {
       
   807         case EQueryTypeObject:
       
   808             {
       
   809             itemCounts.iObjects = iResultCount;
       
   810             break;
       
   811             }
       
   812         case EQueryTypeEvent:
       
   813             {
       
   814             itemCounts.iEvents = iResultCount;
       
   815             break;
       
   816             }
       
   817         case EQueryTypeRelation:
       
   818             {
       
   819             itemCounts.iRelations = iResultCount;
       
   820             break;
       
   821             }
       
   822         default:
       
   823             {
       
   824 #ifdef _DEBUG
       
   825 			User::Panic( _L("MdSFOCr3") , KErrMdEUnknownQueryType );
       
   826 #endif
       
   827 			User::Leave( KErrMdEUnknownQueryType );
       
   828             }
       
   829         }
       
   830 
       
   831     itemCounts.SerializeL( *iResults );
       
   832     }
       
   833 
       
   834 void CMdSSqlFindOperation::CreateIdL()
       
   835     {
       
   836     TMdCItemIds itemIds;
       
   837     itemIds.iNamespaceDefId = iFindClause->NamespaceDef()->GetId();
       
   838     itemIds.iErrorCode = KErrNone;
       
   839     itemIds.iObjectIds.iPtr.iCount = 0;
       
   840     itemIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   841     itemIds.iObjectUris.iPtr.iCount = 0;
       
   842     itemIds.iObjectUris.iPtr.iOffset = KNoOffset;
       
   843     itemIds.iEventIds.iPtr.iCount = 0;
       
   844     itemIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   845     itemIds.iRelationIds.iPtr.iCount = 0;
       
   846     itemIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   847 
       
   848     iResults->PositionL( sizeof(TMdCItemIds) );
       
   849 
       
   850     TUint32 count = iResultIds.Count();
       
   851     switch( iQueryType )  
       
   852         {
       
   853         case EQueryTypeObject:
       
   854             {
       
   855             itemIds.iObjectIds.iPtr.iCount = count;
       
   856             itemIds.iObjectIds.iPtr.iOffset = iResults->Position();
       
   857             break;
       
   858             }
       
   859         case EQueryTypeEvent:
       
   860             {
       
   861             itemIds.iEventIds.iPtr.iCount = count;
       
   862             itemIds.iEventIds.iPtr.iOffset = iResults->Position();
       
   863             break;
       
   864             }
       
   865         case EQueryTypeRelation:
       
   866             {
       
   867             itemIds.iRelationIds.iPtr.iCount = count;
       
   868             itemIds.iRelationIds.iPtr.iOffset = iResults->Position();
       
   869             break;
       
   870             }
       
   871         default:
       
   872             {
       
   873 #ifdef _DEBUG
       
   874 			User::Panic( _L("MdSFOCr4") , KErrMdEUnknownQueryType );
       
   875 #endif
       
   876 			User::Leave( KErrMdEUnknownQueryType );
       
   877             }
       
   878         }
       
   879 
       
   880 	iResults->PositionL( KNoOffset );
       
   881 	itemIds.SerializeL( *iResults );
       
   882 
       
   883     for( TInt i = 0; i < count; i++ )
       
   884         {
       
   885 	    AddIdToContainerL( iResultIds[i] );
       
   886         }
       
   887     }
       
   888 
       
   889 void CMdSSqlFindOperation::CreateDistinctL()
       
   890 	{
       
   891     TMdCItemIds itemIds;
       
   892     itemIds.iNamespaceDefId = iFindClause->NamespaceDef()->GetId();
       
   893     itemIds.iErrorCode = KErrNone;
       
   894     itemIds.iObjectIds.iPtr.iCount = 0;
       
   895     itemIds.iObjectIds.iPtr.iOffset = KNoOffset;
       
   896     itemIds.iEventIds.iPtr.iCount = 0;
       
   897     itemIds.iEventIds.iPtr.iOffset = KNoOffset;
       
   898     itemIds.iRelationIds.iPtr.iCount = 0;
       
   899     itemIds.iRelationIds.iPtr.iOffset = KNoOffset;
       
   900 
       
   901     itemIds.iObjectUris.iPtr.iCount = 0;
       
   902     itemIds.iObjectUris.iPtr.iOffset = sizeof(TMdCItemIds);
       
   903     
       
   904     iResults->PositionL( itemIds.iObjectUris.iPtr.iOffset );
       
   905     const TInt resultRowsCount = iResultRows.Count();
       
   906 	for ( TInt i = 0; i < resultRowsCount; ++i )
       
   907 		{		
       
   908 		if ( !iResultRows[i]->Column( 0 ).IsNull() )
       
   909 			{
       
   910 			TPtrC16 value = TPtr16((TUint16*)0, 0);
       
   911 			iResultRows[i]->Column( 0 ).Get( value );
       
   912 			iResults->InsertL( value );
       
   913 			++itemIds.iObjectUris.iPtr.iCount;
       
   914 			}
       
   915 		}
       
   916 
       
   917     iResults->PositionL( KNoOffset );
       
   918     itemIds.SerializeL( *iResults );
       
   919 	}
       
   920 
       
   921 void CMdSSqlFindOperation::AddToContainerL()
       
   922     {
       
   923     // if old result buffer exist try to use it
       
   924     if( iResults )
       
   925     	{
       
   926     	// create new if the old result buffer is too short
       
   927     	if( iResults->Size() < iMemoryLimit )
       
   928     		{
       
   929     		delete iResults;
       
   930     		iResults = NULL;
       
   931 
       
   932     		iResults = CMdCSerializationBuffer::NewL( iMemoryLimit );
       
   933     		}
       
   934     	// else just move to the begin of the result buffer
       
   935     	else
       
   936     		{
       
   937     		iResults->PositionL( 0 );
       
   938     		}
       
   939     	}
       
   940 	else
       
   941 		{
       
   942 		iResults = CMdCSerializationBuffer::NewL( iMemoryLimit );
       
   943 		}
       
   944 
       
   945     TInt err;
       
   946     switch( iResultMode )  
       
   947         {
       
   948         case EQueryResultModeCount:
       
   949             {
       
   950             TRAP( err, CreateCountL() );
       
   951             break;
       
   952             }
       
   953         case EQueryResultModeItem:
       
   954             {
       
   955             TRAP( err, CreateItemL() );
       
   956             break;
       
   957             }
       
   958         case EQueryResultModeId:
       
   959             {
       
   960             TRAP( err, CreateIdL() );
       
   961           break;
       
   962             }
       
   963         case EQueryResultModeDistinctValues:
       
   964             {
       
   965             TRAP( err, CreateDistinctL() );
       
   966             break;
       
   967             }
       
   968         default:
       
   969             {
       
   970 #ifdef _DEBUG
       
   971 			User::Panic( _L("MdSFOAd3") , KErrMdEUnknownQueryResultMode );
       
   972 #endif
       
   973 			User::Leave( KErrMdEUnknownQueryResultMode );
       
   974             }
       
   975         }
       
   976  
       
   977 	if( err != KErrNone )
       
   978 		{
       
   979 		delete iResults;
       
   980 		iResults = NULL;
       
   981 		}
       
   982 
       
   983    	ConsumeRows();
       
   984     }
       
   985 
       
   986 TMdCOffset CMdSSqlFindOperation::AddObjectToContainerL( RRowData& aRow, TMdCOffset aFreespaceOffset )
       
   987     {
       
   988     TMdCObject object;
       
   989     const TMdCOffset objectOffset = iResults->Position();
       
   990     object.iFlags = EMdEObjectFlagNone;
       
   991 
       
   992 	// Get base objects basic values
       
   993     TUint32 serverSideFlags;
       
   994     TPtrC16 uri;
       
   995     aRow.Column( 0 ).Get( object.iId );
       
   996     aRow.Column( 1 ).Get( object.iDefId );
       
   997     aRow.Column( 2 ).Get( serverSideFlags );
       
   998     aRow.Column( 3 ).Get( object.iMediaId );
       
   999     aRow.Column( 4 ).Get( object.iUsageCount );
       
  1000     aRow.Column( 5 ).Get( object.iGuidHigh );
       
  1001     aRow.Column( 6 ).Get( object.iGuidLow );
       
  1002     if (aRow.Column( 7 ).IsNull())
       
  1003     	{
       
  1004     	object.iId = KNoId;
       
  1005     	object.iUri.iPtr.iCount = 0;
       
  1006     	object.iUri.iPtr.iOffset = KNoOffset;
       
  1007     	object.SerializeL( *iResults );
       
  1008     	return aFreespaceOffset;
       
  1009     	}
       
  1010     aRow.Column( 7 ).Get( uri );
       
  1011 
       
  1012 	// SETTING CLIENT SIDE FLAGS
       
  1013 	// Set not present flag to client side flags 
       
  1014 	// (removed objects are also flaged as not present)
       
  1015 	if( ( serverSideFlags & EMdEObjectFlagNotPresent ) ||
       
  1016 		( serverSideFlags & EMdEObjectFlagRemoved ) )
       
  1017 		{
       
  1018 		object.iFlags |= EMdEObjectFlagNotPresent;
       
  1019 		}
       
  1020 
       
  1021 	// Set confidential flag to client side flags
       
  1022 	if( serverSideFlags & EMdEObjectFlagConfidential )
       
  1023 		{
       
  1024 		object.iFlags |= EMdEObjectFlagConfidential;
       
  1025 		}
       
  1026 
       
  1027 	// Set freetext flag to client side flags
       
  1028 	if( serverSideFlags & EMdEObjectFlagFreetexts )
       
  1029 		{
       
  1030 		object.iFlags |= EMdEObjectFlagFreetexts;
       
  1031 		}
       
  1032 
       
  1033 	// Set placeholder flag to client side flags
       
  1034 	if( serverSideFlags & EMdEObjectFlagPlaceholder )
       
  1035 		{
       
  1036 		object.iFlags |= EMdEObjectFlagPlaceholder;
       
  1037 		
       
  1038 		// object is placeholder, so try add it's URI to harverting 
       
  1039 		// prioritization buffer
       
  1040 		if( iHarvestingPrioritizationCount > 0 )
       
  1041 			{
       
  1042 			iFind.Server().AddHarvestingPrioritizationUriL( uri );
       
  1043 
       
  1044 			iHarvestingPrioritizationCount--;
       
  1045 
       
  1046 			if( iHarvestingPrioritizationCount == 0 )
       
  1047 				{
       
  1048 				iFind.Server().NotifyHarvestingPrioritizationObserver( KErrNone );
       
  1049 				}
       
  1050 			}
       
  1051 		}
       
  1052 	
       
  1053 	const CMdsObjectDef* objectDef = iFindClause->ObjectDef();
       
  1054 	if( !objectDef )
       
  1055 		{
       
  1056 #ifdef _DEBUG
       
  1057 		User::Panic( _L("MdSFOAd4") , KErrMdEUnknownObjectDef );
       
  1058 #endif		
       
  1059 		User::Leave( KErrMdEUnknownObjectDef );
       
  1060 		}
       
  1061 
       
  1062     // Add base objects basic values to result buffer
       
  1063     object.iUri.iPtr.iCount = uri.Length();
       
  1064     object.iUri.iPtr.iOffset = aFreespaceOffset;
       
  1065     iResults->PositionL( aFreespaceOffset );
       
  1066     aFreespaceOffset = iResults->InsertL( uri );
       
  1067 
       
  1068 	const RPointerArray<CMdsPropertyDef>& propertyFilters = iFindClause->PropertyFilters();
       
  1069 
       
  1070 	// No property filters
       
  1071 	if( propertyFilters.Count() <= 0 )
       
  1072 		{
       
  1073 		const TInt allPropertyCount = objectDef->GetAllPropertiesCount();
       
  1074 		object.iProperties.iPtr.iCount = 0;
       
  1075 		object.iProperties.iPtr.iOffset = aFreespaceOffset;
       
  1076 
       
  1077 		// Position after property offsets
       
  1078 		aFreespaceOffset += allPropertyCount * sizeof(TMdCProperty);
       
  1079 		
       
  1080 		for( TInt i = 0; i < allPropertyCount; i++ )
       
  1081 			{
       
  1082 			const CMdsObjectDef::TMdsColumnOrder& propertyColumn = 
       
  1083 				objectDef->GetPropertyColumnL( i );
       
  1084 
       
  1085 			TColumn& column = aRow.Column( propertyColumn.iColumnId );
       
  1086 
       
  1087 			// check if property exists, else continue to with next property
       
  1088 			if( column.IsNull() )
       
  1089 				{
       
  1090 				continue;
       
  1091 				}
       
  1092 
       
  1093 			TMdCProperty property;
       
  1094 
       
  1095 			property.iPropertyDefId = propertyColumn.iPropertyDef.GetId();
       
  1096 			property.iModFlags = EMdEPropertyModNone;
       
  1097 
       
  1098 			const TPropertyType propertyType = propertyColumn.iPropertyDef.GetType();
       
  1099 			switch(propertyType)
       
  1100 				{
       
  1101 				case EPropertyBool:
       
  1102 					{
       
  1103 					TBool value;
       
  1104 					column.Get( value );
       
  1105 					property.iValue.iInt32 = value;
       
  1106 					}
       
  1107     				break;
       
  1108     			case EPropertyInt8:
       
  1109     				{
       
  1110 					TInt32 value32;
       
  1111 					column.Get( value32 );
       
  1112 					property.iValue.iInt32 = value32;
       
  1113     				}
       
  1114     				break;
       
  1115     			case EPropertyUint8:
       
  1116     				{
       
  1117 					TUint32 value32;
       
  1118 					column.Get( value32 );
       
  1119 					property.iValue.iUint32 = value32;
       
  1120     				}
       
  1121     				break;
       
  1122     			case EPropertyInt16:
       
  1123     				{
       
  1124 					TInt32 value32;
       
  1125 					column.Get( value32 );
       
  1126 					property.iValue.iInt32 = value32;
       
  1127     				}
       
  1128     				break;
       
  1129     			case EPropertyUint16:
       
  1130     				{
       
  1131 					TUint32 value32;
       
  1132 					column.Get( value32 );
       
  1133 					property.iValue.iUint32 = value32;
       
  1134     				}
       
  1135     				break;
       
  1136     			case EPropertyInt32:
       
  1137     				{
       
  1138 					TInt32 value;
       
  1139 					column.Get( value );
       
  1140 					property.iValue.iInt32 = value;
       
  1141     				}
       
  1142     				break;
       
  1143     			case EPropertyUint32:
       
  1144     				{
       
  1145 					TUint32 value;
       
  1146 					column.Get( value );
       
  1147 					property.iValue.iUint32 = value;
       
  1148     				}
       
  1149     				break;
       
  1150 				case EPropertyInt64:
       
  1151     				{
       
  1152 					TInt64 value;
       
  1153 					column.Get( value );
       
  1154 					property.iValue.iInt64 = value;
       
  1155     				}
       
  1156     				break;    				
       
  1157     			case EPropertyReal32:
       
  1158     				{
       
  1159 					TReal32 value;
       
  1160 					column.Get( value );
       
  1161 					property.iValue.iReal = value;
       
  1162     				}
       
  1163     				break;
       
  1164     			case EPropertyReal64:
       
  1165     				{
       
  1166 					TReal64 value;
       
  1167 					column.Get( value );
       
  1168 					property.iValue.iReal = value;
       
  1169     				}
       
  1170     				break;
       
  1171     			case EPropertyTime:
       
  1172     				{
       
  1173 					TTime value;
       
  1174 					column.Get( value );
       
  1175 					property.iValue.iInt64 = value.Int64();
       
  1176     				}
       
  1177     				break;
       
  1178     			case EPropertyText:
       
  1179     				{    				
       
  1180 	    			TPtrC16 value;
       
  1181 					column.Get( value );
       
  1182 					if (value.Length() > 0)
       
  1183 						{
       
  1184 						property.iValue.iPtr.iCount = value.Length();
       
  1185 						property.iValue.iPtr.iOffset = aFreespaceOffset;
       
  1186 						iResults->PositionL( aFreespaceOffset );
       
  1187 						aFreespaceOffset = iResults->InsertL( value );
       
  1188 						}
       
  1189 					else
       
  1190 						{
       
  1191 						property.iValue.iPtr.iCount = 0;
       
  1192 						property.iValue.iPtr.iOffset = KNoOffset;
       
  1193 						}
       
  1194     				}
       
  1195     				break;
       
  1196     			default:
       
  1197 #ifdef _DEBUG
       
  1198 					User::Panic( _L("MdSFOAd5") , KErrMdEUnknownPropertyType );
       
  1199 #endif
       
  1200 					User::Leave( KErrMdEUnknownPropertyType );
       
  1201 				}
       
  1202 
       
  1203 		    // store property in buffer
       
  1204 			iResults->PositionL( object.iProperties.iPtr.iOffset
       
  1205 					+ object.iProperties.iPtr.iCount * sizeof(TMdCProperty) );
       
  1206 			++object.iProperties.iPtr.iCount;
       
  1207 		    property.SerializeL( *iResults );
       
  1208 			}
       
  1209 		}
       
  1210 	// Property filters
       
  1211 	else
       
  1212 		{
       
  1213 		const TUint32 propertyCount = propertyFilters.Count();
       
  1214 		object.iProperties.iPtr.iCount = 0;
       
  1215 		object.iProperties.iPtr.iOffset = aFreespaceOffset;
       
  1216 
       
  1217 		// Position after property offsets
       
  1218 		aFreespaceOffset += propertyCount * sizeof(TMdCProperty);
       
  1219 
       
  1220 		for( TInt i = 0; i < propertyCount; i++ )
       
  1221 			{
       
  1222 			CMdsPropertyDef* propDef = propertyFilters[i];
       
  1223 
       
  1224 			if( !propDef )
       
  1225 				{
       
  1226 #ifdef _DEBUG
       
  1227 				User::Panic( _L("MdSFOAd6") , KErrMdEUnknownPropertyDef );
       
  1228 #endif
       
  1229 				User::Leave( KErrMdEUnknownPropertyDef );
       
  1230 				}
       
  1231 
       
  1232 			TColumn& column = aRow.Column( KBaseObjectBasicValueColumnOffset + i );
       
  1233 
       
  1234 			// check if property exists, else continue to with next property
       
  1235 			if( column.IsNull() )
       
  1236 				{
       
  1237 				continue;
       
  1238 				}
       
  1239 
       
  1240 			TMdCProperty property;
       
  1241 
       
  1242 			property.iPropertyDefId = propDef->GetId();
       
  1243 			property.iModFlags = EMdEPropertyModNone;
       
  1244 
       
  1245 			const TPropertyType propertyType = propDef->GetType();
       
  1246 			switch(propertyType)
       
  1247 				{
       
  1248 				case EPropertyBool:
       
  1249 					{
       
  1250 					TBool value;
       
  1251 					column.Get( value );
       
  1252 					property.iValue.iInt32 = value;
       
  1253 					}
       
  1254 					break;
       
  1255 				case EPropertyInt8:
       
  1256 					{
       
  1257 					TInt32 value32;
       
  1258 					column.Get( value32 );
       
  1259 					property.iValue.iInt32 = value32;
       
  1260 					}
       
  1261 					break;
       
  1262 				case EPropertyUint8:
       
  1263 					{
       
  1264 					TUint32 value32;
       
  1265 					column.Get( value32 );
       
  1266 					property.iValue.iUint32 = value32;
       
  1267 					}
       
  1268 					break;
       
  1269 				case EPropertyInt16:
       
  1270 					{
       
  1271 					TInt32 value32;
       
  1272 					column.Get( value32 );
       
  1273 					property.iValue.iInt32 = value32;
       
  1274 					}
       
  1275 					break;
       
  1276 				case EPropertyUint16:
       
  1277 					{
       
  1278 					TUint32 value32;
       
  1279 					column.Get( value32 );
       
  1280 					property.iValue.iUint32 = value32;
       
  1281 					}
       
  1282 					break;
       
  1283 				case EPropertyInt32:
       
  1284 					{
       
  1285 					TInt32 value;
       
  1286 					column.Get( value );
       
  1287 					property.iValue.iInt32 = value;
       
  1288 					}
       
  1289 					break;
       
  1290 				case EPropertyUint32:
       
  1291 					{
       
  1292 					TUint32 value;
       
  1293 					column.Get( value );
       
  1294 					property.iValue.iUint32 = value;
       
  1295 					}
       
  1296 					break;
       
  1297 				case EPropertyInt64:
       
  1298 					{
       
  1299 					TInt64 value;
       
  1300 					column.Get( value );
       
  1301 					property.iValue.iInt64 = value;
       
  1302 					}
       
  1303 					break;    				
       
  1304 				case EPropertyReal32:
       
  1305 					{
       
  1306 					TReal32 value;
       
  1307 					column.Get( value );
       
  1308 					property.iValue.iReal = value;
       
  1309 					}
       
  1310 					break;
       
  1311 				case EPropertyReal64:
       
  1312 					{
       
  1313 					TReal64 value;
       
  1314 					column.Get( value );
       
  1315 					property.iValue.iReal = value;
       
  1316 					}
       
  1317 					break;
       
  1318 				case EPropertyTime:
       
  1319 					{
       
  1320 					TTime value;
       
  1321 					column.Get( value );
       
  1322 					property.iValue.iReal = value.Int64();
       
  1323 					}
       
  1324 					break;
       
  1325 				case EPropertyText:
       
  1326 					{    				
       
  1327 	    			TPtrC16 value;
       
  1328 					column.Get( value );
       
  1329 					if (value.Length() > 0)
       
  1330 						{
       
  1331 						property.iValue.iPtr.iCount = value.Length();
       
  1332 						property.iValue.iPtr.iOffset = aFreespaceOffset;
       
  1333 						iResults->PositionL( aFreespaceOffset );
       
  1334 						aFreespaceOffset = iResults->InsertL( value );
       
  1335 						}
       
  1336 					else
       
  1337 						{
       
  1338 						property.iValue.iPtr.iCount = 0;
       
  1339 						property.iValue.iPtr.iOffset = KNoOffset;
       
  1340 						}
       
  1341 					}
       
  1342 					break;
       
  1343 				default:
       
  1344 #ifdef _DEBUG
       
  1345 					User::Panic( _L("MdSFOAd7") , KErrMdEUnknownPropertyType );
       
  1346 #endif
       
  1347 					User::Leave( KErrMdEUnknownPropertyType );
       
  1348 				}
       
  1349 
       
  1350 		    // store property in buffer
       
  1351 			iResults->PositionL( object.iProperties.iPtr.iOffset
       
  1352 					+ object.iProperties.iPtr.iCount * sizeof(TMdCProperty) );
       
  1353 			++object.iProperties.iPtr.iCount;
       
  1354 		    property.SerializeL( *iResults );
       
  1355 			}
       
  1356 		}
       
  1357 
       
  1358 	if( FindCriteria().IncludesFreetexts() )
       
  1359 		{		
       
  1360 		// In result row the second lastest column is free text count
       
  1361 		const TInt freeTextCountColumn = aRow.Size() - 2;
       
  1362 
       
  1363 		// Get free text count and total free text lenght.
       
  1364 		TUint32 freeTextCount = 0;
       
  1365 		aRow.Column( freeTextCountColumn ).Get( freeTextCount );
       
  1366 
       
  1367 		if( freeTextCount > 0 )
       
  1368 			{
       
  1369 			object.iFreeTexts.iPtr.iCount = freeTextCount;
       
  1370 			object.iFreeTexts.iPtr.iOffset = aFreespaceOffset;
       
  1371 			
       
  1372 			// In result row last column is total free text lenght.
       
  1373 			const TInt totalFreeTextsLengthColumn = aRow.Size() - 1;
       
  1374 
       
  1375 			TUint32 totalFreeTextsLength = 0;
       
  1376 			aRow.Column( totalFreeTextsLengthColumn ).Get( totalFreeTextsLength );
       
  1377 
       
  1378 			// Reserve space for free texts.
       
  1379 			// For every free text possible padding (TUint8), length (TUint16)
       
  1380 			TUint32 freeTextReserve = freeTextCount * CMdCSerializationBuffer::KRequiredSizeForEmptyText;
       
  1381 			// and total free text length * TUint16
       
  1382 			freeTextReserve += totalFreeTextsLength * sizeof( TUint16 );
       
  1383 
       
  1384 			aFreespaceOffset += freeTextReserve;
       
  1385 			}
       
  1386 		else
       
  1387 			{
       
  1388 			object.iFreeTexts.iPtr.iCount = 0;
       
  1389 			object.iFreeTexts.iPtr.iOffset = KNoOffset;
       
  1390 			}
       
  1391 		}
       
  1392 	else
       
  1393 		{
       
  1394 		object.iFreeTexts.iPtr.iCount = 0;
       
  1395 		object.iFreeTexts.iPtr.iOffset = KNoOffset;
       
  1396 		}
       
  1397 
       
  1398 	iResults->PositionL( objectOffset );
       
  1399     object.SerializeL( *iResults );
       
  1400 
       
  1401 	return aFreespaceOffset;
       
  1402     }
       
  1403 
       
  1404 void CMdSSqlFindOperation::ConsumeRows()
       
  1405     {
       
  1406 	if( EQueryResultModeId != iResultMode )
       
  1407 		{    
       
  1408 	    const TInt KRowCount = iResultRows.Count();
       
  1409 
       
  1410 	    for( TInt i = 0; i < KRowCount; i++ )
       
  1411 	    	{
       
  1412 	    	iResultRows[i]->Close();
       
  1413 	    	}
       
  1414 
       
  1415 	    iResultRows.ResetAndDestroy();
       
  1416 		}
       
  1417 	// handle result mode IDs as special case
       
  1418 	else
       
  1419 		{
       
  1420 		iResultIds.Reset();
       
  1421 		}
       
  1422 	}