trilogy 2.9.0 → 2.11.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 -1
- data/Rakefile +16 -1
- data/ext/trilogy-ruby/cext.c +266 -49
- data/ext/trilogy-ruby/extconf.rb +5 -3
- data/ext/trilogy-ruby/inc/trilogy/buffer.h +13 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +11 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +2 -1
- data/ext/trilogy-ruby/inc/trilogy/socket.h +2 -0
- data/ext/trilogy-ruby/src/buffer.c +22 -3
- data/ext/trilogy-ruby/src/client.c +407 -97
- data/ext/trilogy-ruby/src/packet_parser.c +1 -1
- data/ext/trilogy-ruby/src/socket.c +6 -0
- data/lib/trilogy/encoding.rb +2 -0
- data/lib/trilogy/error.rb +7 -0
- data/lib/trilogy/result.rb +2 -0
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +76 -1
- data/trilogy.gemspec +3 -2
- metadata +10 -28
|
@@ -25,6 +25,12 @@ struct trilogy_sock {
|
|
|
25
25
|
SSL *ssl;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
void trilogy_sock_set_fd(trilogy_sock_t *_sock, int fd)
|
|
29
|
+
{
|
|
30
|
+
struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
|
|
31
|
+
sock->fd = fd;
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
static int _cb_raw_fd(trilogy_sock_t *_sock)
|
|
29
35
|
{
|
|
30
36
|
struct trilogy_sock *sock = (struct trilogy_sock *)_sock;
|
data/lib/trilogy/encoding.rb
CHANGED
data/lib/trilogy/error.rb
CHANGED
|
@@ -54,6 +54,12 @@ class Trilogy
|
|
|
54
54
|
include ConnectionError
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
class SynchronizationError < BaseError
|
|
58
|
+
def initialize(message = "This connection is already in use by another thread or fiber")
|
|
59
|
+
super
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
57
63
|
# Trilogy::ClientError is the base error type for invalid queries or parameters
|
|
58
64
|
# that shouldn't be retried.
|
|
59
65
|
class ClientError < BaseError
|
|
@@ -94,6 +100,7 @@ class Trilogy
|
|
|
94
100
|
1160 => BaseConnectionError, # ER_NET_ERROR_ON_WRITE
|
|
95
101
|
1161 => BaseConnectionError, # ER_NET_WRITE_INTERRUPTED
|
|
96
102
|
1927 => BaseConnectionError, # ER_CONNECTION_KILLED
|
|
103
|
+
4031 => BaseConnectionError, # Disconnected by server
|
|
97
104
|
}
|
|
98
105
|
class << self
|
|
99
106
|
def from_code(message, code)
|
data/lib/trilogy/result.rb
CHANGED
data/lib/trilogy/version.rb
CHANGED
data/lib/trilogy.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "socket"
|
|
3
4
|
require "trilogy/version"
|
|
4
5
|
require "trilogy/error"
|
|
5
6
|
require "trilogy/result"
|
|
@@ -7,7 +8,34 @@ require "trilogy/cext"
|
|
|
7
8
|
require "trilogy/encoding"
|
|
8
9
|
|
|
9
10
|
class Trilogy
|
|
11
|
+
IO_TIMEOUT_ERROR =
|
|
12
|
+
if defined?(IO::TimeoutError)
|
|
13
|
+
IO::TimeoutError
|
|
14
|
+
else
|
|
15
|
+
Class.new(StandardError)
|
|
16
|
+
end
|
|
17
|
+
private_constant :IO_TIMEOUT_ERROR
|
|
18
|
+
|
|
19
|
+
Synchronization = Module.new
|
|
20
|
+
|
|
21
|
+
source = public_instance_methods(false).flat_map do |method|
|
|
22
|
+
[
|
|
23
|
+
"def #{method}(...)",
|
|
24
|
+
"raise SynchronizationError unless @mutex.try_lock",
|
|
25
|
+
"begin",
|
|
26
|
+
"super",
|
|
27
|
+
"ensure",
|
|
28
|
+
"@mutex.unlock",
|
|
29
|
+
"end",
|
|
30
|
+
"end",
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
Synchronization.class_eval(source.join(";"), __FILE__, __LINE__)
|
|
34
|
+
|
|
35
|
+
prepend(Synchronization)
|
|
36
|
+
|
|
10
37
|
def initialize(options = {})
|
|
38
|
+
@mutex = Mutex.new
|
|
11
39
|
options[:port] = options[:port].to_i if options[:port]
|
|
12
40
|
mysql_encoding = options[:encoding] || "utf8mb4"
|
|
13
41
|
encoding = Trilogy::Encoding.find(mysql_encoding)
|
|
@@ -15,7 +43,54 @@ class Trilogy
|
|
|
15
43
|
@connection_options = options
|
|
16
44
|
@connected_host = nil
|
|
17
45
|
|
|
18
|
-
|
|
46
|
+
socket = nil
|
|
47
|
+
begin
|
|
48
|
+
if host = options[:host]
|
|
49
|
+
port = options[:port] || 3306
|
|
50
|
+
connect_timeout = options[:connect_timeout] || options[:write_timeout]
|
|
51
|
+
|
|
52
|
+
socket = TCPSocket.new(host, port, connect_timeout: connect_timeout)
|
|
53
|
+
|
|
54
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
55
|
+
|
|
56
|
+
if keepalive_enabled = options[:keepalive_enabled]
|
|
57
|
+
keepalive_idle = options[:keepalive_idle]
|
|
58
|
+
keepalive_interval = options[:keepalive_interval]
|
|
59
|
+
keepalive_count = options[:keepalive_count]
|
|
60
|
+
|
|
61
|
+
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
|
62
|
+
|
|
63
|
+
if keepalive_idle > 0 && defined?(Socket::TCP_KEEPIDLE)
|
|
64
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, keepalive_idle)
|
|
65
|
+
end
|
|
66
|
+
if keepalive_interval > 0 && defined?(Socket::TCP_KEEPINTVL)
|
|
67
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, keepalive_interval)
|
|
68
|
+
end
|
|
69
|
+
if keepalive_count > 0 && defined?(Socket::TCP_KEEPCNT)
|
|
70
|
+
socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, keepalive_count)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
path = options[:socket] ||= "/tmp/mysql.sock"
|
|
75
|
+
socket = UNIXSocket.new(path)
|
|
76
|
+
end
|
|
77
|
+
rescue Errno::ETIMEDOUT, IO_TIMEOUT_ERROR => e
|
|
78
|
+
raise Trilogy::TimeoutError, e.message
|
|
79
|
+
rescue SocketError => e
|
|
80
|
+
connection_str = host ? "#{host}:#{port}" : path
|
|
81
|
+
raise Trilogy::BaseConnectionError, "unable to connect to \"#{connection_str}\": #{e.message}"
|
|
82
|
+
rescue => e
|
|
83
|
+
if e.respond_to?(:errno)
|
|
84
|
+
raise Trilogy::SyscallError.from_errno(e.errno, e.message)
|
|
85
|
+
else
|
|
86
|
+
raise
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
_connect(socket, encoding, charset, options)
|
|
91
|
+
ensure
|
|
92
|
+
# Socket's fd will be dup'd in C
|
|
93
|
+
socket&.close
|
|
19
94
|
end
|
|
20
95
|
|
|
21
96
|
def connection_options
|
data/trilogy.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,44 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trilogy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Engineering
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: bigdecimal
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
type: :
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
|
-
- - "
|
|
23
|
+
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: minitest
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '5.5'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '5.5'
|
|
41
|
-
description:
|
|
25
|
+
version: '0'
|
|
42
26
|
email: opensource+trilogy@github.com
|
|
43
27
|
executables: []
|
|
44
28
|
extensions:
|
|
@@ -87,7 +71,6 @@ homepage: https://github.com/trilogy-libraries/trilogy
|
|
|
87
71
|
licenses:
|
|
88
72
|
- MIT
|
|
89
73
|
metadata: {}
|
|
90
|
-
post_install_message:
|
|
91
74
|
rdoc_options: []
|
|
92
75
|
require_paths:
|
|
93
76
|
- lib
|
|
@@ -95,15 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
95
78
|
requirements:
|
|
96
79
|
- - ">="
|
|
97
80
|
- !ruby/object:Gem::Version
|
|
98
|
-
version: '0'
|
|
81
|
+
version: '3.0'
|
|
99
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
83
|
requirements:
|
|
101
84
|
- - ">="
|
|
102
85
|
- !ruby/object:Gem::Version
|
|
103
86
|
version: '0'
|
|
104
87
|
requirements: []
|
|
105
|
-
rubygems_version: 3.
|
|
106
|
-
signing_key:
|
|
88
|
+
rubygems_version: 3.6.9
|
|
107
89
|
specification_version: 4
|
|
108
90
|
summary: A friendly MySQL-compatible library for Ruby, binding to libtrilogy
|
|
109
91
|
test_files: []
|