trilogy 2.4.1 → 2.6.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 +14 -5
- data/Rakefile +6 -0
- data/ext/trilogy-ruby/cast.c +0 -4
- data/ext/trilogy-ruby/cext.c +118 -34
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +118 -0
- data/ext/trilogy-ruby/inc/trilogy/builder.h +60 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +214 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +4 -1
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +266 -2
- data/ext/trilogy-ruby/inc/trilogy/reader.h +4 -0
- data/ext/trilogy-ruby/inc/trilogy/socket.h +2 -1
- data/ext/trilogy-ruby/src/blocking.c +117 -0
- data/ext/trilogy-ruby/src/builder.c +63 -0
- data/ext/trilogy-ruby/src/client.c +180 -17
- data/ext/trilogy-ruby/src/protocol.c +503 -0
- data/ext/trilogy-ruby/src/reader.c +38 -0
- data/ext/trilogy-ruby/src/socket.c +104 -39
- data/lib/trilogy/encoding.rb +97 -0
- data/lib/trilogy/error.rb +124 -0
- data/lib/trilogy/result.rb +33 -0
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +9 -244
- data/trilogy.gemspec +1 -1
- metadata +7 -4
data/lib/trilogy.rb
CHANGED
@@ -1,177 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "trilogy/version"
|
4
|
+
require "trilogy/error"
|
5
|
+
require "trilogy/result"
|
6
|
+
require "trilogy/cext"
|
7
|
+
require "trilogy/encoding"
|
4
8
|
|
5
9
|
class Trilogy
|
6
|
-
# Trilogy::Error is the base error type. All errors raised by Trilogy
|
7
|
-
# should be descendants of Trilogy::Error
|
8
|
-
module Error
|
9
|
-
attr_reader :error_code
|
10
|
-
end
|
11
|
-
|
12
|
-
# Trilogy::ConnectionError is the base error type for all potentially transient
|
13
|
-
# network errors.
|
14
|
-
module ConnectionError
|
15
|
-
include Error
|
16
|
-
end
|
17
|
-
|
18
|
-
# Trilogy may raise various syscall errors, which we treat as Trilogy::Errors.
|
19
|
-
class SyscallError
|
20
|
-
ERRORS = {}
|
21
|
-
|
22
|
-
Errno.constants
|
23
|
-
.map { |c| Errno.const_get(c) }.uniq
|
24
|
-
.select { |c| c.is_a?(Class) && c < SystemCallError }
|
25
|
-
.each do |c|
|
26
|
-
errno_name = c.to_s.split('::').last
|
27
|
-
ERRORS[c::Errno] = const_set(errno_name, Class.new(c) { include Trilogy::Error })
|
28
|
-
end
|
29
|
-
|
30
|
-
ERRORS.freeze
|
31
|
-
|
32
|
-
class << self
|
33
|
-
def from_errno(errno, message)
|
34
|
-
ERRORS[errno].new(message)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class BaseError < StandardError
|
40
|
-
include Error
|
41
|
-
|
42
|
-
def initialize(error_message = nil, error_code = nil)
|
43
|
-
message = error_code ? "#{error_code}: #{error_message}" : error_message
|
44
|
-
super(message)
|
45
|
-
@error_code = error_code
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class BaseConnectionError < BaseError
|
50
|
-
include ConnectionError
|
51
|
-
end
|
52
|
-
|
53
|
-
# Trilogy::ClientError is the base error type for invalid queries or parameters
|
54
|
-
# that shouldn't be retried.
|
55
|
-
class ClientError < BaseError
|
56
|
-
include Error
|
57
|
-
end
|
58
|
-
|
59
|
-
class QueryError < ClientError
|
60
|
-
end
|
61
|
-
|
62
|
-
class CastError < ClientError
|
63
|
-
end
|
64
|
-
|
65
|
-
class TimeoutError < Errno::ETIMEDOUT
|
66
|
-
include ConnectionError
|
67
|
-
|
68
|
-
def initialize(error_message = nil, error_code = nil)
|
69
|
-
super
|
70
|
-
@error_code = error_code
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class ConnectionRefusedError < Errno::ECONNREFUSED
|
75
|
-
include ConnectionError
|
76
|
-
end
|
77
|
-
|
78
|
-
class ConnectionResetError < Errno::ECONNRESET
|
79
|
-
include ConnectionError
|
80
|
-
end
|
81
|
-
|
82
|
-
# DatabaseError was replaced by ProtocolError, but we'll keep it around as an
|
83
|
-
# ancestor of ProtocolError for compatibility reasons (e.g. so `rescue DatabaseError`
|
84
|
-
# still works. We can remove this class in the next major release.
|
85
|
-
module DatabaseError
|
86
|
-
end
|
87
|
-
|
88
|
-
class ProtocolError < BaseError
|
89
|
-
include DatabaseError
|
90
|
-
|
91
|
-
ERROR_CODES = {
|
92
|
-
1205 => TimeoutError, # ER_LOCK_WAIT_TIMEOUT
|
93
|
-
1044 => BaseConnectionError, # ER_DBACCESS_DENIED_ERROR
|
94
|
-
1045 => BaseConnectionError, # ER_ACCESS_DENIED_ERROR
|
95
|
-
1064 => QueryError, # ER_PARSE_ERROR
|
96
|
-
1152 => BaseConnectionError, # ER_ABORTING_CONNECTION
|
97
|
-
1153 => BaseConnectionError, # ER_NET_PACKET_TOO_LARGE
|
98
|
-
1154 => BaseConnectionError, # ER_NET_READ_ERROR_FROM_PIPE
|
99
|
-
1155 => BaseConnectionError, # ER_NET_FCNTL_ERROR
|
100
|
-
1156 => BaseConnectionError, # ER_NET_PACKETS_OUT_OF_ORDER
|
101
|
-
1157 => BaseConnectionError, # ER_NET_UNCOMPRESS_ERROR
|
102
|
-
1158 => BaseConnectionError, # ER_NET_READ_ERROR
|
103
|
-
1159 => BaseConnectionError, # ER_NET_READ_INTERRUPTED
|
104
|
-
1160 => BaseConnectionError, # ER_NET_ERROR_ON_WRITE
|
105
|
-
1161 => BaseConnectionError, # ER_NET_WRITE_INTERRUPTED
|
106
|
-
1927 => BaseConnectionError, # ER_CONNECTION_KILLED
|
107
|
-
}
|
108
|
-
class << self
|
109
|
-
def from_code(message, code)
|
110
|
-
ERROR_CODES.fetch(code, self).new(message, code)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
class SSLError < BaseError
|
116
|
-
include ConnectionError
|
117
|
-
end
|
118
|
-
|
119
|
-
class ConnectionClosed < IOError
|
120
|
-
include ConnectionError
|
121
|
-
end
|
122
|
-
|
123
|
-
MYSQL_TO_RUBY_ENCODINGS_MAP = {
|
124
|
-
"big5" => "Big5",
|
125
|
-
"dec8" => nil,
|
126
|
-
"cp850" => "CP850",
|
127
|
-
"hp8" => nil,
|
128
|
-
"koi8r" => "KOI8-R",
|
129
|
-
"latin1" => "ISO-8859-1",
|
130
|
-
"latin2" => "ISO-8859-2",
|
131
|
-
"swe7" => nil,
|
132
|
-
"ascii" => "US-ASCII",
|
133
|
-
"ujis" => "eucJP-ms",
|
134
|
-
"sjis" => "Shift_JIS",
|
135
|
-
"hebrew" => "ISO-8859-8",
|
136
|
-
"tis620" => "TIS-620",
|
137
|
-
"euckr" => "EUC-KR",
|
138
|
-
"koi8u" => "KOI8-R",
|
139
|
-
"gb2312" => "GB2312",
|
140
|
-
"greek" => "ISO-8859-7",
|
141
|
-
"cp1250" => "Windows-1250",
|
142
|
-
"gbk" => "GBK",
|
143
|
-
"latin5" => "ISO-8859-9",
|
144
|
-
"armscii8" => nil,
|
145
|
-
"utf8" => "UTF-8",
|
146
|
-
"ucs2" => "UTF-16BE",
|
147
|
-
"cp866" => "IBM866",
|
148
|
-
"keybcs2" => nil,
|
149
|
-
"macce" => "macCentEuro",
|
150
|
-
"macroman" => "macRoman",
|
151
|
-
"cp852" => "CP852",
|
152
|
-
"latin7" => "ISO-8859-13",
|
153
|
-
"utf8mb4" => "UTF-8",
|
154
|
-
"cp1251" => "Windows-1251",
|
155
|
-
"utf16" => "UTF-16",
|
156
|
-
"cp1256" => "Windows-1256",
|
157
|
-
"cp1257" => "Windows-1257",
|
158
|
-
"utf32" => "UTF-32",
|
159
|
-
"binary" => "ASCII-8BIT",
|
160
|
-
"geostd8" => nil,
|
161
|
-
"cp932" => "Windows-31J",
|
162
|
-
"eucjpms" => "eucJP-ms",
|
163
|
-
"utf16le" => "UTF-16LE",
|
164
|
-
"gb18030" => "GB18030",
|
165
|
-
}.freeze
|
166
|
-
|
167
10
|
def initialize(options = {})
|
11
|
+
options[:port] = options[:port].to_i if options[:port]
|
168
12
|
mysql_encoding = options[:encoding] || "utf8mb4"
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
encoding
|
173
|
-
charset = charset_for_mysql_encoding(mysql_encoding)
|
174
|
-
_initialize(encoding, charset, **options)
|
13
|
+
encoding = Trilogy::Encoding.find(mysql_encoding)
|
14
|
+
charset = Trilogy::Encoding.charset(mysql_encoding)
|
15
|
+
|
16
|
+
_initialize(encoding, charset, options)
|
175
17
|
end
|
176
18
|
|
177
19
|
def connection_options
|
@@ -204,81 +46,4 @@ class Trilogy
|
|
204
46
|
ensure
|
205
47
|
self.query_flags = old_flags
|
206
48
|
end
|
207
|
-
|
208
|
-
class Result
|
209
|
-
attr_reader :fields, :rows, :query_time, :affected_rows, :last_insert_id
|
210
|
-
|
211
|
-
def count
|
212
|
-
rows.count
|
213
|
-
end
|
214
|
-
|
215
|
-
def each_hash
|
216
|
-
return enum_for(:each_hash) unless block_given?
|
217
|
-
|
218
|
-
rows.each do |row|
|
219
|
-
this_row = {}
|
220
|
-
|
221
|
-
idx = 0
|
222
|
-
row.each do |col|
|
223
|
-
this_row[fields[idx]] = col
|
224
|
-
idx += 1
|
225
|
-
end
|
226
|
-
|
227
|
-
yield this_row
|
228
|
-
end
|
229
|
-
|
230
|
-
self
|
231
|
-
end
|
232
|
-
|
233
|
-
def each(&bk)
|
234
|
-
rows.each(&bk)
|
235
|
-
end
|
236
|
-
|
237
|
-
include Enumerable
|
238
|
-
end
|
239
|
-
|
240
|
-
private
|
241
|
-
|
242
|
-
def charset_for_mysql_encoding(mysql_encoding)
|
243
|
-
@mysql_encodings_map ||= {
|
244
|
-
"big5" => CHARSET_BIG5_CHINESE_CI,
|
245
|
-
"cp850" => CHARSET_CP850_GENERAL_CI,
|
246
|
-
"koi8r" => CHARSET_KOI8R_GENERAL_CI,
|
247
|
-
"latin1" => CHARSET_LATIN1_GENERAL_CI,
|
248
|
-
"latin2" => CHARSET_LATIN2_GENERAL_CI,
|
249
|
-
"ascii" => CHARSET_ASCII_GENERAL_CI,
|
250
|
-
"ujis" => CHARSET_UJIS_JAPANESE_CI,
|
251
|
-
"sjis" => CHARSET_SJIS_JAPANESE_CI,
|
252
|
-
"hebrew" => CHARSET_HEBREW_GENERAL_CI,
|
253
|
-
"tis620" => CHARSET_TIS620_THAI_CI,
|
254
|
-
"euckr" => CHARSET_EUCKR_KOREAN_CI,
|
255
|
-
"koi8u" => CHARSET_KOI8U_GENERAL_CI,
|
256
|
-
"gb2312" => CHARSET_GB2312_CHINESE_CI,
|
257
|
-
"greek" => CHARSET_GREEK_GENERAL_CI,
|
258
|
-
"cp1250" => CHARSET_CP1250_GENERAL_CI,
|
259
|
-
"gbk" => CHARSET_GBK_CHINESE_CI,
|
260
|
-
"latin5" => CHARSET_LATIN5_TURKISH_CI,
|
261
|
-
"utf8" => CHARSET_UTF8_GENERAL_CI,
|
262
|
-
"ucs2" => CHARSET_UCS2_GENERAL_CI,
|
263
|
-
"cp866" => CHARSET_CP866_GENERAL_CI,
|
264
|
-
"cp932" => CHARSET_CP932_JAPANESE_CI,
|
265
|
-
"eucjpms" => CHARSET_EUCJPMS_JAPANESE_CI,
|
266
|
-
"utf16le" => CHARSET_UTF16_GENERAL_CI,
|
267
|
-
"gb18030" => CHARSET_GB18030_CHINESE_CI,
|
268
|
-
"macce" => CHARSET_MACCE_GENERAL_CI,
|
269
|
-
"macroman" => CHARSET_MACROMAN_GENERAL_CI,
|
270
|
-
"cp852" => CHARSET_CP852_GENERAL_CI,
|
271
|
-
"latin7" => CHARSET_LATIN7_GENERAL_CI,
|
272
|
-
"utf8mb4" => CHARSET_UTF8MB4_GENERAL_CI,
|
273
|
-
"cp1251" => CHARSET_CP1251_GENERAL_CI,
|
274
|
-
"utf16" => CHARSET_UTF16_GENERAL_CI,
|
275
|
-
"cp1256" => CHARSET_CP1256_GENERAL_CI,
|
276
|
-
"cp1257" => CHARSET_CP1257_GENERAL_CI,
|
277
|
-
"utf32" => CHARSET_UTF32_GENERAL_CI,
|
278
|
-
"binary" => CHARSET_BINARY,
|
279
|
-
}.freeze
|
280
|
-
@mysql_encodings_map[mysql_encoding]
|
281
|
-
end
|
282
49
|
end
|
283
|
-
|
284
|
-
require "trilogy/cext"
|
data/trilogy.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.authors = ["GitHub Engineering"]
|
7
7
|
s.email = "opensource+trilogy@github.com"
|
8
8
|
s.license = "MIT"
|
9
|
-
s.homepage = "https://github.com/
|
9
|
+
s.homepage = "https://github.com/trilogy-libraries/trilogy"
|
10
10
|
s.summary = "A friendly MySQL-compatible library for Ruby, binding to libtrilogy"
|
11
11
|
|
12
12
|
s.extensions = "ext/trilogy-ruby/extconf.rb"
|
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.6.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: 2023-
|
11
|
+
date: 2023-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -78,9 +78,12 @@ files:
|
|
78
78
|
- ext/trilogy-ruby/src/vendor/openssl_hostname_validation.c
|
79
79
|
- ext/trilogy-ruby/trilogy-ruby.h
|
80
80
|
- lib/trilogy.rb
|
81
|
+
- lib/trilogy/encoding.rb
|
82
|
+
- lib/trilogy/error.rb
|
83
|
+
- lib/trilogy/result.rb
|
81
84
|
- lib/trilogy/version.rb
|
82
85
|
- trilogy.gemspec
|
83
|
-
homepage: https://github.com/
|
86
|
+
homepage: https://github.com/trilogy-libraries/trilogy
|
84
87
|
licenses:
|
85
88
|
- MIT
|
86
89
|
metadata: {}
|
@@ -99,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
102
|
- !ruby/object:Gem::Version
|
100
103
|
version: '0'
|
101
104
|
requirements: []
|
102
|
-
rubygems_version: 3.4.
|
105
|
+
rubygems_version: 3.4.10
|
103
106
|
signing_key:
|
104
107
|
specification_version: 4
|
105
108
|
summary: A friendly MySQL-compatible library for Ruby, binding to libtrilogy
|