rdp-mysql2 0.2.7.1
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.
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/CHANGELOG.md +142 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +261 -0
- data/Rakefile +5 -0
- data/benchmark/active_record.rb +51 -0
- data/benchmark/active_record_threaded.rb +42 -0
- data/benchmark/allocations.rb +33 -0
- data/benchmark/escape.rb +36 -0
- data/benchmark/query_with_mysql_casting.rb +80 -0
- data/benchmark/query_without_mysql_casting.rb +47 -0
- data/benchmark/sequel.rb +37 -0
- data/benchmark/setup_db.rb +119 -0
- data/benchmark/threaded.rb +44 -0
- data/examples/eventmachine.rb +21 -0
- data/examples/threaded.rb +20 -0
- data/ext/mysql2/client.c +839 -0
- data/ext/mysql2/client.h +41 -0
- data/ext/mysql2/extconf.rb +72 -0
- data/ext/mysql2/mysql2_ext.c +12 -0
- data/ext/mysql2/mysql2_ext.h +42 -0
- data/ext/mysql2/result.c +488 -0
- data/ext/mysql2/result.h +20 -0
- data/lib/active_record/connection_adapters/em_mysql2_adapter.rb +64 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +654 -0
- data/lib/active_record/fiber_patches.rb +104 -0
- data/lib/arel/engines/sql/compilers/mysql2_compiler.rb +11 -0
- data/lib/mysql2.rb +16 -0
- data/lib/mysql2/client.rb +240 -0
- data/lib/mysql2/em.rb +37 -0
- data/lib/mysql2/em_fiber.rb +31 -0
- data/lib/mysql2/error.rb +15 -0
- data/lib/mysql2/result.rb +5 -0
- data/lib/mysql2/version.rb +3 -0
- data/mysql2.gemspec +32 -0
- data/spec/em/em_fiber_spec.rb +22 -0
- data/spec/em/em_spec.rb +49 -0
- data/spec/mysql2/client_spec.rb +430 -0
- data/spec/mysql2/error_spec.rb +69 -0
- data/spec/mysql2/result_spec.rb +333 -0
- data/spec/rcov.opts +3 -0
- data/spec/spec_helper.rb +66 -0
- data/tasks/benchmarks.rake +20 -0
- data/tasks/compile.rake +71 -0
- data/tasks/rspec.rake +16 -0
- data/tasks/vendor_mysql.rake +40 -0
- metadata +236 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
# Necessary monkeypatching to make AR fiber-friendly.
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
|
6
|
+
def self.fiber_pools
|
7
|
+
@fiber_pools ||= []
|
8
|
+
end
|
9
|
+
def self.register_fiber_pool(fp)
|
10
|
+
fiber_pools << fp
|
11
|
+
end
|
12
|
+
|
13
|
+
class FiberedMonitor
|
14
|
+
class Queue
|
15
|
+
def initialize
|
16
|
+
@queue = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def wait(timeout)
|
20
|
+
t = timeout || 5
|
21
|
+
fiber = Fiber.current
|
22
|
+
x = EM::Timer.new(t) do
|
23
|
+
@queue.delete(fiber)
|
24
|
+
fiber.resume(false)
|
25
|
+
end
|
26
|
+
@queue << fiber
|
27
|
+
Fiber.yield.tap do
|
28
|
+
x.cancel
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def signal
|
33
|
+
fiber = @queue.pop
|
34
|
+
fiber.resume(true) if fiber
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def synchronize
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
def new_cond
|
43
|
+
Queue.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# ActiveRecord's connection pool is based on threads. Since we are working
|
48
|
+
# with EM and a single thread, multiple fiber design, we need to provide
|
49
|
+
# our own connection pool that keys off of Fiber.current so that different
|
50
|
+
# fibers running in the same thread don't try to use the same connection.
|
51
|
+
class ConnectionPool
|
52
|
+
def initialize(spec)
|
53
|
+
@spec = spec
|
54
|
+
|
55
|
+
# The cache of reserved connections mapped to threads
|
56
|
+
@reserved_connections = {}
|
57
|
+
|
58
|
+
# The mutex used to synchronize pool access
|
59
|
+
@connection_mutex = FiberedMonitor.new
|
60
|
+
@queue = @connection_mutex.new_cond
|
61
|
+
|
62
|
+
# default 5 second timeout unless on ruby 1.9
|
63
|
+
@timeout = spec.config[:wait_timeout] || 5
|
64
|
+
|
65
|
+
# default max pool size to 5
|
66
|
+
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
67
|
+
|
68
|
+
@connections = []
|
69
|
+
@checked_out = []
|
70
|
+
end
|
71
|
+
|
72
|
+
def clear_stale_cached_connections!
|
73
|
+
cache = @reserved_connections
|
74
|
+
keys = Set.new(cache.keys)
|
75
|
+
|
76
|
+
ActiveRecord::ConnectionAdapters.fiber_pools.each do |pool|
|
77
|
+
pool.busy_fibers.each_pair do |object_id, fiber|
|
78
|
+
keys.delete(object_id)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
keys.each do |key|
|
83
|
+
next unless cache.has_key?(key)
|
84
|
+
checkin cache[key]
|
85
|
+
cache.delete(key)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def current_connection_id #:nodoc:
|
92
|
+
Fiber.current.object_id
|
93
|
+
end
|
94
|
+
|
95
|
+
def checkout_and_verify(c)
|
96
|
+
@checked_out << c
|
97
|
+
c.run_callbacks :checkout
|
98
|
+
c.verify!
|
99
|
+
c
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/lib/mysql2.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'date'
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'rational' unless RUBY_VERSION >= '1.9.2'
|
5
|
+
|
6
|
+
require 'mysql2/version' unless defined? Mysql2::VERSION
|
7
|
+
require 'mysql2/error'
|
8
|
+
require 'mysql2/mysql2'
|
9
|
+
require 'mysql2/client'
|
10
|
+
require 'mysql2/result'
|
11
|
+
|
12
|
+
# = Mysql2
|
13
|
+
#
|
14
|
+
# A modern, simple and very fast Mysql library for Ruby - binding to libmysql
|
15
|
+
module Mysql2
|
16
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
module Mysql2
|
2
|
+
class Client
|
3
|
+
attr_reader :query_options
|
4
|
+
@@default_query_options = {
|
5
|
+
:as => :hash, # the type of object you want each row back as; also supports :array (an array of values)
|
6
|
+
:async => false, # don't wait for a result after sending the query, you'll have to monitor the socket yourself then eventually call Mysql2::Client#async_result
|
7
|
+
:cast_booleans => false, # cast tinyint(1) fields as true/false in ruby
|
8
|
+
:symbolize_keys => false, # return field names as symbols instead of strings
|
9
|
+
:database_timezone => :local, # timezone Mysql2 will assume datetime objects are stored in
|
10
|
+
:application_timezone => nil, # timezone Mysql2 will convert to before handing the object back to the caller
|
11
|
+
:cache_rows => true, # tells Mysql2 to use it's internal row cache for results
|
12
|
+
:connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(opts = {})
|
16
|
+
@query_options = @@default_query_options.dup
|
17
|
+
|
18
|
+
init_connection
|
19
|
+
|
20
|
+
[:reconnect, :connect_timeout].each do |key|
|
21
|
+
next unless opts.key?(key)
|
22
|
+
send(:"#{key}=", opts[key])
|
23
|
+
end
|
24
|
+
# force the encoding to utf8
|
25
|
+
self.charset_name = opts[:encoding] || 'utf8'
|
26
|
+
|
27
|
+
@read_timeout = opts[:read_timeout]
|
28
|
+
if @read_timeout and @read_timeout < 0
|
29
|
+
raise Mysql2::Error, "read_timeout must be a positive integer, you passed #{@read_timeout}"
|
30
|
+
end
|
31
|
+
|
32
|
+
ssl_set(*opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslciper))
|
33
|
+
|
34
|
+
user = opts[:username]
|
35
|
+
pass = opts[:password]
|
36
|
+
host = opts[:host] || 'localhost'
|
37
|
+
port = opts[:port] || 3306
|
38
|
+
database = opts[:database]
|
39
|
+
socket = opts[:socket]
|
40
|
+
flags = opts[:flags] ? opts[:flags] | @query_options[:connect_flags] : @query_options[:connect_flags]
|
41
|
+
|
42
|
+
connect user, pass, host, port, database, socket, flags
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.default_query_options
|
46
|
+
@@default_query_options
|
47
|
+
end
|
48
|
+
|
49
|
+
# NOTE: from ruby-mysql
|
50
|
+
if defined? Encoding
|
51
|
+
CHARSET_MAP = {
|
52
|
+
"armscii8" => nil,
|
53
|
+
"ascii" => Encoding::US_ASCII,
|
54
|
+
"big5" => Encoding::Big5,
|
55
|
+
"binary" => Encoding::ASCII_8BIT,
|
56
|
+
"cp1250" => Encoding::Windows_1250,
|
57
|
+
"cp1251" => Encoding::Windows_1251,
|
58
|
+
"cp1256" => Encoding::Windows_1256,
|
59
|
+
"cp1257" => Encoding::Windows_1257,
|
60
|
+
"cp850" => Encoding::CP850,
|
61
|
+
"cp852" => Encoding::CP852,
|
62
|
+
"cp866" => Encoding::IBM866,
|
63
|
+
"cp932" => Encoding::Windows_31J,
|
64
|
+
"dec8" => nil,
|
65
|
+
"eucjpms" => Encoding::EucJP_ms,
|
66
|
+
"euckr" => Encoding::EUC_KR,
|
67
|
+
"gb2312" => Encoding::EUC_CN,
|
68
|
+
"gbk" => Encoding::GBK,
|
69
|
+
"geostd8" => nil,
|
70
|
+
"greek" => Encoding::ISO_8859_7,
|
71
|
+
"hebrew" => Encoding::ISO_8859_8,
|
72
|
+
"hp8" => nil,
|
73
|
+
"keybcs2" => nil,
|
74
|
+
"koi8r" => Encoding::KOI8_R,
|
75
|
+
"koi8u" => Encoding::KOI8_U,
|
76
|
+
"latin1" => Encoding::ISO_8859_1,
|
77
|
+
"latin2" => Encoding::ISO_8859_2,
|
78
|
+
"latin5" => Encoding::ISO_8859_9,
|
79
|
+
"latin7" => Encoding::ISO_8859_13,
|
80
|
+
"macce" => Encoding::MacCentEuro,
|
81
|
+
"macroman" => Encoding::MacRoman,
|
82
|
+
"sjis" => Encoding::SHIFT_JIS,
|
83
|
+
"swe7" => nil,
|
84
|
+
"tis620" => Encoding::TIS_620,
|
85
|
+
"ucs2" => Encoding::UTF_16BE,
|
86
|
+
"ujis" => Encoding::EucJP_ms,
|
87
|
+
"utf8" => Encoding::UTF_8,
|
88
|
+
}
|
89
|
+
|
90
|
+
MYSQL_CHARSET_MAP = {
|
91
|
+
1 => {:name => "big5", :collation => "big5_chinese_ci"},
|
92
|
+
2 => {:name => "latin2", :collation => "latin2_czech_cs"},
|
93
|
+
3 => {:name => "dec8", :collation => "dec8_swedish_ci"},
|
94
|
+
4 => {:name => "cp850", :collation => "cp850_general_ci"},
|
95
|
+
5 => {:name => "latin1", :collation => "latin1_german1_ci"},
|
96
|
+
6 => {:name => "hp8", :collation => "hp8_english_ci"},
|
97
|
+
7 => {:name => "koi8r", :collation => "koi8r_general_ci"},
|
98
|
+
8 => {:name => "latin1", :collation => "latin1_swedish_ci"},
|
99
|
+
9 => {:name => "latin2", :collation => "latin2_general_ci"},
|
100
|
+
10 => {:name => "swe7", :collation => "swe7_swedish_ci"},
|
101
|
+
11 => {:name => "ascii", :collation => "ascii_general_ci"},
|
102
|
+
12 => {:name => "ujis", :collation => "ujis_japanese_ci"},
|
103
|
+
13 => {:name => "sjis", :collation => "sjis_japanese_ci"},
|
104
|
+
14 => {:name => "cp1251", :collation => "cp1251_bulgarian_ci"},
|
105
|
+
15 => {:name => "latin1", :collation => "latin1_danish_ci"},
|
106
|
+
16 => {:name => "hebrew", :collation => "hebrew_general_ci"},
|
107
|
+
17 => {:name => "filename", :collation => "filename"},
|
108
|
+
18 => {:name => "tis620", :collation => "tis620_thai_ci"},
|
109
|
+
19 => {:name => "euckr", :collation => "euckr_korean_ci"},
|
110
|
+
20 => {:name => "latin7", :collation => "latin7_estonian_cs"},
|
111
|
+
21 => {:name => "latin2", :collation => "latin2_hungarian_ci"},
|
112
|
+
22 => {:name => "koi8u", :collation => "koi8u_general_ci"},
|
113
|
+
23 => {:name => "cp1251", :collation => "cp1251_ukrainian_ci"},
|
114
|
+
24 => {:name => "gb2312", :collation => "gb2312_chinese_ci"},
|
115
|
+
25 => {:name => "greek", :collation => "greek_general_ci"},
|
116
|
+
26 => {:name => "cp1250", :collation => "cp1250_general_ci"},
|
117
|
+
27 => {:name => "latin2", :collation => "latin2_croatian_ci"},
|
118
|
+
28 => {:name => "gbk", :collation => "gbk_chinese_ci"},
|
119
|
+
29 => {:name => "cp1257", :collation => "cp1257_lithuanian_ci"},
|
120
|
+
30 => {:name => "latin5", :collation => "latin5_turkish_ci"},
|
121
|
+
31 => {:name => "latin1", :collation => "latin1_german2_ci"},
|
122
|
+
32 => {:name => "armscii8", :collation => "armscii8_general_ci"},
|
123
|
+
33 => {:name => "utf8", :collation => "utf8_general_ci"},
|
124
|
+
34 => {:name => "cp1250", :collation => "cp1250_czech_cs"},
|
125
|
+
35 => {:name => "ucs2", :collation => "ucs2_general_ci"},
|
126
|
+
36 => {:name => "cp866", :collation => "cp866_general_ci"},
|
127
|
+
37 => {:name => "keybcs2", :collation => "keybcs2_general_ci"},
|
128
|
+
38 => {:name => "macce", :collation => "macce_general_ci"},
|
129
|
+
39 => {:name => "macroman", :collation => "macroman_general_ci"},
|
130
|
+
40 => {:name => "cp852", :collation => "cp852_general_ci"},
|
131
|
+
41 => {:name => "latin7", :collation => "latin7_general_ci"},
|
132
|
+
42 => {:name => "latin7", :collation => "latin7_general_cs"},
|
133
|
+
43 => {:name => "macce", :collation => "macce_bin"},
|
134
|
+
44 => {:name => "cp1250", :collation => "cp1250_croatian_ci"},
|
135
|
+
47 => {:name => "latin1", :collation => "latin1_bin"},
|
136
|
+
48 => {:name => "latin1", :collation => "latin1_general_ci"},
|
137
|
+
49 => {:name => "latin1", :collation => "latin1_general_cs"},
|
138
|
+
50 => {:name => "cp1251", :collation => "cp1251_bin"},
|
139
|
+
51 => {:name => "cp1251", :collation => "cp1251_general_ci"},
|
140
|
+
52 => {:name => "cp1251", :collation => "cp1251_general_cs"},
|
141
|
+
53 => {:name => "macroman", :collation => "macroman_bin"},
|
142
|
+
57 => {:name => "cp1256", :collation => "cp1256_general_ci"},
|
143
|
+
58 => {:name => "cp1257", :collation => "cp1257_bin"},
|
144
|
+
59 => {:name => "cp1257", :collation => "cp1257_general_ci"},
|
145
|
+
63 => {:name => "binary", :collation => "binary"},
|
146
|
+
64 => {:name => "armscii8", :collation => "armscii8_bin"},
|
147
|
+
65 => {:name => "ascii", :collation => "ascii_bin"},
|
148
|
+
66 => {:name => "cp1250", :collation => "cp1250_bin"},
|
149
|
+
67 => {:name => "cp1256", :collation => "cp1256_bin"},
|
150
|
+
68 => {:name => "cp866", :collation => "cp866_bin"},
|
151
|
+
69 => {:name => "dec8", :collation => "dec8_bin"},
|
152
|
+
70 => {:name => "greek", :collation => "greek_bin"},
|
153
|
+
71 => {:name => "hebrew", :collation => "hebrew_bin"},
|
154
|
+
72 => {:name => "hp8", :collation => "hp8_bin"},
|
155
|
+
73 => {:name => "keybcs2", :collation => "keybcs2_bin"},
|
156
|
+
74 => {:name => "koi8r", :collation => "koi8r_bin"},
|
157
|
+
75 => {:name => "koi8u", :collation => "koi8u_bin"},
|
158
|
+
77 => {:name => "latin2", :collation => "latin2_bin"},
|
159
|
+
78 => {:name => "latin5", :collation => "latin5_bin"},
|
160
|
+
79 => {:name => "latin7", :collation => "latin7_bin"},
|
161
|
+
80 => {:name => "cp850", :collation => "cp850_bin"},
|
162
|
+
81 => {:name => "cp852", :collation => "cp852_bin"},
|
163
|
+
82 => {:name => "swe7", :collation => "swe7_bin"},
|
164
|
+
83 => {:name => "utf8", :collation => "utf8_bin"},
|
165
|
+
84 => {:name => "big5", :collation => "big5_bin"},
|
166
|
+
85 => {:name => "euckr", :collation => "euckr_bin"},
|
167
|
+
86 => {:name => "gb2312", :collation => "gb2312_bin"},
|
168
|
+
87 => {:name => "gbk", :collation => "gbk_bin"},
|
169
|
+
88 => {:name => "sjis", :collation => "sjis_bin"},
|
170
|
+
89 => {:name => "tis620", :collation => "tis620_bin"},
|
171
|
+
90 => {:name => "ucs2", :collation => "ucs2_bin"},
|
172
|
+
91 => {:name => "ujis", :collation => "ujis_bin"},
|
173
|
+
92 => {:name => "geostd8", :collation => "geostd8_general_ci"},
|
174
|
+
93 => {:name => "geostd8", :collation => "geostd8_bin"},
|
175
|
+
94 => {:name => "latin1", :collation => "latin1_spanish_ci"},
|
176
|
+
95 => {:name => "cp932", :collation => "cp932_japanese_ci"},
|
177
|
+
96 => {:name => "cp932", :collation => "cp932_bin"},
|
178
|
+
97 => {:name => "eucjpms", :collation => "eucjpms_japanese_ci"},
|
179
|
+
98 => {:name => "eucjpms", :collation => "eucjpms_bin"},
|
180
|
+
99 => {:name => "cp1250", :collation => "cp1250_polish_ci"},
|
181
|
+
128 => {:name => "ucs2", :collation => "ucs2_unicode_ci"},
|
182
|
+
129 => {:name => "ucs2", :collation => "ucs2_icelandic_ci"},
|
183
|
+
130 => {:name => "ucs2", :collation => "ucs2_latvian_ci"},
|
184
|
+
131 => {:name => "ucs2", :collation => "ucs2_romanian_ci"},
|
185
|
+
132 => {:name => "ucs2", :collation => "ucs2_slovenian_ci"},
|
186
|
+
133 => {:name => "ucs2", :collation => "ucs2_polish_ci"},
|
187
|
+
134 => {:name => "ucs2", :collation => "ucs2_estonian_ci"},
|
188
|
+
135 => {:name => "ucs2", :collation => "ucs2_spanish_ci"},
|
189
|
+
136 => {:name => "ucs2", :collation => "ucs2_swedish_ci"},
|
190
|
+
137 => {:name => "ucs2", :collation => "ucs2_turkish_ci"},
|
191
|
+
138 => {:name => "ucs2", :collation => "ucs2_czech_ci"},
|
192
|
+
139 => {:name => "ucs2", :collation => "ucs2_danish_ci"},
|
193
|
+
140 => {:name => "ucs2", :collation => "ucs2_lithuanian_ci"},
|
194
|
+
141 => {:name => "ucs2", :collation => "ucs2_slovak_ci"},
|
195
|
+
142 => {:name => "ucs2", :collation => "ucs2_spanish2_ci"},
|
196
|
+
143 => {:name => "ucs2", :collation => "ucs2_roman_ci"},
|
197
|
+
144 => {:name => "ucs2", :collation => "ucs2_persian_ci"},
|
198
|
+
145 => {:name => "ucs2", :collation => "ucs2_esperanto_ci"},
|
199
|
+
146 => {:name => "ucs2", :collation => "ucs2_hungarian_ci"},
|
200
|
+
192 => {:name => "utf8", :collation => "utf8_unicode_ci"},
|
201
|
+
193 => {:name => "utf8", :collation => "utf8_icelandic_ci"},
|
202
|
+
194 => {:name => "utf8", :collation => "utf8_latvian_ci"},
|
203
|
+
195 => {:name => "utf8", :collation => "utf8_romanian_ci"},
|
204
|
+
196 => {:name => "utf8", :collation => "utf8_slovenian_ci"},
|
205
|
+
197 => {:name => "utf8", :collation => "utf8_polish_ci"},
|
206
|
+
198 => {:name => "utf8", :collation => "utf8_estonian_ci"},
|
207
|
+
199 => {:name => "utf8", :collation => "utf8_spanish_ci"},
|
208
|
+
200 => {:name => "utf8", :collation => "utf8_swedish_ci"},
|
209
|
+
201 => {:name => "utf8", :collation => "utf8_turkish_ci"},
|
210
|
+
202 => {:name => "utf8", :collation => "utf8_czech_ci"},
|
211
|
+
203 => {:name => "utf8", :collation => "utf8_danish_ci"},
|
212
|
+
204 => {:name => "utf8", :collation => "utf8_lithuanian_ci"},
|
213
|
+
205 => {:name => "utf8", :collation => "utf8_slovak_ci"},
|
214
|
+
206 => {:name => "utf8", :collation => "utf8_spanish2_ci"},
|
215
|
+
207 => {:name => "utf8", :collation => "utf8_roman_ci"},
|
216
|
+
208 => {:name => "utf8", :collation => "utf8_persian_ci"},
|
217
|
+
209 => {:name => "utf8", :collation => "utf8_esperanto_ci"},
|
218
|
+
210 => {:name => "utf8", :collation => "utf8_hungarian_ci"},
|
219
|
+
254 => {:name => "utf8", :collation => "utf8_general_cs"}
|
220
|
+
}
|
221
|
+
|
222
|
+
def self.encoding_from_charset(charset)
|
223
|
+
CHARSET_MAP[charset.to_s.downcase]
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.encoding_from_charset_code(code)
|
227
|
+
if mapping = MYSQL_CHARSET_MAP[code]
|
228
|
+
encoding_from_charset(mapping[:name])
|
229
|
+
else
|
230
|
+
nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
def self.local_offset
|
237
|
+
::Time.local(2010).utc_offset.to_r / 86400
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
data/lib/mysql2/em.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
require 'mysql2'
|
5
|
+
|
6
|
+
module Mysql2
|
7
|
+
module EM
|
8
|
+
class Client < ::Mysql2::Client
|
9
|
+
module Watcher
|
10
|
+
def initialize(client, deferable)
|
11
|
+
@client = client
|
12
|
+
@deferable = deferable
|
13
|
+
end
|
14
|
+
|
15
|
+
def notify_readable
|
16
|
+
detach
|
17
|
+
begin
|
18
|
+
@deferable.succeed(@client.async_result)
|
19
|
+
rescue Exception => e
|
20
|
+
@deferable.fail(e)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def query(sql, opts={})
|
26
|
+
if ::EM.reactor_running?
|
27
|
+
super(sql, opts.merge(:async => true))
|
28
|
+
deferable = ::EM::DefaultDeferrable.new
|
29
|
+
::EM.watch(self.socket, Watcher, self, deferable).notify_readable = true
|
30
|
+
deferable
|
31
|
+
else
|
32
|
+
super(sql, opts)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mysql2/em'
|
4
|
+
require 'fiber'
|
5
|
+
|
6
|
+
module Mysql2
|
7
|
+
module EM
|
8
|
+
module Fiber
|
9
|
+
class Client < ::Mysql2::EM::Client
|
10
|
+
def query(sql, opts={})
|
11
|
+
if ::EM.reactor_running?
|
12
|
+
deferable = super(sql, opts)
|
13
|
+
|
14
|
+
fiber = ::Fiber.current
|
15
|
+
deferable.callback do |result|
|
16
|
+
fiber.resume(result)
|
17
|
+
end
|
18
|
+
deferable.errback do |err|
|
19
|
+
fiber.resume(err)
|
20
|
+
end
|
21
|
+
::Fiber.yield.tap do |result|
|
22
|
+
raise result if result.is_a?(::Exception)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
super(sql, opts)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/mysql2/error.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Mysql2
|
2
|
+
class Error < StandardError
|
3
|
+
attr_accessor :error_number, :sql_state
|
4
|
+
|
5
|
+
def initialize msg
|
6
|
+
super
|
7
|
+
@error_number = nil
|
8
|
+
@sql_state = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
# Mysql gem compatibility
|
12
|
+
alias_method :errno, :error_number
|
13
|
+
alias_method :error, :message
|
14
|
+
end
|
15
|
+
end
|