1 module mars.msg;
2 
3 enum RequestState 
4 {
5     executed,
6 
7     // ... client side bugs or tampering of the request
8     rejectedAsDecodingFailed, /// the deconding of the data is failed
9     rejectedAsWrongParameter, /// the value of one of the request parameters is wrong.
10 
11     rejectedAsNotAuthorised,  /// the client is not authorised for the request (ex, subscription before of authentication)
12     rejectedAsForeignKeyViolation, /// update or delete on table violates foreign key constraint on another table (ERR 23503)
13 
14     rejectedAsPGSqlError,     /// PostgreSQL unhandled error
15     internalServerError,
16 }
17 enum MsgTypeStoC {
18     autologinReq     = 60, autologinRep,
19     syncOperationReq = 62, syncOperationRep,
20     importRecordsReq = 64, importRecordsRep,
21     deleteRecordsReq = 66, deleteRecordsRep,
22     insertRecordsReq = 68, insertRecordsRep,
23     updateRecordsReq = 70, updateRecordsRep,
24     pingReq          = 72, pingRep,
25     
26     aborting = 201
27 }
28 
29 
30 
31 struct AutologinReq
32 {
33     static immutable type = MsgTypeStoC.autologinReq;
34     string username;                   /// the username that has performed the autologin.
35     string sqlCreateDatabase;          /// sql statements to execute for the creation of client side tables
36     immutable(string)[] sqlStatements; /// sql statements to prepare, for further operations on the tables
37     immutable(string)[] jsStatements;  /// javascript statements to eval, like constraints, key extraction, etc.
38 }
39 
40 struct DeleteRecordsReq 
41 {
42     static immutable type = MsgTypeStoC.deleteRecordsReq;
43     ulong tableIndex;
44     ulong statementIndex;
45     immutable(ubyte)[] encodedRecords = []; 
46 }
47 
48 struct DeleteRecordsRep
49 {
50     static immutable type =  MsgTypeStoC.deleteRecordsRep;
51 }
52 
53 struct InsertRecordsReq
54 {
55     static immutable type = MsgTypeStoC.insertRecordsReq;
56     ulong tableIndex;
57     ulong statementIndex;
58     immutable(ubyte)[] encodedRecords;
59 }
60 
61 struct InsertRecordsRep
62 {
63     static immutable type = MsgTypeStoC.insertRecordsRep;
64 }
65 
66 struct ImportRecordsReq {
67     static immutable type = MsgTypeStoC.importRecordsReq;
68     ulong tableIndex;
69     ulong statementIndex;
70     immutable(ubyte)[] encodedRecords;
71 }
72 
73 struct PingReq {
74     static immutable type = MsgTypeStoC.pingReq;
75 }
76 
77 struct PingRep {
78     static immutable type = MsgTypeStoC.pingRep;
79 }
80 
81 struct UpdateRecordsReq {
82     static immutable type = MsgTypeStoC.updateRecordsReq;
83     ulong tableIndex;
84     immutable(ubyte)[] encodedRecords;
85 }
86 
87 struct ImportRecordsRep {
88     static immutable type = MsgTypeStoC.importRecordsRep;
89 }
90 
91 struct SyncOperationReq
92 {
93     enum SyncOperation { starting, completed }
94 
95     static immutable type = MsgTypeStoC.syncOperationReq;
96     SyncOperation operation; 
97 }
98 
99 struct SyncOperationReply
100 {
101     static immutable type = MsgTypeStoC.syncOperationRep;
102 }
103 
104 // ----
105 
106 enum MsgType {
107     authenticationRequest, authenticationReply,
108     authenticateRequest, authenticateReply,
109     discardAuthenticationRequest, discardAuthenticationReply,
110 
111     importValuesRequest  = 22, importValuesReply,
112     insertValuesRequest  = 24, insertValuesReply,
113     updateValuesRequest  = 26, updateValuesReply,
114     deleteRecordRequest  = 28, deleteRecordReply,
115 
116     optUpdateReq = 50, optUpdateRep = 51, // request the server to perform an update and confirm an optimistic one
117     subscribeReq = 52, subscribeRep = 52, // request to subscribe to a query
118     pingReq      = 54,                    // request to keep alive the connection
119     pesUpdateReq = 56, pesUpdateRep = 57, // request the server to perform an update pessimistically
120 
121 
122     welcomeBroadcast = 100, goodbyBroadcast,
123 
124 
125     callServerMethodRequest = 150, callServerMethodReply,
126 
127     disconnectRequest = 200,
128     aborting
129 }
130 
131 
132 
133 struct AuthenticationRequest {
134     static immutable type = MsgType.authenticationRequest;
135     string username;
136 }
137 
138 struct AuthenticationReply {
139     enum { seedProvided, 
140         invalidUsername, 
141         alreadyAuthorised, /// one user is already logged in, and authorised.
142     }
143     static immutable type = MsgType.authenticationReply;
144     int status;
145     string seed;
146 }
147 
148 struct AuthenticateRequest {
149     static immutable type = MsgType.authenticateRequest;
150     string hash;
151 }
152 
153 /// Warning, this enum is checked in the client also!
154 enum AuthoriseError {
155     assertCheck,
156 
157     authorised,              
158     databaseOffline,         /// the database is offline, so can't autorise
159     wrongUsernameOrPassword, /// password authentication failed for user "user"
160     unknownError,            /// unknown or not handled error code.
161 }
162 struct AuthenticateReply {
163     static immutable type = MsgType.authenticateReply;
164     int status;
165     string sqlCreateDatabase;
166     immutable(string)[] sqlStatements;
167     immutable(string)[] jsStatements;  /// javascript statements to eval, like constraints, key extraction, etc.
168 }
169 
170 struct DiscardAuthenticationRequest {
171     static immutable type = MsgType.discardAuthenticationRequest;
172 }
173 
174 struct DiscardAuthenticationReply {
175     static immutable type = MsgType.discardAuthenticationReply;
176 }
177 
178 // 
179 struct SubscribeReq 
180 {
181     static immutable type = MsgType.subscribeReq;
182     string select;
183     string parameters;
184 }
185 
186 struct SubscribeRep 
187 {
188     static immutable type = MsgType.subscribeRep;
189     RequestState state;
190     string json;
191 }
192 
193 struct ImportValuesRequest {
194     static immutable type = MsgType.importValuesRequest;
195     int statementIndex;
196     immutable(ubyte)[] bytes;
197 }
198 
199 struct ImportValuesReply {
200     static immutable type = MsgType.importValuesReply;
201     int donno;
202 }
203 
204 
205 
206 // S --> C in the op
207 struct InsertValuesRequest {
208     static immutable type = MsgType.insertValuesRequest;
209     int statementIndex;
210     immutable(ubyte)[] bytes;
211 }
212 
213 enum InsertError {
214     assertCheck,
215     inserted,
216     duplicateKeyViolations,
217     unknownError,
218 }
219 // sent from server to client validating or rejecting the optimistic update
220 struct InsertValuesReply {
221     static immutable type = MsgType.insertValuesReply;
222     int insertStatus; // the insert error
223     immutable(ubyte)[] bytes = []; // the server inserted record
224     immutable(ubyte)[] clientKeys = [];
225     int tableIndex = -1;
226     int statementIndex = -1; // the sql statement to use for emending the client with the server data
227     int statementIndex2 = -1; // idem. For example, on errors, the first one is used to update the deco, then delete
228 }
229 
230 struct DeleteRecordRequest {
231     static immutable type = MsgType.deleteRecordRequest;
232     int statementIndex;
233     immutable(ubyte)[] bytes = []; 
234 }
235 
236 enum DeleteError {
237     assertCheck,
238     deleted,
239     unknownError,
240     rejectedAsForeignKeyViolation,
241 }
242 
243 // the reply is flowing from server to client
244 struct DeleteRecordReply {
245     static immutable type =  MsgType.deleteRecordReply;
246     int deleteStatus;
247     immutable(ubyte)[] serverRecord = []; // if we can't delete the record, we must re-insert it into the client
248     int tableIndex;
249     int statementIndex;
250 }
251 
252 // request an update of a record to the server, that the client has optimistically updated
253 struct OptUpdateReq 
254 {
255     static immutable type = MsgType.optUpdateReq;
256     ulong tableIndex;           /// the index identifier of the updated table.
257     immutable(ubyte)[] keys;    /// the primary keys of the record to update
258     immutable(ubyte)[] record;  /// the new values for that record
259 }
260 
261 struct OptUpdateRep 
262 {
263     static immutable type = MsgType.optUpdateRep;
264     RequestState state;
265 }
266 
267 // request an update of a record to the server, that the client has optimistically updated
268 struct PesUpdateReq 
269 {
270     static immutable type = MsgType.pesUpdateReq;
271     ulong tableIndex;           /// the index identifier of the updated table.
272     immutable(ubyte)[] keys;    /// the primary keys of the record to update
273     immutable(ubyte)[] record;  /// the new values for that record
274 }
275 
276 struct PesUpdateRep 
277 {
278     static immutable type = MsgType.pesUpdateRep;
279     RequestState state;
280 }
281 
282 struct UpdateValuesRequest {
283     static immutable type = MsgType.updateValuesRequest;
284     int statementIndex;
285     immutable(ubyte)[] bytes;
286 }
287 
288 struct UpdateValuesReply {
289     static immutable type = MsgType.updateValuesReply;
290     int donno;
291 }
292 
293 struct CallServerMethodRequest {
294     static immutable type = MsgType.callServerMethodRequest;
295     string method; immutable(ubyte)[] parameters;
296 }
297 
298 struct CallServerMethodReply {
299     static immutable type = MsgType.callServerMethodReply;
300     string returns;
301 }