Novell is now a part of Micro Focus

How to Use the GroupWise Filter and Query

Articles and Tips: article

Cecilia Milla
Software Engineer
Cisco Systems
cmilla@cisco.com

01 Dec 2000


This AppNote provides a brief overview of the Filter Expression Syntax, along with the MSGFIND_VB sample for Visual Basic and the QUERY_CPP taken from the samples in the NDK.

Introduction

Developers are able to search the GroupWise Information store programmatically as they would in the GroupWise Client. Two ways to query or filter messages are to use the find method and the Query object. The former is relatively easy; however, it limits the search to the object where the find is being called. The latter is a little more complicated but extends the search to Documents. Both methods require the use of the Filter Expression Syntax. Documentation on the Filter Expression Syntax is not exhaustive to all possible searches, however, should be able to get you started. After a brief overview of the Filter Expression Syntax, we will take a look at the MSGFIND_VB sample for Visual Basic and the QUERY_CPP taken from the samples in the NDK.

Filter Expression Syntax

The Filter Expression Syntax is roughly categorized in six sections, which are Basic Expressions, Numeric Statements, Text Statements, Date Statements, Enumerated Statements, and lastly, Unary Statements. These categories sometimes overlap one another and are not meant to cover all possible searches. Each of these searches uses compound statements or are grouped by using parenthesis.

Basic Expressions include compound statements such as "OR" and "AND" which include the other categories mentioned above. For instance, within a Basic Expression you may combine Unary and Number statements together. These could be separated by parenthesis or grouped as one. The following are samples from the documentation:

Groups Example


 (TASK) OR (APPOINTMENT) AND (SUBJECT CONTAINS "PROJECT7")

 Compound Statement Example

 (CREATE_DATE >= YESTERDAY AND CREATE_DATE <= TODAY)

 Groups and Compound Statements Example

 (FROM CONTAINS "TJEFFERSON" OR FROM CONTAINS "jADAMS") AND

 (MESSAGE BEGINS WITH "When in the course" AND CREATE_DATE =

 1776/7/4)

Numeric Statements are searches for fields that contain a count or number. For example, a search for the number of recipients or document number would be considered a numeric search. These searches would contain the following numeric operations:

  • "=" (equal to)

  • "<>" (not equal to)

  • "<" (greater than)

  • "<" (less than)

  • "<=" (greater than or equal to)

  • "<=" (less than or equal to)

Another category is the Text Statements, which are field searches that contain text, such as subject or author. The text operations listed are MATCHES, CONTAINS, or BEGINSWITH. The syntax can contain AND, OR, and NOT as well as CASE (for case-sensitivity). Again, the documentation does not have all the possible text searches so use trial and error in your searches.

The next category is Date Statements, which embody searches by date. The possible searches that are documented are ASSIGNED_DATE, CREATE_DATE, DELIVERED_DATE, DUEEND_DATE, RETRIEVED_DATE, START_DATE, and MODIFY_DATE. These dates can be set to TODAY, TOMMOROW, YESTERDAY, THIS_WEEK, THIS_MONTH, or THIS_YEAR. The date operations are the same as the numeric operations mentioned earlier.

The Enumerated Statements are BoxType, Priority, and AttachmentType searches. A user can find messages in INCOMING, OUTGOING, PERSONAL, or DRAFT BoxType. He can also find messages of low, medium, or high priority. In addition, for Enumerated Statements he can search for attachments of different types. These attachment types are file, message, movie, OLEEmbedded (embedded OLE object), OLELinked (linked OLE object), sound annotation, or it can be simply be unknown.

Find Method

The find method can be seen in the MessageList, Messages, AddressBookEntries, and AllMessages objects. Once you have obtained one of the mentioned objects the find method can be called. In the sample code MSGFIND_VB the application would need to log in to GroupWise. The following code within the sample does so. (The sample can be found at: http://www.developer.novell.com/ndk/doc/samplecode/gwobjapi_sample/index.htm)

Me.Caption = "Creating GroupWare Session...": DoEvents

     Set GWApp = CreateObject("NovellGroupWareSession")


     Me.Caption = "Logging In...": DoEvents

     Set GWRootAccount = GWApp.Login(txtUserID, txtParameters)

The MSGFIND_VB sample allows the user to search within a specific folder or search all the messages within the account. To search messages within the folder the user would then choose a specific folder. From within the chosen folder the Messages object is obtained. The Messages object is a property of the Folder object and it has a Find method. To search all messages within the account, a property of the root account called the AllMessages object is obtained. Within the AllMessages collection is the Find method. Both the AllMessages and Messages objects return a MessageList object from the Find method. From within the MessageList object yet another Find method can be called which returns a more refined MessageList object. The Find method from within the MessageList object can be called many times to refine the current message list.

Query Object

The QUERY_CPP sample shows how to do a query or find through the Query object. Although the code is in C++, the query concept is the same as it would be in Visual Basic. First log in and obtain the (root) Account object in GroupWise:

// Login to GW session

if(!SUCCEEDED(pIGWSession->Login(vUserId, vCmdLine, vPassword, vWhenToPrompt, vReserved, &pDIGWAccount))) {&
     ErrorMessage("Couldn't login to session");

     return FALSE;

}

// Get the Root Account's Interface

if(FAILED(pDIGWAccount->QueryInterface(IID_IGWAccount, (LPVOID*)&pIGWAccount)))&
{

     ErrorMessage("QueryInterface on IID_IGWAccount Failed");

     return FALSE;

}

pDIGWAccount->Release();

From the Account object there exists a method called CreateQuery, which returns a Query object. In the documentation for the Query object, it states that the Query's Expression, Location, and SetLocally properties need to be set. In reality, only the Expression (the Filter Expression) needs to be added before starting the query. After calling the Start method, the Query can be polled to determine when the query is done. These are shown in the following code:

// Put what are we querying for

pIGWQuery->put_Expression(bStr);

// Start the query

pIGWQuery->Start();

// Loop until query is completed

while(bCompleted == FALSE) {

     pIGWQuery->get_Completed(&bCompleted);&
     pIGWQuery->Refresh();

     }

The QUERY_CPP sample separates each field according to some of the Filter Expression Syntax types mentioned earlier. The types that the QUERRY_CPP sample uses are TEXT, NUMERIC, DATE, UNARY, BOXTYPE (Enumerated), Priority (Enumerated), and ATTACHMENT (Enumerated). Needless to say, there are many more possible searches; however, these are the ones shown by the sample. Also shown in the sample is a list of other possible field searches found in Options.h within the QUERY_CPP sample. The following is a subset of the many possible searches available in GroupWise (determining whether or not other searches will work is a matter of trial and error):

{ "APPOINTMENT", GW_UNARY_FIELD },

{ "ASSIGNED_DATE", GW_DATE_FIELD },

{ "ATTACHMENT_LIST", GW_TEXT_FIELD }, 

{ "ATTACHMENT_TYPE", GW_ATTACHMENT_FIELD },

{ "AUTHOR", GW_TEXT_FIELD },

{ "BC", GW_TEXT_FIELD },

{ "BOX_TYPE", GW_BOXTYPE_FIELD },

{ "CALLER_COMPANY", GW_TEXT_FIELD },

{ "CALLER_NAME", GW_TEXT_FIELD },

{ "CALLER_PHONE_NUMBER", GW_TEXT_FIELD },

{ "CC", GW_TEXT_FIELD },

{ "CLASS_NAME", GW_TEXT_FIELD },

{ "CREATE_DATE", GW_DATE_FIELD },

{ "CURRENT_VERSION_NUMBER", GW_NUMERIC_FIELD },

{ "DELIVERED_DATE", GW_DATE_FIELD },

{ "DOCUMENT_CREATOR", GW_TEXT_FIELD },

{ "DOCUMENT_FILENAME", GW_TEXT_FIELD },

{ "DOCUMENT_NUMBER", GW_NUMERIC_FIELD },

{ "DOCUMENT_TYPE", GW_TEXT_FIELD },

{ "DUEEND_DATE", GW_DATE_FIELD },

{ "FROM", GW_TEXT_FIELD },

{ "LIBRARY", GW_TEXT_FIELD },

{ "MESSAGE", GW_TEXT_FIELD },

{ "NUMBER_ACCEPTED", GW_NUMERIC_FIELD },

{ "NUMBER_COMPLETED", GW_NUMERIC_FIELD },

{ "NUMBER_DELETED", GW_NUMERIC_FIELD },

{ "NUMBER_OPENED", GW_NUMERIC_FIELD },

{ "NUMBER_READ", GW_NUMERIC_FIELD },

{ "NUMBER_REPLIED", GW_NUMERIC_FIELD },

{ "OFFICIAL_VERSION_NUMBER", GW_NUMERIC_FIELD },

{ "PLACE", GW_TEXT_FIELD },

{ "PRIORITY", GW_PRIORITY_FIELD },

{ "RETRIEVED_BY", GW_TEXT_FIELD },

{ "RETRIEVED_DATE", GW_DATE_FIELD },

{ "SIZE", GW_NUMERIC_FIELD },

{ "START_DATE", GW_DATE_FIELD },

{ "SUBJECT", GW_TEXT_FIELD },

{ "TASK", GW_UNARY_FIELD },

{ "TO", GW_TEXT_FIELD },

{ "TOTAL_RECIPIENTS", GW_NUMERIC_FIELD },

{ "VERSION_NUMBER", GW_NUMERIC_FIELD },

{ "VIEWNAME", GW_TEXT_FIELD }

As with the Find method mentioned earlier, a MessageList is returned with the messages which meet the Filter Expression requirements. Both using the Query object and Find methods return the same results, however, by using the Query Object, you can further your search to other objects such as the Documents or DocumentLibraries collections. With the Find method, only certain objects of Message and address types obtain such a method. Also, the Query object can represent either a stand-alone query or a query associated with a query folder. The Query object contains a method called CreateFolder, which returns the Folder object. The results of the query are returned within that Folder.

Note: For queries on Documents or DocumentLibraries, the Query object will return a DocumentReference object, which is a subtype of Message. DocumentReference has the same methods available in the Message object. The fact that DocumentReference is returned is not stated in the documentation and an assumption would be that the Documents or DocumentLibraries objects would be returned--which is not so. However, you will be able to get the DocumentLibraries and other similar objects through the properties of the DocumentReference object.

Conclusion

The Filter Expression Syntax currently documented is not an exhaustive list to all the possible searches in GroupWise. However, when categorized in the six sections, the format of the searches becomes clearer. These categories are namely, Basic Expressions, Numeric Statements, Text Statements, Date Statements, Enumerated Statements, and lastly, Unary Statements. Both the Find method and the Query object use the Filter Expression Syntax. The Find method is a method found in Messages, AllMessages, MessageList, and AddressBookEntries. The Query object is obtained through the CreateQuery method from the Account object. Both ways of doing searches will result in a MessageList object being returned. Unless, however, the user is searching Documents or DocumentLibraries, in this case, DocumentReference is returned. The difference between the Find method and the Query object is that the Query object extends to Document searches as well as to Message type searches, whereas, the Find method (although easy) is found only in the mentioned objects. Also, with the Query object one can create a query folder. Both methods are available to maintain and manipulate data available in GroupWise.

Copyright 2000 by Novell, Inc. All rights reserved. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying and recording, for any purpose without the express written permission of Novell.

All product names mentioned are trademarks of their respective companies or distributors.

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates