Novell is now a part of Micro Focus

GroupWise Message Logging

Articles and Tips: article

KEN CIRCEO
Technical Writer
GroupWare Division

CAROL OERTLI
Technical Editor
GroupWare Division

01 Dec 1996


Explains how to use the GroupWise Message Logging API to access stored data necessary in producing customized billing, tracking, and statistical reports.

Introduction

Gathering information about message traffic on your GroupWise system enables you to perform valuable tasks, such as:

  • Billing customers for messages delivered

  • Tracking messages

  • Gathering statistics to help optimize your GroupWise system

The GroupWise Message Transfer Agent (MTA) provides message logging to help you with such tasks by collecting and storing data as it processes messages. You can access the stored data through the GroupWise Message Logging API, allowing value added programs to produce customized billing, tracking, and statistical reports.

You can turn message logging on and off through Admin. This option is configurable and should be set to match the logging requirements, thus optimizing MTA performance.

With message logging turned on, you can choose whether or not you want the GroupWise MTA to perform logging correlation on the data gathered. Logging correlation maintains the relationship between messages and their corresponding delivery reports (delivery/nondelivery). For example, if a user sends a message and receives a report of "Delivered," updating the database will depend on the logging correlation.

  • With correlation disabled, the GroupWise MTA does not update the message record associated with the report. However, if the Log Reports parameter is set to "Yes," correlation can be performed offline, reducing the load on the GroupWise MTA.

  • With correlation enabled, the GroupWise MTA updates the delivery status field of the associated message record with the value of the status in the report.

For optimal MTA performance, make sure the correlation selection matches the requirements of the application that is using the logging database.

Selecting Types of Messages to Log

With message logging turned on, the following types of messages can be logged:

  • All mail messages.These are GroupWise messages that travel from a sender to a recipient.

  • Reports. These indicate whether mail messages are delivered or undeliverable. Reports must be logged if offline correlation by a value added program is desired.

  • User statuses. These are additional responses to mail messages that provide specific, user-requested information about messages sent, such as indicating that messages have been opened or deleted by the recipients. To measure throughput accurately, user statuses must be logged.

  • Other messages containing system information, such as administration messages for updating domains and post offices. As with user statuses, other messages must be logged to measure throughput accurately.

Selecting Amount of Data to Log (Verbosity)

With message logging turned on, you can choose between two levels:

  • Brief logging collects message flow data suitable for billing and tracking, such as message identifier, message type, sender, priority, size, next hop, final destination, and customizable flags.

  • Full logging collects the same data that the brief logging collects plus data suitable for detailed statistical reporting, such as arrival time, queued time, time to send to the next hop, completed time, connection count, and transport specific information.

For a list of specific data logged at the brief and full logging levels, see "MTA Logging Fields" in the Message Logging documentation in the GroupWise SDK.

Configuring Message Logging

Different configurations are appropriate for different message tasks. See Exploring the Logged Information later in this article for information.


Configuration
Settings
Database Contents
Advantages
Disadvantages

Minimum (Simplest Billing)

Correlate:No Log Report: No Log Status: No Log Other: No Verbosity: Brief

Mail Messages (no correlation)

Small database

Low processing overhead

Cannot measure throughput

Cannot correlate

Billing based on arrival only

Speed (Optimal Billing)

Correlate: No Log Report: Yes Log Status: No Log Other: No Verbosity: Brief

Mail Messages (no online correlation)

Reports

Low overhead

Can correlate offline

Billing based on correlation

Medium sizeddatabase

Cannot measure throughput

Size (Optimal Billing)

Correlate:Yes Log Report: No Log Status: No Log Other: No Verbosity: Brief

Mail Messages (online correlation)

Small database

Online correlation

Billing based on correlation

Medium overhead

Cannot measure throughput

Maximum (Billing, Tracking, and Statistics)

Correlate:Yes Log Report: Yes Log Status: Yes Log Other: Yes Verbosity: Full

Mail Messages (online correlation)

Reports

User Status Messages

Other Messages

Can measure throughput

Online correlation

Billing based on correlation

Large database

Large overhead

Running GroupWise With Message Logging

Once message logging is turned on and configured, it requires minimal attention. However, you may periodically need to:

  • Manually archive the current logging database and start a new one

  • Disable or modify the logging configuration after it has been started. If you do this, some messages may not get correlated.

Data Stores and Corruption

The message logging database consists of a data dictionary and 16 record stores. The storage is divided into 16 stores to improve performance and reduce the conflicts of trying to lock a single store. In the event of a power failure, message store corruption can occur. Call MTALogCheckStore to check a specific store for corruption. The data dictionary is store 0. Stores 1 through 16 contain the message logging information. If LOG_ERR_DB_CORRUPT is returned from MTALogCheckStore, you can call MTALogRepairStore to repair the database. Because this may take some time (depending on the size of your store), a callback routine is available to give you a continuing status and allow you to terminate the repair process. See the MTALogCheckStore function in the GroupWise SDK.

Exploring the Logged Information

Figure 1 illustrates the structure of each message record in the message logging database. The accompanying table lists the fields in each record, a description of each field, the logging level (brief/full) at which the information is recorded, and the event (arrival, queuing, or transfer) at which each piece of information is logged.

MTA Logging Fields

A message is logged to the database at three different times as it passes through the MTA. Each logging event is discussed below. The last column in the table refers to a logging event and indicates when the value for the field is set or updated.

  • Arrive: The MTA picks up the message from its input queue.

  • Queue: The MTA has made the routing decisions and is splitting the message to multiple destinations. As the message is successfully queued to the responsible Transport Module, this event is logged.

  • Transfer: The Transport Module has successfully sent the message to its next hop or to its final destination.

Figure 1: Message records in the message logging database.


Field
Description
Log Level
Event

Type

Messagetype associated with the record. These types include MESSAGE, REPORT, USERSTATUS, ADMINMESSAGE, and ALL (using the syntax RECORD_TYPE_MESSAGE, for example).

New types may be added in the future as new applications use the MessageTransfer Service.

Brief

Arrive

IdentifierINDEXED

Unique identifier for the message

Brief

Arrive

Originator

Domain Originator's domain

ARI UNINDEXED. Additional Routing Information. In caseswhere the originator resides in an external domain relative to the logging MTA, the ARIis stored.

PO INDEXED. Post Office

UserId INDEXED. GroupWise user ID. Available only in messages originating from GroupWise 5.

Brief

Arrive

Report

Tracking level selected for this message. Possible values are TRACK_OFF=0, TRACK_ON=1, and TRACK_CONTENT=2.This field tells whether the originator requested a delivery report for the message.

Brief

Arrive

Arrival Time

Thetime of day the message arrived at this MTA. The time is stored in the following fields:year, month, day, hour, minute, seconds, and hundredths of a second.

Full

Arrive

Queued Time

The time of day when the MTA placed the message in the queue ready for transfer. The timeisstored in the following fields: year, month, day, hour, minute, seconds, and hundredths of a second.

Full

Queue

Priority

The priority assigned to the message. This priority is either assigned by the originating useror by the originating application. Values range from 0 to 15, with 8 15 beingidentical to0 7 respectively, except that 8 15 are order dependent.

0 Busy searches, some administrative messages1 Remote requests2 High priority mail, administrative messages3 Reports and user statuses forpriority 24 Normal priority mail, administrative messages5 Reports and user statuses for priority 46 Low priority mail, administrativemessages7 Reports and user statuses for priority 6

Brief

Arrive

User Flags

Applications using the MTA logging database can set these flags to indicate the state of the record,(for example, correlated or billed). This field is initialized at 0.

Brief

Arrive

Next Hop Name

Name of the destination Post Office or next domain in the route

Brief

Queue

Next Hop Type

Type of the next hopRELAYED=0 The message is relayed to another domain en route to itsfinal destination.DELIVERY=1 The message is delivered to its final destination. This destination may be a PostOffice or an Admin server. New uses may be added in the future.

Full

Queue

Next Hop Size

Number of bytes in the message file

Brief

Queue

Next Hop Completed Time

The time of day the message completed transfer to the next hop. The time is stored in the followingfields: year, month, day, hour, minute, seconds, and hundredths of a second.

Full

Transfer

Next Hop Time to Send

Number of milliseconds required to transfer the message. This value is optional and is obtained fromthe Transport Module.

Full

Transfer

Next Hop Connection Count

Number of attempts to open a transport connection. A value of 0 indicates that the connection wasalready established for an earlier message and the same connection is being used.

Full

Transfer

Next Hop Module Name

Name of the Transport Module that successfully sent the message (such as FileCopy or TCP/IP)

Full

Transfer

Next Hop User Defined

Transport specificinformation in binary format. This information is provided by theimplementors of new transport modules to collect data pertaining to a specific transport.

Full

Transfer

Destination Name

Fullname of the destination application(ARI:Domain.PO)

Brief

Arrive

Destination Number

Host number in the original message to which the reports can be mapped

Brief

Arrive

Destination Status

Current status of the message. In the arrive event, this field is set to Pending if a reportis requested, and to Delivered if a report is not requested.

PENDING No report received from destinationDELIVERED A delivery report received for this destination

NON DELIVERED A non delivery report received forthis destination

This field can be updated by the MTA (Correlation active) or by anoffline process

Brief

Arrive

Logging Events

This example shows the logging events that occur as a message is routed to multiple recipients.

Figure 2: Logging example.

The MTA Logging Options for this example are displayed in the dialog box shown. The administrator has chosen to correlate delivery and nondelivery reports for messages as they pass through the MTA. All the fields will be logged for mail messages but no other kinds of messages will be logged to the database.

Scenario

A user sends a message from North.Supp to four destinations: one recipient in East.Sales, three recipients in East.Dev, two recipients in West.MarCom, and one recipient in West.Testing. The message is routed through the Central domain, which performs the MTA logging.

Figure 3: A message sent to four destinations.

Events

  1. Arrival event. When the MTA in Central receives the message, it is handled by the router. The router extracts the following information from the message and logs it to the database:

Type:   MAIL_MESSAGE

ID: 3E453B405A10:2:34987

Originator: North.Supp

Report: ON

Arrival time: 11/15/1995 08:19:08

Queued time: NA

Priority: 4

User  ags: 00000000

Next Hop: NA

Destination: NA

The router in the MTA makes the routing decisions based on the local configuration. Each destination is checked and the next domain or delivery Post Office is determined.

Queue event. The message is divided into two copies. One is sent to the East domain and the other to the west. The message record is updated to contain queued time and next hop subrecords.

Type:   MAIL_MESSAGE

ID: 3E453B405A10:2:34987

Originator: North.Supp

Report: ON

Arrival time: 11/15/1995 08:19:08

Queued time: 11/15/1995 08:19:08

Priority: 4

User  ags: 00000000

Next Hop:   

    Name: East

    Type: RELAY   

    Size: 3420   

    Completed time: NA   

    Time to send: NA   

    Connection count: NA   

    Module name: ASYNC   

    User defined: NA

Next    Hop:   

    Name: West   

    Type: RELAY   

    Size: 3420

    Completed time: NA   

    Time to send: NA 

    Connection count: NA   

    Module name: TCP_IP

    User defined: NA

Destination:   

    Name: East.Sales

    Number: 1   

    Delivery: PENDING

    Destination:

    Name: East.Dev   

    Number: 2   

    Delivery: PENDING

Destination:   

    Name: West.MarCom 

    Queue: NONE   

    Number: 3   

    Delivery: PENDING

Destination:

    Name: West.Testing   

    Number: 4   

    Delivery: PENDING

The copies of the message generated by the dispatcher are queued to the corresponding transport modules, and the dispatcher signals the transport modules that there are message transfers to be made.

Transfer event. The transport module determines when the message is to be transferred based on the local scheduling policy. Once the message is sent, the transport module updates its portion of the database entry. The completion time, time to send, connection count, transport module name, and user defined information fields are updated at this point.

Note: The transport module name was assigned when the message was queued, but is reassigned here because, if an alternate transport mechanism is used, a module other than the initial one may relay the message.

Next Hop:

   Name: East

   Type: RELAY   

   Size: 3420   

   Completed time: 11/15/1995 08:20:24   

   Time to send: 3450

   Connection count: 1   

   Module name: ASYNC

   User defined: [user defined]

The West domain is connected via a TCP/IP link:

Next Hop:

   Name: West

   Type: RELAY   

   Size: 3420   

   Completed time: 11/15/1995 08:19:13   

   Time to send: 20  

   Connection count: 1   

   Module name: TCP_IP

   User defined: [user defined]

Delivery Report is received. The message is delivered to the Post Offices. When the MTA in West delivers a copy of the message to Post Office West. Testing, a delivery report is generated and sent back to the originator in North.Supp. Because the MTA Logging Options for this example specify that the MTA correlates all reports, the MTA, upon receiving the report, looks up the record for the original message in the database and updates the destination record for this Post Office.

Destination:

  Name: West.Testing   

  Number: 4   

  Delivery: DELIVERED

The MTA Logging Options also specified that the reports are not logged to the database. Therefore, after correlating this report, the MTA routes it forward without logging the report separately to the database.

The complete record after the four events is:

Type: MAIL_MESSAGE

ID: 3E453B405A10:2:34987

Originator: North.Supp

Report: ON

Arrival time: 11/15/1995 08:19:08

Queued time: 11/15/1995 08:19:08

Priority: 4

User  ags: 00000000

Next Hop:

   Name: East

   Type: RELAY

   Size: 3420

   Completed time: 11/15/1995 08:20:24

   Time to send: 3450

   Connection count:1

   Module name: ASYNC

   User defined: [USER DEFINED]

Next Hop:

   Name: West

   Type: RELAY

   Size: 3420

   Completed time: 11/15/1995 08:19:13

   Time to send: 20

   Connection count: 1

   Module name: TCP_IP

   User defined: [USER DEFINED]

Destination:

   Name: East.Sales

   Number: 1

   Delivery: PENDING

Destination:

   Name: East.Dev

   Number: 2

   Delivery: PENDING

Destination:

   Name: West.MarCom

   Number: 3

   Delivery: PENDING

Destination:

   Name: West.Testing

   Number: 4

   Delivery: DELIVERED

Other Options

Assume the MTA Logging Options were as shown in this dialog box.

Figure 4: MTA Logging options.

The MTA does not correlate reports to messages. Only the basic fields are included and the MTA logs reports to the database. The resulting records from the events described above are shown below. The mail message has considerably fewer fields in the next hop subrecords.

Type: MAIL_MESSAGE

ID: 3E453B405A10:2:34987

Originator: North.Supp

Report: ON

Arrival time: 11/15/1995 08:19:08

Priority: 4

User flags: 00000000

Next Hop:

   Name: East

   Size: 3420

Next Hop:

   Name: West

   Size: 3420

Destination:

   Name: East.Sales

   Number: 1

   Delivery: PENDING

Destination:

   Name: East.Dev

   Number: 2

   Delivery: PENDING

Destination:

   Name: West.MarCom

   Number: 3

   Delivery: PENDING

Destination:

   Name: West.Testing

   Number: 4

   Delivery: PENDING

The received report is logged as an entry to the database. The Message Identifier and the Originator are the same as in the corresponding message. The destination record indicates the delivered status; message/report correlation can be done offline through the Logging API.

Type: REPORT

ID: 3E453B405A10:2:34987

Originator: North.Supp

Arrival time: 11/15/1995 08:36:12

Priority: 5

User flags: 00000000

Next Hop:

   Name: North

   Size: 368

Destination:

   Number: 4

   Delivery: DELIVERED

Logging API Overview

Before accessing the message log database, you must call MTALogOpenDataBase( ). This function will return a pointer to a database context which should be kept and passed into the appropriate functions. The information stored in the database context is for internal use only. When you are finished with the database, you must call MTALogCloseDataBase( ) to free all resources associated with the database context.

If you are writing multithreaded applications, each thread must open the database and get a new database context pointer.

After you have obtained a valid database context pointer, you should create a cursor (a pointer into the database). The four types of cursors are:

  • Message ID (MTALogCreateMessageIDCursor)

  • Originator (MTALogCreateOriginatorCursor)

  • Date (MTALogCreateDateCursor)

  • Direct access (MTALogCreateCursor)

Message ID, originator, and date cursors can be used to traverse or query the database to find matching message IDs, originator addresses, or records where the Arrival Time is within a set interval. The calls to create these cursors can find and optionally load the message record fields for the first matching record.

MTALogMoveCursorToNext( ) will find and load the next matching record. MTALogMoveCursorToNext( ) may be called repeatedly until a LOG_NOT_FOUND is returned. When you are finished with a cursor, you should call MTALogDestroyCursor( ) to free any resources associated with the cursor.

The direct access cursor is used to retrieve a message directly from the database without searching. To create a direct access cursor, you must know the store and database reference number (DRN). Message records contain Store and DRN fields. You can retain the values from these fields for direct access to the record at a later time. This cursor should not be used in conjunction with MTALogMoveCursorToNext( ). Though this cursor is not used for searching, MTALogDestroyCursor( ) must be called to free any resources associated with the cursor.

Once there is a cursor pointing to a record in the database, you can delete the record, set its user flags, correlate associated records, or traverse the destination or next hop subrecords. Correlation is done by calling MTALogCorrelate( ). The procedure MTALogCorrelate( ) will perform depends on the type of record (message or report) the cursor is pointing to. If the cursor points to a message record, all report records with the same message ID are located.

The destination delivery status is updated to correlate with each report record status. If the cursor points to a report record, the message record with the same message ID is loaded and the proper destination delivery status in the message record is set according to the report record status.

You can traverse all destination subrecords by calling MTALogLoadFirstDestination( ), then MTALogLoadNextDestination( ) until LOG_NOT_FOUND is returned. These calls will find and load the destination subrecord information. To find and load a specific destination subrecord, call MTALogLoadDestination( ) and provide the destination number of that record. Because delivery reports make a reference to the destination number rather than the name of the destination, the destination number is required to tie a record delivery report to a certain destination of a message record.

Traversing all next hop subrecords is similar to traversing the destination subrecords. Call MTALogLoadFirstHop( ) and the MTALogLoadNextHop( ) until LOG_NOT_FOUND is returned. These calls will find and load the hop subrecord information. To find a specific hop subrecord call MTALogLoadHop( ) and provide the name of the hop.

After the database has been opened, if an error occurs, you can call MTALogGetErrorNumber( ) to obtain the internal error number. When you install Admin, it will copy a file called ERROR.TXT to the primary domain directory. Use the error number to cross reference in the ERROR.TXTfor extended meaning and possible solutions.

Data Structures

The three basic data types defined for cross platform purposes are:

L_UBYTE unsigned 8 bit

L_UWORD unsigned 16 bit

L_UDWORD unsigned 32 bit



L_STRING Fields defined with L_STRING are general strings. 

         The format  of the string is determined at run 

         time. String type is set  when the database is 

         opened or with the MTALogSetStringType  function. 

         L_STRING is declared as L_UBYTE.



typedef enum {

RECORD_TYPE_ALL,

RECORD_TYPE_MESSAGE,

RECORD_TYPE_ADMIN,

RECORD_TYPE_REPORT,

RECORD_TYPE_STATUS

} RECORD_TYPE;



typedef enum {

MSG_STATUS_NONE,

MSG_STATUS_PENDING,

MSG_STATUS_NON_DELIVERED,

MSG_STATUS_DELIVERED

} MSG_STATUS;



typedef struct {

L_UWORD year;

L_UBYTE month;

L_UBYTE day;

L_UBYTE hour;

L_UBYTE minute;

L_UBYTE second;

L_UBYTE hundredth;

} F_TMSTAMP;



#define MESSAGEIDLEN  256

#define ORG_DOMLEN    256

#define ORG_ARIPOLEN  256

#define ORG_USERIDLEN 256





typedef struct {

L_UDWORD udStore;

L_UDWORD udDrn;

RECORD_TYPE eType; /* will never be RECORD_TYPE_ALL */

L_UBYTE ubId[MESSAGEIDLEN + 1];

L_STRING saDomain[ORG_DOMLEN + 2];

L_STRING saAri_PO[ORG_ARIPOLEN + 2];

L_STRING saUser[ORG_USERIDLEN + 2];

L_STRING saARI[ORG_ARILEN + 2];

L_STRING saPO[ORG_POLEN + 2];

L_UBYTE ubReport;

F_TMSTAMP ArrivalTime;

F_TMSTAMP QueuedTime;

L_UBYTE ubPriority;

L_UBYTE ubUserFlags;

} MESSAGE_RECORD;



#define HOPNAMELEN     256

#define NEXTMODULELEN  256

#define USERDEFINEDLEN 256





typedef struct{

L_STRING saName[HOPNAMELEN + 2];

L_UBYTE ubType;

L_UDWORD udSize;

F_TMSTAMP CompletionTime;

L_UDWORD udTimeToSend;

L_UWORD uwConnectionCount;

L_STRING saNextModule[NEXTMODULELEN + 2];

L_UBYTE ubaUserDe ned[USERDEFINEDLEN];

L_UWORD uwUserDefSize;

L_UDWORD udNumber;

} HOP_RECORD;



#define DESTINATIONNAMELEN 256

typedef struct {

L_STRING saName[DESTINATIONNAMELEN];

L_UBYTE ubNumber; MSG_STATUS eStatus;

L_UDWORD udHopNumber; } DESTINATION_RECORD;

Error Codes


Message
Explanation

LOG_SUCCESS

(0)The function executed successfully.

LOG_NOT_FOUND

(1)Not Found. If a create cursor function, suchas MTALogCreateCursor( ) returns this value,no record matched the cursor specifications.

LOG_ERR_NULL_POINTER

(2)A NULL pointer was passed as an argument when it was not allowed.

LOG_ERR_DB_OPEN

(11)MTALogOpenDataBase( ) could not open the given logging database due to incorrect path orfilename, insufficient rights, or missing database file.

LOG_ERR_DB_LOCK

(12)MTALogSetUserFlags( ) and MTALogCorrelate must get a lock on the logging database in order to update the records with new User Flags and Destination Delivery Statuses. It is possible that it timed out before a lock could occur. Retry the function.

LOG_ERR_DB_CORRUPT

(13)MTALogCheckStore( ) has determined that your database is corrupted.

LOG_ERR_TRANS_ACTIVE

(14)MTALogCheckStore( ) has determined that the transaction is already active.

LOG_ERR_MAINT_SEQUENCE

(15)MTALogRepairStore( ) could not obtain a maintenance sequence number.

LOG_ERR_STORE_REBUILD

(16)MTALogRepairStore( ) detected an error while repairing the store.

LOG_ERR_SESSION_OPEN

(20) MTALogOpenDataBase( ) failed to obtain a session handle to the database.

LOG_ERR_POOL_RESET

(21)When a call to MTALogMoveCursorToNext( ) is made, the memory pool which holds the new record must be reset. If you get this error, memory has been corrupted, and the program should not continue.

LOG_ERR_GET_FIELD

(30)Could not read a field from the memory pool. Possible corrupt record.

LOG_ERR_PUT_FIELD

(31)Error occurred writing a value into the memory pool. MTALogSetUserFlags( ) and MTALogCorrelate( ) are the only API routines that write to the memory pool.

LOG_ERR_PUT_RECORD

(32)Error occurred writing memory pool record to the logging database.

LOG_ERR_MISSING_FIELD

(33)An expected record field was not found in the current record.

LOG_ERR_INVALID_CURSOR

(40)The given cursor is not valid. It may be corrupt, or it may not have been initializedcorrectly. It must have a valid pointer into the memory pool record.

LOG_ERR_CURSOR_SETUP

(41)Error occurred setting up or validating a database query.

LOG_ERR_CURSOR_INIT

(42)Error occurred initializing cursor.

LOG_ERR_CURSOR_INDEX

(43)Error occurred setting index for cursor.

LOG_ERR_RECORD_TYPE

(50) Error setting the record type for cursor.

LOG_ERR_RECORD_READ

(51)Error reading record from logging database into memory pool.

LOG_ERR_RECORD_DELETE

(52) Error occurred deleting record from logging database.

LOG_ERR_NO_MEMORY

(60) Could not allocate enough memory for current operation.

Sample Code Segments

This section shows the API functions required to implement various tasks and provide better understanding of how functions can be used in combination. For clarity, declarations of variables are shown as well. These examples do not contain error checking.

Correlate Messages to Reports

Using C:\TEST.DB database, sets bit 1 of the UserFlags field to indicate that the report record has been correlated.

Note: The user determines the definition of UserFlags. It is 8 bits and can be used for bit fields or an 8 bit value.

RCODE rc;

DB_CONTEXT *pDBContext;

CURSOR *pCursor;

MESSAGE_RECORD MessageRecord;





MTALogOpenDataBase ("C:\\TEST.DB", &pDBContext);&


rc = MTALogCreateMessageIDCursor (pDBContext,

NULL,

RECORD_TYPE_MESSAGE,

&MessageRecord,&
&pCursor);&


while (rc == LOG_SUCCESS)

{

   #define CORRELATED 1

   if ( !(MessageRecord.UserFlags & CORRELATED) )

   {

   

MTALogCorrelate (pCursor);

MTALogSetUserFlags (pCursor, CORRELATED);

   }



   MTALogMoveCursorToNext (pCursor, &MessageRecord);&
}



MTALogDestroyCursor (pCursor);



MTALogCloseDataBase (pDBContext);

Delete a Specific Record

Deletes a record with a message ID of "3099E597 3521 0000@"

RCODE rc;

DB_CONTEXT *pDBContext;

CURSOR *pCursor;



MTALogOpenDataBase ("C:\\TEST.DB", &pDBContext,&
STR_NATIVE)



rc = MTALogCreateMessageIDCursor (pDBContext,

"3099E59735210000@",

RECORD_TYPE_MESSAGE,

&MessageRecord, &pCursor);&
if (rc == LOG_SUCCESS)

   MTALogDeleteCursorRecord (pCursor);



   MTALogDestroyCursor (pCursor);



   MTALogCloseDataBase (pDBContext);

Traverse All Destinations in a Message Record

RCODE rc;

DB_CONTEXT *pDBContext;

CURSOR *pCursor;

DESTINATION_RECORD DestRec;





MTALogOpenDataBase ("C:\\TEST.DB", &pDBContext,&
STR_NATIVE)



rc = MTALogCreateMessageIDCursor (pDBContext,

NULL,

RECORD_TYPE_MESSAGE,

NULL,

&pCursor);&


rc = MTALogLoadFirstDestination (pCursor, &DestRec);&


while (rc == LOG_SUCCESS)

{

   // use populated DESTINATION_RECORD structure here



   rc = MTALogLoadNextDestination (pCursor, &DestRec);&
}



MTALogDestroyCursor (pCursor);



MTALogCloseDataBase (pDBContext);

Traverse All Records with Automatic Record Loading

Use C:\TEST.DB database to do this.

RCODE rc;

DB_CONTEXT *pDBContext;

CURSOR *pCursor;

MESSAGE_RECORD MessageRecord;





MTALogOpenDataBase ("C:\\TEST.DB", &pDBContext,&
STR_NATIVE)



rc = MTALogCreateMessageIDCursor (pDBContext,

NULL,

RECORD_TYPE_ALL,

&MessageRecord,&
&pCursor);&


while (rc == LOG_SUCCESS)

{

   // use populated MessageRecord structure here.

   printf ("ID: %s", MessageRecord.Id);



   rc = MTALogMoveCursorToNext (pCursor, &MessageRecord);&
}



MTALogDestroyCursor (pCursor);



MTALogCloseDataBase (pDBContext);

* 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