Contents
Notation
Base data types
Integers
- 16 bit, big-endian, unsigned integer:
-define (uint16 (Value), <<Value:16/unsigned-integer-big-unit:1>>). -define (sizeof_uint16, 2).
- 32 bit, big-endian, unsigned integer:
-define (uint32 (Value), <<Value:32/unsigned-integer-big-unit:1>>). -define (sizeof_uint32, 4).
- 64 bit, big-endian, unsigned integer:
-define (uint64 (Value), <<Value:64/unsigned-integer-big-unit:1>>). -define (sizeof_uint64, 8).
Buffer
- binary:
-define (binary (Data), <<Value/binary>>).
Strings
- binary (no encoding) string:
-define (binary_string (String), << ?uint16 (?lengthof (String)), <<Byte:8/unsigned-integer-big-unit:1 || Byte <- String>> >>).
- UTF-8 encoded string:
-define (utf8_string (String), << ?uint16 (?lengthof (String)), <<Byte:8/unsigned-integer-big-unit:1 || Byte <- String>> >>).
Miscellaneous
- size of binary:
-define (sizeof (Data), erlang:size (Data)).
- length of list (as elements) or strings (as number of bytes):
-define (lengthof (List), erlang:length (List)).
Generic data types
- identifiers:
-define (identifiers (Identifiers), << ?uint32 (?lengthof (Identifiers)), <<?uint64 (Identifier) || Identifier <- Identifiers>> >>).
- records:
-define (records (Records), << ?uint32 (?lengthof (Records)), <<?attributes (Attributes) || Attributes <- Records>> >>).
- attributes:
-define (attributes (Attributes), << ?uint32 (?lengthof (Attributes)), <<?attribute (Key, Value) || {Key, Value} <- Attributes>> >>).
- attribute:
-define (attribute (Key, Value), << ?uint32 (Key), ?binary_string (Value)>>).
- keys:
-define (keys (Keys), << ?uint32 (?lengthof (Keys)), <<?uint32 (Key) || Key <- Keys>> >>).
- filters:
-define (filters (Filters), << ?uint32 (?lengthof (Filters)), <<?filter (Key, MinimumValue, MaximumValue) || {Key, MinimumValue, MaximumValue} <- Filters>> >>).
- filter:
-define (filter (Key, MinimumValue, MaximumValue), << ?uint32 (Key), ?binary_string (MinimumValue), ?binary_string (MaximumValue)>>).
Generic messages, requests and replies
Summary
- each message is encoded as the size of the message, concatenated with its raw data;
- each operation request and reply is encoded as the a message where the raw data is a concatenation of the request / reply identifier and its raw data;
Definitions
- message:
-define (message (Data), << ?uint32 (?sizeof (Data)), ?binary (Data)>>).
- operation request:
-define (operation_request (RequestIdentifier, Data), ?message ( << ?uint32 (RequestIdentifier), ?binary (Data)>>)).
- operation reply:
-define (operation_reply (ReplyIdentifier, Data), ?message ( << ?uint32 (ReplyIdentifier), ?binary (Data)>>)).
- operation failed message:
-define (operation_failed_reply_identifier, 1). -define (operation_failed_reply (ReplyIdentifier, Message), ?message ( << ?uint32 (ReplyIdentifier), ?utf8_string (Message)>>)).
Store operation
Summary
- multiple records can be stored at the same time (thus the store operation could behave as a transaction);
- each record is composed of multiple attributes in the form of key-value pairs;
- each key is a number;
- each value in an arbitrary binary string;
- the outcome is a list of record identifiers;
Definitions
Identifiers
-define (store_request_identifier, 10). -define (store_succeeded_reply_identifier, 11).
Requests
- store request:
-define (store_request (Records), ?operation_request ( ?store_request_identifier, ?records (Records))).
Replies
- store succeeded reply:
-define (store_succeeded_reply (Identifiers), ?operation_reply ( ?store_succeeded_reply_identifier, ?identifiers (Identifiers))).
- store failed reply: see the generic operation failed reply;
Examples
- store request used to insert a power consumption record:
- the timestamp key is 1;
- the client key is 2;
- the sensor key 3;
- the consumption key is 4;
?store_request ( [ [ {1, ?uint32 (1231925013)}, % the number of seconds since the UNIX epoch {2, ?uint32 (102)}, % the client identifier for "clive" {3, ?uint32 (77)}, % the sensor identifier for "whasing machine" {4, ?uint32 (7)}], % the power consumption [ {1, ?uint32 (1231925013)}, {2, ?uint32 (102)}, {3, ?uint32 (78)}, % the sensor identifier for "light bulb" {4, ?uint32 (1)}]]).
- store succeeded response for the previous request:
?store_succeeded_response ( [1001, 1002, 1003]).
Select operation
Summary
Definitions
Identifiers
-define (select_request_identifier, 20). -define (select_succeeded_reply_identifier, 21).
Requests
- select request:
-define (select_request (Filters, Attributes), ?operation_request ( ?select_request_identifier, << ?filters (Filters), ?keys (Attributes)>>)).
Replies
- select succeeded reply:
-define (select_succeeded_reply (Records), ?operation_reply ( ?select_succeeded_reply_identifier, ?records (Records))).
- select failed reply: see the generic operation failed reply;