trilogy 2.6.0 → 2.7.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 +4 -4
- data/README.md +1 -2
- data/ext/trilogy-ruby/cext.c +10 -23
- data/ext/trilogy-ruby/extconf.rb +5 -1
- data/ext/trilogy-ruby/src/buffer.c +6 -1
- data/ext/trilogy-ruby/src/socket.c +17 -4
- data/lib/trilogy/error.rb +12 -18
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +3 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f36747c1d61f440a5ff6b5d37981b0a11ad26a1b973ebeb9bab84e832b2841a3
|
4
|
+
data.tar.gz: b654bac6dbc4d3451c5101e9f8574de4aee4044d6aa280c0736e3e18ad09c723
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81aefe81cfe750d70a42915c6a16f6d7211455b255a6588088c8ac6c682240636df5c2269b7090e78ba2ce6f991e3266f1c2b57711130e84fde85a8d38b22a1c
|
7
|
+
data.tar.gz: 3df0441086b141c6c0ebb0d3a216d14205547bd340c06cf0884e1985ac6550023ea8960200c5afe31821160883a3cd96a07a942efb05a9d335153dcdafa83976
|
data/README.md
CHANGED
@@ -27,7 +27,6 @@ $ gem install trilogy
|
|
27
27
|
``` ruby
|
28
28
|
client = Trilogy.new(host: "127.0.0.1", port: 3306, username: "root", read_timeout: 2)
|
29
29
|
if client.ping
|
30
|
-
client.query_options[:database_timezone] = :utc
|
31
30
|
client.change_db "mydb"
|
32
31
|
|
33
32
|
result = client.query("SELECT id, created_at FROM users LIMIT 10")
|
@@ -63,7 +62,7 @@ bundle exec rake build
|
|
63
62
|
|
64
63
|
The official Ruby bindings are inside of the canonical trilogy repository itself.
|
65
64
|
|
66
|
-
1. Fork it ( https://github.com/
|
65
|
+
1. Fork it ( https://github.com/trilogy-libraries/trilogy/fork )
|
67
66
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
67
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
69
68
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/ext/trilogy-ruby/cext.c
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
VALUE Trilogy_CastError;
|
19
19
|
static VALUE Trilogy_BaseConnectionError, Trilogy_ProtocolError, Trilogy_SSLError, Trilogy_QueryError,
|
20
|
-
Trilogy_ConnectionClosedError,
|
20
|
+
Trilogy_ConnectionClosedError,
|
21
21
|
Trilogy_TimeoutError, Trilogy_SyscallError, Trilogy_Result, Trilogy_EOFError;
|
22
22
|
|
23
23
|
static ID id_socket, id_host, id_port, id_username, id_password, id_found_rows, id_connect_timeout, id_read_timeout,
|
@@ -43,9 +43,7 @@ static void mark_trilogy(void *ptr)
|
|
43
43
|
static void free_trilogy(void *ptr)
|
44
44
|
{
|
45
45
|
struct trilogy_ctx *ctx = ptr;
|
46
|
-
|
47
|
-
trilogy_free(&ctx->conn);
|
48
|
-
}
|
46
|
+
trilogy_free(&ctx->conn);
|
49
47
|
xfree(ptr);
|
50
48
|
}
|
51
49
|
|
@@ -90,12 +88,8 @@ static struct trilogy_ctx *get_open_ctx(VALUE obj)
|
|
90
88
|
NORETURN(static void trilogy_syserr_fail_str(int, VALUE));
|
91
89
|
static void trilogy_syserr_fail_str(int e, VALUE msg)
|
92
90
|
{
|
93
|
-
if (e ==
|
94
|
-
|
95
|
-
} else if (e == ECONNRESET) {
|
96
|
-
rb_raise(Trilogy_ConnectionResetError, "%" PRIsVALUE, msg);
|
97
|
-
} else if (e == EPIPE) {
|
98
|
-
// Backwards compatibility: This error class makes no sense, but matches legacy behavior
|
91
|
+
if (e == EPIPE) {
|
92
|
+
// Backwards compatibility: This error message is a bit odd, but includes "TRILOGY_CLOSED_CONNECTION" to match legacy string matching
|
99
93
|
rb_raise(Trilogy_EOFError, "%" PRIsVALUE ": TRILOGY_CLOSED_CONNECTION: EPIPE", msg);
|
100
94
|
} else {
|
101
95
|
VALUE exc = rb_funcall(Trilogy_SyscallError, id_from_errno, 2, INT2NUM(e), msg);
|
@@ -309,6 +303,7 @@ static int try_connect(struct trilogy_ctx *ctx, trilogy_handshake_t *handshake,
|
|
309
303
|
int rc = args.rc;
|
310
304
|
|
311
305
|
if (rc != TRILOGY_OK) {
|
306
|
+
trilogy_sock_close(sock);
|
312
307
|
return rc;
|
313
308
|
}
|
314
309
|
|
@@ -316,8 +311,10 @@ static int try_connect(struct trilogy_ctx *ctx, trilogy_handshake_t *handshake,
|
|
316
311
|
escape the GVL on each wait operation without going through call_without_gvl */
|
317
312
|
sock->wait_cb = _cb_ruby_wait;
|
318
313
|
rc = trilogy_connect_send_socket(&ctx->conn, sock);
|
319
|
-
if (rc < 0)
|
314
|
+
if (rc < 0) {
|
315
|
+
trilogy_sock_close(sock);
|
320
316
|
return rc;
|
317
|
+
}
|
321
318
|
|
322
319
|
while (1) {
|
323
320
|
rc = trilogy_connect_recv(&ctx->conn, handshake);
|
@@ -425,7 +422,7 @@ static void authenticate(struct trilogy_ctx *ctx, trilogy_handshake_t *handshake
|
|
425
422
|
}
|
426
423
|
}
|
427
424
|
|
428
|
-
static VALUE
|
425
|
+
static VALUE rb_trilogy_connect(VALUE self, VALUE encoding, VALUE charset, VALUE opts)
|
429
426
|
{
|
430
427
|
struct trilogy_ctx *ctx = get_ctx(self);
|
431
428
|
trilogy_sockopt_t connopt = {0};
|
@@ -436,7 +433,6 @@ static VALUE rb_trilogy_initialize(VALUE self, VALUE encoding, VALUE charset, VA
|
|
436
433
|
connopt.encoding = NUM2INT(charset);
|
437
434
|
|
438
435
|
Check_Type(opts, T_HASH);
|
439
|
-
rb_ivar_set(self, id_connection_options, opts);
|
440
436
|
|
441
437
|
if ((val = rb_hash_lookup(opts, ID2SYM(id_ssl_mode))) != Qnil) {
|
442
438
|
Check_Type(val, T_FIXNUM);
|
@@ -578,9 +574,6 @@ static VALUE rb_trilogy_initialize(VALUE self, VALUE encoding, VALUE charset, VA
|
|
578
574
|
}
|
579
575
|
|
580
576
|
int rc = try_connect(ctx, &handshake, &connopt);
|
581
|
-
if (rc == TRILOGY_TIMEOUT) {
|
582
|
-
rb_raise(Trilogy_TimeoutError, "trilogy_connect_recv");
|
583
|
-
}
|
584
577
|
if (rc != TRILOGY_OK) {
|
585
578
|
if (connopt.path) {
|
586
579
|
handle_trilogy_error(ctx, rc, "trilogy_connect - unable to connect to %s", connopt.path);
|
@@ -1104,7 +1097,7 @@ RUBY_FUNC_EXPORTED void Init_cext()
|
|
1104
1097
|
VALUE Trilogy = rb_const_get(rb_cObject, rb_intern("Trilogy"));
|
1105
1098
|
rb_define_alloc_func(Trilogy, allocate_trilogy);
|
1106
1099
|
|
1107
|
-
rb_define_private_method(Trilogy, "
|
1100
|
+
rb_define_private_method(Trilogy, "_connect", rb_trilogy_connect, 3);
|
1108
1101
|
rb_define_method(Trilogy, "change_db", rb_trilogy_change_db, 1);
|
1109
1102
|
rb_define_alias(Trilogy, "select_db", "change_db");
|
1110
1103
|
rb_define_method(Trilogy, "query", rb_trilogy_query, 1);
|
@@ -1159,12 +1152,6 @@ RUBY_FUNC_EXPORTED void Init_cext()
|
|
1159
1152
|
Trilogy_TimeoutError = rb_const_get(Trilogy, rb_intern("TimeoutError"));
|
1160
1153
|
rb_global_variable(&Trilogy_TimeoutError);
|
1161
1154
|
|
1162
|
-
Trilogy_ConnectionRefusedError = rb_const_get(Trilogy, rb_intern("ConnectionRefusedError"));
|
1163
|
-
rb_global_variable(&Trilogy_ConnectionRefusedError);
|
1164
|
-
|
1165
|
-
Trilogy_ConnectionResetError = rb_const_get(Trilogy, rb_intern("ConnectionResetError"));
|
1166
|
-
rb_global_variable(&Trilogy_ConnectionResetError);
|
1167
|
-
|
1168
1155
|
Trilogy_BaseConnectionError = rb_const_get(Trilogy, rb_intern("BaseConnectionError"));
|
1169
1156
|
rb_global_variable(&Trilogy_BaseConnectionError);
|
1170
1157
|
|
data/ext/trilogy-ruby/extconf.rb
CHANGED
@@ -2,8 +2,12 @@ require "mkmf"
|
|
2
2
|
|
3
3
|
# concatenate trilogy library sources to allow the compiler to optimise across
|
4
4
|
# source files
|
5
|
+
|
6
|
+
trilogy_src_dir = File.realpath("src", __dir__)
|
5
7
|
File.binwrite("trilogy.c",
|
6
|
-
Dir["#{
|
8
|
+
Dir["#{trilogy_src_dir}/**/*.c"].map { |src|
|
9
|
+
%{#line 1 "#{src}"\n} + File.binread(src)
|
10
|
+
}.join)
|
7
11
|
|
8
12
|
$objs = %w[trilogy.o cast.o cext.o]
|
9
13
|
$CFLAGS << " -I #{__dir__}/inc -std=gnu99 -fvisibility=hidden"
|
@@ -57,4 +57,9 @@ int trilogy_buffer_putc(trilogy_buffer_t *buffer, uint8_t c)
|
|
57
57
|
return TRILOGY_OK;
|
58
58
|
}
|
59
59
|
|
60
|
-
void trilogy_buffer_free(trilogy_buffer_t *buffer)
|
60
|
+
void trilogy_buffer_free(trilogy_buffer_t *buffer)
|
61
|
+
{
|
62
|
+
free(buffer->buff);
|
63
|
+
buffer->buff = NULL;
|
64
|
+
buffer->len = buffer->cap = 0;
|
65
|
+
}
|
@@ -100,8 +100,15 @@ static int _cb_raw_close(trilogy_sock_t *_sock)
|
|
100
100
|
if (sock->fd != -1) {
|
101
101
|
rc = close(sock->fd);
|
102
102
|
}
|
103
|
+
|
103
104
|
if (sock->addr) {
|
104
|
-
|
105
|
+
if (sock->base.opts.hostname == NULL && sock->base.opts.path != NULL) {
|
106
|
+
/* We created these with calloc so must free them instead of calling freeaddrinfo */
|
107
|
+
free(sock->addr->ai_addr);
|
108
|
+
free(sock->addr);
|
109
|
+
} else {
|
110
|
+
freeaddrinfo(sock->addr);
|
111
|
+
}
|
105
112
|
}
|
106
113
|
|
107
114
|
free(sock->base.opts.hostname);
|
@@ -189,6 +196,7 @@ static int raw_connect_internal(struct trilogy_sock *sock, const struct addrinfo
|
|
189
196
|
{
|
190
197
|
int sockerr;
|
191
198
|
socklen_t sockerr_len = sizeof(sockerr);
|
199
|
+
int rc = TRILOGY_SYSERR;
|
192
200
|
|
193
201
|
sock->fd = socket(ai->ai_family, SOCK_STREAM, ai->ai_protocol);
|
194
202
|
if (sock->fd < 0) {
|
@@ -244,8 +252,8 @@ static int raw_connect_internal(struct trilogy_sock *sock, const struct addrinfo
|
|
244
252
|
}
|
245
253
|
}
|
246
254
|
|
247
|
-
if (trilogy_sock_wait_write((trilogy_sock_t *)sock) < 0) {
|
248
|
-
goto
|
255
|
+
if ((rc = trilogy_sock_wait_write((trilogy_sock_t *)sock)) < 0) {
|
256
|
+
goto failrc;
|
249
257
|
}
|
250
258
|
|
251
259
|
if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerr_len) < 0) {
|
@@ -263,9 +271,11 @@ static int raw_connect_internal(struct trilogy_sock *sock, const struct addrinfo
|
|
263
271
|
return TRILOGY_OK;
|
264
272
|
|
265
273
|
fail:
|
274
|
+
rc = TRILOGY_SYSERR;
|
275
|
+
failrc:
|
266
276
|
close(sock->fd);
|
267
277
|
sock->fd = -1;
|
268
|
-
return
|
278
|
+
return rc;
|
269
279
|
}
|
270
280
|
|
271
281
|
static int _cb_raw_connect(trilogy_sock_t *_sock)
|
@@ -377,6 +387,9 @@ static ssize_t ssl_io_return(struct trilogy_sock *sock, ssize_t ret)
|
|
377
387
|
int rc = SSL_get_error(sock->ssl, (int)ret);
|
378
388
|
if (rc == SSL_ERROR_WANT_WRITE || rc == SSL_ERROR_WANT_READ) {
|
379
389
|
return (ssize_t)TRILOGY_AGAIN;
|
390
|
+
} else if (rc == SSL_ERROR_ZERO_RETURN) {
|
391
|
+
// Server has closed the connection for writing by sending the close_notify alert
|
392
|
+
return (ssize_t)TRILOGY_CLOSED_CONNECTION;
|
380
393
|
} else if (rc == SSL_ERROR_SYSCALL && !ERR_peek_error()) {
|
381
394
|
if (errno == 0) {
|
382
395
|
// On OpenSSL <= 1.1.1, SSL_ERROR_SYSCALL with an errno value
|
data/lib/trilogy/error.rb
CHANGED
@@ -12,7 +12,7 @@ class Trilogy
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# Trilogy may raise various syscall errors, which we treat as Trilogy::Errors.
|
15
|
-
|
15
|
+
module SyscallError
|
16
16
|
ERRORS = {}
|
17
17
|
|
18
18
|
Errno.constants
|
@@ -20,7 +20,10 @@ class Trilogy
|
|
20
20
|
.select { |c| c.is_a?(Class) && c < SystemCallError }
|
21
21
|
.each do |c|
|
22
22
|
errno_name = c.to_s.split('::').last
|
23
|
-
ERRORS[c::Errno] = const_set(errno_name, Class.new(c) {
|
23
|
+
ERRORS[c::Errno] = const_set(errno_name, Class.new(c) {
|
24
|
+
include Trilogy::ConnectionError
|
25
|
+
singleton_class.define_method(:===, Module.instance_method(:===))
|
26
|
+
})
|
24
27
|
end
|
25
28
|
|
26
29
|
ERRORS.freeze
|
@@ -32,6 +35,11 @@ class Trilogy
|
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
38
|
+
ConnectionRefusedError = SyscallError::ECONNREFUSED
|
39
|
+
deprecate_constant :ConnectionRefusedError
|
40
|
+
ConnectionResetError = SyscallError::ECONNRESET
|
41
|
+
deprecate_constant :ConnectionResetError
|
42
|
+
|
35
43
|
class BaseError < StandardError
|
36
44
|
include Error
|
37
45
|
|
@@ -58,21 +66,7 @@ class Trilogy
|
|
58
66
|
class CastError < ClientError
|
59
67
|
end
|
60
68
|
|
61
|
-
class TimeoutError <
|
62
|
-
include ConnectionError
|
63
|
-
|
64
|
-
def initialize(error_message = nil, error_code = nil)
|
65
|
-
super
|
66
|
-
@error_code = error_code
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
class ConnectionRefusedError < Errno::ECONNREFUSED
|
71
|
-
include ConnectionError
|
72
|
-
end
|
73
|
-
|
74
|
-
class ConnectionResetError < Errno::ECONNRESET
|
75
|
-
include ConnectionError
|
69
|
+
class TimeoutError < BaseConnectionError
|
76
70
|
end
|
77
71
|
|
78
72
|
# DatabaseError was replaced by ProtocolError, but we'll keep it around as an
|
@@ -117,7 +111,7 @@ class Trilogy
|
|
117
111
|
include ConnectionError
|
118
112
|
end
|
119
113
|
|
120
|
-
#
|
114
|
+
# Occurs when a socket read or write returns EOF or when an operation is
|
121
115
|
# attempted on a socket which previously encountered an error.
|
122
116
|
class EOFError < BaseConnectionError
|
123
117
|
end
|
data/lib/trilogy/version.rb
CHANGED
data/lib/trilogy.rb
CHANGED
@@ -12,8 +12,10 @@ class Trilogy
|
|
12
12
|
mysql_encoding = options[:encoding] || "utf8mb4"
|
13
13
|
encoding = Trilogy::Encoding.find(mysql_encoding)
|
14
14
|
charset = Trilogy::Encoding.charset(mysql_encoding)
|
15
|
+
@connection_options = options
|
16
|
+
@connected_host = nil
|
15
17
|
|
16
|
-
|
18
|
+
_connect(encoding, charset, options)
|
17
19
|
end
|
18
20
|
|
19
21
|
def connection_options
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trilogy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
|
-
rubygems_version: 3.4.
|
105
|
+
rubygems_version: 3.4.7
|
106
106
|
signing_key:
|
107
107
|
specification_version: 4
|
108
108
|
summary: A friendly MySQL-compatible library for Ruby, binding to libtrilogy
|