trilogy 2.4.1 → 2.5.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 +14 -5
- data/Rakefile +6 -0
- data/ext/trilogy-ruby/cast.c +0 -4
- data/ext/trilogy-ruby/cext.c +110 -33
- 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 +96 -39
- data/lib/trilogy/encoding.rb +97 -0
- data/lib/trilogy/error.rb +118 -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 +6 -3
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.key?(: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.5.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-08-16 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: {}
|