API Reference | developer.brewmp.com API Reference | developer.brewmp.com

Developer

API Reference

PIM_AEECLSID_CONTACTSTORE

Brew Release
Brew MP 1.0.2
See Also
Description
Implementation of the pim_IRecordStore interface. This class provides a way to interact with the contact record store to add, delete, update and search records as well as receive notifications and detect changes to the contact entries.
To associate a contact with one or more groups, use the extended field X-BREW-GROUPS.
To associate a contact with a group, having the following in your octet sequence
X-BREW-GROUPS:group1;group2;group3...;groupN
where group1, group2...groupN are escaped group names. Escaping should be done as described in RFC 2426,
To loct a contact and prevent it from deletion use X-BREW-PROTECTED.
To lock a contact use
X-BREW-PROTECTED:yes
To unlock a contact use
X-BREW-PROTECTED:no
If X-BREW-PROTECTED is not present the contact is assumed to be unlock.
This class only supports retrieving complete records, i.e., the Offset for pim_IRecordStore_GetRecord() should always be 0.
Also, pim_IRecordStore_Search supported only for following fields. A NULL terminated string with the following contents should be passed as search criteria to pim_IRecordStore_Search.
GROUPNAME=''
Note that need not be escaped.

pim_AEECLSID_ContactStore implements pim_IRecordStore interface and defines the record format to be a single byte per character text string that contains the contact record in vCard format, as defined by RFC 2426. A user of pim_AEECLSID_ContactStore is expected to provide a vCard formatted string when a new contact record is being stored in the database. Here is a sample block representing a vCard:

   BEGIN:vCard
   VERSION:3.0
   FN:Frank Dawson
   ORG:Lotus Development Corporation
   EMAIL;TYPE=INTERNET,PREF:Frank_Dawson@Lotus.com
   EMAIL;TYPE=INTERNET:fdawson@earthlink.net
   URL:http://home.earthlink.net/~fdawson
   END:vCard


Some sample usage scenarios are described below (proper error handling and memory management should be handled by users of the code snippets):

Creating a pim_IRecordStore object using pim_AEECLSID_ContactStore

   pim_IRecordStore* piContactStore= 0;
   int nErr;
   
   // Assumption: piShell is a valid IShell pointer
   nErr = IShell_CreateInstance(piShell, pim_AEECLSID_ContactStore, (void **)&piContactStore);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

Adding a record to the contact store

   // A record can be added to the contact record store using pim_IRecordStore 
   // interface. First, a vCard formatted single byte per character text
   // string should be created. Then the string can be stored in the contact
   // store.
   int nErr;
   pim_IRecordStore *piContactStore;
   char *Entry;
   pim_IRecordStore_RecordID ID;


   // Assumption: piEnv is a valid IEnv pointer, and piContactStore points
   // to an already created instance of pim_AEECLSID_ContactStore
   // Also, Entry points to a valid vContact formatted record
   nErr = pim_IRecordStore_AddRecord(piContactStore, Entry, 1 + std_strlen(Entry), &ID);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

Deleting a record from the contact store

   // Assumption: piContactStore is a valid pim_IRecordStore object 
   // and ID is the pim_IRecordStore_RecordID value obtained from a 
   // previous call to pim_IRecordStore_AddRecord(), pim_IRecordStore_Search() 
   // or pim_IRecordStore_GetChangedSince()
   int nErr;

   nErr = pim_IRecordStore_RemoveRecord(piContactStore, ID);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

Reading a record from the contact store based on a record ID

A record can be read from the contact store using pim_IRecordStore interface.
   // Assumption: piContactStore is a valid pim_IRecordStore object 
   // and ID is the pim_IRecordStore_RecordID value obtained from a 
   // previous call to pim_IRecordStore_AddRecord(), pim_IRecordStore_Search() 
   // or pim_IRecordStore_GetChangedSince()
   char* Entry;
   int EntryLen = 0;
   int EntryLenReq = 0;

   // Create a baseline for future comparisons.
   nErr = pim_IRecordStore_GetRecord(piContactStore, 
                                     RecordID, 0, 
                                     Entry, EntryLen, &EntryLenReq);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

   // Remember to deallocate using IENV_FREEIF() after done using Entry.
   nErr = IEnv_ErrMallocNoZI(piEnv, EntryLenReq, (void **)Entry);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }
   EntryLen = EntryLenReq;

   nErr = pim_IRecordStore_GetRecord(piContactStore, 
                                     RecordID, 0, 
                                     Entry, EntryLen, &EntryLenReq);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }


Registering for notification on changes in Contact records

Registering for notifications on changes in contact records can be done by simply using the pim_IRecordStore_OnChange() API, but for efficiently determining the type of changes (add, delete, update etc), it is recommended that the client maintain a list of records it has already seen to be compared with the list returned by pim_IRecordStore_GetChangedSince() API. This will also help the client in finding the changes if it is not memory resident. A sequence diagram below also depicts how to use the sequence number to easily find out changes that happened to the contact records.
   // Assumption: piContactStore is a valid pim_IRecordStore object, 
   // piSignal is a valid ISignal object and piEnv is a valid Env object.
   int64 SeqNum = 0LL;
   int64 CurrentSeqNum = 0LL;
   pim_IRecordStore_RecordID* IDs;
   int IDsLen = 0;
   int IDsLenReq = 0;

   // Create a baseline for future comparisons.
   nErr = pim_IRecordStore_GetChangedSince(piContactStore, 
                                           &CurrentSeqNum, SeqNum,
                                           IDs, IDsLen, &IDsLenReq);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

   // Remember to deallocate using IENV_FREEIF() after done using IDs.
   nErr = IEnv_ErrMallocNoZI(piEnv, IDsLenReq, (void **)IDs);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }
   IDsLen = IDsLenReq;

   nErr = pim_IRecordStore_GetChangedSince(piContactStore, 
                                           &CurrentSeqNum, SeqNum,
                                           IDs, IDsLen, &IDsLenReq);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

   nErr = pim_IRecordStore_OnChange(piContactStore, piSignal);
   if (AEE_SUCCESS != nErr) {
      // Handle error here.
   }

Additionally, the following sequence diagram depicts how a client may use the sequence number information to efficiently find out what changes occurred in the contact record store.
Application                                                               System
       |                                                                    |
       |                                                                    |
    1) |--> pim_IRecordStore_GetChangesSince() with baseline seq num   ---->|
       |<-- Baseline seq num should either be read from persistent storage -|
       |--- or can be 0 for the very first time. It is recommended that  ---|
       |--- sequence number and record IDs be stored in persistent storage -|
       |--- so that the application can use those values for their most  ---|
       |--- recent baseline snapshot to enhance efficiency.              ---|
    2) |<-- Current seq num and snapshot of current record identifiers <----|
       |--- Client remembers new seq num obtained from this call to use  ---|
       |--- in next call to pim_IRecordStore_GetChangesSince()           ---|
       |--- Client remembers snapshot of record identifiers e.g. {1,2,3} ---|
    3) |-----------------> pim_IRecordStore_OnChange()  ------------------->|
       |                               .                                    |
       |                               .                                    |
       |                               .                                    |
    4) |<---------- contact store got changed and Signal is set  <---------|
    5) |--> pim_IRecordStore_GetChangedSince() with seq num from step 2 --->|
    6) |<-- Current seq num and snapshot of current record identifiers <----|
       |--- Client obtains list of added, updated and deleted record IDs. --|
       |--- Client remembers snapshot of record identifiers based on -------|
       |--- list of added and updated IDs. e.g. {1,3,4,5}                ---|
    7) |---------> pim_IRecordStore_GetRecord() with record IDs 1,3,4,5 --->|
       |--- Client goes to sleep/gets terminated.                        ---|
       |                               .                                    |
       |                               .                                    |
       |                               .                                    |
       |--- Client wakes up.                                             ---|
    8) |--> pim_IRecordStore_GetChangesSince() with seq num from step 5 --->|
    9) |<---- pim_IRecordStore_ESTALESEQNUM. Maybe many changes have     ---|
       |--- happened to callhistory.                                   <----|
       |--- Client prepares for "slow sync" by providing valid values for --|
       |--- AddedIDs, UpdatedIDs and UnchangedIDs.                       ---|
   10) |--> pim_IRecordStore_GetChangesSince() with valid AddedIDs,      ---|
       |--- UpdatedIDs and UnchangedIDs.                    --------------->|
   11) |<-- Current seq num and snapshot of current record identifiers <----|
       |--- Client compares added, updated and unchanged record IDs with ---|
       |--- previous snapshot to find out records that were deleted.     ---|
       |--- Client remembers new seq num obtained from this call to use  ---|
       |--- in next call to pim_IRecordStore_GetChangesSince()           ---|

Default Interface Name