trilogy_w_prepared_statements 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,1014 @@
1
+ #ifndef TRILOGY_PROTOCOL_H
2
+ #define TRILOGY_PROTOCOL_H
3
+
4
+ #include "trilogy/builder.h"
5
+ #include "trilogy/charset.h"
6
+
7
+ #include <stdbool.h>
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ #define TRILOGY_CAPABILITIES(XX) \
13
+ XX(TRILOGY_CAPABILITIES_NONE, 0) \
14
+ /* Not used. This flag is assumed by current servers. \
15
+ * \
16
+ * From client: tells the server the client intends to use the newer \
17
+ * password hashing algorithm. \
18
+ */ \
19
+ XX(TRILOGY_CAPABILITIES_LONG_PASSWORD, 0x00000001) \
20
+ /* From client: tells the server to set the affected_rows field to the \
21
+ * number of rows found by the query instead of the actual number of rows \
22
+ * updated. \
23
+ * \
24
+ * For example, the following update statement would set affected_rows to \
25
+ * 1: `UPDATE users SET login = "brianmario1" WHERE login = "brianmario";` \
26
+ * \
27
+ * But an update statement which didn't actually perform any updates like: \
28
+ * `UPDATE users SET login = "brianmario" WHERE login = "brianmario";` \
29
+ * would have normally set affected_rows to 0. That's where this flag \
30
+ * comes in to play. By setting this flag during the authentication phase \
31
+ * of a connection - the above query will set affected_rows to 1. \
32
+ */ \
33
+ XX(TRILOGY_CAPABILITIES_FOUND_ROWS, 0x00000002) \
34
+ /* Not used. This flag was only used by the older (pre-4.1) protocol. \
35
+ * \
36
+ * From server: the server supports a longer flags field in column \
37
+ * definition packets. \
38
+ * \
39
+ * From client: the client supports longer flags field in column \
40
+ * definition packets. \
41
+ */ \
42
+ XX(TRILOGY_CAPABILITIES_LONG_FLAG, 0x00000004) \
43
+ /* From server: the server supports a database name being passed in the \
44
+ * handshake response packet. \
45
+ * \
46
+ * From client: tells the server there is a database name in the handshake \
47
+ * response packet. \
48
+ */ \
49
+ XX(TRILOGY_CAPABILITIES_CONNECT_WITH_DB, 0x00000008) \
50
+ /* From client: tells the server to not allow `database.table.column` \
51
+ * notation in query syntax. \
52
+ */ \
53
+ XX(TRILOGY_CAPABILITIES_NO_SCHEMA, 0x00000010) \
54
+ /* Not implemented. \
55
+ * \
56
+ * From server: the server supports compression. \
57
+ * \
58
+ * From client: tells the server to enable the compression protocol. \
59
+ */ \
60
+ XX(TRILOGY_CAPABILITIES_COMPRESS, 0x00000020) \
61
+ /* Not used since 3.22. \
62
+ */ \
63
+ XX(TRILOGY_CAPABILITIES_ODBC, 0x00000040) \
64
+ /* Not implemented. \
65
+ * \
66
+ * From server: server support `LOAD DATA INFILE` and `LOAD XML`. \
67
+ * \
68
+ * From client: tells the server that the client supports `LOAD DATA LOCAL \
69
+ * INFILE`. \
70
+ */ \
71
+ XX(TRILOGY_CAPABILITIES_LOCAL_FILES, 0x00000080) \
72
+ /* From server: the query parser can ignore spaces before the '(' \
73
+ * character. \
74
+ * \
75
+ * From client: tells the server to ignore spaces before the '(' \
76
+ * character. \
77
+ */ \
78
+ XX(TRILOGY_CAPABILITIES_IGNORE_SPACE, 0x00000100) \
79
+ /* From server: the server supports the 4.1+ protocol. \
80
+ * \
81
+ * From client: the client is using the 4.1+ protocol. This will always be \
82
+ * set, as trilogy only supports the 4.1+ protocol. \
83
+ */ \
84
+ XX(TRILOGY_CAPABILITIES_PROTOCOL_41, 0x00000200) \
85
+ /* Not used. \
86
+ * \
87
+ * From server: the server supports interactive and non-interactive \
88
+ * clients. \
89
+ * \
90
+ * From client: the client is interactive. \
91
+ */ \
92
+ XX(TRILOGY_CAPABILITIES_INTERACTIVE, 0x00000400) \
93
+ /* Not implemented. \
94
+ * \
95
+ * From server: the server supports ssl. \
96
+ * \
97
+ * From client: tells the server it should switch to an ssl connection. \
98
+ */ \
99
+ XX(TRILOGY_CAPABILITIES_SSL, 0x00000800) \
100
+ /* Not used. \
101
+ * \
102
+ * This is assumed for the 4.1+ protocol. \
103
+ */ \
104
+ XX(TRILOGY_CAPABILITIES_TRANSACTIONS, 0x00002000) \
105
+ /* Not used. \
106
+ */ \
107
+ XX(TRILOGY_CAPABILITIES_RESERVED, 0x00004000) \
108
+ /* From server: server supports the 4.1+ protocol's native authentication \
109
+ * scheme. \
110
+ * \
111
+ * From client: client supports the 4.1+ protocol's native authentication \
112
+ * scheme. This will always be set. \
113
+ */ \
114
+ XX(TRILOGY_CAPABILITIES_SECURE_CONNECTION, 0x00008000) \
115
+ /* Not implemented. \
116
+ * \
117
+ * From server: the server can handle multiple statements per \
118
+ * query/prepared statement. \
119
+ * \
120
+ * From client: tells the server it may send multiple statements per \
121
+ * query/ prepared statement. \
122
+ */ \
123
+ XX(TRILOGY_CAPABILITIES_MULTI_STATEMENTS, 0x00010000) \
124
+ /* From server: the server is capable of sending multiple result sets from \
125
+ * a query. \
126
+ * \
127
+ * From client: tells the server it's capable of handling multiple result \
128
+ * sets from a query. \
129
+ */ \
130
+ XX(TRILOGY_CAPABILITIES_MULTI_RESULTS, 0x00020000) \
131
+ /* Not implemented. \
132
+ * \
133
+ * From server: the server is capable of sending multiple result sets from \
134
+ * a prepared statement. \
135
+ * \
136
+ * From client: tells the server it's capable of handling multiple result \
137
+ * sets from a prepared statement. \
138
+ */ \
139
+ XX(TRILOGY_CAPABILITIES_PS_MULTI_RESULTS, 0x00040000) \
140
+ /* Not implemented. \
141
+ * \
142
+ * From server: the server supports the pluggable authentication protocol. \
143
+ * \
144
+ * From client: tells the server that the client supports the pluggable \
145
+ * authentication protocol. \
146
+ */ \
147
+ XX(TRILOGY_CAPABILITIES_PLUGIN_AUTH, 0x00080000) \
148
+ /* Not implemented. \
149
+ * \
150
+ * From server: the server allows connection attributes to be set in the \
151
+ * handshake response packet during authentication. \
152
+ * \
153
+ * From client: tells the server that there are connection attributes in \
154
+ * the handshake response. \
155
+ */ \
156
+ XX(TRILOGY_CAPABILITIES_CONNECT_ATTRS, 0x00100000) \
157
+ /* Not implemented. \
158
+ * \
159
+ * From server: the server is capable of parsing length-encoded data in \
160
+ * the handshake response during authentication. \
161
+ * \
162
+ * From client: tells the server that the authentication data in the \
163
+ * handshake response is length-encoded. \
164
+ */ \
165
+ XX(TRILOGY_CAPABILITIES_PLUGIN_AUTH_LENENC_CLIENT_DATA, 0x00200000) \
166
+ /* From server: the server supports the expired password extension. \
167
+ * \
168
+ * From client: the client supports expired passwords. \
169
+ */ \
170
+ XX(TRILOGY_CAPABILITIES_CAN_HANDLE_EXPIRED_PASSWORDS, 0x00400000) \
171
+ /* From server: the server may set the \
172
+ * TRILOGY_SERVER_STATUS_SESSION_STATE_CHANGED flag in OK packets. Which \
173
+ * will also mean the OK packet includes session-state change data. \
174
+ * \
175
+ * From client: tells the server that the client expects the server to \
176
+ * send session-state change data in OK packets. \
177
+ */ \
178
+ XX(TRILOGY_CAPABILITIES_SESSION_TRACK, 0x00800000) \
179
+ /* From server: the server will send OK packets in place of EOF packets. \
180
+ * \
181
+ * From client: tells the server that it expects to be sent OK packets in \
182
+ * place of EOF packets. \
183
+ */ \
184
+ XX(TRILOGY_CAPABILITIES_DEPRECATE_EOF, 0x01000000)
185
+
186
+ typedef enum {
187
+ #define XX(name, code) name = code,
188
+ TRILOGY_CAPABILITIES(XX)
189
+ #undef XX
190
+
191
+ /* A convenience bitmask with common client capabilities set. */
192
+ TRILOGY_CAPABILITIES_CLIENT = (TRILOGY_CAPABILITIES_PROTOCOL_41 | TRILOGY_CAPABILITIES_SECURE_CONNECTION |
193
+ TRILOGY_CAPABILITIES_DEPRECATE_EOF | TRILOGY_CAPABILITIES_SESSION_TRACK |
194
+ TRILOGY_CAPABILITIES_PLUGIN_AUTH | TRILOGY_CAPABILITIES_TRANSACTIONS)
195
+ } TRILOGY_CAPABILITIES_t;
196
+
197
+ #define TRILOGY_SERVER_STATUS(XX) \
198
+ /* The connection session is in a transaction. \
199
+ */ \
200
+ XX(TRILOGY_SERVER_STATUS_IN_TRANS, 0x0001) \
201
+ /* The connection session has `autocommit` enabled. `autocommit` mode \
202
+ * makes the database write any updates to tables immediately. This mode is \
203
+ * enabled by default in. This mode is implicitly disabled for all \
204
+ * statements between a `START TRANSACTION` and corresponding `COMMIT`. It \
205
+ * can be disabled with the statement: `SET autocommit=0`. \
206
+ */ \
207
+ XX(TRILOGY_SERVER_STATUS_AUTOCOMMIT, 0x0002) \
208
+ \
209
+ /* This flag means there are more results available to be read from the \
210
+ * result set. It will be set on the last (EOF/OK) packet from a result \
211
+ * set. \
212
+ */ \
213
+ XX(TRILOGY_SERVER_STATUS_MORE_RESULTS_EXISTS, 0x0008) \
214
+ \
215
+ /* No good index was used to perform the query. \
216
+ */ \
217
+ XX(TRILOGY_SERVER_STATUS_NO_GOOD_INDEX_USED, 0x0010) \
218
+ \
219
+ /* No index was used to perform the query. \
220
+ */ \
221
+ XX(TRILOGY_SERVER_STATUS_NO_INDEX_USED, 0x0020) \
222
+ \
223
+ /* When using the prepared statement protocol, this will be set when a \
224
+ * read- only, non-scrollable cursor was opened from an `execute` command. \
225
+ * It will also be set for replies to `fetch` commands. \
226
+ */ \
227
+ XX(TRILOGY_SERVER_STATUS_CURSOR_EXISTS, 0x0040) \
228
+ \
229
+ /* When using the prepared statement protocol, this will be set when a \
230
+ * read- only cursor has been exhausted. This will be set for replies to \
231
+ * `fetch` commands. \
232
+ */ \
233
+ XX(TRILOGY_SERVER_STATUS_LAST_ROW_SENT, 0x0080) \
234
+ \
235
+ /* This will be set if a database was dropped. \
236
+ */ \
237
+ XX(TRILOGY_SERVER_STATUS_DB_DROPPED, 0x0100) \
238
+ \
239
+ /* This will be set if the `NO_BACKSLASH_ESCAPES` sql mode is enabled. The \
240
+ * caller can enable this mode by using the statement: \
241
+ * `SET SQL_MODE=NO_BACKSLASH_ESCAPES`. \
242
+ * \
243
+ * The `NO_BACKSLASH_ESCAPES` sql mode disables the use of the backslash \
244
+ * ('\') character as an escape character. \
245
+ */ \
246
+ XX(TRILOGY_SERVER_STATUS_NO_BACKSLASH_ESCAPES, 0x0200) \
247
+ \
248
+ /* This will be set if a re-prepare of a prepared statement meant that a \
249
+ * different number of columns would be returned as part of the result \
250
+ * set. \
251
+ */ \
252
+ XX(TRILOGY_SERVER_STATUS_METADATA_CHANGED, 0x0400) \
253
+ \
254
+ /* This will be set if the last query that was executed took longer than \
255
+ * the `long_query_time` system variable. \
256
+ */ \
257
+ XX(TRILOGY_SERVER_STATUS_QUERY_WAS_SLOW, 0x0800) \
258
+ \
259
+ /* The prepared statement result set contains out parameters. \
260
+ */ \
261
+ XX(TRILOGY_SERVER_STATUS_PS_OUT_PARAMS, 0x1000) \
262
+ \
263
+ /* Set if the current multi-statement transaction is a read-only \
264
+ * transaction. If this is set, `TRILOGY_SERVER_STATUS_IN_TRANS` will be set \
265
+ * as well. \
266
+ */ \
267
+ XX(TRILOGY_SERVER_STATUS_STATUS_IN_TRANS_READONLY, 0x2000) \
268
+ \
269
+ /* If set, the OK packet contains includes session-state change data. \
270
+ */ \
271
+ XX(TRILOGY_SERVER_STATUS_SESSION_STATE_CHANGED, 0x4000)
272
+
273
+ typedef enum {
274
+ #define XX(name, code) name = code,
275
+ TRILOGY_SERVER_STATUS(XX)
276
+ #undef XX
277
+ } TRILOGY_SERVER_STATUS_t;
278
+
279
+ #define TRILOGY_TYPES(XX) \
280
+ XX(TRILOGY_TYPE_DECIMAL, 0x00) \
281
+ XX(TRILOGY_TYPE_TINY, 0x01) \
282
+ XX(TRILOGY_TYPE_SHORT, 0x02) \
283
+ XX(TRILOGY_TYPE_LONG, 0x03) \
284
+ XX(TRILOGY_TYPE_FLOAT, 0x04) \
285
+ XX(TRILOGY_TYPE_DOUBLE, 0x05) \
286
+ XX(TRILOGY_TYPE_NULL, 0x06) \
287
+ XX(TRILOGY_TYPE_TIMESTAMP, 0x07) \
288
+ XX(TRILOGY_TYPE_LONGLONG, 0x08) \
289
+ XX(TRILOGY_TYPE_INT24, 0x09) \
290
+ XX(TRILOGY_TYPE_DATE, 0x0a) \
291
+ XX(TRILOGY_TYPE_TIME, 0x0b) \
292
+ XX(TRILOGY_TYPE_DATETIME, 0x0c) \
293
+ XX(TRILOGY_TYPE_YEAR, 0x0d) \
294
+ XX(TRILOGY_TYPE_VARCHAR, 0x0f) \
295
+ XX(TRILOGY_TYPE_BIT, 0x10) \
296
+ XX(TRILOGY_TYPE_JSON, 0xf5) \
297
+ XX(TRILOGY_TYPE_NEWDECIMAL, 0xf6) \
298
+ XX(TRILOGY_TYPE_ENUM, 0xf7) \
299
+ XX(TRILOGY_TYPE_SET, 0xf8) \
300
+ XX(TRILOGY_TYPE_TINY_BLOB, 0xf9) \
301
+ XX(TRILOGY_TYPE_MEDIUM_BLOB, 0xfa) \
302
+ XX(TRILOGY_TYPE_LONG_BLOB, 0xfb) \
303
+ XX(TRILOGY_TYPE_BLOB, 0xfc) \
304
+ XX(TRILOGY_TYPE_VAR_STRING, 0xfd) \
305
+ XX(TRILOGY_TYPE_STRING, 0xfe) \
306
+ XX(TRILOGY_TYPE_GEOMETRY, 0xff)
307
+
308
+ typedef enum {
309
+ #define XX(name, code) name = code,
310
+ TRILOGY_TYPES(XX)
311
+ #undef XX
312
+ } TRILOGY_TYPE_t;
313
+
314
+ #define TRILOGY_COLUMN_FLAGS(XX) \
315
+ XX(TRILOGY_COLUMN_FLAG_NONE, 0x0) \
316
+ /* The column has the `NOT NULL` flag set. Requiring all values to not be \
317
+ * NULL. \
318
+ */ \
319
+ XX(TRILOGY_COLUMN_FLAG_NOT_NULL, 0x1) \
320
+ /* The column is part of a primary key. \
321
+ */ \
322
+ XX(TRILOGY_COLUMN_FLAG_PRI_KEY, 0x2) \
323
+ /* The column has the `UNIQUE` flag set. Requring all values to be unique. \
324
+ */ \
325
+ XX(TRILOGY_COLUMN_FLAG_UNIQUE_KEY, 0x4) \
326
+ /* The column is part of a key. \
327
+ */ \
328
+ XX(TRILOGY_COLUMN_FLAG_MULTIPLE_KEY, 0x8) \
329
+ /* The column is a blob. \
330
+ */ \
331
+ XX(TRILOGY_COLUMN_FLAG_BLOB, 0x10) \
332
+ /* The column is a numeric type and has the `UNSIGNED` flag set. \
333
+ */ \
334
+ XX(TRILOGY_COLUMN_FLAG_UNSIGNED, 0x20) \
335
+ /* The column is flagged as zero fill. \
336
+ */ \
337
+ XX(TRILOGY_COLUMN_FLAG_ZEROFILL, 0x40) \
338
+ /* This column is flagged as binary. This will be set for any of the \
339
+ * binary field types like BINARY, VARBINARY, TINYBLOB, BLOB, MEDIUMBLOB \
340
+ * and LONGBLOB. \
341
+ */ \
342
+ XX(TRILOGY_COLUMN_FLAG_BINARY, 0x80) \
343
+ /* The column is an `ENUM` \
344
+ */ \
345
+ XX(TRILOGY_COLUMN_FLAG_ENUM, 0x100) \
346
+ /* The column is configured to auto-increment. \
347
+ */ \
348
+ XX(TRILOGY_COLUMN_FLAG_AUTO_INCREMENT, 0x200) \
349
+ /* The column is a `TIMESTAMP`. \
350
+ */ \
351
+ XX(TRILOGY_COLUMN_FLAG_TIMESTAMP, 0x400) \
352
+ /* The column is a `SET`. \
353
+ */ \
354
+ XX(TRILOGY_COLUMN_FLAG_SET, 0x800) \
355
+ /* The column has no default value configured. \
356
+ */ \
357
+ XX(TRILOGY_COLUMN_FLAG_NO_DEFAULT_VALUE, 0x1000) \
358
+ /* The column is configured to set it's value to `NOW()` on row update. \
359
+ */ \
360
+ XX(TRILOGY_COLUMN_FLAG_ON_UPDATE_NOW, 0x2000) \
361
+ /* The column is used in a partition function. \
362
+ */ \
363
+ XX(TRILOGY_COLUMN_FLAG_IN_PART_FUNC, 0x80000)
364
+
365
+ typedef enum {
366
+ #define XX(name, code) name = code,
367
+ TRILOGY_COLUMN_FLAGS(XX)
368
+ #undef XX
369
+ } TRILOGY_COLUMN_FLAG_t;
370
+
371
+ // Typical response packet types
372
+ typedef enum {
373
+ TRILOGY_PACKET_OK = 0x0,
374
+ TRILOGY_PACKET_EOF = 0xfe,
375
+ TRILOGY_PACKET_ERR = 0xff,
376
+ TRILOGY_PACKET_UNKNOWN
377
+ } TRILOGY_PACKET_TYPE_t;
378
+
379
+ /*
380
+ * source_uuid:transaction_id
381
+ * (UUID string) ":" (bigint string)
382
+ * 36 + 1 + 20 = 57
383
+ */
384
+ #define TRILOGY_MAX_LAST_GTID_LEN 57
385
+
386
+ #define TRILOGY_SESSION_TRACK(XX) \
387
+ XX(TRILOGY_SESSION_TRACK_SYSTEM_VARIABLES, 0x00) \
388
+ XX(TRILOGY_SESSION_TRACK_SCHEMA, 0x01) \
389
+ XX(TRILOGY_SESSION_TRACK_STATE_CHANGE, 0x02) \
390
+ XX(TRILOGY_SESSION_TRACK_GTIDS, 0x03) \
391
+ XX(TRILOGY_SESSION_TRACK_TRANSACTION_CHARACTERISTICS, 0x04) \
392
+ XX(TRILOGY_SESSION_TRACK_TRANSACTION_STATE, 0x05)
393
+
394
+ typedef enum {
395
+ #define XX(name, code) name = code,
396
+ TRILOGY_SESSION_TRACK(XX)
397
+ #undef XX
398
+ } TRILOGY_SESSION_TRACK_TYPE_t;
399
+
400
+ /* trilogy_build_auth_packet - Build a handshake response (or authentication)
401
+ * packet.
402
+ *
403
+ * This should be sent in response to the initial handshake packet the server
404
+ * sends upon connection.
405
+ *
406
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
407
+ * user - The username to use for authentication. Must be a C-string.
408
+ * pass - The password to use for authentication. Optional, and can be NULL.
409
+ * pass_len - The length of password in bytes.
410
+ * auth_plugin - Plugin authentication mechanism that the server requested.
411
+ * scramble - The scramble value the server sent in the initial handshake.
412
+ * flags - Bitmask of TRILOGY_CAPABILITIES_t flags.
413
+ * The TRILOGY_CAPABILITIES_PROTOCOL_41 and
414
+ * TRILOGY_CAPABILITIES_SECURE_CONNECTION flags will always be set
415
+ * internally.
416
+ *
417
+ * Return values:
418
+ * TRILOGY_OK - The packet was successfully built and written to the
419
+ * builder's internal buffer.
420
+ * TRILOGY_SYSERR - A system error occurred, check errno.
421
+ */
422
+ int trilogy_build_auth_packet(trilogy_builder_t *builder, const char *user, const char *pass, size_t pass_len,
423
+ const char *database, const char *auth_plugin, const char *scramble,
424
+ TRILOGY_CAPABILITIES_t flags);
425
+
426
+ /* trilogy_build_auth_switch_response_packet - Build a response for when
427
+ * authentication switching it requested.
428
+ *
429
+ * This should be sent in response to the initial switch request packet the server
430
+ * sends upon connection.
431
+ *
432
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
433
+ * pass - The password to use for authentication.
434
+ * pass_len - The length of password in bytes.
435
+ * auth_plugin - Plugin authentication mechanism that the server requested.
436
+ * scramble - The scramble value received from the server.
437
+ *
438
+ * Return values:
439
+ * TRILOGY_OK - The packet was successfully built and written to the
440
+ * builder's internal buffer.
441
+ * TRILOGY_SYSERR - A system error occurred, check errno.
442
+ */
443
+ int trilogy_build_auth_switch_response_packet(trilogy_builder_t *builder, const char *pass, size_t pass_len,
444
+ const char *auth_plugin, const char *scramble);
445
+
446
+ /* trilogy_build_change_db_packet - Build a change database command packet. This
447
+ * command will change the default database for the connection.
448
+ *
449
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
450
+ * name - The name of the databaset to set as the default.
451
+ * name_len - The length of name in bytes.
452
+ *
453
+ * Return values:
454
+ * TRILOGY_OK - The packet was successfully built and written to the
455
+ * builder's internal buffer.
456
+ * TRILOGY_SYSERR - A system error occurred, check errno.
457
+ */
458
+ int trilogy_build_change_db_packet(trilogy_builder_t *builder, const char *name, size_t name_len);
459
+
460
+ /* trilogy_build_ping_packet - Build a ping command packet.
461
+ *
462
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
463
+ *
464
+ * Return values:
465
+ * TRILOGY_OK - The packet was successfully built and written to the
466
+ * builder's internal buffer.
467
+ * TRILOGY_SYSERR - A system error occurred, check errno.
468
+ */
469
+ int trilogy_build_ping_packet(trilogy_builder_t *builder);
470
+
471
+ /* trilogy_build_query_packet - Build a query command packet.
472
+ *
473
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
474
+ * query - The query string to be used by the command.
475
+ * query_len - The length of query in bytes.
476
+ * Return values:
477
+ * TRILOGY_OK - The packet was successfully built and written to the
478
+ * builder's internal buffer.
479
+ * TRILOGY_SYSERR - A system error occurred, check errno.
480
+ */
481
+ int trilogy_build_query_packet(trilogy_builder_t *builder, const char *sql, size_t sql_len);
482
+
483
+ /* trilogy_build_quit_packet - Build a quit command packet.
484
+ *
485
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
486
+ *
487
+ * Return values:
488
+ * TRILOGY_OK - The packet was successfully built and written to the
489
+ * builder's internal buffer.
490
+ * TRILOGY_SYSERR - A system error occurred, check errno.
491
+ */
492
+ int trilogy_build_quit_packet(trilogy_builder_t *builder);
493
+
494
+ /* trilogy_build_ssl_request_packet - Build an SSL request packet.
495
+ *
496
+ * This should be sent in response to the initial handshake packet the server
497
+ * sends upon connection, where an auth packet would normally be sent. A regular
498
+ * auth packet is to be sent after the SSL handshake completes.
499
+ *
500
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
501
+ * flags - Bitmask of TRILOGY_CAPABILITIES_t flags.
502
+ * The TRILOGY_CAPABILITIES_PROTOCOL_41 and
503
+ * TRILOGY_CAPABILITIES_SECURE_CONNECTION flags will always be set
504
+ * internally.
505
+ * The TRILOGY_CAPABILITIES_SSL flag will also be set.
506
+ *
507
+ * Return values:
508
+ * TRILOGY_OK - The packet was successfully built and written to the
509
+ * builder's internal buffer.
510
+ * TRILOGY_SYSERR - A system error occurred, check errno.
511
+ */
512
+ int trilogy_build_ssl_request_packet(trilogy_builder_t *builder, TRILOGY_CAPABILITIES_t flags);
513
+
514
+ #define TRILOGY_SERVER_VERSION_SIZE 32
515
+
516
+ typedef struct {
517
+ uint8_t proto_version;
518
+ char server_version[TRILOGY_SERVER_VERSION_SIZE];
519
+ uint32_t conn_id;
520
+ char scramble[21];
521
+ uint32_t capabilities;
522
+ TRILOGY_CHARSET_t server_charset;
523
+ uint16_t server_status;
524
+ char auth_plugin[32];
525
+ } trilogy_handshake_t;
526
+
527
+ typedef struct {
528
+ uint64_t affected_rows;
529
+ uint64_t last_insert_id;
530
+ uint16_t status_flags;
531
+ uint16_t warning_count;
532
+ uint16_t txn_status_flags;
533
+ const char *session_status;
534
+ size_t session_status_len;
535
+ const char *session_state_changes;
536
+ size_t session_state_changes_len;
537
+ const char *info;
538
+ size_t info_len;
539
+ const char *last_gtid;
540
+ size_t last_gtid_len;
541
+ } trilogy_ok_packet_t;
542
+
543
+ /* trilogy_stmt_ok_packet_t - Represents a MySQL binary protocol prepare response packet.
544
+ */
545
+ typedef struct {
546
+ uint32_t id;
547
+ uint16_t column_count;
548
+ uint16_t parameter_count;
549
+ uint16_t warning_count;
550
+ } trilogy_stmt_ok_packet_t;
551
+
552
+ typedef struct {
553
+ uint16_t warning_count;
554
+ uint16_t status_flags;
555
+ } trilogy_eof_packet_t;
556
+
557
+ typedef struct {
558
+ uint16_t error_code;
559
+ uint8_t sql_state_marker[1];
560
+ uint8_t sql_state[5];
561
+ const char *error_message;
562
+ size_t error_message_len;
563
+ } trilogy_err_packet_t;
564
+
565
+ typedef struct {
566
+ char auth_plugin[32];
567
+ char scramble[21];
568
+ } trilogy_auth_switch_request_packet_t;
569
+
570
+ typedef struct {
571
+ const char *catalog;
572
+ size_t catalog_len;
573
+ const char *schema;
574
+ size_t schema_len;
575
+ const char *table;
576
+ size_t table_len;
577
+ const char *original_table;
578
+ size_t original_table_len;
579
+ const char *name;
580
+ size_t name_len;
581
+ const char *original_name;
582
+ size_t original_name_len;
583
+ TRILOGY_CHARSET_t charset;
584
+ uint32_t len;
585
+ TRILOGY_TYPE_t type;
586
+ uint16_t flags;
587
+ uint8_t decimals;
588
+ const char *default_value;
589
+ size_t default_value_len;
590
+ } trilogy_column_packet_t;
591
+
592
+ typedef struct {
593
+ uint64_t column_count;
594
+ } trilogy_result_packet_t;
595
+
596
+ typedef struct {
597
+ bool is_null;
598
+ const void *data;
599
+ size_t data_len;
600
+ } trilogy_value_t;
601
+
602
+ /* trilogy_binary_value_t - MySQL binary protocol value type
603
+ *
604
+ */
605
+ typedef struct {
606
+ // Flag denoting the value is NULL.
607
+ bool is_null;
608
+
609
+ /* Flag denoting the numeric value is unsigned.
610
+ * If this is true, the unsigned numerical value types should be used
611
+ * from the `as` union below.
612
+ *
613
+ * For example, if the value's MySQL type is TRILOGY_TYPE_LONGLONG and
614
+ * `is_unsigned` is `true`, the caller should use the `.as.uint64` field
615
+ * below to access the properly unsigned value.
616
+ */
617
+ bool is_unsigned;
618
+
619
+ // The MySQL column type of this value.
620
+ TRILOGY_TYPE_t type;
621
+
622
+ /* This union is used for accessing the underlying binary type for the value.
623
+ * Each field member is documented with the MySQL column/value type it maps to.
624
+ */
625
+ union {
626
+ /* MySQL types that use this field:
627
+ *
628
+ * TRILOGY_TYPE_DOUBLE
629
+ */
630
+ double dbl;
631
+
632
+ /* MySQL types that use this field:
633
+ *
634
+ * TRILOGY_TYPE_LONGLONG
635
+ *
636
+ * Refer to the `is_unsigned` field above to see which member below should
637
+ * be used to access the value.
638
+ */
639
+ int64_t int64;
640
+ uint64_t uint64;
641
+
642
+ /* MySQL types that use this field:
643
+ *
644
+ * TRILOGY_TYPE_FLOAT
645
+ */
646
+ float flt;
647
+
648
+ /* MySQL types that use this field:
649
+ *
650
+ * TRILOGY_TYPE_LONG
651
+ * TRILOGY_TYPE_INT24
652
+ *
653
+ * Refer to the `is_unsigned` field above to see which member below should
654
+ * be used to access the value.
655
+ */
656
+ uint32_t uint32;
657
+ int32_t int32;
658
+
659
+ /* MySQL types that use this field:
660
+ *
661
+ * TRILOGY_TYPE_SHORT
662
+ *
663
+ * Refer to the `is_unsigned` field above to see which member below should
664
+ * be used to access the value.
665
+ */
666
+ uint16_t uint16;
667
+ int16_t int16;
668
+
669
+ /* MySQL types that use this field:
670
+ *
671
+ * TRILOGY_TYPE_TINY
672
+ *
673
+ * Refer to the `is_unsigned` field above to see which member below should
674
+ * be used to access the value.
675
+ */
676
+ uint8_t uint8;
677
+ int8_t int8;
678
+
679
+ /* MySQL types that use this field:
680
+ *
681
+ * TRILOGY_TYPE_STRING
682
+ * TRILOGY_TYPE_VARCHAR
683
+ * TRILOGY_TYPE_VAR_STRING
684
+ * TRILOGY_TYPE_ENUM
685
+ * TRILOGY_TYPE_SET
686
+ * TRILOGY_TYPE_LONG_BLOB
687
+ * TRILOGY_TYPE_MEDIUM_BLOB
688
+ * TRILOGY_TYPE_BLOB
689
+ * TRILOGY_TYPE_TINY_BLOB
690
+ * TRILOGY_TYPE_GEOMETRY
691
+ * TRILOGY_TYPE_BIT
692
+ * TRILOGY_TYPE_DECIMAL
693
+ * TRILOGY_TYPE_NEWDECIMAL
694
+ */
695
+ struct {
696
+ const void *data;
697
+ size_t len;
698
+ } str;
699
+
700
+ /* MySQL types that use this field:
701
+ *
702
+ * TRILOGY_TYPE_YEAR
703
+ */
704
+ uint16_t year;
705
+
706
+ /* MySQL types that use this field:
707
+ *
708
+ * TRILOGY_TYPE_DATE
709
+ * TRILOGY_TYPE_DATETIME
710
+ * TRILOGY_TYPE_TIMESTAMP
711
+ */
712
+ struct {
713
+ uint16_t year;
714
+ uint8_t month, day;
715
+ struct {
716
+ uint8_t hour, minute, second;
717
+ uint32_t micro_seconds;
718
+ } datetime;
719
+ } date;
720
+
721
+ /* MySQL types that use this field:
722
+ *
723
+ * TRILOGY_TYPE_TIME
724
+ */
725
+ struct {
726
+ bool is_negative;
727
+ uint32_t days;
728
+ uint8_t hour, minute, second;
729
+ uint32_t micro_seconds;
730
+ } time;
731
+ } as;
732
+ } trilogy_binary_value_t;
733
+
734
+ /* trilogy_build_stmt_prepare_packet - Build a prepared statement prepare command packet.
735
+ *
736
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
737
+ * query - The query string to be used by the prepared statement.
738
+ * query_len - The length of query in bytes.
739
+ *
740
+ * Return values:
741
+ * TRILOGY_OK - The packet was successfully built and written to the
742
+ * builder's internal buffer.
743
+ * TRILOGY_SYSERR - A system error occurred, check errno.
744
+ */
745
+ int trilogy_build_stmt_prepare_packet(trilogy_builder_t *builder, const char *sql, size_t sql_len);
746
+
747
+ // Prepared statement flags
748
+ typedef enum {
749
+ TRILOGY_CURSOR_TYPE_NO_CURSOR = 0x00,
750
+ TRILOGY_CURSOR_TYPE_READ_ONLY = 0x01,
751
+ TRILOGY_CURSOR_TYPE_FOR_UPDATE = 0x02,
752
+ TRILOGY_CURSOR_TYPE_SCROLLABLE = 0x04,
753
+ TRILOGY_CURSOR_TYPE_UNKNOWN
754
+ } TRILOGY_STMT_FLAGS_t;
755
+
756
+ /* trilogy_build_stmt_execute_packet - Build a prepared statement execute command packet.
757
+ *
758
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
759
+ * stmt_id - The statement id for which to build the execute packet with.
760
+ * flags - The flags (TRILOGY_STMT_FLAGS_t) to be used with this execute command packet.
761
+ * binds - Pointer to an array of trilogy_binary_value_t's.
762
+ * num_binds - The number of elements in the binds array above.
763
+ *
764
+ * Return values:
765
+ * TRILOGY_OK - The packet was successfully built and written to the
766
+ * builder's internal buffer.
767
+ * TRILOGY_PROTOCOL_VIOLATION - num_binds is > 0 but binds is NULL.
768
+ * TRILOGY_UNKNOWN_TYPE - An unsupported or unknown MySQL type was used in the list
769
+ * of binds.
770
+ * TRILOGY_SYSERR - A system error occurred, check errno.
771
+ */
772
+ int trilogy_build_stmt_execute_packet(trilogy_builder_t *builder, uint32_t stmt_id, uint8_t flags,
773
+ trilogy_binary_value_t *binds, uint16_t num_binds);
774
+
775
+ /* trilogy_build_stmt_bind_data_packet - Build a prepared statement bind long data command packet.
776
+ *
777
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
778
+ * stmt_id - The statement id for which to build the bind data packet with.
779
+ * param_id - The parameter index for which the supplied data should be bound to.
780
+ * data - A pointer to the buffer containing the data to be bound.
781
+ * data_len - The length of the data buffer.
782
+ *
783
+ * Return values:
784
+ * TRILOGY_OK - The packet was successfully built and written to the
785
+ * builder's internal buffer.
786
+ * TRILOGY_SYSERR - A system error occurred, check errno.
787
+ */
788
+ int trilogy_build_stmt_bind_data_packet(trilogy_builder_t *builder, uint32_t stmt_id, uint16_t param_id, uint8_t *data,
789
+ size_t data_len);
790
+
791
+ /* trilogy_build_stmt_reset_packet - Build a prepared statement reset command packet.
792
+ *
793
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
794
+ * stmt_id - The statement id for which to build the reset packet with.
795
+ *
796
+ * Return values:
797
+ * TRILOGY_OK - The packet was successfully built and written to the
798
+ * builder's internal buffer.
799
+ * TRILOGY_SYSERR - A system error occurred, check errno.
800
+ */
801
+ int trilogy_build_stmt_reset_packet(trilogy_builder_t *builder, uint32_t stmt_id);
802
+
803
+ /* trilogy_build_stmt_close_packet - Build a prepared statement close command packet.
804
+ *
805
+ * builder - A pointer to a pre-initialized trilogy_builder_t.
806
+ * stmt_id - The statement id for which to build the close packet with.
807
+ *
808
+ * Return values:
809
+ * TRILOGY_OK - The packet was successfully built and written to the
810
+ * builder's internal buffer.
811
+ * TRILOGY_SYSERR - A system error occurred, check errno.
812
+ */
813
+ int trilogy_build_stmt_close_packet(trilogy_builder_t *builder, uint32_t stmt_id);
814
+
815
+ /* The following parsing functions assume the buffer and length passed in point
816
+ * to one full MySQL-compatible packet. If the buffer contains more than one packet or
817
+ * has any extra data at the end, these functions will return
818
+ * TRILOGY_EXTRA_DATA_IN_PACKET.
819
+ */
820
+
821
+ /* trilogy_parse_handshake_packet - Parse an initial handshake packet from a
822
+ * buffer.
823
+ *
824
+ * buff - A pointer to the buffer containing the initial handshake packet
825
+ * data.
826
+ * len - The length of buff in bytes.
827
+ * out_packet - Out parameter; A pointer to a pre-allocated trilogy_handshake_t.
828
+ *
829
+ * Return values:
830
+ * TRILOGY_OK - The packet was was parsed and the out
831
+ * parameter has been filled in.
832
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
833
+ * to parse the packet.
834
+ * TRILOGY_PROTOCOL_VIOLATION - The protocol version parsed wasn't what
835
+ * the Trilogy API supports (0xa); Or the
836
+ * packet is corrupt.
837
+ * TRILOGY_INVALID_CHARSET - The charset parsed isn't in the range
838
+ * supported by the Trilogy API.
839
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
840
+ * buffer.
841
+ */
842
+ int trilogy_parse_handshake_packet(const uint8_t *buff, size_t len, trilogy_handshake_t *out_packet);
843
+
844
+ /* trilogy_parse_ok_packet - Parse an OK packet.
845
+ *
846
+ * buff - A pointer to the buffer containing the OK packet data.
847
+ * len - The length of buff in bytes.
848
+ * capabilities - A bitmask of TRILOGY_CAPABILITIES_t flags.
849
+ * out_packet - Out parameter; A pointer to a pre-allocated trilogy_ok_packet_t.
850
+ *
851
+ * Return values:
852
+ * TRILOGY_OK - The packet was was parsed and the out
853
+ * parameter has been filled in.
854
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
855
+ * to parse the packet.
856
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
857
+ * buffer.
858
+ */
859
+ int trilogy_parse_ok_packet(const uint8_t *buff, size_t len, uint32_t capabilities, trilogy_ok_packet_t *out_packet);
860
+
861
+ /* trilogy_parse_eof_packet - Parse an EOF packet.
862
+ *
863
+ * buff - A pointer to the buffer containing the EOF packet data.
864
+ * len - The lenght of buff in bytes.
865
+ * capabilities - A bitmask of TRILOGY_CAPABILITIES_t flags.
866
+ * out_packet - Out parameter; A pointer to a pre-allocated
867
+ * trilogy_eof_packet_t.
868
+ *
869
+ * Return values:
870
+ * TRILOGY_OK - The packet was was parsed and the out
871
+ * parameter has been filled in.
872
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
873
+ * to parse the packet.
874
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
875
+ * buffer.
876
+ */
877
+ int trilogy_parse_eof_packet(const uint8_t *buff, size_t len, uint32_t capabilities, trilogy_eof_packet_t *out_packet);
878
+
879
+ /* trilogy_parse_err_packet - Parse an ERR packet.
880
+ *
881
+ * buff - A pointer to the buffer containing the ERR packet data.
882
+ * len - The length of buffer in bytes.
883
+ * capabilities - A bitmask of TRILOGY_CAPABILITIES_t flags.
884
+ * out_packet - Out parameter; A pointer to a pre-allocated
885
+ * trilogy_err_packet_t.
886
+ *
887
+ * Return values:
888
+ * TRILOGY_OK - The packet was was parsed and the out
889
+ * parameter has been filled in.
890
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
891
+ * to parse the packet.
892
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
893
+ * buffer.
894
+ */
895
+ int trilogy_parse_err_packet(const uint8_t *buff, size_t len, uint32_t capabilities, trilogy_err_packet_t *out_packet);
896
+
897
+ /* trilogy_parse_auth_switch_request_packet - Parse an AuthSwitchRequest packet.
898
+ *
899
+ * buff - A pointer to the buffer containing the AuthSwitchRequest packet data.
900
+ * len - The length of buffer in bytes.
901
+ * capabilities - A bitmask of TRILOGY_CAPABILITIES_t flags.
902
+ * out_packet - Out parameter; A pointer to a pre-allocated
903
+ * trilogy_auth_switch_request_t.
904
+ *
905
+ * Return values:
906
+ * TRILOGY_OK - The packet was was parsed and the out
907
+ * parameter has been filled in.
908
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
909
+ * to parse the packet.
910
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
911
+ * buffer.
912
+ */
913
+ int trilogy_parse_auth_switch_request_packet(const uint8_t *buff, size_t len, uint32_t capabilities,
914
+ trilogy_auth_switch_request_packet_t *out_packet);
915
+
916
+ /* trilogy_parse_result_packet - Parse a result packet.
917
+ *
918
+ * buff - A pointer to the buffer containing the result packet data.
919
+ * len - The length of buffer in bytes.
920
+ * out_packet - Out parameter; A pointer to a pre-allocated
921
+ * trilogy_result_packet_t.
922
+ *
923
+ * Return values:
924
+ * TRILOGY_OK - The packet was was parsed and the out
925
+ * parameter has been filled in. TRILOGY_TRUNCATED_PACKET - There isn't enough
926
+ * data in the buffer to parse the packet. TRILOGY_EXTRA_DATA_IN_PACKET - There
927
+ * are unparsed bytes left in the buffer.
928
+ */
929
+ int trilogy_parse_result_packet(const uint8_t *buff, size_t len, trilogy_result_packet_t *out_packet);
930
+
931
+ /* trilogy_parse_column_packet - Parse a column info packet.
932
+ *
933
+ * buff - A pointer to the buffer containing the column packet data.
934
+ * len - The length of buffer in bytes.
935
+ * field_list - Boolean to tell the parser it should expect default value
936
+ * information at the end of the packet. This will be the case
937
+ * when parsing column info packets in response to a field list
938
+ * command.
939
+ * out_packet - Out parameter; A pointer to a pre-allocated
940
+ * trilogy_column_packet_t.
941
+ *
942
+ * Return values:
943
+ * TRILOGY_OK - The packet was was parsed and the out
944
+ * parameter has been filled in. TRILOGY_TRUNCATED_PACKET - There isn't enough
945
+ * data in the buffer to parse the packet. TRILOGY_EXTRA_DATA_IN_PACKET - There
946
+ * are unparsed bytes left in the buffer.
947
+ */
948
+ int trilogy_parse_column_packet(const uint8_t *buff, size_t len, bool field_list, trilogy_column_packet_t *out_packet);
949
+
950
+ /* trilogy_parse_row_packet - Parse a row packet.
951
+ *
952
+ * buff - A pointer to the buffer containing the result packet data.
953
+ * len - The length of buffer in bytes.
954
+ * column_count - The number of columns in the response. This parser needs this
955
+ * in order to know how many values to parse.
956
+ * out_packet - Out parameter; A pointer to a pre-allocated array of
957
+ * trilogy_value_t's. There must be enough space to fit all of the
958
+ * values. This can be computed with:
959
+ * `(sizeof(trilogy_value_t) * column_count)`.
960
+ *
961
+ * Return values:
962
+ * TRILOGY_OK - The packet was was parsed and the out
963
+ * parameter has been filled in.
964
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
965
+ * to parse the packet.
966
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
967
+ * buffer.
968
+ */
969
+ int trilogy_parse_row_packet(const uint8_t *buff, size_t len, uint64_t column_count, trilogy_value_t *out_values);
970
+
971
+ /* trilogy_parse_stmt_ok_packet - Parse a prepared statement ok packet.
972
+ *
973
+ * buff - A pointer to the buffer containing the result packet data.
974
+ * len - The length of buffer in bytes.
975
+ * out_packet - Out parameter; A pointer to a pre-allocated trilogy_stmt_ok_packet_t.
976
+ *
977
+ * Return values:
978
+ * TRILOGY_OK - The packet was was parsed and the out
979
+ * parameter has been filled in.
980
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
981
+ * to parse the packet.
982
+ * TRILOGY_PROTOCOL_VIOLATION - Filler byte was something other than zero.
983
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
984
+ * buffer.
985
+ */
986
+ int trilogy_parse_stmt_ok_packet(const uint8_t *buff, size_t len, trilogy_stmt_ok_packet_t *out_packet);
987
+
988
+ /* trilogy_parse_stmt_row_packet - Parse a prepared statement row packet.
989
+ *
990
+ * buff - A pointer to the buffer containing the result packet data.
991
+ * len - The length of buffer in bytes.
992
+ * columns - The list of columns from the prepared statement. This parser needs
993
+ * this in order to match up the value types.
994
+ * column_count - The number of columns in prepared statement. This parser needs this
995
+ * in order to know how many values to parse.
996
+ * out_values - Out parameter; A pointer to a pre-allocated array of
997
+ * trilogy_binary_value_t's. There must be enough space to fit all of the
998
+ * values. This can be computed with:
999
+ * `(sizeof(trilogy_binary_value_t) * column_count)`.
1000
+ *
1001
+ * Return values:
1002
+ * TRILOGY_OK - The packet was was parsed and the out
1003
+ * parameter has been filled in.
1004
+ * TRILOGY_TRUNCATED_PACKET - There isn't enough data in the buffer
1005
+ * to parse the packet.
1006
+ * TRILOGY_PROTOCOL_VIOLATION - Invalid length parsed for a TIME/DATETIME/TIMESTAMP value.
1007
+ * TRILOGY_UNKNOWN_TYPE - An unsupported or unknown MySQL type was seen in the packet.
1008
+ * TRILOGY_EXTRA_DATA_IN_PACKET - There are unparsed bytes left in the
1009
+ * buffer.
1010
+ */
1011
+ int trilogy_parse_stmt_row_packet(const uint8_t *buff, size_t len, trilogy_column_packet_t *columns,
1012
+ uint64_t column_count, trilogy_binary_value_t *out_values);
1013
+
1014
+ #endif