MAPIStore 1.0 backend.context structure

This structure holds couple of pointer on functions which perform operations specific to mapistore contexts:
  • backend.context.get_path
  • backend.context.get_root_folder

context.get_path

In MAPIStore, backends can't register FMID to mapistore URI themselves. This is the role of mapistore middleware.

To understand this choice, an overview of message creation provides a good example. When a MAPI client creates a message, it doesn't perform this action through a unique operation. It may even not do it through a single network transaction. This is different from an IMAP message where the email is composed and pushed at once. In the case of MAPI, a client will successively call (for a draft email): CreateMessage, SetProps, ModifyRecipients, SaveChangesMessage. If a client releases the message before it reaches the SaveChangesMessage, the message is destroyed and won't be anymore available on the system. However, during the message creation process, the message virtually exists and has a MID associated. It is just that nobody except the client creating the message can access it.

From an openchange perspective, it means that the MID exists but is not yet stored within the indexing.tdb database of the user and is not permanently associated to a mapistore URI:
  • When the createmessage's backend function is called, it receives a MID.
  • It generates a mapistore URI for this MID
  • It stores internally this MID to mapistore URI mapping
  • It goes this way through the entire message creation
When the message is finally save, it is time to expose the message publicly and reference it. This is where the context.get_path functions matters:
  • The mapistore middleware will register the MID (or FID) within the indexing.tdb of the user
  • However it doesn't know the mapistore URI which was associated
  • It queries the backend using context.get_path to retrieve the URI associated to the FMID
  • It registers the message within the indexing.tdb database

You have also figured out that such behavior doesn't only apply to messages but also to folders. When a CreateFolder is called, the FID is passed to CreateFolder, the backend generates a URI and internally associates it to this FID. When mapistore middleware registers the folder, it queries context.get_path with the FID and retrieve the URI.

This is an indirect way to retrieve data, but it is also useful when a call returns an error etc.

context.get_root_folder

mapistore v1 is using object concepts. For example you may have noticed that we have divided backend functions from context functions. Forthcoming documentation also describe folder, message, table or property functions. Each of these subsets of functions represent an objet. So we have:
  • a backend object
  • a context object
  • a fodler object
  • a message object
  • etc.

When we create a context, we are in fact opening a folder, except that this folder is a root folder. For this very special case, we are only creating a context but the folder is however opened. It means that a context is also a folder. The get_root_folder functions returns a folder representation of the context object created. It lets backends directly call folder operations on contexts rather than having to open (again) the folder to call its operations.