trilogy 2.2.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/ext/trilogy-ruby/cast.c +12 -7
- data/ext/trilogy-ruby/cext.c +230 -88
- data/ext/trilogy-ruby/extconf.rb +1 -1
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +18 -1
- data/ext/trilogy-ruby/inc/trilogy/client.h +58 -0
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +56 -35
- data/ext/trilogy-ruby/inc/trilogy/socket.h +2 -0
- data/ext/trilogy-ruby/src/blocking.c +23 -0
- data/ext/trilogy-ruby/src/client.c +51 -3
- data/ext/trilogy-ruby/src/protocol.c +21 -6
- data/ext/trilogy-ruby/src/socket.c +25 -0
- data/ext/trilogy-ruby/trilogy-ruby.h +4 -1
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +238 -20
- metadata +3 -3
@@ -299,6 +299,50 @@ int trilogy_change_db_send(trilogy_conn_t *conn, const char *name, size_t name_l
|
|
299
299
|
*/
|
300
300
|
int trilogy_change_db_recv(trilogy_conn_t *conn);
|
301
301
|
|
302
|
+
/* trilogy_set_option_send - Send a set option command to the server. This
|
303
|
+
* will change server capabilities based on the option selected.
|
304
|
+
*
|
305
|
+
* This should only be called while the connection is ready for commands.
|
306
|
+
*
|
307
|
+
* conn - A connected trilogy_conn_t pointer. Using a disconnected
|
308
|
+
* trilogy_conn_t is undefined.
|
309
|
+
* option - The server option to send.
|
310
|
+
*
|
311
|
+
* Return values:
|
312
|
+
* TRILOGY_OK - The change database command was successfully sent to the
|
313
|
+
* server.
|
314
|
+
* TRILOGY_AGAIN - The socket wasn't ready for writing. The caller should wait
|
315
|
+
* for writeability using `conn->sock`. Then call
|
316
|
+
* trilogy_flush_writes.
|
317
|
+
* TRILOGY_SYSERR - A system error occurred, check errno.
|
318
|
+
*/
|
319
|
+
int trilogy_set_option_send(trilogy_conn_t *conn, const uint16_t option);
|
320
|
+
|
321
|
+
/* trilogy_set_option_recv - Read the set option command response from the
|
322
|
+
* server.
|
323
|
+
*
|
324
|
+
* This should be called after all data written by trilogy_set_option_send is
|
325
|
+
* flushed to the network. Calling this at any other time during the connection
|
326
|
+
* lifecycle is undefined.
|
327
|
+
*
|
328
|
+
* conn - A connected trilogy_conn_t pointer. Using a disconnected trilogy_conn_t is
|
329
|
+
* undefined.
|
330
|
+
*
|
331
|
+
* Return values:
|
332
|
+
* TRILOGY_OK - The set option command was successfully
|
333
|
+
* sent to the server.
|
334
|
+
* TRILOGY_AGAIN - The socket wasn't ready for reading. The
|
335
|
+
* caller should wait for readability using
|
336
|
+
* `conn->sock`. Then call this function until
|
337
|
+
* it returns a different value.
|
338
|
+
* TRILOGY_UNEXPECTED_PACKET - The response packet wasn't what was expected.
|
339
|
+
* TRILOGY_PROTOCOL_VIOLATION - An error occurred while processing a network
|
340
|
+
* packet.
|
341
|
+
* TRILOGY_CLOSED_CONNECTION - The connection is closed.
|
342
|
+
* TRILOGY_SYSERR - A system error occurred, check errno.
|
343
|
+
*/
|
344
|
+
int trilogy_set_option_recv(trilogy_conn_t *conn);
|
345
|
+
|
302
346
|
/* trilogy_query_send - Send a query command to the server.
|
303
347
|
*
|
304
348
|
* This should only be called while the connection is ready for commands.
|
@@ -543,4 +587,18 @@ int trilogy_close_recv(trilogy_conn_t *conn);
|
|
543
587
|
*/
|
544
588
|
void trilogy_free(trilogy_conn_t *conn);
|
545
589
|
|
590
|
+
/* trilogy_free - Discard the connection and free any internal buffers.
|
591
|
+
*
|
592
|
+
* The server won't be notified that connection was closed. This is useful to
|
593
|
+
* silently close connections that were inherited after forking without disrupting
|
594
|
+
* the parent's process connections.
|
595
|
+
*
|
596
|
+
* conn - A pre-initialized trilogy_conn_t pointer.
|
597
|
+
*
|
598
|
+
* Return values:
|
599
|
+
* TRILOGY_OK - The connection was successfuly discarded and freed.
|
600
|
+
* TRILOGY_SYSERR - A system error occurred, check errno. The connection wasn't freed.
|
601
|
+
*/
|
602
|
+
int trilogy_discard(trilogy_conn_t *conn);
|
603
|
+
|
546
604
|
#endif
|
@@ -90,16 +90,14 @@
|
|
90
90
|
* From client: the client is interactive. \
|
91
91
|
*/ \
|
92
92
|
XX(TRILOGY_CAPABILITIES_INTERACTIVE, 0x00000400) \
|
93
|
-
/*
|
94
|
-
* \
|
95
|
-
* From server: the server supports ssl. \
|
93
|
+
/* From server: the server supports ssl. \
|
96
94
|
* \
|
97
95
|
* From client: tells the server it should switch to an ssl connection. \
|
98
96
|
*/ \
|
99
97
|
XX(TRILOGY_CAPABILITIES_SSL, 0x00000800) \
|
100
|
-
/*
|
98
|
+
/* From server: the server supports transactions and is capable of reporting transaction status. \
|
101
99
|
* \
|
102
|
-
*
|
100
|
+
* From client: the client is aware of servers that support transactions. \
|
103
101
|
*/ \
|
104
102
|
XX(TRILOGY_CAPABILITIES_TRANSACTIONS, 0x00002000) \
|
105
103
|
/* Not used. \
|
@@ -112,27 +110,21 @@
|
|
112
110
|
* scheme. This will always be set. \
|
113
111
|
*/ \
|
114
112
|
XX(TRILOGY_CAPABILITIES_SECURE_CONNECTION, 0x00008000) \
|
115
|
-
/*
|
116
|
-
* \
|
117
|
-
* From server: the server can handle multiple statements per \
|
113
|
+
/* From server: the server can handle multiple statements per \
|
118
114
|
* query/prepared statement. \
|
119
115
|
* \
|
120
116
|
* From client: tells the server it may send multiple statements per \
|
121
117
|
* query/ prepared statement. \
|
122
118
|
*/ \
|
123
119
|
XX(TRILOGY_CAPABILITIES_MULTI_STATEMENTS, 0x00010000) \
|
124
|
-
/*
|
125
|
-
* \
|
126
|
-
* From server: the server is capable of sending multiple result sets from \
|
120
|
+
/* From server: the server is capable of sending multiple result sets from \
|
127
121
|
* a query. \
|
128
122
|
* \
|
129
123
|
* From client: tells the server it's capable of handling multiple result \
|
130
124
|
* sets from a query. \
|
131
125
|
*/ \
|
132
126
|
XX(TRILOGY_CAPABILITIES_MULTI_RESULTS, 0x00020000) \
|
133
|
-
/*
|
134
|
-
* \
|
135
|
-
* From server: the server is capable of sending multiple result sets from \
|
127
|
+
/* From server: the server is capable of sending multiple result sets from \
|
136
128
|
* a prepared statement. \
|
137
129
|
* \
|
138
130
|
* From client: tells the server it's capable of handling multiple result \
|
@@ -193,7 +185,8 @@ typedef enum {
|
|
193
185
|
/* A convenience bitmask with common client capabilities set. */
|
194
186
|
TRILOGY_CAPABILITIES_CLIENT = (TRILOGY_CAPABILITIES_PROTOCOL_41 | TRILOGY_CAPABILITIES_SECURE_CONNECTION |
|
195
187
|
TRILOGY_CAPABILITIES_DEPRECATE_EOF | TRILOGY_CAPABILITIES_SESSION_TRACK |
|
196
|
-
TRILOGY_CAPABILITIES_PLUGIN_AUTH | TRILOGY_CAPABILITIES_TRANSACTIONS
|
188
|
+
TRILOGY_CAPABILITIES_PLUGIN_AUTH | TRILOGY_CAPABILITIES_TRANSACTIONS |
|
189
|
+
TRILOGY_CAPABILITIES_MULTI_RESULTS)
|
197
190
|
} TRILOGY_CAPABILITIES_t;
|
198
191
|
|
199
192
|
#define TRILOGY_SERVER_STATUS(XX) \
|
@@ -399,22 +392,34 @@ typedef enum {
|
|
399
392
|
#undef XX
|
400
393
|
} TRILOGY_SESSION_TRACK_TYPE_t;
|
401
394
|
|
395
|
+
#define TRILOGY_SET_SERVER_OPTION(XX) \
|
396
|
+
XX(TRILOGY_SET_SERVER_MULTI_STATEMENTS_ON, 0x00) \
|
397
|
+
XX(TRILOGY_SET_SERVER_MULTI_STATEMENTS_OFF, 0x01) \
|
398
|
+
|
399
|
+
typedef enum {
|
400
|
+
#define XX(name, code) name = code,
|
401
|
+
TRILOGY_SET_SERVER_OPTION(XX)
|
402
|
+
#undef XX
|
403
|
+
} TRILOGY_SET_SERVER_OPTION_TYPE_t;
|
404
|
+
|
402
405
|
/* trilogy_build_auth_packet - Build a handshake response (or authentication)
|
403
406
|
* packet.
|
404
407
|
*
|
405
408
|
* This should be sent in response to the initial handshake packet the server
|
406
409
|
* sends upon connection.
|
407
410
|
*
|
408
|
-
* builder
|
409
|
-
* user
|
410
|
-
* pass
|
411
|
-
* pass_len
|
412
|
-
*
|
413
|
-
*
|
414
|
-
*
|
415
|
-
*
|
416
|
-
*
|
417
|
-
*
|
411
|
+
* builder - A pointer to a pre-initialized trilogy_builder_t.
|
412
|
+
* user - The username to use for authentication. Must be a C-string.
|
413
|
+
* pass - The password to use for authentication. Optional, and can be NULL.
|
414
|
+
* pass_len - The length of password in bytes.
|
415
|
+
* database - The initial database to connect to. Optional, and can be NULL.
|
416
|
+
* client_encoding - The charset to use for the connection.
|
417
|
+
* auth_plugin - Plugin authentication mechanism that the server requested.
|
418
|
+
* scramble - The scramble value the server sent in the initial handshake.
|
419
|
+
* flags - Bitmask of TRILOGY_CAPABILITIES_t flags.
|
420
|
+
* The TRILOGY_CAPABILITIES_PROTOCOL_41 and
|
421
|
+
* TRILOGY_CAPABILITIES_SECURE_CONNECTION flags will always be set
|
422
|
+
* internally.
|
418
423
|
*
|
419
424
|
* Return values:
|
420
425
|
* TRILOGY_OK - The packet was successfully built and written to the
|
@@ -422,8 +427,8 @@ typedef enum {
|
|
422
427
|
* TRILOGY_SYSERR - A system error occurred, check errno.
|
423
428
|
*/
|
424
429
|
int trilogy_build_auth_packet(trilogy_builder_t *builder, const char *user, const char *pass, size_t pass_len,
|
425
|
-
const char *database,
|
426
|
-
TRILOGY_CAPABILITIES_t flags);
|
430
|
+
const char *database, TRILOGY_CHARSET_t client_encoding, const char *auth_plugin,
|
431
|
+
const char *scramble, TRILOGY_CAPABILITIES_t flags);
|
427
432
|
|
428
433
|
/* trilogy_build_auth_switch_response_packet - Build a response for when
|
429
434
|
* authentication switching it requested.
|
@@ -449,7 +454,7 @@ int trilogy_build_auth_switch_response_packet(trilogy_builder_t *builder, const
|
|
449
454
|
* command will change the default database for the connection.
|
450
455
|
*
|
451
456
|
* builder - A pointer to a pre-initialized trilogy_builder_t.
|
452
|
-
* name - The name of the
|
457
|
+
* name - The name of the database to set as the default.
|
453
458
|
* name_len - The length of name in bytes.
|
454
459
|
*
|
455
460
|
* Return values:
|
@@ -459,6 +464,20 @@ int trilogy_build_auth_switch_response_packet(trilogy_builder_t *builder, const
|
|
459
464
|
*/
|
460
465
|
int trilogy_build_change_db_packet(trilogy_builder_t *builder, const char *name, size_t name_len);
|
461
466
|
|
467
|
+
/* trilogy_build_set_option_packet - Build a set option command packet. This
|
468
|
+
* command will enable/disable server capabilities for the connection. Options
|
469
|
+
* must be one of `enum_mysql_set_option`.
|
470
|
+
*
|
471
|
+
* builder - A pointer to a pre-initialized trilogy_builder_t.
|
472
|
+
* option - An integer corresponding to the operation to perform.
|
473
|
+
*
|
474
|
+
* Return values:
|
475
|
+
* TRILOGY_OK - The packet was successfully built and written to the
|
476
|
+
* builder's internal buffer.
|
477
|
+
* TRILOGY_SYSERR - A system error occurred, check errno.
|
478
|
+
*/
|
479
|
+
int trilogy_build_set_option_packet(trilogy_builder_t *builder, const uint16_t option);
|
480
|
+
|
462
481
|
/* trilogy_build_ping_packet - Build a ping command packet.
|
463
482
|
*
|
464
483
|
* builder - A pointer to a pre-initialized trilogy_builder_t.
|
@@ -499,19 +518,21 @@ int trilogy_build_quit_packet(trilogy_builder_t *builder);
|
|
499
518
|
* sends upon connection, where an auth packet would normally be sent. A regular
|
500
519
|
* auth packet is to be sent after the SSL handshake completes.
|
501
520
|
*
|
502
|
-
* builder
|
503
|
-
* flags
|
504
|
-
*
|
505
|
-
*
|
506
|
-
*
|
507
|
-
*
|
521
|
+
* builder - A pointer to a pre-initialized trilogy_builder_t.
|
522
|
+
* flags - Bitmask of TRILOGY_CAPABILITIES_t flags.
|
523
|
+
* The TRILOGY_CAPABILITIES_PROTOCOL_41 and
|
524
|
+
* TRILOGY_CAPABILITIES_SECURE_CONNECTION flags will always be set
|
525
|
+
* internally.
|
526
|
+
* The TRILOGY_CAPABILITIES_SSL flag will also be set.
|
527
|
+
* client_encoding - The charset to use for the connection.
|
508
528
|
*
|
509
529
|
* Return values:
|
510
530
|
* TRILOGY_OK - The packet was successfully built and written to the
|
511
531
|
* builder's internal buffer.
|
512
532
|
* TRILOGY_SYSERR - A system error occurred, check errno.
|
513
533
|
*/
|
514
|
-
int trilogy_build_ssl_request_packet(trilogy_builder_t *builder, TRILOGY_CAPABILITIES_t flags
|
534
|
+
int trilogy_build_ssl_request_packet(trilogy_builder_t *builder, TRILOGY_CAPABILITIES_t flags,
|
535
|
+
TRILOGY_CHARSET_t client_encoding);
|
515
536
|
|
516
537
|
#define TRILOGY_SERVER_VERSION_SIZE 32
|
517
538
|
|
@@ -41,6 +41,7 @@ typedef struct {
|
|
41
41
|
char *username;
|
42
42
|
char *password;
|
43
43
|
size_t password_len;
|
44
|
+
uint8_t encoding;
|
44
45
|
|
45
46
|
trilogy_ssl_mode_t ssl_mode;
|
46
47
|
trilogy_tls_version_t tls_min_version;
|
@@ -107,5 +108,6 @@ static inline int trilogy_sock_fd(trilogy_sock_t *sock) { return sock->fd_cb(soc
|
|
107
108
|
trilogy_sock_t *trilogy_sock_new(const trilogy_sockopt_t *opts);
|
108
109
|
int trilogy_sock_resolve(trilogy_sock_t *raw);
|
109
110
|
int trilogy_sock_upgrade_ssl(trilogy_sock_t *raw);
|
111
|
+
int trilogy_sock_discard(trilogy_sock_t *sock);
|
110
112
|
|
111
113
|
#endif
|
@@ -139,6 +139,29 @@ int trilogy_change_db(trilogy_conn_t *conn, const char *name, size_t name_len)
|
|
139
139
|
}
|
140
140
|
}
|
141
141
|
|
142
|
+
int trilogy_set_option(trilogy_conn_t *conn, const uint16_t option)
|
143
|
+
{
|
144
|
+
int rc = trilogy_set_option_send(conn, option);
|
145
|
+
|
146
|
+
if (rc == TRILOGY_AGAIN) {
|
147
|
+
rc = flush_full(conn);
|
148
|
+
}
|
149
|
+
|
150
|
+
if (rc < 0) {
|
151
|
+
return rc;
|
152
|
+
}
|
153
|
+
|
154
|
+
while (1) {
|
155
|
+
rc = trilogy_set_option_recv(conn);
|
156
|
+
|
157
|
+
if (rc != TRILOGY_AGAIN) {
|
158
|
+
return rc;
|
159
|
+
}
|
160
|
+
|
161
|
+
CHECKED(trilogy_sock_wait_read(conn->socket));
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
142
165
|
int trilogy_ping(trilogy_conn_t *conn)
|
143
166
|
{
|
144
167
|
int rc = trilogy_ping_send(conn);
|
@@ -357,8 +357,9 @@ int trilogy_auth_send(trilogy_conn_t *conn, const trilogy_handshake_t *handshake
|
|
357
357
|
}
|
358
358
|
|
359
359
|
rc = trilogy_build_auth_packet(&builder, conn->socket->opts.username, conn->socket->opts.password,
|
360
|
-
conn->socket->opts.password_len, conn->socket->opts.database,
|
361
|
-
|
360
|
+
conn->socket->opts.password_len, conn->socket->opts.database,
|
361
|
+
conn->socket->opts.encoding, handshake->auth_plugin, handshake->scramble,
|
362
|
+
conn->socket->opts.flags);
|
362
363
|
|
363
364
|
if (rc < 0) {
|
364
365
|
return rc;
|
@@ -378,7 +379,7 @@ int trilogy_ssl_request_send(trilogy_conn_t *conn)
|
|
378
379
|
}
|
379
380
|
|
380
381
|
conn->socket->opts.flags |= TRILOGY_CAPABILITIES_SSL;
|
381
|
-
rc = trilogy_build_ssl_request_packet(&builder, conn->socket->opts.flags);
|
382
|
+
rc = trilogy_build_ssl_request_packet(&builder, conn->socket->opts.flags, conn->socket->opts.encoding);
|
382
383
|
|
383
384
|
if (rc < 0) {
|
384
385
|
return rc;
|
@@ -466,6 +467,44 @@ int trilogy_change_db_send(trilogy_conn_t *conn, const char *name, size_t name_l
|
|
466
467
|
|
467
468
|
int trilogy_change_db_recv(trilogy_conn_t *conn) { return read_generic_response(conn); }
|
468
469
|
|
470
|
+
int trilogy_set_option_send(trilogy_conn_t *conn, const uint16_t option)
|
471
|
+
{
|
472
|
+
trilogy_builder_t builder;
|
473
|
+
int err = begin_command_phase(&builder, conn, 0);
|
474
|
+
if (err < 0) {
|
475
|
+
return err;
|
476
|
+
}
|
477
|
+
|
478
|
+
err = trilogy_build_set_option_packet(&builder, option);
|
479
|
+
|
480
|
+
if (err < 0) {
|
481
|
+
return err;
|
482
|
+
}
|
483
|
+
|
484
|
+
return begin_write(conn);
|
485
|
+
}
|
486
|
+
|
487
|
+
int trilogy_set_option_recv(trilogy_conn_t *conn) {
|
488
|
+
int rc = read_packet(conn);
|
489
|
+
|
490
|
+
if (rc < 0) {
|
491
|
+
return rc;
|
492
|
+
}
|
493
|
+
|
494
|
+
switch (current_packet_type(conn)) {
|
495
|
+
case TRILOGY_PACKET_OK:
|
496
|
+
case TRILOGY_PACKET_EOF: // COM_SET_OPTION returns an EOF packet, but it should be treated as an OK packet.
|
497
|
+
return read_ok_packet(conn);
|
498
|
+
|
499
|
+
case TRILOGY_PACKET_ERR:
|
500
|
+
return read_err_packet(conn);
|
501
|
+
|
502
|
+
default:
|
503
|
+
return TRILOGY_UNEXPECTED_PACKET;
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
|
469
508
|
int trilogy_ping_send(trilogy_conn_t *conn)
|
470
509
|
{
|
471
510
|
trilogy_builder_t builder;
|
@@ -725,4 +764,13 @@ void trilogy_free(trilogy_conn_t *conn)
|
|
725
764
|
trilogy_buffer_free(&conn->packet_buffer);
|
726
765
|
}
|
727
766
|
|
767
|
+
int trilogy_discard(trilogy_conn_t *conn)
|
768
|
+
{
|
769
|
+
int rc = trilogy_sock_discard(conn->socket);
|
770
|
+
if (rc == TRILOGY_OK) {
|
771
|
+
trilogy_free(conn);
|
772
|
+
}
|
773
|
+
return rc;
|
774
|
+
}
|
775
|
+
|
728
776
|
#undef CHECKED
|
@@ -10,6 +10,7 @@
|
|
10
10
|
#define TRILOGY_CMD_CHANGE_DB 0x02
|
11
11
|
#define TRILOGY_CMD_QUERY 0x03
|
12
12
|
#define TRILOGY_CMD_PING 0x0e
|
13
|
+
#define TRILOGY_CMD_SET_OPTION 0x1b
|
13
14
|
|
14
15
|
#define SCRAMBLE_LEN 20
|
15
16
|
|
@@ -493,8 +494,8 @@ static void trilogy_pack_scramble_sha2_hash(const char *scramble, const char *pa
|
|
493
494
|
}
|
494
495
|
|
495
496
|
int trilogy_build_auth_packet(trilogy_builder_t *builder, const char *user, const char *pass, size_t pass_len,
|
496
|
-
const char *database,
|
497
|
-
TRILOGY_CAPABILITIES_t flags)
|
497
|
+
const char *database, TRILOGY_CHARSET_t client_encoding, const char *auth_plugin,
|
498
|
+
const char *scramble, TRILOGY_CAPABILITIES_t flags)
|
498
499
|
{
|
499
500
|
int rc = TRILOGY_OK;
|
500
501
|
|
@@ -506,8 +507,6 @@ int trilogy_build_auth_packet(trilogy_builder_t *builder, const char *user, cons
|
|
506
507
|
|
507
508
|
uint32_t max_packet_len = TRILOGY_MAX_PACKET_LEN;
|
508
509
|
|
509
|
-
uint8_t client_encoding = TRILOGY_CHARSET_UTF8_GENERAL_CI;
|
510
|
-
|
511
510
|
unsigned int auth_response_len = 0;
|
512
511
|
uint8_t auth_response[EVP_MAX_MD_SIZE];
|
513
512
|
|
@@ -646,12 +645,28 @@ fail:
|
|
646
645
|
return rc;
|
647
646
|
}
|
648
647
|
|
649
|
-
int
|
648
|
+
int trilogy_build_set_option_packet(trilogy_builder_t *builder, const uint16_t option)
|
649
|
+
{
|
650
|
+
int rc = TRILOGY_OK;
|
651
|
+
|
652
|
+
CHECKED(trilogy_builder_write_uint8(builder, TRILOGY_CMD_SET_OPTION));
|
653
|
+
CHECKED(trilogy_builder_write_uint16(builder, option));
|
654
|
+
|
655
|
+
trilogy_builder_finalize(builder);
|
656
|
+
|
657
|
+
return TRILOGY_OK;
|
658
|
+
|
659
|
+
fail:
|
660
|
+
return rc;
|
661
|
+
}
|
662
|
+
|
663
|
+
|
664
|
+
int trilogy_build_ssl_request_packet(trilogy_builder_t *builder, TRILOGY_CAPABILITIES_t flags,
|
665
|
+
TRILOGY_CHARSET_t client_encoding)
|
650
666
|
{
|
651
667
|
static const char zeroes[23] = {0};
|
652
668
|
|
653
669
|
const uint32_t max_packet_len = TRILOGY_MAX_PACKET_LEN;
|
654
|
-
const uint8_t client_encoding = TRILOGY_CHARSET_UTF8_GENERAL_CI;
|
655
670
|
const uint32_t capabilities = flags | TRILOGY_CAPABILITIES_CLIENT | TRILOGY_CAPABILITIES_SSL;
|
656
671
|
|
657
672
|
int rc = TRILOGY_OK;
|
@@ -621,3 +621,28 @@ fail:
|
|
621
621
|
sock->ssl = NULL;
|
622
622
|
return TRILOGY_OPENSSL_ERR;
|
623
623
|
}
|
624
|
+
|
625
|
+
int trilogy_sock_discard(trilogy_sock_t *_sock)
|
626
|
+
{
|
627
|
+
struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
|
628
|
+
|
629
|
+
if (sock->fd < 0) {
|
630
|
+
return TRILOGY_OK;
|
631
|
+
}
|
632
|
+
|
633
|
+
int null_fd = open("/dev/null", O_RDWR | O_CLOEXEC);
|
634
|
+
if (null_fd < 0) {
|
635
|
+
return TRILOGY_SYSERR;
|
636
|
+
}
|
637
|
+
|
638
|
+
if (dup2(null_fd, sock->fd) < 0) {
|
639
|
+
close(null_fd);
|
640
|
+
return TRILOGY_SYSERR;
|
641
|
+
}
|
642
|
+
|
643
|
+
if (close(null_fd) < 0) {
|
644
|
+
return TRILOGY_SYSERR;
|
645
|
+
}
|
646
|
+
|
647
|
+
return TRILOGY_OK;
|
648
|
+
}
|
@@ -9,6 +9,7 @@
|
|
9
9
|
#define TRILOGY_FLAGS_CAST_BOOLEANS 2
|
10
10
|
#define TRILOGY_FLAGS_LOCAL_TIMEZONE 4
|
11
11
|
#define TRILOGY_FLAGS_FLATTEN_ROWS 8
|
12
|
+
#define TRILOGY_FLAGS_CAST_ALL_DECIMALS_TO_BIGDECIMALS 16
|
12
13
|
#define TRILOGY_FLAGS_DEFAULT (TRILOGY_FLAGS_CAST)
|
13
14
|
|
14
15
|
struct rb_trilogy_cast_options {
|
@@ -16,6 +17,7 @@ struct rb_trilogy_cast_options {
|
|
16
17
|
bool cast_booleans;
|
17
18
|
bool database_local_time;
|
18
19
|
bool flatten_rows;
|
20
|
+
bool cast_decimals_to_bigdecimals;
|
19
21
|
};
|
20
22
|
|
21
23
|
struct column_info {
|
@@ -23,9 +25,10 @@ struct column_info {
|
|
23
25
|
TRILOGY_CHARSET_t charset;
|
24
26
|
uint32_t len;
|
25
27
|
uint16_t flags;
|
28
|
+
uint8_t decimals;
|
26
29
|
};
|
27
30
|
|
28
|
-
extern VALUE
|
31
|
+
extern VALUE Trilogy_CastError;
|
29
32
|
|
30
33
|
VALUE
|
31
34
|
rb_trilogy_cast_value(const trilogy_value_t *value, const struct column_info *column,
|
data/lib/trilogy/version.rb
CHANGED