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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +80 -0
- data/Rakefile +22 -0
- data/ext/trilogy-ruby/cast.c +277 -0
- data/ext/trilogy-ruby/cext.c +1048 -0
- data/ext/trilogy-ruby/extconf.rb +17 -0
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +281 -0
- data/ext/trilogy-ruby/inc/trilogy/buffer.h +64 -0
- data/ext/trilogy-ruby/inc/trilogy/builder.h +165 -0
- data/ext/trilogy-ruby/inc/trilogy/charset.h +277 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +760 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +44 -0
- data/ext/trilogy-ruby/inc/trilogy/packet_parser.h +34 -0
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +1014 -0
- data/ext/trilogy-ruby/inc/trilogy/reader.h +216 -0
- data/ext/trilogy-ruby/inc/trilogy/socket.h +111 -0
- data/ext/trilogy-ruby/inc/trilogy/vendor/curl_hostcheck.h +29 -0
- data/ext/trilogy-ruby/inc/trilogy/vendor/openssl_hostname_validation.h +51 -0
- data/ext/trilogy-ruby/inc/trilogy.h +8 -0
- data/ext/trilogy-ruby/src/blocking.c +358 -0
- data/ext/trilogy-ruby/src/buffer.c +60 -0
- data/ext/trilogy-ruby/src/builder.c +236 -0
- data/ext/trilogy-ruby/src/charset.c +212 -0
- data/ext/trilogy-ruby/src/client.c +903 -0
- data/ext/trilogy-ruby/src/error.c +17 -0
- data/ext/trilogy-ruby/src/packet_parser.c +140 -0
- data/ext/trilogy-ruby/src/protocol.c +1175 -0
- data/ext/trilogy-ruby/src/reader.c +282 -0
- data/ext/trilogy-ruby/src/socket.c +623 -0
- data/ext/trilogy-ruby/src/vendor/curl_hostcheck.c +206 -0
- data/ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c +175 -0
- data/ext/trilogy-ruby/trilogy-ruby.h +37 -0
- data/lib/trilogy/version.rb +3 -0
- data/lib/trilogy.rb +61 -0
- data/trilogy.gemspec +27 -0
- 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
|