trilogy_w_prepared_statements 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +80 -0
  4. data/Rakefile +22 -0
  5. data/ext/trilogy-ruby/cast.c +277 -0
  6. data/ext/trilogy-ruby/cext.c +1048 -0
  7. data/ext/trilogy-ruby/extconf.rb +17 -0
  8. data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
  9. data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
  10. data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
  11. data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
  12. data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
  13. data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
  14. data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
  15. data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
  16. data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
  17. data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
  18. data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
  19. data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
  20. data/ext/trilogy-ruby/inc/trilogy.h +8 -0
  21. data/ext/trilogy-ruby/src/blocking.c +358 -0
  22. data/ext/trilogy-ruby/src/buffer.c +60 -0
  23. data/ext/trilogy-ruby/src/builder.c +236 -0
  24. data/ext/trilogy-ruby/src/charset.c +212 -0
  25. data/ext/trilogy-ruby/src/client.c +903 -0
  26. data/ext/trilogy-ruby/src/error.c +17 -0
  27. data/ext/trilogy-ruby/src/packet_parser.c +140 -0
  28. data/ext/trilogy-ruby/src/protocol.c +1175 -0
  29. data/ext/trilogy-ruby/src/reader.c +282 -0
  30. data/ext/trilogy-ruby/src/socket.c +623 -0
  31. data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
  32. data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
  33. data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
  34. data/lib/trilogy/version.rb +3 -0
  35. data/lib/trilogy.rb +61 -0
  36. data/trilogy.gemspec +27 -0
  37. metadata +107 -0
@@ -0,0 +1,760 @@
1
+ #ifndef TRILOGY_CLIENT_H
2
+ #define TRILOGY_CLIENT_H
3
+
4
+ #include <sys/socket.h>
5
+ #include <sys/types.h>
6
+ #include <unistd.h>
7
+
8
+ #include "trilogy/buffer.h"
9
+ #include "trilogy/packet_parser.h"
10
+ #include "trilogy/protocol.h"
11
+ #include "trilogy/socket.h"
12
+
13
+ /* Trilogy Non-blocking Client API
14
+ *
15
+ * This API is designed for allowing the caller to deal with I/O themselves.
16
+ * The API is split into `_send` and `_recv` calls. Allowing the caller to wait
17
+ * on writeability before calling a `_send` function, and waiting for
18
+ * readability before `_recv` calls. This can especially be useful for
19
+ * applications that live inside of managed runtime or event-loop.
20
+ *
21
+ * Some pseudo-code typical lifecycle of a connection might look something like
22
+ * this:
23
+ *
24
+ * trilogy_conn_t conn;
25
+ * trilogy_init(&conn);
26
+ *
27
+ * trilogy_connect_send(&conn, addrinfo);
28
+ *
29
+ * trilogy_handshake_t handshake;
30
+ * trilogy_connect_recv(&conn, &handshake);
31
+ *
32
+ * trilogy_auth_send(&conn, &handshake, "root", NULL, 0, 0);
33
+ * int rc = trilogy_auth_recv(&conn, &handshake);
34
+ * if (rc == TRILOGY_AUTH_SWITCH) {
35
+ * trilogy_auth_switch_send(&conn, &handshake);
36
+ * trilogy_auth_recv(&conn, &handshake);
37
+ * }
38
+ *
39
+ * At this point the connection is open, authenticated, and ready for commands.
40
+ * From here a caller can start issuing commands:
41
+ *
42
+ * char* db_name = "test";
43
+ * trilogy_change_db_send(&conn, db_name, strlen(db_name));
44
+ * trilogy_change_db_recv(&conn);
45
+ *
46
+ * Assuming the connection isn't in an error state, and all responses have been
47
+ * read off the network - it's ready for another command.
48
+ *
49
+ * Specific to the trilogy_query_send/trilogy_query_recv lifecycle - if
50
+ * TRILOGY_HAVE_RESULTS is returned from trilogy_query_recv, the caller *must* read
51
+ * all columns and rows from the server before the connection will be command-
52
+ * ready again. This is a requirement of a MySQL-compatible protocol.
53
+ *
54
+ * trilogy_close_send/trilogy_close_recv may be used to sent a quit command to the
55
+ * server. While this is considered best practice, simply calling trilogy_free
56
+ * to close the socket and free any internal buffers is enough to clean things
57
+ * up.
58
+ */
59
+
60
+ #define TRILOGY_DEFAULT_BUF_SIZE 32768
61
+
62
+ /* trilogy_column_t - The Trilogy client's column type.
63
+ */
64
+ typedef trilogy_column_packet_t trilogy_column_t;
65
+
66
+ /* trilogy_conn_t - The Trilogy client's instance type.
67
+ *
68
+ * This type is shared for the non-blocking and blocking versions of the API.
69
+ */
70
+ typedef struct {
71
+ uint64_t affected_rows;
72
+ uint64_t last_insert_id;
73
+ uint16_t warning_count;
74
+ char last_gtid[TRILOGY_MAX_LAST_GTID_LEN];
75
+ size_t last_gtid_len;
76
+
77
+ uint16_t error_code;
78
+ const char *error_message;
79
+ size_t error_message_len;
80
+
81
+ uint32_t capabilities;
82
+ uint16_t server_status;
83
+
84
+ trilogy_sock_t *socket;
85
+
86
+ // private:
87
+ uint8_t recv_buff[TRILOGY_DEFAULT_BUF_SIZE];
88
+ size_t recv_buff_pos;
89
+ size_t recv_buff_len;
90
+
91
+ trilogy_packet_parser_t packet_parser;
92
+ trilogy_buffer_t packet_buffer;
93
+ size_t packet_buffer_written;
94
+
95
+ uint64_t column_count;
96
+ bool started_reading_rows;
97
+ } trilogy_conn_t;
98
+
99
+ /* trilogy_init - Initialize a pre-allocated trilogy_conn_t pointer.
100
+ *
101
+ * conn - A pre-allocated trilogy_conn_t pointer.
102
+ *
103
+ * Return values:
104
+ * TRILOGY_OK - The trilogy_conn_t pointer was properly initialized
105
+ * TRILOGY_SYSERR - A system error occurred, check errno.
106
+ */
107
+ int trilogy_init(trilogy_conn_t *conn);
108
+
109
+ /* trilogy_flush_writes - Attempt to flush the internal packet buffer to the
110
+ * network. This must be used if a `_send` function returns TRILOGY_AGAIN, and
111
+ * should continue to be called until it returns a value other than
112
+ * TRILOGY_AGAIN.
113
+ *
114
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
115
+ * undefined.
116
+ *
117
+ * Return values:
118
+ * TRILOGY_OK - The entire packet buffer has been written to the network.
119
+ * TRILOGY_AGAIN - Only part of the packet buffer was written to the network or
120
+ * the socket wasn't ready for writing. The caller should wait
121
+ * for writabilty using `conn->sock`. Then call this function
122
+ * until it returns a different value.
123
+ * TRILOGY_SYSERR - A system error occurred, check errno.
124
+ */
125
+ int trilogy_flush_writes(trilogy_conn_t *conn);
126
+
127
+ /* trilogy_connect_send - Create a socket and attempt initial connection to the
128
+ * server.
129
+ *
130
+ * conn - A pre-initialized trilogy_conn_t pointer.
131
+ * addr - A pre-initialized trilogy_sockopt_t pointer with the connection
132
+ * parameters.
133
+ *
134
+ * Return values:
135
+ * TRILOGY_OK - The socket was created and the initial connection has been
136
+ * established.
137
+ * TRILOGY_SYSERR - A system error occurred, check errno.
138
+ */
139
+ int trilogy_connect_send(trilogy_conn_t *conn, const trilogy_sockopt_t *opts);
140
+
141
+ /* trilogy_connect_send_socket - Attempt initial connection to the server using an
142
+ * existing trilogy_sock_t. The socket must _not_ have been connected yet.
143
+ *
144
+ * sock - An instance of trilogy_sock_t
145
+ *
146
+ * Return values:
147
+ * TRILOGY_OK - The socket was created and the initial connection has been
148
+ * established.
149
+ * TRILOGY_SYSERR - A system error occurred, check errno.
150
+ */
151
+ int trilogy_connect_send_socket(trilogy_conn_t *conn, trilogy_sock_t *sock);
152
+
153
+ /* trilogy_connect_recv - Read the initial handshake from the server.
154
+ *
155
+ * This should be called after trilogy_connect_send returns TRILOGY_OK. Calling
156
+ * this at any other time during the connection lifecycle is undefined.
157
+ *
158
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
159
+ * trilogy_conn_t is undefined.
160
+ * handshake_out - A pre-allocated trilogy_handshake_t pointer. If TRILOGY_OK is
161
+ * returned, this struct will be filled out and ready to use.
162
+ *
163
+ * Return values:
164
+ * TRILOGY_OK - The initial handshake packet was read off the
165
+ * network.
166
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
167
+ * should wait for readability using `conn->sock`.
168
+ * Then call this function again.
169
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
170
+ * packet.
171
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
172
+ * TRILOGY_SYSERR - A system error occurred, check errno.
173
+ */
174
+ int trilogy_connect_recv(trilogy_conn_t *conn, trilogy_handshake_t *handshake_out);
175
+
176
+ /* trilogy_ssl_request_send - Send an SSL handshake request to the server.
177
+ *
178
+ * This should be called after a successful connection to the server. Calling
179
+ * this at any other time during the connection lifecycle is undefined. It is an
180
+ * error to call this function if TRILOGY_CAPABILITIES_SSL was not set by the
181
+ * server.
182
+ *
183
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
184
+ * trilogy_conn_t is undefined.
185
+ *
186
+ * Return values:
187
+ * TRILOGY_OK - Authorization info was successfully sent to the server.
188
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
189
+ * for writeability using `conn->sock`. Then call
190
+ * trilogy_flush_writes.
191
+ * TRILOGY_SYSERR - A system error occurred, check errno.
192
+ */
193
+ int trilogy_ssl_request_send(trilogy_conn_t *conn);
194
+
195
+ /* trilogy_auth_send - Send a authorization info to the server.
196
+ *
197
+ * This should be called after a successful connection to the server. Calling
198
+ * this at any other time during the connection lifecycle is undefined.
199
+ *
200
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
201
+ * trilogy_conn_t is undefined.
202
+ * handshake - A pre-initialized trilogy_handshake_t pointer.
203
+ *
204
+ * Return values:
205
+ * TRILOGY_OK - Authorization info was successfully sent to the server.
206
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
207
+ * for writeability using `conn->sock`. Then call
208
+ * trilogy_flush_writes.
209
+ * TRILOGY_SYSERR - A system error occurred, check errno.
210
+ */
211
+ int trilogy_auth_send(trilogy_conn_t *conn, const trilogy_handshake_t *handshake);
212
+
213
+ /* trilogy_auth_recv - Read the authorization response from the server.
214
+ *
215
+ * This should be called after all data written by trilogy_auth_send is flushed to
216
+ * the network. Calling this at any other time during the connection lifecycle
217
+ * is undefined.
218
+ *
219
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
220
+ * undefined.
221
+ *
222
+ * Return values:
223
+ * TRILOGY_OK - Authorization completed successfully. The
224
+ * connection is ready for commands.
225
+ * TRILOGY_AUTH_SWITCH - The server requested an auth switch. Use
226
+ * `trilogy_auth_switch_send` to reply with the
227
+ * confirmation of the switch.
228
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
229
+ * should wait for readability using `conn->sock`.
230
+ * Then call this function until it returns a
231
+ * different value.
232
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
233
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
234
+ * packet.
235
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
236
+ * TRILOGY_SYSERR - A system error occurred, check errno.
237
+ */
238
+ int trilogy_auth_recv(trilogy_conn_t *conn, trilogy_handshake_t *handshake);
239
+
240
+ /* trilogy_auth_switch_send - Send a reply after an authentication switch request.
241
+ *
242
+ * This should be called after the server requests and auth switch. Calling
243
+ * this at any other time during the connection lifecycle is undefined.
244
+ *
245
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is undefined.
246
+ * handshake - A pre-initialized trilogy_handshake_t pointer.
247
+ *
248
+ * Return values:
249
+ * TRILOGY_OK - Authorization info was successfully sent to the server.
250
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
251
+ * for writeability using `conn->sock`. Then call
252
+ * trilogy_flush_writes.
253
+ * TRILOGY_SYSERR - A system error occurred, check errno.
254
+ */
255
+ int trilogy_auth_switch_send(trilogy_conn_t *conn, const trilogy_handshake_t *handshake);
256
+
257
+ /* trilogy_change_db_send - Send a change database command to the server. This
258
+ * will change the default database for this connection.
259
+ *
260
+ * This should only be called while the connection is ready for commands.
261
+ *
262
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
263
+ * trilogy_conn_t is undefined.
264
+ * name - The name of the database.
265
+ * name_len - The length of the database name in bytes.
266
+ *
267
+ * Return values:
268
+ * TRILOGY_OK - The change database command was successfully sent to the
269
+ * server.
270
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
271
+ * for writeability using `conn->sock`. Then call
272
+ * trilogy_flush_writes.
273
+ * TRILOGY_SYSERR - A system error occurred, check errno.
274
+ */
275
+ int trilogy_change_db_send(trilogy_conn_t *conn, const char *name, size_t name_len);
276
+
277
+ /* trilogy_change_db_recv - Read the change database command response from the
278
+ * server.
279
+ *
280
+ * This should be called after all data written by trilogy_change_db_send is
281
+ * flushed to the network. Calling this at any other time during the connection
282
+ * lifecycle is undefined.
283
+ *
284
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
285
+ * undefined.
286
+ *
287
+ * Return values:
288
+ * TRILOGY_OK - The change database command was successfully
289
+ * sent to the server.
290
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The
291
+ * caller should wait for readability using
292
+ * `conn->sock`. Then call this function until
293
+ * it returns a different value.
294
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
295
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
296
+ * packet.
297
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
298
+ * TRILOGY_SYSERR - A system error occurred, check errno.
299
+ */
300
+ int trilogy_change_db_recv(trilogy_conn_t *conn);
301
+
302
+ /* trilogy_query_send - Send a query command to the server.
303
+ *
304
+ * This should only be called while the connection is ready for commands.
305
+ *
306
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
307
+ * trilogy_conn_t is undefined.
308
+ * query - The query string.
309
+ * query_len - The length of query string in bytes.
310
+ *
311
+ * Return values:
312
+ * TRILOGY_OK - The query command was successfully sent to the server.
313
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should
314
+ * wait for writeability using `conn->sock`. Then call
315
+ * trilogy_flush_writes.
316
+ * TRILOGY_SYSERR - A system error occurred, check errno.
317
+ */
318
+ int trilogy_query_send(trilogy_conn_t *conn, const char *query, size_t query_len);
319
+
320
+ /* trilogy_query_recv - Read the query command response from the server.
321
+ *
322
+ * This should be called after all data written by trilogy_query_send is flushed
323
+ * to the network. Calling this at any other time during the connection
324
+ * lifecycle is undefined.
325
+ *
326
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
327
+ * trilogy_conn_t is undefined.
328
+ * column_count_out - Out parameter; If TRILOGY_HAVE_RESULTS is returned, this
329
+ * will be set to the number of columns in the result set.
330
+ *
331
+ * Return values:
332
+ * TRILOGY_OK - The query response was received and fully read.
333
+ * TRILOGY_HAVE_RESULTS - The query response was received and there are
334
+ * results to be read.
335
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
336
+ * should wait for readability using `conn->sock`.
337
+ * Then call this function until it returns a
338
+ * different value.
339
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
340
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
341
+ * packet.
342
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
343
+ * TRILOGY_SYSERR - A system error occurred, check errno.
344
+ */
345
+ int trilogy_query_recv(trilogy_conn_t *conn, uint64_t *column_count_out);
346
+
347
+ /* trilogy_read_column - Read a column from the result set.
348
+ *
349
+ * This should be called as many times as there are columns in the result set.
350
+ * Calling this more times than that is undefined. This should also only be
351
+ * called after a query command has completed and returned TRILOGY_HAVE_RESULTS.
352
+ * Calling this at any other time during the connection lifecycle is undefined.
353
+ *
354
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
355
+ * trilogy_conn_t is undefined.
356
+ * column_out - Out parameter; A pointer to a pre-allocated trilogy_column_t. If
357
+ * TRILOGY_OK is returned this will be filled out. This value will be
358
+ * invalid after any other call to this API. The caller should make
359
+ * a copy if they want to keep the value around.
360
+ *
361
+ * Return values:
362
+ * TRILOGY_OK - The column was successfully read.
363
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
364
+ * should wait for readability using `conn->sock`.
365
+ * Then call this function until it returns a
366
+ * different value.
367
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
368
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
369
+ * packet.
370
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
371
+ * TRILOGY_SYSERR - A system error occurred, check errno.
372
+ */
373
+ int trilogy_read_column(trilogy_conn_t *conn, trilogy_column_t *column_out);
374
+
375
+ /* trilogy_read_row - Read a column from the result set.
376
+ *
377
+ * This should be called after reading all columns from the network. Calling
378
+ * this at any other time during the connection lifecycle is undefined.
379
+ *
380
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected
381
+ * trilogy_conn_t is undefined.
382
+ * values_out - Out parameter; A pre-allocated trilogy_value_t pointer, which will
383
+ * be filled out by this function. It should be allocated with
384
+ * enough space to hold a trilogy_value_t pointer for each column.
385
+ * Something like: `(sizeof(trilogy_value_t) * column_count)`. This
386
+ * pointer is invalid after any other call to this API. The caller
387
+ * should make a copy of the values inside if they want to keep
388
+ * them around.
389
+ *
390
+ * Return values:
391
+ * TRILOGY_OK - The query response was received and fully read.
392
+ * TRILOGY_EOF - There are no more rows to be read.
393
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
394
+ * should wait for readability using `conn->sock`.
395
+ * Then call this function until it returns a
396
+ * different value.
397
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
398
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
399
+ * packet.
400
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
401
+ * TRILOGY_SYSERR - A system error occurred, check errno.
402
+ */
403
+ int trilogy_read_row(trilogy_conn_t *conn, trilogy_value_t *values_out);
404
+
405
+ /* trilogy_drain_results - A convenience function to read and throw away the
406
+ * remaining rows from a result set. Any MySQL-compatible protocol requires that all
407
+ * responses from a command are read off the network before any other commands
408
+ * can be issued. A caller could otherwise do the same thing this function does
409
+ * by calling trilogy_read_row until it returns TRILOGY_EOF. But this call does that
410
+ * in a much more efficient manner by only reading packet frames then throwing
411
+ * them away, skipping the parsing of value information from inside each packet.
412
+ *
413
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
414
+ * undefined.
415
+ *
416
+ * Return values:
417
+ * TRILOGY_OK - The rest of the result was drained and the
418
+ * connection is ready for another command.
419
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
420
+ * should wait for readability using `conn->sock`.
421
+ * Then call this function until it returns a
422
+ * different value.
423
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
424
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
425
+ * packet.
426
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
427
+ * TRILOGY_SYSERR - A system error occurred, check errno.
428
+ */
429
+ int trilogy_drain_results(trilogy_conn_t *conn);
430
+
431
+ /* trilogy_ping_send - Send a ping command to the server.
432
+ *
433
+ * This should only be called while the connection is ready for commands.
434
+ *
435
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t
436
+ * is undefined.
437
+ *
438
+ * Return values:
439
+ * TRILOGY_OK - The ping command was successfully sent to the server.
440
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
441
+ * for writeability using `conn->sock`. Then call
442
+ * trilogy_flush_writes.
443
+ * TRILOGY_SYSERR - A system error occurred, check errno.
444
+ */
445
+ int trilogy_ping_send(trilogy_conn_t *conn);
446
+
447
+ /* trilogy_ping_recv - Read the ping command response from the server.
448
+ *
449
+ * This should be called after all data written by trilogy_ping_send is flushed to
450
+ * the network. Calling this at any other time during the connection lifecycle
451
+ * is undefined.
452
+ *
453
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
454
+ * undefined.
455
+ *
456
+ * Return values:
457
+ * TRILOGY_OK - The ping command was successfully sent to the
458
+ * server.
459
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
460
+ * should wait for readability using `conn->sock`.
461
+ * Then call this function until it returns a
462
+ * different value.
463
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
464
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
465
+ * packet.
466
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
467
+ * TRILOGY_SYSERR - A system error occurred, check errno.
468
+ */
469
+ int trilogy_ping_recv(trilogy_conn_t *conn);
470
+
471
+ /* trilogy_escape - Escape a string, making it safe to use in a query.
472
+ *
473
+ * This function assumes the input is in an ASCII-compatible encoding. Passing
474
+ * in a string in any other encoding is undefined and will likely corrupt the
475
+ * input. Potentially leaving the caller open to SQL-injection style attacks.
476
+ *
477
+ * If the TRILOGY_SERVER_STATUS_NO_BACKSLASH_ESCAPES flag is set, it will disable
478
+ * the use of the backslash character ("\") as an escape character. Making
479
+ * backslash an ordinary character like any other.
480
+ *
481
+ * That mode can be enabled at runtime by issuing setting the
482
+ * NO_BACKSLASH_ESCAPES sql mode. This can be done with a query like:
483
+ * "SET SQL_MODE=NO_BACKSLASH_ESCAPES"
484
+ *
485
+ * conn - A pre-initialized trilogy_conn_t pointer.
486
+ * str - The string to be escaped.
487
+ * len - The length of `str` in bytes.
488
+ * escaped_str_out - Out parameter; The dereferenced value of this pointer will
489
+ * point to the escaped version of `str` if TRILOGY_OK was
490
+ * returned.
491
+ * escaped_len_out - Out parameter; The length of the buffer `escaped_str_out`
492
+ * points to if TRILOGY_OK was returned.
493
+ *
494
+ * Return values:
495
+ * TRILOGY_OK - The input string has been processed.
496
+ * TRILOGY_SYSERR - A system error occurred, check errno.
497
+ */
498
+ int trilogy_escape(trilogy_conn_t *conn, const char *str, size_t len, const char **escaped_str_out,
499
+ size_t *escaped_len_out);
500
+
501
+ /* trilogy_close_send - Send a quit command to the server.
502
+ *
503
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
504
+ * undefined.
505
+ *
506
+ * Return values:
507
+ * TRILOGY_OK - The quit command was successfully sent to the server.
508
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
509
+ * for writeability using `conn->sock`. Then call
510
+ * trilogy_flush_writes.
511
+ * TRILOGY_SYSERR - A system error occurred, check errno.
512
+ */
513
+ int trilogy_close_send(trilogy_conn_t *conn);
514
+
515
+ /* trilogy_close_recv - Read the quit command response from the MySQL-compatible server.
516
+ *
517
+ * This should be called after all data written by trilogy_close_send is flushed
518
+ * to the network. Calling this at any other time during the connection
519
+ * lifecycle is undefined.
520
+ *
521
+ * conn - A pre-initialized trilogy_conn_t pointer. It can also be connected but
522
+ * a disconnected trilogy_conn_t will also return TRILOGY_OK.
523
+ *
524
+ * Return values:
525
+ * TRILOGY_OK - The quit command response successfully read from
526
+ * the server.
527
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
528
+ * should wait for readability using `conn->sock`.
529
+ * Then call this function until it returns a
530
+ * different value.
531
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
532
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
533
+ * packet.
534
+ * TRILOGY_SYSERR - A system error occurred, check errno.
535
+ */
536
+ int trilogy_close_recv(trilogy_conn_t *conn);
537
+
538
+ /* trilogy_free - Close the connection and free any internal buffers.
539
+ *
540
+ * conn - A pre-initialized trilogy_conn_t pointer.
541
+ *
542
+ * Returns nothing.
543
+ */
544
+ void trilogy_free(trilogy_conn_t *conn);
545
+
546
+ /* trilogy_stmt_prepare_send - Send a prepared statement prepare command to the server.
547
+ *
548
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
549
+ * undefined.
550
+ * stmt - A pointer to the buffer containing the statement to prepare.
551
+ * stmt_len - The length of the data buffer.
552
+ *
553
+ * Return values:
554
+ * TRILOGY_OK - The quit command was successfully sent to the server.
555
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
556
+ * for writeability using `conn->sock`. Then call
557
+ * trilogy_flush_writes.
558
+ * TRILOGY_SYSERR - A system error occurred, check errno.
559
+ */
560
+ int trilogy_stmt_prepare_send(trilogy_conn_t *conn, const char *stmt, size_t stmt_len);
561
+
562
+ /* trilogy_stmt_t - The trilogy client's prepared statement type.
563
+ */
564
+ typedef trilogy_stmt_ok_packet_t trilogy_stmt_t;
565
+
566
+ /* trilogy_stmt_prepare_recv - Read the prepared statement prepare command response
567
+ * from the MySQL-compatible server.
568
+ *
569
+ * This should be called after all data written by trilogy_stmt_prepare_send is flushed
570
+ * to the network. Calling this at any other time during the connection
571
+ * lifecycle is undefined.
572
+ *
573
+ * Following a successful call to this function, the caller will also need to read off
574
+ * `trilogy_stmt_t.column_count` parameters as column packets, then
575
+ * `trilogy_stmt_t.column_count` columns as column packets. This must be done before
576
+ * the socket will be command-ready again.
577
+ *
578
+ * conn - A pre-initialized trilogy_conn_t pointer. It can also be connected but
579
+ * a disconnected trilogy_conn_t will also return TRILOGY_OK.
580
+ * stmt_out - A pointer to a pre-allocated trilogy_stmt_t.
581
+ *
582
+ * Return values:
583
+ * TRILOGY_OK - The prepare command response successfully read from
584
+ * the server.
585
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
586
+ * should wait for readability using `conn->sock`.
587
+ * Then call this function until it returns a
588
+ * different value.
589
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
590
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
591
+ * packet.
592
+ * TRILOGY_SYSERR - A system error occurred, check errno.
593
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
594
+ */
595
+ int trilogy_stmt_prepare_recv(trilogy_conn_t *conn, trilogy_stmt_t *stmt_out);
596
+
597
+ /* trilogy_stmt_bind_data_send - Send a prepared statement bind long data command to the server.
598
+ *
599
+ * There is no pairing `trilogy_stmt_bind_data_recv` fucntion to this one because the server
600
+ * doesn't send a response to this command.
601
+ *
602
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
603
+ * undefined.
604
+ * stmt - Pointer to a valid trilogy_stmt_t, representing the prepared statement for which
605
+ * to bind the supplied parameter data to.
606
+ * param_num - The parameter index for which the supplied data should be bound to.
607
+ * data - A pointer to the buffer containing the data to be bound.
608
+ * data_len - The length of the data buffer.
609
+ *
610
+ * Return values:
611
+ * TRILOGY_OK - The bind data command was successfully sent to the server.
612
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
613
+ * for writeability using `conn->sock`. Then call
614
+ * trilogy_flush_writes.
615
+ * TRILOGY_SYSERR - A system error occurred, check errno.
616
+ */
617
+ int trilogy_stmt_bind_data_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint16_t param_num, uint8_t *data,
618
+ size_t data_len);
619
+
620
+ /* trilogy_stmt_execute_send - Send a prepared statement execute command to the server.
621
+ *
622
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
623
+ * undefined.
624
+ * stmt - Pointer to a valid trilogy_stmt_t, representing the prepared statement you're
625
+ * requesting to execute.
626
+ * flags - The flags (TRILOGY_STMT_FLAGS_t) to be used with this execute command packet.
627
+ * binds - Pointer to an array of trilogy_binary_value_t's. The array size should match that
628
+ * of `trilogy_stmt_t.column_count`.
629
+ *
630
+ * Return values:
631
+ * TRILOGY_OK - The execute command was successfully sent to the server.
632
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
633
+ * for writeability using `conn->sock`. Then call
634
+ * trilogy_flush_writes.
635
+ * TRILOGY_SYSERR - A system error occurred, check errno.
636
+ */
637
+ int trilogy_stmt_execute_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint8_t flags, trilogy_binary_value_t *binds);
638
+
639
+ /* trilogy_stmt_execute_recv - Read the prepared statement execute command response
640
+ * from the MySQL-compatible server.
641
+ *
642
+ * This should be called after all data written by trilogy_stmt_execute_send is flushed
643
+ * to the network. Calling this at any other time during the connection
644
+ * lifecycle is undefined.
645
+ *
646
+ * conn - A pre-initialized trilogy_conn_t pointer. It can also be connected but
647
+ * a disconnected trilogy_conn_t will also return TRILOGY_OK.
648
+ * column_count_out - Out parameter; A pointer to a pre-allocated uint64_t. Represents the
649
+ * number of columns in the response.
650
+ *
651
+ * Return values:
652
+ * TRILOGY_OK - The prepare command response successfully read from
653
+ * the server.
654
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
655
+ * should wait for readability using `conn->sock`.
656
+ * Then call this function until it returns a
657
+ * different value.
658
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
659
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
660
+ * packet.
661
+ * TRILOGY_SYSERR - A system error occurred, check errno.
662
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
663
+ */
664
+ int trilogy_stmt_execute_recv(trilogy_conn_t *conn, uint64_t *column_count_out);
665
+
666
+ /* trilogy_stmt_read_row - Read a row from the prepared statement execute response.
667
+ *
668
+ * This should only be called after a sucessful call to trilogy_stmt_execute_recv.
669
+ * You should continue calling this until TRILOGY_EOF is returned. Denoting the end
670
+ * of the result set.
671
+ *
672
+ * conn - A pre-initialized trilogy_conn_t pointer. It can also be connected but
673
+ * a disconnected trilogy_conn_t will also return TRILOGY_OK.
674
+ * stmt - Pointer to a valid trilogy_stmt_t, representing the prepared statement you're
675
+ * requesting to execute.
676
+ * columns - The list of columns from the prepared statement.
677
+ * column_count - The number of columns in prepared statement.
678
+ * values_out - Out parameter; A pointer to a pre-allocated array of
679
+ * trilogy_binary_value_t's. There must be enough space to fit all of the
680
+ * values. This can be computed with:
681
+ * `(sizeof(trilogy_binary_value_t) * column_count)`.
682
+ *
683
+ * Return values:
684
+ * TRILOGY_OK - The prepare command response successfully read from
685
+ * the server.
686
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
687
+ * should wait for readability using `conn->sock`.
688
+ * Then call this function until it returns a
689
+ * different value.
690
+ * TRILOGY_EOF - There are no more rows to read from the result set.
691
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
692
+ * TRILOGY_PROTOCOL_VIOLATION - Invalid length parsed for a TIME/DATETIME/TIMESTAMP value.
693
+ * TRILOGY_UNKNOWN_TYPE - An unsupported or unknown MySQL type was seen.
694
+ * TRILOGY_SYSERR - A system error occurred, check errno.
695
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
696
+ */
697
+ int trilogy_stmt_read_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_column_packet_t *columns,
698
+ trilogy_binary_value_t *values_out);
699
+
700
+ /* trilogy_stmt_reset_send - Send a prepared statement reset command to the server.
701
+ *
702
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
703
+ * undefined.
704
+ * stmt - Pointer to a valid trilogy_stmt_t, representing the prepared statement you're
705
+ * requesting to reset.
706
+ *
707
+ * Return values:
708
+ * TRILOGY_OK - The reset command was successfully sent to the server.
709
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
710
+ * for writeability using `conn->sock`. Then call
711
+ * trilogy_flush_writes.
712
+ * TRILOGY_SYSERR - A system error occurred, check errno.
713
+ */
714
+ int trilogy_stmt_reset_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt);
715
+
716
+ /* trilogy_stmt_reset_recv - Read the prepared statement reset command response
717
+ * from the MySQL-compatible server.
718
+ *
719
+ * This should be called after all data written by trilogy_stmt_reset_send is flushed
720
+ * to the network. Calling this at any other time during the connection
721
+ * lifecycle is undefined.
722
+ *
723
+ * conn - A pre-initialized trilogy_conn_t pointer. It can also be connected but
724
+ * a disconnected trilogy_conn_t will also return TRILOGY_OK.
725
+ *
726
+ * Return values:
727
+ * TRILOGY_OK - The reset command response successfully read from
728
+ * the server.
729
+ * TRILOGY_AGAIN - The socket wasn't ready for reading. The caller
730
+ * should wait for readability using `conn->sock`.
731
+ * Then call this function until it returns a
732
+ * different value.
733
+ * TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
734
+ * TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
735
+ * packet.
736
+ * TRILOGY_SYSERR - A system error occurred, check errno.
737
+ * TRILOGY_CLOSED_CONNECTION - The connection is closed.
738
+ */
739
+ int trilogy_stmt_reset_recv(trilogy_conn_t *conn);
740
+
741
+ /* trilogy_stmt_close_send - Send a prepared statement close command to the server.
742
+ *
743
+ * There is no pairing `trilogy_stmt_close_recv` fucntion to this one because the server
744
+ * doesn't send a response to this command.
745
+ *
746
+ * conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
747
+ * undefined.
748
+ * stmt - Pointer to a valid trilogy_stmt_t, representing the prepared statement you're
749
+ * requesting to close.
750
+ *
751
+ * Return values:
752
+ * TRILOGY_OK - The close command was successfully sent to the server.
753
+ * TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
754
+ * for writeability using `conn->sock`. Then call
755
+ * trilogy_flush_writes.
756
+ * TRILOGY_SYSERR - A system error occurred, check errno.
757
+ */
758
+ int trilogy_stmt_close_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt);
759
+
760
+ #endif