The Email Sample Application
•
|
Message: Holds one object per sent email. Each object stores values such as Size and SendDate timestamp and links to Participant objects in three different roles: sender, internal recipient, and external recipient.
|
•
|
Participant: Represents a sender or receiver of the linked Message. Holds the ReceiptDate timestamp for that participant and links to identifying Person and Address objects.
|
•
|
Address: Stores each participant’s email address, a redundant link to Person, and a link to a Domain object.
|
•
|
Person: Stores Directory Server properties such as a Name, Department, and Office.
|
•
|
Domain: Stores unique domain names such as “yahoo.com”.
|
Message objects are stored in a shard named
YYYY-MM-DD based on their
SendDate. The related
Participant,
Address,
Person, and
Domain objects are stored in the same shard. This means, for example, that
Person and
Domain objects are replicated to every shard in which they are referenced.
<field name="InReplyTo" type="XLINK" table="Message" inverse="Responses" junction="ThreadID"/>
<field name="Sender" type="LINK" table="Participant" inverse="MessageAsSender"/>
<field name="ExternalRecipients" type="LINK" table="Participant" inverse="MessageAsExternalRecipient"/>
<field name="InternalRecipients" type="LINK" table="Participant" inverse="MessageAsInternalRecipient"/>
<field name="Responses" type="XLINK" table="Message" inverse="InReplyTo" junction="_ID"/>
<alias name="$SalesEmails" expression="Sender.Person.WHERE(Department:Sales)"/>
<field name="MessageAddress" type="LINK" table="Address" inverse="Messages"/>
<field name="MessageAsExternalRecipient" type="LINK" table="Message" inverse="ExternalRecipients"/>
<field name="MessageAsInternalRecipient" type="LINK" table="Message" inverse="InternalRecipients"/>
<field name="MessageAsSender" type="LINK" table="Message" inverse="Sender"/>
<field name="Person" type="LINK" table="Person" inverse="Messages"/>
<field name="Domain" type="LINK" table="Domain" inverse="Addresses"/>
<field name="Messages" type="LINK" table="Participant" inverse="MessageAddress"/>
<field name="Person" type="LINK" table="Person" inverse="MessageAddresses"/>
<field name="DirectReports" type="LINK" table="Person" inverse="Manager"/>
<field name="Manager" type="LINK" table="Person" inverse="DirectReports"/>
<field name="MessageAddresses" type="LINK" table="Address" inverse="Person"/>
<field name="Messages" type="LINK" table="Participant" inverse="Person"/>
<field name="Addresses" type="LINK" table="Address" inverse="Domain"/>
"InReplyTo": {"type": "XLINK", "table": "Message", "inverse": "Responses", "junction": "ThreadID"},
"Sender": {"type": "LINK", "table": "Participant", "inverse": "MessageAsSender"},
"ExternalRecipients": {"type": "LINK", "table": "Participant", "inverse": "MessageAsExternalRecipient"},
"InternalRecipients": {"type": "LINK", "table": "Participant", "inverse": "MessageAsInternalRecipient"}
"Responses": {"type": "XLINK", "table": "Message", "inverse": "InReplyTo", "junction": "_ID"},
"SendDate": {"type": "TIMESTAMP"},
"Size": {"type": "INTEGER"},
"Subject": {"type": "TEXT"},
"Tags": {"collection": "true", "type": "TEXT"},
"ThreadID": {"type": "TEXT"}
"$SalesEmails": {"expression": "Sender.Person.WHERE(Department:Sales)"}
"MessageAddress": {"type": "LINK", "table": "Address", "inverse": "Messages"},
"MessageAsExternalRecipient": {"type": "LINK", "table": "Message", "inverse": "ExternalRecipients"},
"MessageAsInternalRecipient": {"type": "LINK", "table": "Message", "inverse": "InternalRecipients"},
"MessageAsSender": {"type": "LINK", "table": "Message", "inverse": "Sender"},
"Person": {"type": "LINK", "table": "Person", "inverse": "Messages"},
"ReceiptDate": {"type": "TIMESTAMP"}
"Domain": {"type": "LINK", "table": "Domain", "inverse": "Addresses"},
"Messages": {"type": "LINK", "table": "Participant", "inverse": "MessageAddress"},
"Name": {"type": "TEXT"},
"Person": {"type": "LINK", "table": "Person", "inverse": "MessageAddresses"}
"DirectReports": {"type": "LINK", "table": "Person", "inverse": "Manager"},
"FirstName": {"type": "TEXT"},
"LastName": {"type": "TEXT"},
"Department": {"type": "TEXT"},
"Office": {"type": "TEXT"}
"Manager": {"type": "LINK", "table": "Person", "inverse": "DirectReports"},
"MessageAddresses": {"type": "LINK", "table": "Address", "inverse": "Person"},
"Messages": {"type": "LINK", "table": "Participant", "inverse": "Person"},
"Addresses": {"type": "LINK", "table": "Address", "inverse": "Domain"},
"IsInternal": {"type": "BOOLEAN"},
•
|
The auto-merge option schedules a background task to check all shards and automatically merge any new data every hour.
|
•
|
The Message table contains a group field called Participants, which contains the link field Sender and a second-level group called Recipients, which contains the links InternalRecipients and ExternalRecipients.
|
•
|
The Message table contains a reflexive, cross-shard relationship formed by the xlinks InReplyTo and Responses.
|
•
|
The Message table defines an alias called $SalesEmails, which is assigned the expression Sender.Person.WHERE(Department:Sales). $SalesEmails is dynamically expanded when used in DQL queries.
|
•
|
The application defines a data-aging task, assigning its schedule the cron expression " 0 3 * * *", which means “every day at 03:00".
|