mysql2 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'spec_helper'
3
+ require 'rubygems'
3
4
  require 'active_record'
4
5
  require 'active_record/connection_adapters/mysql2_adapter'
5
6
 
@@ -28,6 +29,7 @@ describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
28
29
  context "columns" do
29
30
  before(:all) do
30
31
  ActiveRecord::Base.default_timezone = 'Pacific Time (US & Canada)'
32
+ ActiveRecord::Base.time_zone_aware_attributes = true
31
33
  ActiveRecord::Base.establish_connection(:adapter => 'mysql2', :database => 'test')
32
34
  Mysql2Test2.connection.execute %[
33
35
  CREATE TABLE IF NOT EXISTS mysql2_test2 (
@@ -123,9 +125,9 @@ describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
123
125
  test.double_test.should eql('1.0000'.to_f)
124
126
  test.decimal_test.should eql(BigDecimal.new('1.0000'))
125
127
  test.date_test.should eql(Date.parse('2010-01-01'))
126
- test.date_time_test.should eql(DateTime.parse('2010-01-01 00:00:00'))
128
+ test.date_time_test.should eql(Time.utc(2010,1,1,0,0,0))
127
129
  test.timestamp_test.class.should eql(ActiveSupport::TimeWithZone)
128
- test.time_test.class.should eql(ActiveSupport::TimeWithZone)
130
+ test.time_test.class.should eql(Time)
129
131
  test.year_test.should eql(2010)
130
132
  test.char_test.should eql('abcdefghij')
131
133
  test.varchar_test.should eql('abcdefghij')
@@ -144,4 +146,4 @@ describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
144
146
  test.set_test.should eql('val1,val2')
145
147
  end
146
148
  end
147
- end
149
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'spec_helper'
3
3
  require 'mysql2/em'
4
4
 
5
5
  describe Mysql2::EM::Client do
@@ -23,4 +23,4 @@ describe Mysql2::EM::Client do
23
23
  results[0].keys.should include("second_query")
24
24
  results[1].keys.should include("first_query")
25
25
  end
26
- end
26
+ end
@@ -1,11 +1,19 @@
1
1
  # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
  describe Mysql2::Client do
5
5
  before(:each) do
6
6
  @client = Mysql2::Client.new
7
7
  end
8
8
 
9
+ if defined? Encoding
10
+ it "should raise an exception on create for invalid encodings" do
11
+ lambda {
12
+ c = Mysql2::Client.new(:encoding => "fake")
13
+ }.should raise_error(Mysql2::Error)
14
+ end
15
+ end
16
+
9
17
  it "should be able to connect via SSL options" do
10
18
  pending("DON'T WORRY, THIS TEST PASSES :) - but is machine-specific. You need to have MySQL running with SSL configured and enabled. Then update the paths in this test to your needs and remove the pending state.")
11
19
  ssl_client = nil
@@ -74,6 +82,25 @@ describe Mysql2::Client do
74
82
  info[:version].class.should eql(String)
75
83
  end
76
84
 
85
+ if defined? Encoding
86
+ context "strings returned by #info" do
87
+ it "should default to the connection's encoding if Encoding.default_internal is nil" do
88
+ Encoding.default_internal = nil
89
+ @client.info[:version].encoding.should eql(Encoding.find('utf-8'))
90
+
91
+ client2 = Mysql2::Client.new :encoding => 'ascii'
92
+ client2.info[:version].encoding.should eql(Encoding.find('us-ascii'))
93
+ end
94
+
95
+ it "should use Encoding.default_internal" do
96
+ Encoding.default_internal = Encoding.find('utf-8')
97
+ @client.info[:version].encoding.should eql(Encoding.default_internal)
98
+ Encoding.default_internal = Encoding.find('us-ascii')
99
+ @client.info[:version].encoding.should eql(Encoding.default_internal)
100
+ end
101
+ end
102
+ end
103
+
77
104
  it "should respond to #server_info" do
78
105
  @client.should respond_to :server_info
79
106
  end
@@ -87,6 +114,25 @@ describe Mysql2::Client do
87
114
  server_info[:version].class.should eql(String)
88
115
  end
89
116
 
117
+ if defined? Encoding
118
+ context "strings returned by #server_info" do
119
+ it "should default to the connection's encoding if Encoding.default_internal is nil" do
120
+ Encoding.default_internal = nil
121
+ @client.server_info[:version].encoding.should eql(Encoding.find('utf-8'))
122
+
123
+ client2 = Mysql2::Client.new :encoding => 'ascii'
124
+ client2.server_info[:version].encoding.should eql(Encoding.find('us-ascii'))
125
+ end
126
+
127
+ it "should use Encoding.default_internal" do
128
+ Encoding.default_internal = Encoding.find('utf-8')
129
+ @client.server_info[:version].encoding.should eql(Encoding.default_internal)
130
+ Encoding.default_internal = Encoding.find('us-ascii')
131
+ @client.server_info[:version].encoding.should eql(Encoding.default_internal)
132
+ end
133
+ end
134
+ end
135
+
90
136
  it "should respond to #socket" do
91
137
  @client.should respond_to :socket
92
138
  end
@@ -158,4 +204,4 @@ describe Mysql2::Client do
158
204
  @client.affected_rows.should eql(1)
159
205
  end
160
206
  end
161
- end
207
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
  describe Mysql2::Error do
5
5
  before(:each) do
@@ -13,4 +13,4 @@ describe Mysql2::Error do
13
13
  it "should respond to #sql_state" do
14
14
  @error.should respond_to(:sql_state)
15
15
  end
16
- end
16
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
2
+ require 'spec_helper'
3
3
 
4
4
  describe Mysql2::Result do
5
5
  before(:all) do
@@ -47,6 +47,22 @@ describe Mysql2::Result do
47
47
  end
48
48
  end
49
49
 
50
+ context "#fields" do
51
+ before(:all) do
52
+ @client.query "USE test"
53
+ @test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1")
54
+ end
55
+
56
+ it "method should exist" do
57
+ @test_result.should respond_to(:fields)
58
+ end
59
+
60
+ it "should return an array of field names in proper order" do
61
+ result = @client.query "SELECT 'a', 'b', 'c'"
62
+ result.fields.should eql(['a', 'b', 'c'])
63
+ end
64
+ end
65
+
50
66
  context "row data type mapping" do
51
67
  before(:all) do
52
68
  @client.query "USE test"
@@ -176,7 +192,7 @@ describe Mysql2::Result do
176
192
 
177
193
  it "should return Time for a TIME value" do
178
194
  @test_result['time_test'].class.should eql(Time)
179
- if RUBY_VERSION =~ /1.9.2/
195
+ if RUBY_VERSION >= "1.9.2"
180
196
  @test_result['time_test'].strftime("%F %T").should eql('0000-01-01 11:44:00')
181
197
  else
182
198
  @test_result['time_test'].strftime("%F %T").should eql('2000-01-01 11:44:00')
@@ -193,16 +209,83 @@ describe Mysql2::Result do
193
209
  @test_result['enum_test'].should eql('val1')
194
210
  end
195
211
 
212
+ if defined? Encoding
213
+ context "string encoding for ENUM values" do
214
+ it "should default to the connection's encoding if Encoding.default_internal is nil" do
215
+ Encoding.default_internal = nil
216
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
217
+ result['enum_test'].encoding.should eql(Encoding.find('utf-8'))
218
+
219
+ client2 = Mysql2::Client.new :encoding => 'ascii'
220
+ client2.query "USE test"
221
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
222
+ result['enum_test'].encoding.should eql(Encoding.find('us-ascii'))
223
+ end
224
+
225
+ it "should use Encoding.default_internal" do
226
+ Encoding.default_internal = Encoding.find('utf-8')
227
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
228
+ result['enum_test'].encoding.should eql(Encoding.default_internal)
229
+ Encoding.default_internal = Encoding.find('us-ascii')
230
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
231
+ result['enum_test'].encoding.should eql(Encoding.default_internal)
232
+ end
233
+ end
234
+ end
235
+
196
236
  it "should return String for a SET value" do
197
237
  @test_result['set_test'].class.should eql(String)
198
238
  @test_result['set_test'].should eql('val1,val2')
199
239
  end
200
240
 
241
+ if defined? Encoding
242
+ context "string encoding for SET values" do
243
+ it "should default to the connection's encoding if Encoding.default_internal is nil" do
244
+ Encoding.default_internal = nil
245
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
246
+ result['set_test'].encoding.should eql(Encoding.find('utf-8'))
247
+
248
+ client2 = Mysql2::Client.new :encoding => 'ascii'
249
+ client2.query "USE test"
250
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
251
+ result['set_test'].encoding.should eql(Encoding.find('us-ascii'))
252
+ end
253
+
254
+ it "should use Encoding.default_internal" do
255
+ Encoding.default_internal = Encoding.find('utf-8')
256
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
257
+ result['set_test'].encoding.should eql(Encoding.default_internal)
258
+ Encoding.default_internal = Encoding.find('us-ascii')
259
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
260
+ result['set_test'].encoding.should eql(Encoding.default_internal)
261
+ end
262
+ end
263
+ end
264
+
201
265
  it "should return String for a BINARY value" do
202
266
  @test_result['binary_test'].class.should eql(String)
203
267
  @test_result['binary_test'].should eql("test#{"\000"*6}")
204
268
  end
205
269
 
270
+ if defined? Encoding
271
+ context "string encoding for BINARY values" do
272
+ it "should default to binary if Encoding.default_internal is nil" do
273
+ Encoding.default_internal = nil
274
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
275
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
276
+ end
277
+
278
+ it "should not use Encoding.default_internal" do
279
+ Encoding.default_internal = Encoding.find('utf-8')
280
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
281
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
282
+ Encoding.default_internal = Encoding.find('us-ascii')
283
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
284
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
285
+ end
286
+ end
287
+ end
288
+
206
289
  {
207
290
  'char_test' => 'CHAR',
208
291
  'varchar_test' => 'VARCHAR',
@@ -220,6 +303,47 @@ describe Mysql2::Result do
220
303
  @test_result[field].class.should eql(String)
221
304
  @test_result[field].should eql("test")
222
305
  end
306
+
307
+ if defined? Encoding
308
+ context "string encoding for #{type} values" do
309
+ if ['VARBINARY', 'TINYBLOB', 'BLOB', 'MEDIUMBLOB', 'LONGBLOB'].include?(type)
310
+ it "should default to binary if Encoding.default_internal is nil" do
311
+ Encoding.default_internal = nil
312
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
313
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
314
+ end
315
+
316
+ it "should not use Encoding.default_internal" do
317
+ Encoding.default_internal = Encoding.find('utf-8')
318
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
319
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
320
+ Encoding.default_internal = Encoding.find('us-ascii')
321
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
322
+ result['binary_test'].encoding.should eql(Encoding.find('binary'))
323
+ end
324
+ else
325
+ it "should default to utf-8 if Encoding.default_internal is nil" do
326
+ Encoding.default_internal = nil
327
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
328
+ result[field].encoding.should eql(Encoding.find('utf-8'))
329
+
330
+ client2 = Mysql2::Client.new :encoding => 'ascii'
331
+ client2.query "USE test"
332
+ result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
333
+ result[field].encoding.should eql(Encoding.find('us-ascii'))
334
+ end
335
+
336
+ it "should use Encoding.default_internal" do
337
+ Encoding.default_internal = Encoding.find('utf-8')
338
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
339
+ result[field].encoding.should eql(Encoding.default_internal)
340
+ Encoding.default_internal = Encoding.find('us-ascii')
341
+ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
342
+ result[field].encoding.should eql(Encoding.default_internal)
343
+ end
344
+ end
345
+ end
346
+ end
223
347
  end
224
348
  end
225
- end
349
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql2
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 9
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 1
8
- - 8
9
- version: 0.1.8
9
+ - 9
10
+ version: 0.1.9
10
11
  platform: ruby
11
12
  authors:
12
13
  - Brian Lopez
@@ -14,7 +15,7 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-06-02 00:00:00 -07:00
18
+ date: 2010-07-17 00:00:00 -07:00
18
19
  default_executable:
19
20
  dependencies: []
20
21
 
@@ -23,7 +24,7 @@ email: seniorlopez@gmail.com
23
24
  executables: []
24
25
 
25
26
  extensions:
26
- - ext/extconf.rb
27
+ - ext/mysql2/extconf.rb
27
28
  extra_rdoc_files:
28
29
  - README.rdoc
29
30
  files:
@@ -40,13 +41,20 @@ files:
40
41
  - benchmark/sequel.rb
41
42
  - benchmark/setup_db.rb
42
43
  - examples/eventmachine.rb
43
- - ext/extconf.rb
44
- - ext/mysql2_ext.c
45
- - ext/mysql2_ext.h
44
+ - ext/mysql2/extconf.rb
45
+ - ext/mysql2/mysql2_ext.c
46
+ - ext/mysql2/mysql2_ext.h
47
+ - ext/mysql2/result.c
48
+ - ext/mysql2/result.h
49
+ - lib/active_record/connection_adapters/em_mysql2_adapter.rb
46
50
  - lib/active_record/connection_adapters/mysql2_adapter.rb
51
+ - lib/active_record/fiber_patches.rb
47
52
  - lib/arel/engines/sql/compilers/mysql2_compiler.rb
48
53
  - lib/mysql2.rb
54
+ - lib/mysql2/client.rb
49
55
  - lib/mysql2/em.rb
56
+ - lib/mysql2/error.rb
57
+ - lib/mysql2/result.rb
50
58
  - lib/sequel/adapters/mysql2.rb
51
59
  - mysql2.gemspec
52
60
  - spec/active_record/active_record_spec.rb
@@ -68,23 +76,27 @@ require_paths:
68
76
  - lib
69
77
  - ext
70
78
  required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
71
80
  requirements:
72
81
  - - ">="
73
82
  - !ruby/object:Gem::Version
83
+ hash: 3
74
84
  segments:
75
85
  - 0
76
86
  version: "0"
77
87
  required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
78
89
  requirements:
79
90
  - - ">="
80
91
  - !ruby/object:Gem::Version
92
+ hash: 3
81
93
  segments:
82
94
  - 0
83
95
  version: "0"
84
96
  requirements: []
85
97
 
86
98
  rubyforge_project:
87
- rubygems_version: 1.3.6
99
+ rubygems_version: 1.3.7
88
100
  signing_key:
89
101
  specification_version: 3
90
102
  summary: A simple, fast Mysql library for Ruby, binding to libmysql
@@ -1,748 +0,0 @@
1
- #include "mysql2_ext.h"
2
-
3
- /*
4
- * non-blocking mysql_*() functions that we won't be wrapping since
5
- * they do not appear to hit the network nor issue any interruptible
6
- * or blocking system calls.
7
- *
8
- * - mysql_affected_rows()
9
- * - mysql_error()
10
- * - mysql_fetch_fields()
11
- * - mysql_fetch_lengths() - calls cli_fetch_lengths or emb_fetch_lengths
12
- * - mysql_field_count()
13
- * - mysql_get_client_info()
14
- * - mysql_get_client_version()
15
- * - mysql_get_server_info()
16
- * - mysql_get_server_version()
17
- * - mysql_insert_id()
18
- * - mysql_num_fields()
19
- * - mysql_num_rows()
20
- * - mysql_options()
21
- * - mysql_real_escape_string()
22
- * - mysql_ssl_set()
23
- */
24
-
25
- static VALUE nogvl_init(void *ptr) {
26
- struct nogvl_connect_args *args = ptr;
27
-
28
- /* may initialize embedded server and read /etc/services off disk */
29
- args->mysql = mysql_init(NULL);
30
-
31
- return args->mysql == NULL ? Qfalse : Qtrue;
32
- }
33
-
34
- static VALUE nogvl_connect(void *ptr)
35
- {
36
- struct nogvl_connect_args *args = ptr;
37
- MYSQL *client;
38
-
39
- client = mysql_real_connect(args->mysql, args->host,
40
- args->user, args->passwd,
41
- args->db, args->port, args->unix_socket,
42
- args->client_flag);
43
-
44
- return client ? Qtrue : Qfalse;
45
- }
46
-
47
- /* Mysql2::Client */
48
- static VALUE rb_mysql_client_new(int argc, VALUE * argv, VALUE klass) {
49
- mysql2_client_wrapper * client;
50
- struct nogvl_connect_args args = {
51
- .host = "localhost",
52
- .user = NULL,
53
- .passwd = NULL,
54
- .db = NULL,
55
- .port = 3306,
56
- .unix_socket = NULL,
57
- .client_flag = 0
58
- };
59
- VALUE obj, opts;
60
- VALUE rb_host, rb_socket, rb_port, rb_database,
61
- rb_username, rb_password, rb_reconnect,
62
- rb_connect_timeout;
63
- VALUE rb_ssl_client_key, rb_ssl_client_cert, rb_ssl_ca_cert,
64
- rb_ssl_ca_path, rb_ssl_cipher;
65
- char *ssl_client_key = NULL, *ssl_client_cert = NULL, *ssl_ca_cert = NULL,
66
- *ssl_ca_path = NULL, *ssl_cipher = NULL;
67
- unsigned int connect_timeout = 0;
68
- my_bool reconnect = 1;
69
-
70
- obj = Data_Make_Struct(klass, mysql2_client_wrapper, NULL, rb_mysql_client_free, client);
71
-
72
- if (rb_scan_args(argc, argv, "01", &opts) == 1) {
73
- Check_Type(opts, T_HASH);
74
-
75
- if ((rb_host = rb_hash_aref(opts, sym_host)) != Qnil) {
76
- Check_Type(rb_host, T_STRING);
77
- args.host = RSTRING_PTR(rb_host);
78
- }
79
-
80
- if ((rb_socket = rb_hash_aref(opts, sym_socket)) != Qnil) {
81
- Check_Type(rb_socket, T_STRING);
82
- args.unix_socket = RSTRING_PTR(rb_socket);
83
- }
84
-
85
- if ((rb_port = rb_hash_aref(opts, sym_port)) != Qnil) {
86
- Check_Type(rb_port, T_FIXNUM);
87
- args.port = FIX2INT(rb_port);
88
- }
89
-
90
- if ((rb_username = rb_hash_aref(opts, sym_username)) != Qnil) {
91
- Check_Type(rb_username, T_STRING);
92
- args.user = RSTRING_PTR(rb_username);
93
- }
94
-
95
- if ((rb_password = rb_hash_aref(opts, sym_password)) != Qnil) {
96
- Check_Type(rb_password, T_STRING);
97
- args.passwd = RSTRING_PTR(rb_password);
98
- }
99
-
100
- if ((rb_database = rb_hash_aref(opts, sym_database)) != Qnil) {
101
- Check_Type(rb_database, T_STRING);
102
- args.db = RSTRING_PTR(rb_database);
103
- }
104
-
105
- if ((rb_reconnect = rb_hash_aref(opts, sym_reconnect)) != Qnil) {
106
- reconnect = rb_reconnect == Qfalse ? 0 : 1;
107
- }
108
-
109
- if ((rb_connect_timeout = rb_hash_aref(opts, sym_connect_timeout)) != Qnil) {
110
- Check_Type(rb_connect_timeout, T_FIXNUM);
111
- connect_timeout = FIX2INT(rb_connect_timeout);
112
- }
113
-
114
- // SSL options
115
- if ((rb_ssl_client_key = rb_hash_aref(opts, sym_sslkey)) != Qnil) {
116
- Check_Type(rb_ssl_client_key, T_STRING);
117
- ssl_client_key = RSTRING_PTR(rb_ssl_client_key);
118
- }
119
-
120
- if ((rb_ssl_client_cert = rb_hash_aref(opts, sym_sslcert)) != Qnil) {
121
- Check_Type(rb_ssl_client_cert, T_STRING);
122
- ssl_client_cert = RSTRING_PTR(rb_ssl_client_cert);
123
- }
124
-
125
- if ((rb_ssl_ca_cert = rb_hash_aref(opts, sym_sslca)) != Qnil) {
126
- Check_Type(rb_ssl_ca_cert, T_STRING);
127
- ssl_ca_cert = RSTRING_PTR(rb_ssl_ca_cert);
128
- }
129
-
130
- if ((rb_ssl_ca_path = rb_hash_aref(opts, sym_sslcapath)) != Qnil) {
131
- Check_Type(rb_ssl_ca_path, T_STRING);
132
- ssl_ca_path = RSTRING_PTR(rb_ssl_ca_path);
133
- }
134
-
135
- if ((rb_ssl_cipher = rb_hash_aref(opts, sym_sslcipher)) != Qnil) {
136
- Check_Type(rb_ssl_cipher, T_STRING);
137
- ssl_cipher = RSTRING_PTR(rb_ssl_cipher);
138
- }
139
- }
140
-
141
- if (rb_thread_blocking_region(nogvl_init, &args, RUBY_UBF_IO, 0) == Qfalse) {
142
- // TODO: warning - not enough memory?
143
- return rb_raise_mysql2_error(args.mysql);
144
- }
145
-
146
- // set default reconnect behavior
147
- if (mysql_options(args.mysql, MYSQL_OPT_RECONNECT, &reconnect) != 0) {
148
- // TODO: warning - unable to set reconnect behavior
149
- rb_warn("%s\n", mysql_error(args.mysql));
150
- }
151
-
152
- // set default connection timeout behavior
153
- if (connect_timeout != 0 && mysql_options(args.mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout) != 0) {
154
- // TODO: warning - unable to set connection timeout
155
- rb_warn("%s\n", mysql_error(args.mysql));
156
- }
157
-
158
- // force the encoding to utf8
159
- if (mysql_options(args.mysql, MYSQL_SET_CHARSET_NAME, "utf8") != 0) {
160
- // TODO: warning - unable to set charset
161
- rb_warn("%s\n", mysql_error(args.mysql));
162
- }
163
-
164
- if (ssl_ca_cert != NULL || ssl_client_key != NULL) {
165
- mysql_ssl_set(args.mysql, ssl_client_key, ssl_client_cert, ssl_ca_cert, ssl_ca_path, ssl_cipher);
166
- }
167
-
168
- if (rb_thread_blocking_region(nogvl_connect, &args, RUBY_UBF_IO, 0) == Qfalse) {
169
- // unable to connect
170
- return rb_raise_mysql2_error(args.mysql);;
171
- }
172
-
173
- client->client = args.mysql;
174
-
175
- rb_obj_call_init(obj, argc, argv);
176
- return obj;
177
- }
178
-
179
- static VALUE rb_mysql_client_init(RB_MYSQL_UNUSED int argc, RB_MYSQL_UNUSED VALUE * argv, VALUE self) {
180
- return self;
181
- }
182
-
183
- static void rb_mysql_client_free(void * ptr) {
184
- mysql2_client_wrapper * client = ptr;
185
-
186
- if (client->client) {
187
- /*
188
- * we'll send a QUIT message to the server, but that message is more of a
189
- * formality than a hard requirement since the socket is getting shutdown
190
- * anyways, so ensure the socket write does not block our interpreter
191
- */
192
- int fd = client->client->net.fd;
193
- int flags;
194
-
195
- if (fd >= 0) {
196
- /*
197
- * if the socket is dead we have no chance of blocking,
198
- * so ignore any potential fcntl errors since they don't matter
199
- */
200
- flags = fcntl(fd, F_GETFL);
201
- if (flags > 0 && !(flags & O_NONBLOCK))
202
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
203
- }
204
-
205
- mysql_close(client->client);
206
- }
207
- xfree(ptr);
208
- }
209
-
210
- static VALUE nogvl_close(void * ptr) {
211
- mysql_close((MYSQL *)ptr);
212
- return Qnil;
213
- }
214
-
215
- /*
216
- * Immediately disconnect from the server, normally the garbage collector
217
- * will disconnect automatically when a connection is no longer needed.
218
- * Explicitly closing this will free up server resources sooner than waiting
219
- * for the garbage collector.
220
- */
221
- static VALUE rb_mysql_client_close(VALUE self) {
222
- mysql2_client_wrapper *client;
223
-
224
- Data_Get_Struct(self, mysql2_client_wrapper, client);
225
-
226
- if (client->client) {
227
- rb_thread_blocking_region(nogvl_close, client->client, RUBY_UBF_IO, 0);
228
- client->client = NULL;
229
- } else {
230
- rb_raise(cMysql2Error, "already closed MySQL connection");
231
- }
232
- return Qnil;
233
- }
234
-
235
- /*
236
- * mysql_send_query is unlikely to block since most queries are small
237
- * enough to fit in a socket buffer, but sometimes large UPDATE and
238
- * INSERTs will cause the process to block
239
- */
240
- static VALUE nogvl_send_query(void *ptr)
241
- {
242
- struct nogvl_send_query_args *args = ptr;
243
- int rv;
244
- const char *sql = RSTRING_PTR(args->sql);
245
- long sql_len = RSTRING_LEN(args->sql);
246
-
247
- rv = mysql_send_query(args->mysql, sql, sql_len);
248
-
249
- return rv == 0 ? Qtrue : Qfalse;
250
- }
251
-
252
- static VALUE rb_mysql_client_query(int argc, VALUE * argv, VALUE self) {
253
- struct nogvl_send_query_args args;
254
- fd_set fdset;
255
- int fd, retval;
256
- int async = 0;
257
- VALUE opts;
258
- VALUE rb_async;
259
-
260
- if (rb_scan_args(argc, argv, "11", &args.sql, &opts) == 2) {
261
- if ((rb_async = rb_hash_aref(opts, sym_async)) != Qnil) {
262
- async = rb_async == Qtrue ? 1 : 0;
263
- }
264
- }
265
-
266
- Check_Type(args.sql, T_STRING);
267
-
268
- GetMysql2Client(self, args.mysql);
269
- if (!args.mysql) {
270
- rb_raise(cMysql2Error, "closed MySQL connection");
271
- return Qnil;
272
- }
273
- if (rb_thread_blocking_region(nogvl_send_query, &args, RUBY_UBF_IO, 0) == Qfalse) {
274
- return rb_raise_mysql2_error(args.mysql);;
275
- }
276
-
277
- if (!async) {
278
- // the below code is largely from do_mysql
279
- // http://github.com/datamapper/do
280
- fd = args.mysql->net.fd;
281
- for(;;) {
282
- FD_ZERO(&fdset);
283
- FD_SET(fd, &fdset);
284
-
285
- retval = rb_thread_select(fd + 1, &fdset, NULL, NULL, NULL);
286
-
287
- if (retval < 0) {
288
- rb_sys_fail(0);
289
- }
290
-
291
- if (retval > 0) {
292
- break;
293
- }
294
- }
295
-
296
- return rb_mysql_client_async_result(self);
297
- } else {
298
- return Qnil;
299
- }
300
- }
301
-
302
- static VALUE rb_mysql_client_escape(VALUE self, VALUE str) {
303
- MYSQL * client;
304
- VALUE newStr;
305
- unsigned long newLen, oldLen;
306
-
307
- Check_Type(str, T_STRING);
308
- oldLen = RSTRING_LEN(str);
309
- char escaped[(oldLen*2)+1];
310
-
311
- GetMysql2Client(self, client);
312
- if (!client) {
313
- rb_raise(cMysql2Error, "closed MySQL connection");
314
- return Qnil;
315
- }
316
- newLen = mysql_real_escape_string(client, escaped, RSTRING_PTR(str), RSTRING_LEN(str));
317
- if (newLen == oldLen) {
318
- // no need to return a new ruby string if nothing changed
319
- return str;
320
- } else {
321
- newStr = rb_str_new(escaped, newLen);
322
- #ifdef HAVE_RUBY_ENCODING_H
323
- rb_enc_associate_index(newStr, utf8Encoding);
324
- #endif
325
- return newStr;
326
- }
327
- }
328
-
329
- static VALUE rb_mysql_client_info(RB_MYSQL_UNUSED VALUE self) {
330
- VALUE version = rb_hash_new();
331
- rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_client_version()));
332
- rb_hash_aset(version, sym_version, rb_str_new2(mysql_get_client_info()));
333
- return version;
334
- }
335
-
336
- static VALUE rb_mysql_client_server_info(VALUE self) {
337
- MYSQL * client;
338
- VALUE version;
339
-
340
- GetMysql2Client(self, client);
341
- if (!client) {
342
- rb_raise(cMysql2Error, "closed MySQL connection");
343
- return Qnil;
344
- }
345
- version = rb_hash_new();
346
- rb_hash_aset(version, sym_id, LONG2FIX(mysql_get_server_version(client)));
347
- rb_hash_aset(version, sym_version, rb_str_new2(mysql_get_server_info(client)));
348
- return version;
349
- }
350
-
351
- static VALUE rb_mysql_client_socket(VALUE self) {
352
- MYSQL * client = GetMysql2Client(self, client);
353
- if (!client) {
354
- rb_raise(cMysql2Error, "closed MySQL connection");
355
- return Qnil;
356
- }
357
- return INT2NUM(client->net.fd);
358
- }
359
-
360
- /*
361
- * even though we did rb_thread_select before calling this, a large
362
- * response can overflow the socket buffers and cause us to eventually
363
- * block while calling mysql_read_query_result
364
- */
365
- static VALUE nogvl_read_query_result(void *ptr)
366
- {
367
- MYSQL * client = ptr;
368
- my_bool res = mysql_read_query_result(client);
369
-
370
- return res == 0 ? Qtrue : Qfalse;
371
- }
372
-
373
- /* mysql_store_result may (unlikely) read rows off the socket */
374
- static VALUE nogvl_store_result(void *ptr)
375
- {
376
- MYSQL * client = ptr;
377
- return (VALUE)mysql_store_result(client);
378
- }
379
-
380
- static VALUE rb_mysql_client_async_result(VALUE self) {
381
- MYSQL * client;
382
- MYSQL_RES * result;
383
- GetMysql2Client(self, client);
384
- if (!client) {
385
- rb_raise(cMysql2Error, "closed MySQL connection");
386
- return Qnil;
387
- }
388
- if (rb_thread_blocking_region(nogvl_read_query_result, client, RUBY_UBF_IO, 0) == Qfalse) {
389
- return rb_raise_mysql2_error(client);
390
- }
391
-
392
- result = (MYSQL_RES *)rb_thread_blocking_region(nogvl_store_result, client, RUBY_UBF_IO, 0);
393
- if (result == NULL) {
394
- if (mysql_field_count(client) != 0) {
395
- rb_raise_mysql2_error(client);
396
- }
397
- return Qnil;
398
- }
399
-
400
- return rb_mysql_result_to_obj(result);
401
- }
402
-
403
- static VALUE rb_mysql_client_last_id(VALUE self) {
404
- MYSQL * client;
405
- GetMysql2Client(self, client);
406
- if (!client) {
407
- rb_raise(cMysql2Error, "closed MySQL connection");
408
- return Qnil;
409
- }
410
- return ULL2NUM(mysql_insert_id(client));
411
- }
412
-
413
- static VALUE rb_mysql_client_affected_rows(VALUE self) {
414
- MYSQL * client;
415
- GetMysql2Client(self, client);
416
- if (!client) {
417
- rb_raise(cMysql2Error, "closed MySQL connection");
418
- return Qnil;
419
- }
420
- return ULL2NUM(mysql_affected_rows(client));
421
- }
422
-
423
- /* Mysql2::Result */
424
- static VALUE rb_mysql_result_to_obj(MYSQL_RES * r) {
425
- VALUE obj;
426
- mysql2_result_wrapper * wrapper;
427
- obj = Data_Make_Struct(cMysql2Result, mysql2_result_wrapper, rb_mysql_result_mark, rb_mysql_result_free, wrapper);
428
- wrapper->numberOfFields = 0;
429
- wrapper->numberOfRows = 0;
430
- wrapper->lastRowProcessed = 0;
431
- wrapper->resultFreed = 0;
432
- wrapper->result = r;
433
- rb_obj_call_init(obj, 0, NULL);
434
- return obj;
435
- }
436
-
437
- /* this may be called manually or during GC */
438
- static void rb_mysql_result_free_result(mysql2_result_wrapper * wrapper) {
439
- if (wrapper && wrapper->resultFreed != 1) {
440
- mysql_free_result(wrapper->result);
441
- wrapper->resultFreed = 1;
442
- }
443
- }
444
-
445
- /* this is called during GC */
446
- static void rb_mysql_result_free(void * wrapper) {
447
- mysql2_result_wrapper * w = wrapper;
448
- /* FIXME: this may call flush_use_result, which can hit the socket */
449
- rb_mysql_result_free_result(w);
450
- xfree(wrapper);
451
- }
452
-
453
- static void rb_mysql_result_mark(void * wrapper) {
454
- mysql2_result_wrapper * w = wrapper;
455
- if (w) {
456
- rb_gc_mark(w->fields);
457
- rb_gc_mark(w->rows);
458
- }
459
- }
460
-
461
- /*
462
- * for small results, this won't hit the network, but there's no
463
- * reliable way for us to tell this so we'll always release the GVL
464
- * to be safe
465
- */
466
- static VALUE nogvl_fetch_row(void *ptr)
467
- {
468
- MYSQL_RES *result = ptr;
469
-
470
- return (VALUE)mysql_fetch_row(result);
471
- }
472
-
473
- static VALUE rb_mysql_result_fetch_row(int argc, VALUE * argv, VALUE self) {
474
- VALUE rowHash, opts, block;
475
- mysql2_result_wrapper * wrapper;
476
- MYSQL_ROW row;
477
- MYSQL_FIELD * fields = NULL;
478
- unsigned int i = 0, symbolizeKeys = 0;
479
- unsigned long * fieldLengths;
480
- void * ptr;
481
-
482
- GetMysql2Result(self, wrapper);
483
-
484
- if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
485
- Check_Type(opts, T_HASH);
486
- if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
487
- symbolizeKeys = 1;
488
- }
489
- }
490
-
491
- ptr = wrapper->result;
492
- row = (MYSQL_ROW)rb_thread_blocking_region(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
493
- if (row == NULL) {
494
- return Qnil;
495
- }
496
-
497
- if (wrapper->numberOfFields == 0) {
498
- wrapper->numberOfFields = mysql_num_fields(wrapper->result);
499
- wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
500
- }
501
-
502
- rowHash = rb_hash_new();
503
- fields = mysql_fetch_fields(wrapper->result);
504
- fieldLengths = mysql_fetch_lengths(wrapper->result);
505
- for (i = 0; i < wrapper->numberOfFields; i++) {
506
-
507
- // lazily create fields, but only once
508
- // we'll use cached versions from here on out
509
- VALUE field = rb_ary_entry(wrapper->fields, i);
510
- if (field == Qnil) {
511
- if (symbolizeKeys) {
512
- char buf[fields[i].name_length+1];
513
- memcpy(buf, fields[i].name, fields[i].name_length);
514
- buf[fields[i].name_length] = 0;
515
- field = ID2SYM(rb_intern(buf));
516
- } else {
517
- field = rb_str_new(fields[i].name, fields[i].name_length);
518
- #ifdef HAVE_RUBY_ENCODING_H
519
- rb_enc_associate_index(field, utf8Encoding);
520
- #endif
521
- }
522
- rb_ary_store(wrapper->fields, i, field);
523
- }
524
-
525
- if (row[i]) {
526
- VALUE val;
527
- switch(fields[i].type) {
528
- case MYSQL_TYPE_NULL: // NULL-type field
529
- val = Qnil;
530
- break;
531
- case MYSQL_TYPE_BIT: // BIT field (MySQL 5.0.3 and up)
532
- val = rb_str_new(row[i], fieldLengths[i]);
533
- break;
534
- case MYSQL_TYPE_TINY: // TINYINT field
535
- case MYSQL_TYPE_SHORT: // SMALLINT field
536
- case MYSQL_TYPE_LONG: // INTEGER field
537
- case MYSQL_TYPE_INT24: // MEDIUMINT field
538
- case MYSQL_TYPE_LONGLONG: // BIGINT field
539
- case MYSQL_TYPE_YEAR: // YEAR field
540
- val = rb_cstr2inum(row[i], 10);
541
- break;
542
- case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
543
- case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up)
544
- val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
545
- break;
546
- case MYSQL_TYPE_FLOAT: // FLOAT field
547
- case MYSQL_TYPE_DOUBLE: // DOUBLE or REAL field
548
- val = rb_float_new(strtod(row[i], NULL));
549
- break;
550
- case MYSQL_TYPE_TIME: { // TIME field
551
- int hour, min, sec, tokens;
552
- tokens = sscanf(row[i], "%2d:%2d:%2d", &hour, &min, &sec);
553
- val = rb_funcall(rb_cTime, intern_utc, 6, INT2NUM(0), INT2NUM(1), INT2NUM(1), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
554
- break;
555
- }
556
- case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
557
- case MYSQL_TYPE_DATETIME: { // DATETIME field
558
- int year, month, day, hour, min, sec, tokens;
559
- tokens = sscanf(row[i], "%4d-%2d-%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min, &sec);
560
- if (year+month+day+hour+min+sec == 0) {
561
- val = Qnil;
562
- } else {
563
- if (month < 1 || day < 1) {
564
- rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
565
- val = Qnil;
566
- } else {
567
- val = rb_funcall(rb_cTime, intern_utc, 6, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec));
568
- }
569
- }
570
- break;
571
- }
572
- case MYSQL_TYPE_DATE: // DATE field
573
- case MYSQL_TYPE_NEWDATE: { // Newer const used > 5.0
574
- int year, month, day, tokens;
575
- tokens = sscanf(row[i], "%4d-%2d-%2d", &year, &month, &day);
576
- if (year+month+day == 0) {
577
- val = Qnil;
578
- } else {
579
- if (month < 1 || day < 1) {
580
- rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
581
- val = Qnil;
582
- } else {
583
- val = rb_funcall(cDate, intern_new, 3, INT2NUM(year), INT2NUM(month), INT2NUM(day));
584
- }
585
- }
586
- break;
587
- }
588
- case MYSQL_TYPE_TINY_BLOB:
589
- case MYSQL_TYPE_MEDIUM_BLOB:
590
- case MYSQL_TYPE_LONG_BLOB:
591
- case MYSQL_TYPE_BLOB:
592
- case MYSQL_TYPE_VAR_STRING:
593
- case MYSQL_TYPE_VARCHAR:
594
- case MYSQL_TYPE_STRING: // CHAR or BINARY field
595
- case MYSQL_TYPE_SET: // SET field
596
- case MYSQL_TYPE_ENUM: // ENUM field
597
- case MYSQL_TYPE_GEOMETRY: // Spatial fielda
598
- default:
599
- val = rb_str_new(row[i], fieldLengths[i]);
600
- #ifdef HAVE_RUBY_ENCODING_H
601
- // rudimentary check for binary content
602
- if ((fields[i].flags & BINARY_FLAG) || fields[i].charsetnr == 63) {
603
- rb_enc_associate_index(val, binaryEncoding);
604
- } else {
605
- rb_enc_associate_index(val, utf8Encoding);
606
- }
607
- #endif
608
- break;
609
- }
610
- rb_hash_aset(rowHash, field, val);
611
- } else {
612
- rb_hash_aset(rowHash, field, Qnil);
613
- }
614
- }
615
- return rowHash;
616
- }
617
-
618
- static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
619
- VALUE opts, block;
620
- mysql2_result_wrapper * wrapper;
621
- unsigned long i;
622
-
623
- GetMysql2Result(self, wrapper);
624
-
625
- rb_scan_args(argc, argv, "01&", &opts, &block);
626
-
627
- if (wrapper->lastRowProcessed == 0) {
628
- wrapper->numberOfRows = mysql_num_rows(wrapper->result);
629
- if (wrapper->numberOfRows == 0) {
630
- return Qnil;
631
- }
632
- wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
633
- }
634
-
635
- if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
636
- // we've already read the entire dataset from the C result into our
637
- // internal array. Lets hand that over to the user since it's ready to go
638
- for (i = 0; i < wrapper->numberOfRows; i++) {
639
- rb_yield(rb_ary_entry(wrapper->rows, i));
640
- }
641
- } else {
642
- unsigned long rowsProcessed = 0;
643
- rowsProcessed = RARRAY_LEN(wrapper->rows);
644
- for (i = 0; i < wrapper->numberOfRows; i++) {
645
- VALUE row;
646
- if (i < rowsProcessed) {
647
- row = rb_ary_entry(wrapper->rows, i);
648
- } else {
649
- row = rb_mysql_result_fetch_row(argc, argv, self);
650
- rb_ary_store(wrapper->rows, i, row);
651
- wrapper->lastRowProcessed++;
652
- }
653
-
654
- if (row == Qnil) {
655
- // we don't need the mysql C dataset around anymore, peace it
656
- rb_mysql_result_free_result(wrapper);
657
- return Qnil;
658
- }
659
-
660
- if (block != Qnil) {
661
- rb_yield(row);
662
- }
663
- }
664
- if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
665
- // we don't need the mysql C dataset around anymore, peace it
666
- rb_mysql_result_free_result(wrapper);
667
- }
668
- }
669
-
670
- return wrapper->rows;
671
- }
672
-
673
- static VALUE rb_mysql_error_error_number(VALUE obj) {
674
- return rb_iv_get(obj, "error_number");
675
- }
676
-
677
- static VALUE rb_mysql_error_sql_state(VALUE obj) {
678
- return rb_iv_get(obj, "sql_state");
679
- }
680
-
681
- static VALUE rb_raise_mysql2_error(MYSQL *client) {
682
- VALUE e = rb_exc_new2(cMysql2Error, mysql_error(client));
683
- rb_iv_set(e, "error_number", INT2FIX(mysql_errno(client)));
684
- rb_iv_set(e, "sql_state", rb_tainted_str_new2(mysql_sqlstate(client)));
685
- rb_exc_raise(e);
686
- return Qnil;
687
- }
688
-
689
- /* Ruby Extension initializer */
690
- void Init_mysql2_ext() {
691
- rb_require("date");
692
- rb_require("bigdecimal");
693
-
694
- cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
695
- cDate = rb_const_get(rb_cObject, rb_intern("Date"));
696
- cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
697
-
698
- VALUE mMysql2 = rb_define_module("Mysql2");
699
-
700
- VALUE cMysql2Client = rb_define_class_under(mMysql2, "Client", rb_cObject);
701
- rb_define_singleton_method(cMysql2Client, "new", rb_mysql_client_new, -1);
702
- rb_define_method(cMysql2Client, "initialize", rb_mysql_client_init, -1);
703
- rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0);
704
- rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1);
705
- rb_define_method(cMysql2Client, "escape", rb_mysql_client_escape, 1);
706
- rb_define_method(cMysql2Client, "info", rb_mysql_client_info, 0);
707
- rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0);
708
- rb_define_method(cMysql2Client, "socket", rb_mysql_client_socket, 0);
709
- rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0);
710
- rb_define_method(cMysql2Client, "last_id", rb_mysql_client_last_id, 0);
711
- rb_define_method(cMysql2Client, "affected_rows", rb_mysql_client_affected_rows, 0);
712
-
713
- cMysql2Error = rb_define_class_under(mMysql2, "Error", rb_eStandardError);
714
- rb_define_method(cMysql2Error, "error_number", rb_mysql_error_error_number, 0);
715
- rb_define_method(cMysql2Error, "sql_state", rb_mysql_error_sql_state, 0);
716
-
717
- cMysql2Result = rb_define_class_under(mMysql2, "Result", rb_cObject);
718
- rb_define_method(cMysql2Result, "each", rb_mysql_result_each, -1);
719
-
720
- VALUE mEnumerable = rb_const_get(rb_cObject, rb_intern("Enumerable"));
721
- rb_include_module(cMysql2Result, mEnumerable);
722
-
723
- intern_new = rb_intern("new");
724
- intern_utc = rb_intern("utc");
725
-
726
- sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
727
- sym_reconnect = ID2SYM(rb_intern("reconnect"));
728
- sym_database = ID2SYM(rb_intern("database"));
729
- sym_username = ID2SYM(rb_intern("username"));
730
- sym_password = ID2SYM(rb_intern("password"));
731
- sym_host = ID2SYM(rb_intern("host"));
732
- sym_port = ID2SYM(rb_intern("port"));
733
- sym_socket = ID2SYM(rb_intern("socket"));
734
- sym_connect_timeout = ID2SYM(rb_intern("connect_timeout"));
735
- sym_id = ID2SYM(rb_intern("id"));
736
- sym_version = ID2SYM(rb_intern("version"));
737
- sym_sslkey = ID2SYM(rb_intern("sslkey"));
738
- sym_sslcert = ID2SYM(rb_intern("sslcert"));
739
- sym_sslca = ID2SYM(rb_intern("sslca"));
740
- sym_sslcapath = ID2SYM(rb_intern("sslcapath"));
741
- sym_sslcipher = ID2SYM(rb_intern("sslcipher"));
742
- sym_async = ID2SYM(rb_intern("async"));
743
-
744
- #ifdef HAVE_RUBY_ENCODING_H
745
- utf8Encoding = rb_enc_find_index("UTF-8");
746
- binaryEncoding = rb_enc_find_index("binary");
747
- #endif
748
- }