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.
Files changed (50) hide show
  1. data/.gitignore +12 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/CHANGELOG.md +142 -0
  5. data/Gemfile +3 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.rdoc +261 -0
  8. data/Rakefile +5 -0
  9. data/benchmark/active_record.rb +51 -0
  10. data/benchmark/active_record_threaded.rb +42 -0
  11. data/benchmark/allocations.rb +33 -0
  12. data/benchmark/escape.rb +36 -0
  13. data/benchmark/query_with_mysql_casting.rb +80 -0
  14. data/benchmark/query_without_mysql_casting.rb +47 -0
  15. data/benchmark/sequel.rb +37 -0
  16. data/benchmark/setup_db.rb +119 -0
  17. data/benchmark/threaded.rb +44 -0
  18. data/examples/eventmachine.rb +21 -0
  19. data/examples/threaded.rb +20 -0
  20. data/ext/mysql2/client.c +839 -0
  21. data/ext/mysql2/client.h +41 -0
  22. data/ext/mysql2/extconf.rb +72 -0
  23. data/ext/mysql2/mysql2_ext.c +12 -0
  24. data/ext/mysql2/mysql2_ext.h +42 -0
  25. data/ext/mysql2/result.c +488 -0
  26. data/ext/mysql2/result.h +20 -0
  27. data/lib/active_record/connection_adapters/em_mysql2_adapter.rb +64 -0
  28. data/lib/active_record/connection_adapters/mysql2_adapter.rb +654 -0
  29. data/lib/active_record/fiber_patches.rb +104 -0
  30. data/lib/arel/engines/sql/compilers/mysql2_compiler.rb +11 -0
  31. data/lib/mysql2.rb +16 -0
  32. data/lib/mysql2/client.rb +240 -0
  33. data/lib/mysql2/em.rb +37 -0
  34. data/lib/mysql2/em_fiber.rb +31 -0
  35. data/lib/mysql2/error.rb +15 -0
  36. data/lib/mysql2/result.rb +5 -0
  37. data/lib/mysql2/version.rb +3 -0
  38. data/mysql2.gemspec +32 -0
  39. data/spec/em/em_fiber_spec.rb +22 -0
  40. data/spec/em/em_spec.rb +49 -0
  41. data/spec/mysql2/client_spec.rb +430 -0
  42. data/spec/mysql2/error_spec.rb +69 -0
  43. data/spec/mysql2/result_spec.rb +333 -0
  44. data/spec/rcov.opts +3 -0
  45. data/spec/spec_helper.rb +66 -0
  46. data/tasks/benchmarks.rake +20 -0
  47. data/tasks/compile.rake +71 -0
  48. data/tasks/rspec.rake +16 -0
  49. data/tasks/vendor_mysql.rake +40 -0
  50. 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
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module SqlCompiler
3
+ class Mysql2Compiler < GenericCompiler
4
+ def limited_update_conditions(conditions, taken)
5
+ conditions << " LIMIT #{taken}"
6
+ conditions
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -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
@@ -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
@@ -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