mysql2 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -33,8 +33,8 @@ void init_mysql2_client();
33
33
 
34
34
  typedef struct {
35
35
  VALUE encoding;
36
- short int active;
37
- short int closed;
36
+ char active;
37
+ char closed;
38
38
  MYSQL *client;
39
39
  } mysql_client_wrapper;
40
40
 
@@ -31,7 +31,10 @@ elsif mc = (with_config('mysql-config') || Dir[GLOB].first) then
31
31
  mc = Dir[GLOB].first if mc == true
32
32
  cflags = `#{mc} --cflags`.chomp
33
33
  exit 1 if $? != 0
34
- libs = `#{mc} --libs`.chomp
34
+ libs = `#{mc} --libs_r`.chomp
35
+ if libs.empty?
36
+ libs = `#{mc} --libs`.chomp
37
+ end
35
38
  exit 1 if $? != 0
36
39
  $CPPFLAGS += ' ' + cflags
37
40
  $libs = libs + " " + $libs
@@ -62,4 +65,8 @@ unless RUBY_PLATFORM =~ /mswin/ or RUBY_PLATFORM =~ /sparc/
62
65
  end
63
66
  # $CFLAGS << ' -O0 -ggdb3 -Wextra'
64
67
 
68
+ if hard_mysql_path = $libs[%r{-L(/[^ ]+)}, 1]
69
+ $LDFLAGS << " -Wl,-rpath,#{hard_mysql_path}"
70
+ end
71
+
65
72
  create_makefile('mysql2/mysql2')
@@ -1,9 +1,19 @@
1
1
  #ifndef MYSQL2_EXT
2
2
  #define MYSQL2_EXT
3
3
 
4
+ // tell rbx not to use it's caching compat layer
5
+ // by doing this we're making a promize to RBX that
6
+ // we'll never modify the pointers we get back from RSTRING_PTR
7
+ #define RSTRING_NOT_MODIFIED
4
8
  #include <ruby.h>
5
9
  #include <fcntl.h>
6
10
 
11
+ #ifndef HAVE_UINT
12
+ #define HAVE_UINT
13
+ typedef unsigned short ushort;
14
+ typedef unsigned int uint;
15
+ #endif
16
+
7
17
  #ifdef HAVE_MYSQL_H
8
18
  #include <mysql.h>
9
19
  #include <mysql_com.h>
@@ -1,17 +1,27 @@
1
1
  #include <mysql2_ext.h>
2
2
 
3
3
  #ifdef HAVE_RUBY_ENCODING_H
4
- rb_encoding *binaryEncoding;
4
+ static rb_encoding *binaryEncoding;
5
5
  #endif
6
6
 
7
- VALUE cMysql2Result;
8
- VALUE cBigDecimal, cDate, cDateTime;
9
- VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
7
+ #define MYSQL2_MAX_YEAR 2058
8
+
9
+ #ifdef NEGATIVE_TIME_T
10
+ /* 1901-12-13 20:45:52 UTC : The oldest time in 32-bit signed time_t. */
11
+ #define MYSQL2_MIN_YEAR 1902
12
+ #else
13
+ /* 1970-01-01 00:00:00 UTC : The Unix epoch - the oldest time in portable time_t. */
14
+ #define MYSQL2_MIN_YEAR 1970
15
+ #endif
16
+
17
+ static VALUE cMysql2Result;
18
+ static VALUE cBigDecimal, cDate, cDateTime;
19
+ static VALUE opt_decimal_zero, opt_float_zero, opt_time_year, opt_time_month, opt_utc_offset;
10
20
  extern VALUE mMysql2, cMysql2Client, cMysql2Error;
11
21
  static VALUE intern_encoding_from_charset;
12
22
  static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code,
13
23
  intern_localtime, intern_local_offset, intern_civil, intern_new_offset;
14
- static ID sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
24
+ static VALUE sym_symbolize_keys, sym_as, sym_array, sym_database_timezone, sym_application_timezone,
15
25
  sym_local, sym_utc, sym_cast_booleans, sym_cache_rows;
16
26
  static ID intern_merge;
17
27
 
@@ -53,7 +63,7 @@ static VALUE nogvl_fetch_row(void *ptr) {
53
63
 
54
64
  static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int symbolize_keys) {
55
65
  mysql2_result_wrapper * wrapper;
56
-
66
+ VALUE rb_field;
57
67
  GetMysql2Result(self, wrapper);
58
68
 
59
69
  if (wrapper->fields == Qnil) {
@@ -61,7 +71,7 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int
61
71
  wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
62
72
  }
63
73
 
64
- VALUE rb_field = rb_ary_entry(wrapper->fields, idx);
74
+ rb_field = rb_ary_entry(wrapper->fields, idx);
65
75
  if (rb_field == Qnil) {
66
76
  MYSQL_FIELD *field = NULL;
67
77
  #ifdef HAVE_RUBY_ENCODING_H
@@ -98,12 +108,15 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
98
108
  unsigned int i = 0;
99
109
  unsigned long * fieldLengths;
100
110
  void * ptr;
101
-
111
+ #ifdef HAVE_RUBY_ENCODING_H
112
+ rb_encoding *default_internal_enc;
113
+ rb_encoding *conn_enc;
114
+ #endif
102
115
  GetMysql2Result(self, wrapper);
103
116
 
104
117
  #ifdef HAVE_RUBY_ENCODING_H
105
- rb_encoding *default_internal_enc = rb_default_internal_encoding();
106
- rb_encoding *conn_enc = rb_to_encoding(wrapper->encoding);
118
+ default_internal_enc = rb_default_internal_encoding();
119
+ conn_enc = rb_to_encoding(wrapper->encoding);
107
120
  #endif
108
121
 
109
122
  ptr = wrapper->result;
@@ -190,7 +203,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
190
203
  rb_raise(cMysql2Error, "Invalid date: %s", row[i]);
191
204
  val = Qnil;
192
205
  } else {
193
- if (year < 1902 || year+month+day > 2058) { // use DateTime instead
206
+ if (year < MYSQL2_MIN_YEAR || year+month+day > MYSQL2_MAX_YEAR) { // use DateTime instead
194
207
  VALUE offset = INT2NUM(0);
195
208
  if (db_timezone == intern_local) {
196
209
  offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
@@ -248,7 +261,7 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID db_timezone, ID app_timezo
248
261
  val = rb_str_new(row[i], fieldLengths[i]);
249
262
  #ifdef HAVE_RUBY_ENCODING_H
250
263
  // if binary flag is set, respect it's wishes
251
- if (fields[i].flags & BINARY_FLAG) {
264
+ if (fields[i].flags & BINARY_FLAG && fields[i].charsetnr == 63) {
252
265
  rb_enc_associate(val, binaryEncoding);
253
266
  } else {
254
267
  // lookup the encoding configured on this field
@@ -8,10 +8,10 @@ typedef struct {
8
8
  VALUE fields;
9
9
  VALUE rows;
10
10
  VALUE encoding;
11
- long numberOfFields;
11
+ unsigned int numberOfFields;
12
12
  unsigned long numberOfRows;
13
13
  unsigned long lastRowProcessed;
14
- short int resultFreed;
14
+ char resultFreed;
15
15
  MYSQL_RES *result;
16
16
  } mysql2_result_wrapper;
17
17
 
@@ -15,8 +15,8 @@ module ActiveRecord
15
15
  end
16
16
 
17
17
  require 'fiber'
18
- require 'eventmachine' unless defined? EventMachine
19
- require 'mysql2' unless defined? Mysql2
18
+ require 'eventmachine'
19
+ require 'mysql2'
20
20
  require 'active_record/connection_adapters/mysql2_adapter'
21
21
  require 'active_record/fiber_patches'
22
22
 
@@ -35,25 +35,26 @@ module Mysql2
35
35
  results = @client.async_result
36
36
  @deferable.succeed(results)
37
37
  rescue Exception => e
38
- puts e.backtrace.join("\n\t")
39
38
  @deferable.fail(e)
40
39
  end
41
40
  end
42
41
  end
43
42
 
44
43
  def query(sql, opts={})
45
- if EM.reactor_running?
44
+ if ::EM.reactor_running?
46
45
  super(sql, opts.merge(:async => true))
47
- deferable = ::EM::DefaultDeferrable.new
48
- ::EM.watch(self.socket, Watcher, self, deferable).notify_readable = true
46
+ deferrable = ::EM::DefaultDeferrable.new
47
+ ::EM.watch(self.socket, Watcher, self, deferrable).notify_readable = true
49
48
  fiber = Fiber.current
50
- deferable.callback do |result|
49
+ deferrable.callback do |result|
51
50
  fiber.resume(result)
52
51
  end
53
- deferable.errback do |err|
52
+ deferrable.errback do |err|
54
53
  fiber.resume(err)
55
54
  end
56
- Fiber.yield
55
+ Fiber.yield.tap do |result|
56
+ raise result if result.is_a?(Exception)
57
+ end
57
58
  else
58
59
  super(sql, opts)
59
60
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'mysql2' unless defined? Mysql2
3
+ require 'mysql2'
4
4
 
5
5
  module ActiveRecord
6
6
  class Base
@@ -18,6 +18,9 @@ module ActiveRecord
18
18
  end
19
19
 
20
20
  module ConnectionAdapters
21
+ class Mysql2IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths) #:nodoc:
22
+ end
23
+
21
24
  class Mysql2Column < Column
22
25
  BOOL = "tinyint(1)"
23
26
  def extract_default(default)
@@ -239,10 +242,7 @@ module ActiveRecord
239
242
 
240
243
  def active?
241
244
  return false unless @connection
242
- @connection.query 'select 1'
243
- true
244
- rescue Mysql2::Error
245
- false
245
+ @connection.ping
246
246
  end
247
247
 
248
248
  def reconnect!
@@ -447,7 +447,7 @@ module ActiveRecord
447
447
  if current_index != row[:Key_name]
448
448
  next if row[:Key_name] == PRIMARY # skip the primary key
449
449
  current_index = row[:Key_name]
450
- indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [], [])
450
+ indexes << Mysql2IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [], [])
451
451
  end
452
452
 
453
453
  indexes.last.columns << row[:Column_name]
@@ -623,7 +623,7 @@ module ActiveRecord
623
623
 
624
624
  # increase timeout so mysql server doesn't disconnect us
625
625
  wait_timeout = @config[:wait_timeout]
626
- wait_timeout = 2592000 unless wait_timeout.is_a?(Fixnum)
626
+ wait_timeout = 2147483 unless wait_timeout.is_a?(Fixnum)
627
627
  variable_assignments << "@@wait_timeout = #{wait_timeout}"
628
628
 
629
629
  execute("SET #{variable_assignments.join(', ')}", :skip_logging)
@@ -24,7 +24,7 @@ module ActiveRecord
24
24
  fiber.resume(false)
25
25
  end
26
26
  @queue << fiber
27
- returning Fiber.yield do
27
+ Fiber.yield.tap do
28
28
  x.cancel
29
29
  end
30
30
  end
@@ -69,14 +69,8 @@ module ActiveRecord
69
69
  @checked_out = []
70
70
  end
71
71
 
72
- private
73
-
74
- def current_connection_id #:nodoc:
75
- Fiber.current.object_id
76
- end
77
-
78
- # Remove stale fibers from the cache.
79
- def remove_stale_cached_threads!(cache, &block)
72
+ def clear_stale_cached_connections!
73
+ cache = @reserved_connections
80
74
  keys = Set.new(cache.keys)
81
75
 
82
76
  ActiveRecord::ConnectionAdapters.fiber_pools.each do |pool|
@@ -87,11 +81,17 @@ module ActiveRecord
87
81
 
88
82
  keys.each do |key|
89
83
  next unless cache.has_key?(key)
90
- block.call(key, cache[key])
84
+ checkin cache[key]
91
85
  cache.delete(key)
92
86
  end
93
87
  end
94
88
 
89
+ private
90
+
91
+ def current_connection_id #:nodoc:
92
+ Fiber.current.object_id
93
+ end
94
+
95
95
  def checkout_and_verify(c)
96
96
  @checked_out << c
97
97
  c.run_callbacks :checkout
@@ -3,6 +3,7 @@ require 'date'
3
3
  require 'bigdecimal'
4
4
  require 'rational' unless RUBY_VERSION >= '1.9.2'
5
5
 
6
+ require 'mysql2/version' unless defined? Mysql2::VERSION
6
7
  require 'mysql2/error'
7
8
  require 'mysql2/mysql2'
8
9
  require 'mysql2/client'
@@ -12,5 +13,4 @@ require 'mysql2/result'
12
13
  #
13
14
  # A modern, simple and very fast Mysql library for Ruby - binding to libmysql
14
15
  module Mysql2
15
- VERSION = "0.2.6"
16
16
  end
@@ -24,6 +24,11 @@ module Mysql2
24
24
  # force the encoding to utf8
25
25
  self.charset_name = opts[:encoding] || 'utf8'
26
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
+
27
32
  ssl_set(*opts.values_at(:sslkey, :sslcert, :sslca, :sslcapath, :sslciper))
28
33
 
29
34
  user = opts[:username]
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'eventmachine' unless defined? EventMachine
4
- require 'mysql2' unless defined? Mysql2
3
+ require 'eventmachine'
4
+ require 'mysql2'
5
5
 
6
6
  module Mysql2
7
7
  module EM
@@ -23,10 +23,14 @@ module Mysql2
23
23
  end
24
24
 
25
25
  def query(sql, opts={})
26
- super(sql, opts.merge(:async => true))
27
- deferable = ::EM::DefaultDeferrable.new
28
- ::EM.watch(self.socket, Watcher, self, deferable).notify_readable = true
29
- deferable
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
30
34
  end
31
35
  end
32
36
  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,3 @@
1
+ module Mysql2
2
+ VERSION = "0.2.7"
3
+ end
@@ -1,89 +1,32 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
1
+ require File.expand_path('../lib/mysql2/version', __FILE__)
5
2
 
6
3
  Gem::Specification.new do |s|
7
4
  s.name = %q{mysql2}
8
- s.version = "0.2.6"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
5
+ s.version = Mysql2::VERSION
11
6
  s.authors = ["Brian Lopez"]
12
- s.date = %q{2010-10-19}
7
+ s.date = Time.now.utc.strftime("%Y-%m-%d")
13
8
  s.email = %q{seniorlopez@gmail.com}
14
9
  s.extensions = ["ext/mysql2/extconf.rb"]
15
10
  s.extra_rdoc_files = [
16
11
  "README.rdoc"
17
12
  ]
18
- s.files = [
19
- ".gitignore",
20
- ".rspec",
21
- "CHANGELOG.md",
22
- "MIT-LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "benchmark/active_record.rb",
27
- "benchmark/allocations.rb",
28
- "benchmark/escape.rb",
29
- "benchmark/query_with_mysql_casting.rb",
30
- "benchmark/query_without_mysql_casting.rb",
31
- "benchmark/sequel.rb",
32
- "benchmark/setup_db.rb",
33
- "examples/eventmachine.rb",
34
- "examples/threaded.rb",
35
- "ext/mysql2/client.c",
36
- "ext/mysql2/client.h",
37
- "ext/mysql2/extconf.rb",
38
- "ext/mysql2/mysql2_ext.c",
39
- "ext/mysql2/mysql2_ext.h",
40
- "ext/mysql2/result.c",
41
- "ext/mysql2/result.h",
42
- "lib/active_record/connection_adapters/em_mysql2_adapter.rb",
43
- "lib/active_record/connection_adapters/mysql2_adapter.rb",
44
- "lib/active_record/fiber_patches.rb",
45
- "lib/arel/engines/sql/compilers/mysql2_compiler.rb",
46
- "lib/mysql2.rb",
47
- "lib/mysql2/client.rb",
48
- "lib/mysql2/em.rb",
49
- "lib/mysql2/error.rb",
50
- "lib/mysql2/result.rb",
51
- "mysql2.gemspec",
52
- "spec/em/em_spec.rb",
53
- "spec/mysql2/client_spec.rb",
54
- "spec/mysql2/error_spec.rb",
55
- "spec/mysql2/result_spec.rb",
56
- "spec/rcov.opts",
57
- "spec/spec_helper.rb",
58
- "tasks/benchmarks.rake",
59
- "tasks/compile.rake",
60
- "tasks/jeweler.rake",
61
- "tasks/rspec.rake",
62
- "tasks/vendor_mysql.rake"
63
- ]
13
+ s.files = `git ls-files`.split("\n")
64
14
  s.homepage = %q{http://github.com/brianmario/mysql2}
65
15
  s.rdoc_options = ["--charset=UTF-8"]
66
16
  s.require_paths = ["lib", "ext"]
67
- s.rubygems_version = %q{1.3.7}
17
+ s.rubygems_version = %q{1.4.2}
68
18
  s.summary = %q{A simple, fast Mysql library for Ruby, binding to libmysql}
69
- s.test_files = [
70
- "spec/em/em_spec.rb",
71
- "spec/mysql2/client_spec.rb",
72
- "spec/mysql2/error_spec.rb",
73
- "spec/mysql2/result_spec.rb",
74
- "spec/spec_helper.rb",
75
- "examples/eventmachine.rb",
76
- "examples/threaded.rb"
77
- ]
78
-
79
- if s.respond_to? :specification_version then
80
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
81
- s.specification_version = 3
19
+ s.test_files = `git ls-files spec examples`.split("\n")
82
20
 
83
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
84
- else
85
- end
86
- else
87
- end
21
+ # tests
22
+ s.add_development_dependency 'eventmachine'
23
+ s.add_development_dependency 'rake-compiler', "~> 0.7.1"
24
+ s.add_development_dependency 'rspec'
25
+ # benchmarks
26
+ s.add_development_dependency 'activerecord'
27
+ s.add_development_dependency 'mysql'
28
+ s.add_development_dependency 'do_mysql'
29
+ s.add_development_dependency 'sequel'
30
+ s.add_development_dependency 'faker'
88
31
  end
89
32