SearchSortExample: enhanced search and sort for Message Store

This example demonstrates the enhanced search and sort API for message stores. This API was implemented in Symbian^3.


Prior to Symbian^3, the Message Store API had limited support for selecting and sorting message records and fields. From Symbian^3, the API implements more extensive search and sort options.

This example demonstrates the new functionality by implementing the following use cases:

  • Display the header information for all message entries.

  • Perform a simple (single search criteria) non-iterative search-sort and display the matching entries. This has the following options:

    • case sensitivity on / off,

    • whole word search on / off.

  • Perform a combined (more than one search criteria) non-iterative search-sort and display the number of matching entries. This has the following options:

    • case sensitivity on / off,

    • whole word search on / off.

  • Perform an iterative search-sort (searches for entries one at a time) and display the number of matching entries.

  • Perform a search-sort using a query ID. The query ID is generated by a previous search-sort operation.

Before implementing these use cases, the example creates a POP3/SMTP message store with five message entries.

Class summary

The example demonstrates the following classes and enums:

  • CMsvSearchSortOperation

  • CMsvSearchSortQuery

  • TMsvMessagePart

  • TMsvSearchSortResultType


Click on the following link to download the example:

Click: browse to view the example code.

Design and implementation

Project Implementation

The project implements the following classes:

CKeyReader: Derived from CActive. This reads keypresses and calls the appropriate example function.

CMessAsyncWaiter: Derived from CActive. This handles the CMsvSearchSortOperation::RequestL() asynchronous request. This RequestL() function takes CMessAsyncWaiter::iStatus as one of its parameters and then waits on the status. When the search is complete the client is notified of the event's completion by CMessAsyncWaiter::RunL() being called, after which the example prepares the buffer and displays the results.

CSearchsortExample: Derived from CBase and MMsvSessionObserver. MMsvSessionObserver is an interface for notification of events from a Message Server session.

CSearchsortExample implements HandleSessionEventL() to handle the two event types EMsvEntriesCreated and EMsvServerReady. It also creates the SMTP message entries and carries out searching and sorting.

Simple non-iterative search-sort

The example starts by creating a message server session using CMsvSession, which represents a channel of communication between a client thread (client-side MTM, user interface MTM, or message client application) and the Message Server thread. Then it creates an instance of CMsvSearchSortOperation to perform the search-sort operation, and passes the session object into it.

A search-sort query is created using CMsvSearchSortQuery::NewL() and is configured using various member functions of class CMsvSearchSortQuery for instance whether to search for whole or partial words and the case sensitivity.

The search and sort options are added to the query using CMsvSearchSortQuery::AddSearchOptionL() and CMsvSearchSortQuery::AddSortOptionL().

The search-sort operation is started by calling CMsvSearchSortOperation::RequestL(), passing the query as a parameter. If no iterator parameter is specified, the search defaults to non-iterative.

An instance of the CMessAsyncWaiter class is created for handling the asynchronous search request. This object is waited on until the Message Server completes the request. The results of the search are stored in an array using CMsvSearchSortOperation::GetResultsL().

The result count is displayed by calling CMsvSearchSortOperation::GetResultCountL().

The query ID of the search is retrieved from the Message server, for later use, using the CMsvSearchSortOperation::GetQueryId() function.

Simple iterative search-sort

Iterative search-sort follows the same steps as described above, except that an iterator parameter is passed to the RequestL() function. To retrieve the results, CMsvSearchSortOperation::GetNextResultL() is called in a while loop to retrieve one entry at a time. Iterative searching is useful when the client may not have enough memory to store an array of results.

Combined search-sort

A combined search-sort is done by adding additional search options using CMsvSearchSortQuery::AddSearchOptionL().

Search-sort using a query ID

A query ID identifies a search-sort query. It is obtained by calling CMsvSearchSortOperation::GetQueryIdL() following the completion of CMsvSearchSortOperation::RequestL(). In this example, the query ID generated by the simple non-iterative search-sort is used to repeat the same search-sort. The overloaded CMsvSearchSortOperation::RequestL() function is used to initiate a search-sort operation with a query ID.

After the request completes, a list of index entry ID objects (TMsvId or TMsvEntry depending on how the query was configured, using CMsvSearchSortQuery::SetResultType()) is retrieved using CMsvSearchSortOperation::GetResultsL(). Finally the matching results are displayed in the console.

Building and configuring

To build the example:

  • You can build the example from your IDE or the command line.

    If you use an IDE, import the bld.inf file of the example into your IDE, and use the build command of the IDE.

    If you use the command line, open a command prompt, and set the current directory to the source code directory of the example. You can then build the example with the SBSv1 build tools with the following commands:

    bldmake bldfiles

    abld build

  • For the emulator, the example builds an executable called searchsortexample.exe in the epoc32\release\winscw\<udeb or urel>\ folder.

Running the example

searchsortexample.exe takes user input from the console. The menu for the current example is as shown below:

The user input is handled by CKeyReader::RunL().

For simple and combined non-iterative search-sort, the user provides the following inputs: 1) the text in the "To" field to search for, 2) whether case sensitivity is on of off, 3) whether whole word searching is on or off.

The input values are saved in variables which are passed to the function CSearchsortExample::SearchSortRequestWithoutIteratorL(), and the settings are made accordingly.

For the combined search-sort the 2nd and 3rd search options (size and subject) are hard coded. The iterative search-sort searches by size, which is also hard coded.

To execute a search-sort using a query ID, CMsvSearchSortOperation::RequestL(CMsvSearchSortQuery *,TBool,TRequestStatus &,TInt) must first have been called because it generates the query ID. So, either option 2 or 3 must have been called before option 5.