diff --git a/.rubocop.yml b/.rubocop.yml index 5ebfb8bdf..8f634d507 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,31 +1,35 @@ inherit_from: .rubocop_todo.yml AllCops: + TargetRubyVersion: 1.9 + DisplayCopNames: true Exclude: - 'pkg/**/*' - 'tmp/**/*' - 'vendor/**/*' +Layout/CaseIndentation: + EnforcedStyle: end + +Layout/IndentHash: + EnforcedStyle: consistent + +Layout/IndentHeredoc: + EnforcedStyle: powerpack + Lint/EndAlignment: - AlignWith: variable + EnforcedStyleAlignWith: variable -Style/CaseIndentation: - IndentWhenRelativeTo: end +Style/Encoding: + AutoCorrectEncodingComment: '# encoding: UTF-8' + EnforcedStyle: always -Style/IndentHash: - EnforcedStyle: consistent +Style/TrailingCommaInArguments: + EnforcedStyleForMultiline: consistent_comma -Style/TrailingComma: +Style/TrailingCommaInLiteral: EnforcedStyleForMultiline: consistent_comma Style/TrivialAccessors: AllowPredicates: true - -# TODO: remove when we end support for < 1.9.3 - -Style/HashSyntax: - EnforcedStyle: hash_rockets - -Style/Lambda: - Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 92b70061b..e675d69af 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2015-09-06 13:16:09 -0400 using RuboCop version 0.34.0. +# on 2017-11-25 19:54:28 -0500 using RuboCop version 0.50.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -8,43 +8,54 @@ # Offense count: 2 Metrics/AbcSize: - Max: 93 + Max: 90 + +# Offense count: 31 +# Configuration parameters: CountComments, ExcludedMethods. +Metrics/BlockLength: + Max: 825 # Offense count: 1 +# Configuration parameters: CountBlocks. Metrics/BlockNesting: Max: 5 # Offense count: 1 +# Configuration parameters: CountComments. Metrics/ClassLength: Max: 125 -# Offense count: 2 +# Offense count: 3 Metrics/CyclomaticComplexity: Max: 30 -# Offense count: 290 -# Configuration parameters: AllowURI, URISchemes. +# Offense count: 313 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# URISchemes: http, https Metrics/LineLength: Max: 232 -# Offense count: 5 +# Offense count: 6 # Configuration parameters: CountComments. Metrics/MethodLength: - Max: 60 + Max: 57 -# Offense count: 1 +# Offense count: 2 Metrics/PerceivedComplexity: Max: 27 -# Offense count: 40 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. -Style/BlockDelimiters: - Enabled: false +# Offense count: 3 +# Configuration parameters: Blacklist. +# Blacklist: END, (?-mix:EO[A-Z]{1}) +Naming/HeredocDelimiterNaming: + Exclude: + - 'tasks/compile.rake' -# Offense count: 12 +# Offense count: 10 Style/Documentation: Exclude: + - 'spec/**/*' + - 'test/**/*' - 'benchmark/active_record.rb' - 'benchmark/allocations.rb' - 'benchmark/query_with_mysql_casting.rb' @@ -52,24 +63,24 @@ Style/Documentation: - 'lib/mysql2/client.rb' - 'lib/mysql2/em.rb' - 'lib/mysql2/error.rb' - - 'lib/mysql2/field.rb' - 'lib/mysql2/result.rb' - 'lib/mysql2/statement.rb' - - 'lib/mysql2/version.rb' -# Offense count: 9 +# Offense count: 14 # Configuration parameters: AllowedVariables. Style/GlobalVars: Exclude: - 'ext/mysql2/extconf.rb' -# Offense count: 14 +# Offense count: 17 # Cop supports --auto-correct. +# Configuration parameters: Strict. Style/NumericLiterals: MinDigits: 20 -# Offense count: 680 +# Offense count: 726 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. +# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes Style/StringLiterals: Enabled: false diff --git a/Gemfile b/Gemfile index 846e0fd53..3f64bcc33 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# encoding: UTF-8 + source 'https://rubygems.org' gemspec @@ -8,7 +10,9 @@ gem 'rake-compiler', '~> 1.0' group :test do gem 'eventmachine' unless RUBY_PLATFORM =~ /mswin|mingw/ gem 'rspec', '~> 3.2' - gem 'rubocop', '~> 0.34.0' + # https://github.com/bbatsov/rubocop/pull/3328 + # https://github.com/bbatsov/rubocop/pull/4789 + gem 'rubocop', '~> 0.50.0' unless RUBY_VERSION =~ /1.9/ end group :benchmarks do diff --git a/Rakefile b/Rakefile index 3d988cbc8..1b7a093cf 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'rake' # Load custom tasks (careful attention to define tasks before prerequisites) @@ -8,17 +9,11 @@ load 'tasks/compile.rake' load 'tasks/generate.rake' load 'tasks/benchmarks.rake' -# TODO: remove engine check when rubinius stops crashing on RuboCop -has_rubocop = if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' - begin - require 'rubocop/rake_task' - RuboCop::RakeTask.new - task :default => [:spec, :rubocop] - rescue LoadError # rubocop:disable Lint/HandleExceptions - end -end - -unless has_rubocop +begin + require 'rubocop/rake_task' + RuboCop::RakeTask.new + task default: [:spec, :rubocop] +rescue LoadError warn 'RuboCop is not available' - task :default => :spec + task default: :spec end diff --git a/benchmark/active_record.rb b/benchmark/active_record.rb index e25df0ce7..90191dcff 100644 --- a/benchmark/active_record.rb +++ b/benchmark/active_record.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -8,7 +9,7 @@ ActiveRecord::Base.default_timezone = :local ActiveRecord::Base.time_zone_aware_attributes = true -opts = { :database => 'test' } +opts = { database: 'test' } class TestModel < ActiveRecord::Base self.table_name = 'mysql2_test' @@ -17,12 +18,12 @@ class TestModel < ActiveRecord::Base batch_size = 1000 Benchmark.ips do |x| - %w(mysql mysql2).each do |adapter| - TestModel.establish_connection(opts.merge(:adapter => adapter)) + %w[mysql mysql2].each do |adapter| + TestModel.establish_connection(opts.merge(adapter: adapter)) x.report(adapter) do TestModel.limit(batch_size).to_a.each do |r| - r.attributes.keys.each do |k| + r.attributes.each_key do |k| r.send(k.to_sym) end end diff --git a/benchmark/active_record_threaded.rb b/benchmark/active_record_threaded.rb index f55f3a10f..013b2d57c 100644 --- a/benchmark/active_record_threaded.rb +++ b/benchmark/active_record_threaded.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -6,14 +7,14 @@ require 'active_record' number_of_threads = 25 -opts = { :database => 'test', :pool => number_of_threads } +opts = { database: 'test', pool: number_of_threads } Benchmark.ips do |x| - %w(mysql mysql2).each do |adapter| - ActiveRecord::Base.establish_connection(opts.merge(:adapter => adapter)) + %w[mysql mysql2].each do |adapter| + ActiveRecord::Base.establish_connection(opts.merge(adapter: adapter)) x.report(adapter) do - number_of_threads.times.map do + Array.new(number_of_threads) do Thread.new { ActiveRecord::Base.connection.execute('SELECT SLEEP(1)') } end.each(&:join) end diff --git a/benchmark/allocations.rb b/benchmark/allocations.rb index 4e3579313..372ffb9a2 100644 --- a/benchmark/allocations.rb +++ b/benchmark/allocations.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -13,7 +14,7 @@ class TestModel < ActiveRecord::Base def bench_allocations(feature, iterations = 10, batch_size = 1000) puts "GC overhead for #{feature}" - TestModel.establish_connection(:adapter => 'mysql2', :database => 'test') + TestModel.establish_connection(adapter: 'mysql2', database: 'test') GC::Profiler.clear GC::Profiler.enable iterations.times { yield batch_size } @@ -23,7 +24,7 @@ def bench_allocations(feature, iterations = 10, batch_size = 1000) bench_allocations('coercion') do |batch_size| TestModel.limit(batch_size).to_a.each do |r| - r.attributes.keys.each do |k| + r.attributes.each_key do |k| r.send(k.to_sym) end end diff --git a/benchmark/escape.rb b/benchmark/escape.rb index 2a666decd..fad2190e6 100644 --- a/benchmark/escape.rb +++ b/benchmark/escape.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -15,7 +16,7 @@ def run_escape_benchmarks(str) mysql.quote str end - mysql2 = Mysql2::Client.new(:host => "localhost", :username => "root") + mysql2 = Mysql2::Client.new(host: "localhost", username: "root") x.report "Mysql2 #{str.inspect}" do mysql2.escape str end diff --git a/benchmark/query_with_mysql_casting.rb b/benchmark/query_with_mysql_casting.rb index 7685926fa..33fa024f2 100644 --- a/benchmark/query_with_mysql_casting.rb +++ b/benchmark/query_with_mysql_casting.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -41,10 +42,10 @@ def mysql_cast(type, value) debug = ENV['DEBUG'] Benchmark.ips do |x| - mysql2 = Mysql2::Client.new(:host => "localhost", :username => "root") + mysql2 = Mysql2::Client.new(host: "localhost", username: "root") mysql2.query "USE #{database}" x.report "Mysql2" do - mysql2_result = mysql2.query sql, :symbolize_keys => true + mysql2_result = mysql2.query sql, symbolize_keys: true mysql2_result.each { |res| puts res.inspect if debug } end diff --git a/benchmark/query_without_mysql_casting.rb b/benchmark/query_without_mysql_casting.rb index 1afc7c9d3..1fc6af235 100644 --- a/benchmark/query_without_mysql_casting.rb +++ b/benchmark/query_without_mysql_casting.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' @@ -13,15 +14,15 @@ debug = ENV['DEBUG'] Benchmark.ips do |x| - mysql2 = Mysql2::Client.new(:host => "localhost", :username => "root") + mysql2 = Mysql2::Client.new(host: "localhost", username: "root") mysql2.query "USE #{database}" x.report "Mysql2 (cast: true)" do - mysql2_result = mysql2.query sql, :symbolize_keys => true, :cast => true + mysql2_result = mysql2.query sql, symbolize_keys: true, cast: true mysql2_result.each { |res| puts res.inspect if debug } end x.report "Mysql2 (cast: false)" do - mysql2_result = mysql2.query sql, :symbolize_keys => true, :cast => false + mysql2_result = mysql2.query sql, symbolize_keys: true, cast: false mysql2_result.each { |res| puts res.inspect if debug } end diff --git a/benchmark/sequel.rb b/benchmark/sequel.rb index 470ba36be..afd67654c 100644 --- a/benchmark/sequel.rb +++ b/benchmark/sequel.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') require 'rubygems' diff --git a/benchmark/setup_db.rb b/benchmark/setup_db.rb index 105d43ebc..6ba3033dd 100644 --- a/benchmark/setup_db.rb +++ b/benchmark/setup_db.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib') # This script is for generating psudo-random data into a single table consisting of nearly every @@ -49,7 +50,7 @@ ] # connect to localhost by default, pass options as needed -@client = Mysql2::Client.new :host => "localhost", :username => "root", :database => "test" +@client = Mysql2::Client.new host: "localhost", username: "root", database: "test" @client.query create_table_sql @client.query 'TRUNCATE mysql2_test' @@ -80,38 +81,38 @@ def insert_record(args) five_words = Faker::Lorem.words(rand(5)) twenty5_paragraphs = Faker::Lorem.paragraphs(rand(25)) insert_record( - :bit_test => 1, - :tiny_int_test => rand(128), - :small_int_test => rand(32767), - :medium_int_test => rand(8388607), - :int_test => rand(2147483647), - :big_int_test => rand(9223372036854775807), - :float_test => rand(32767) / 1.87, - :float_zero_test => 0.0, - :double_test => rand(8388607) / 1.87, - :decimal_test => rand(8388607) / 1.87, - :decimal_zero_test => 0, - :date_test => '2010-4-4', - :date_time_test => '2010-4-4 11:44:00', - :timestamp_test => '2010-4-4 11:44:00', - :time_test => '11:44:00', - :year_test => Time.now.year, - :char_test => five_words.join.slice(0, 10), # CHAR(10) - :varchar_test => five_words.join.slice(0, 10), # VARCHAR(10) - :binary_test => five_words.join.byteslice(0, 10), # BINARY(10) - :varbinary_test => five_words.join.byteslice(0, 10), # VARBINARY(10) - :tiny_blob_test => five_words.join.byteslice(0, 255), # TINYBLOB - :tiny_text_test => Faker::Lorem.paragraph(rand(5)).byteslice(0, 255), # TINYTEXT - :blob_test => twenty5_paragraphs, - :text_test => twenty5_paragraphs, - :medium_blob_test => twenty5_paragraphs, - :medium_text_test => twenty5_paragraphs, - :long_blob_test => twenty5_paragraphs, - :long_text_test => twenty5_paragraphs, - :enum_test => %w(val1 val2).sample, - :set_test => %w(val1 val2 val1,val2).sample, + bit_test: 1, + tiny_int_test: rand(128), + small_int_test: rand(32767), + medium_int_test: rand(8388607), + int_test: rand(2147483647), + big_int_test: rand(9223372036854775807), + float_test: rand(32767) / 1.87, + float_zero_test: 0.0, + double_test: rand(8388607) / 1.87, + decimal_test: rand(8388607) / 1.87, + decimal_zero_test: 0, + date_test: '2010-4-4', + date_time_test: '2010-4-4 11:44:00', + timestamp_test: '2010-4-4 11:44:00', + time_test: '11:44:00', + year_test: Time.now.year, + char_test: five_words.join.slice(0, 10), # CHAR(10) + varchar_test: five_words.join.slice(0, 10), # VARCHAR(10) + binary_test: five_words.join.byteslice(0, 10), # BINARY(10) + varbinary_test: five_words.join.byteslice(0, 10), # VARBINARY(10) + tiny_blob_test: five_words.join.byteslice(0, 255), # TINYBLOB + tiny_text_test: Faker::Lorem.paragraph(rand(5)).byteslice(0, 255), # TINYTEXT + blob_test: twenty5_paragraphs, + text_test: twenty5_paragraphs, + medium_blob_test: twenty5_paragraphs, + medium_text_test: twenty5_paragraphs, + long_blob_test: twenty5_paragraphs, + long_text_test: twenty5_paragraphs, + enum_test: %w[val1 val2].sample, + set_test: %w[val1 val2 val1,val2].sample, ) - if n % 100 == 0 + if (n % 100).zero? $stdout.putc '.' $stdout.flush end diff --git a/examples/threaded.rb b/examples/threaded.rb index 489edaf9c..eaf769f8b 100644 --- a/examples/threaded.rb +++ b/examples/threaded.rb @@ -6,12 +6,12 @@ # Should never exceed worst case 3.5 secs across all 20 threads Timeout.timeout(3.5) do - 20.times.map do + Array.new(20) do Thread.new do overhead = rand(3) puts ">> thread #{Thread.current.object_id} query, #{overhead} sec overhead" # 3 second overhead per query - Mysql2::Client.new(:host => "localhost", :username => "root").query("SELECT sleep(#{overhead}) as result") + Mysql2::Client.new(host: "localhost", username: "root").query("SELECT sleep(#{overhead}) as result") puts "<< thread #{Thread.current.object_id} result, #{overhead} sec overhead" end end.each(&:join) diff --git a/ext/mysql2/extconf.rb b/ext/mysql2/extconf.rb index c9350b45a..bb08556a2 100644 --- a/ext/mysql2/extconf.rb +++ b/ext/mysql2/extconf.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'mkmf' require 'English' @@ -13,7 +14,7 @@ def asplode(lib) end def add_ssl_defines(header) - all_modes_found = %w(SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY).inject(true) do |m, ssl_mode| + all_modes_found = %w[SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY].inject(true) do |m, ssl_mode| m && have_const(ssl_mode, header) end $CFLAGS << ' -DFULL_SSL_MODE_SUPPORT' if all_modes_found @@ -34,7 +35,7 @@ def add_ssl_defines(header) # borrowed from mysqlplus # http://github.com/oldmoe/mysqlplus/blob/master/ext/extconf.rb -dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w( +dirs = ENV.fetch('PATH').split(File::PATH_SEPARATOR) + %w[ /opt /opt/local /opt/local/mysql @@ -46,12 +47,12 @@ def add_ssl_defines(header) /usr/local/mysql-* /usr/local/lib/mysql5* /usr/local/opt/mysql5* -).map { |dir| dir << '/bin' } +].map { |dir| dir << '/bin' } # For those without HOMEBREW_ROOT in PATH dirs << "#{ENV['HOMEBREW_ROOT']}/bin" if ENV['HOMEBREW_ROOT'] -GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}" +GLOB = "{#{dirs.join(',')}}/{mysql_config,mysql_config5,mariadb_config}".freeze # If the user has provided a --with-mysql-dir argument, we must respect it or fail. inc, lib = dir_config('mysql') @@ -101,7 +102,7 @@ def add_ssl_defines(header) asplode 'mysql.h' end -%w(errmsg.h).each do |h| +%w[errmsg.h].each do |h| header = [prefix, h].compact.join('/') asplode h unless have_header header end @@ -151,7 +152,7 @@ def add_ssl_defines(header) case sanitizers when true # Try them all, turn on whatever we can - enabled_sanitizers = %w(address cfi integer memory thread undefined).select do |s| + enabled_sanitizers = %w[address cfi integer memory thread undefined].select do |s| try_link('int main() {return 0;}', "-Werror -fsanitize=#{s}") end abort "-----\nCould not enable any sanitizers!\n-----" if enabled_sanitizers.empty? diff --git a/lib/mysql2.rb b/lib/mysql2.rb index 9414a693d..4ec3198f6 100644 --- a/lib/mysql2.rb +++ b/lib/mysql2.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'date' require 'bigdecimal' @@ -23,7 +24,7 @@ if dll_path require 'Win32API' LoadLibrary = Win32API.new('Kernel32', 'LoadLibrary', ['P'], 'I') - if 0 == LoadLibrary.call(dll_path) + if LoadLibrary.call(dll_path).zero? abort "Failed to load libmysql.dll from #{dll_path}" end end diff --git a/lib/mysql2/client.rb b/lib/mysql2/client.rb index 8b63bc8ec..2c3a92d72 100644 --- a/lib/mysql2/client.rb +++ b/lib/mysql2/client.rb @@ -1,25 +1,27 @@ +# encoding: UTF-8 + module Mysql2 class Client attr_reader :query_options, :read_timeout def self.default_query_options @default_query_options ||= { - :as => :hash, # the type of object you want each row back as; also supports :array (an array of values) - :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 - :cast_booleans => false, # cast tinyint(1) fields as true/false in ruby - :symbolize_keys => false, # return field names as symbols instead of strings - :database_timezone => :local, # timezone Mysql2 will assume datetime objects are stored in - :application_timezone => nil, # timezone Mysql2 will convert to before handing the object back to the caller - :cache_rows => true, # tells Mysql2 to use its internal row cache for results - :connect_flags => REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION, - :cast => true, - :default_file => nil, - :default_group => nil, + as: :hash, # the type of object you want each row back as; also supports :array (an array of values) + 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 + cast_booleans: false, # cast tinyint(1) fields as true/false in ruby + symbolize_keys: false, # return field names as symbols instead of strings + database_timezone: :local, # timezone Mysql2 will assume datetime objects are stored in + application_timezone: nil, # timezone Mysql2 will convert to before handing the object back to the caller + cache_rows: true, # tells Mysql2 to use its internal row cache for results + connect_flags: REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION, + cast: true, + default_file: nil, + default_group: nil, } end def initialize(opts = {}) - fail Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash + raise Mysql2::Error, "Options parameter must be a Hash" unless opts.is_a? Hash opts = Mysql2::Util.key_hash_as_symbols(opts) @read_timeout = nil @query_options = self.class.default_query_options.dup @@ -50,15 +52,15 @@ def initialize(opts = {}) ssl_set(*ssl_options) if ssl_options.any? || opts.key?(:sslverify) self.ssl_mode = parse_ssl_mode(opts[:ssl_mode]) if opts[:ssl_mode] - case opts[:flags] + flags = case opts[:flags] when Array - flags = parse_flags_array(opts[:flags], @query_options[:connect_flags]) + parse_flags_array(opts[:flags], @query_options[:connect_flags]) when String - flags = parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags]) + parse_flags_array(opts[:flags].split(' '), @query_options[:connect_flags]) when Integer - flags = @query_options[:connect_flags] | opts[:flags] + @query_options[:connect_flags] | opts[:flags] else - flags = @query_options[:connect_flags] + @query_options[:connect_flags] end # SSL verify is a connection flag rather than a mysql_ssl_set option diff --git a/lib/mysql2/console.rb b/lib/mysql2/console.rb index d8fb9e324..1e3885ffa 100644 --- a/lib/mysql2/console.rb +++ b/lib/mysql2/console.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + # Loaded by script/console. Land helpers here. Pry.config.prompt = lambda do |context, *| diff --git a/lib/mysql2/em.rb b/lib/mysql2/em.rb index b4210f089..381a2a739 100644 --- a/lib/mysql2/em.rb +++ b/lib/mysql2/em.rb @@ -17,7 +17,7 @@ def notify_readable detach begin result = @client.async_result - rescue => e + rescue StandardError => e @deferable.fail(e) else @deferable.succeed(result) @@ -41,7 +41,7 @@ def close(*args) def query(sql, opts = {}) if ::EM.reactor_running? - super(sql, opts.merge(:async => true)) + super(sql, opts.merge(async: true)) deferable = ::EM::DefaultDeferrable.new @watch = ::EM.watch(socket, Watcher, self, deferable) @watch.notify_readable = true diff --git a/lib/mysql2/error.rb b/lib/mysql2/error.rb index d75a0ca84..a66fce45d 100644 --- a/lib/mysql2/error.rb +++ b/lib/mysql2/error.rb @@ -3,16 +3,16 @@ module Mysql2 class Error < StandardError ENCODE_OPTS = { - :undef => :replace, - :invalid => :replace, - :replace => '?'.freeze, + undef: :replace, + invalid: :replace, + replace: '?'.freeze, }.freeze attr_reader :error_number, :sql_state # Mysql gem compatibility - alias_method :errno, :error_number - alias_method :error, :message + alias errno error_number + alias error message def initialize(msg) @server_version ||= nil diff --git a/lib/mysql2/field.rb b/lib/mysql2/field.rb index 516ec17c2..94a006739 100644 --- a/lib/mysql2/field.rb +++ b/lib/mysql2/field.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + module Mysql2 Field = Struct.new(:name, :type) end diff --git a/lib/mysql2/result.rb b/lib/mysql2/result.rb index 585104e0b..255026a2b 100644 --- a/lib/mysql2/result.rb +++ b/lib/mysql2/result.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + module Mysql2 class Result attr_reader :server_flags diff --git a/lib/mysql2/statement.rb b/lib/mysql2/statement.rb index 5b3752651..482ccce19 100644 --- a/lib/mysql2/statement.rb +++ b/lib/mysql2/statement.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + module Mysql2 class Statement include Enumerable diff --git a/lib/mysql2/version.rb b/lib/mysql2/version.rb index f7d30593d..2afa42fc0 100644 --- a/lib/mysql2/version.rb +++ b/lib/mysql2/version.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + module Mysql2 - VERSION = "0.4.10" + VERSION = "0.4.10".freeze end diff --git a/mysql2.gemspec b/mysql2.gemspec index 1c5b42f0f..3e9d4e5e3 100644 --- a/mysql2.gemspec +++ b/mysql2.gemspec @@ -1,3 +1,5 @@ +# encoding: UTF-8 + require File.expand_path('../lib/mysql2/version', __FILE__) Mysql2::GEMSPEC = Gem::Specification.new do |s| diff --git a/spec/em/em_spec.rb b/spec/em/em_spec.rb index d676e2f93..4daab27bc 100644 --- a/spec/em/em_spec.rb +++ b/spec/em/em_spec.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'spec_helper' begin require 'eventmachine' @@ -49,13 +50,13 @@ end it "should not swallow exceptions raised in callbacks" do - expect { + expect do EM.run do client = Mysql2::EM::Client.new DatabaseCredentials['root'] defer = client.query "SELECT sleep(0.1) as first_query" defer.callback do client.close - fail 'some error' + raise 'some error' end defer.errback do # This _shouldn't_ be run, but it needed to prevent the specs from @@ -63,7 +64,7 @@ EM.stop_event_loop end end - }.to raise_error('some error') + end.to raise_error('some error') end context 'when an exception is raised by the client' do @@ -123,9 +124,9 @@ end EM.add_timer(0.1) do expect(callbacks_run).to eq([:callback]) - expect { + expect do client.close - }.not_to raise_error + end.not_to raise_error EM.stop_event_loop end end diff --git a/spec/mysql2/client_spec.rb b/spec/mysql2/client_spec.rb index c628acc82..a11bf8bde 100644 --- a/spec/mysql2/client_spec.rb +++ b/spec/mysql2/client_spec.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'spec_helper' RSpec.describe Mysql2::Client do @@ -6,46 +7,46 @@ let(:cnf_file) { File.expand_path('../../my.cnf', __FILE__) } it "should not raise an exception for valid defaults group" do - expect { - new_client(:default_file => cnf_file, :default_group => "test") - }.not_to raise_error + expect do + new_client(default_file: cnf_file, default_group: "test") + end.not_to raise_error end it "should not raise an exception without default group" do - expect { - new_client(:default_file => cnf_file) - }.not_to raise_error + expect do + new_client(default_file: cnf_file) + end.not_to raise_error end end it "should raise an exception upon connection failure" do - expect { + expect do # The odd local host IP address forces the mysql client library to # use a TCP socket rather than a domain socket. new_client('host' => '127.0.0.2', 'port' => 999999) - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "should raise an exception on create for invalid encodings" do - expect { - new_client(:encoding => "fake") - }.to raise_error(Mysql2::Error) + expect do + new_client(encoding: "fake") + end.to raise_error(Mysql2::Error) end it "should raise an exception on non-string encodings" do - expect { - new_client(:encoding => :fake) - }.to raise_error(TypeError) + expect do + new_client(encoding: :fake) + end.to raise_error(TypeError) end it "should not raise an exception on create for a valid encoding" do - expect { - new_client(:encoding => "utf8") - }.not_to raise_error + expect do + new_client(encoding: "utf8") + end.not_to raise_error - expect { - new_client(DatabaseCredentials['root'].merge(:encoding => "big5")) - }.not_to raise_error + expect do + new_client(DatabaseCredentials['root'].merge(encoding: "big5")) + end.not_to raise_error end Klient = Class.new(Mysql2::Client) do @@ -57,18 +58,18 @@ def connect(*args) end it "should accept connect flags and pass them to #connect" do - client = Klient.new :flags => Mysql2::Client::FOUND_ROWS + client = Klient.new flags: Mysql2::Client::FOUND_ROWS expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to be > 0 end it "should parse flags array" do - client = Klient.new :flags => %w( FOUND_ROWS -PROTOCOL_41 ) + client = Klient.new flags: %w[FOUND_ROWS -PROTOCOL_41] expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS) expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0) end it "should parse flags string" do - client = Klient.new :flags => "FOUND_ROWS -PROTOCOL_41" + client = Klient.new flags: "FOUND_ROWS -PROTOCOL_41" expect(client.connect_args.last[6] & Mysql2::Client::FOUND_ROWS).to eql(Mysql2::Client::FOUND_ROWS) expect(client.connect_args.last[6] & Mysql2::Client::PROTOCOL_41).to eql(0) end @@ -135,7 +136,7 @@ def connect(*args) # You may need to adjust the lines below to match your SSL certificate paths ssl_client = nil - expect { + expect do ssl_client = new_client( 'host' => 'mysql2gem.example.com', # must match the certificates :sslkey => '/etc/mysql/client-key.pem', @@ -144,7 +145,7 @@ def connect(*args) :sslcipher => 'DHE-RSA-AES256-SHA', :sslverify => true, ) - }.not_to raise_error + end.not_to raise_error results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }] expect(results['Ssl_cipher']).not_to be_empty @@ -164,7 +165,8 @@ def run_gc end it "should terminate connections when calling close" do - expect { + # rubocop:disable Lint/AmbiguousBlockAssociation + expect do client = Mysql2::Client.new(DatabaseCredentials['root']) connection_id = client.thread_id client.close @@ -178,27 +180,30 @@ def run_gc sleep(0.1) end expect(closed).to eq(true) - }.to_not change { + end.to_not change { @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a } + # rubocop:enable Lint/AmbiguousBlockAssociation end it "should not leave dangling connections after garbage collection" do run_gc - expect { - expect { + # rubocop:disable Lint/AmbiguousBlockAssociation + expect do + expect do 10.times do Mysql2::Client.new(DatabaseCredentials['root']).query('SELECT 1') end - }.to change { + end.to change { @client.query("SHOW STATUS LIKE 'Threads_connected'").first['Value'].to_i }.by(10) run_gc - }.to_not change { + end.to_not change { @client.query("SHOW STATUS LIKE 'Aborted_%'").to_a + @client.query("SHOW STATUS LIKE 'Threads_connected'").to_a } + # rubocop:enable Lint/AmbiguousBlockAssociation end context "#automatic_close" do @@ -209,24 +214,24 @@ def run_gc if RUBY_PLATFORM =~ /mingw|mswin/ it "cannot be disabled" do expect do - client = new_client(:automatic_close => false) + client = new_client(automatic_close: false) expect(client.automatic_close?).to be(true) end.to output(/always closed by garbage collector/).to_stderr expect do - client = new_client(:automatic_close => true) + client = new_client(automatic_close: true) expect(client.automatic_close?).to be(true) end.to_not output(/always closed by garbage collector/).to_stderr expect do - client = new_client(:automatic_close => true) + client = new_client(automatic_close: true) client.automatic_close = false expect(client.automatic_close?).to be(true) end.to output(/always closed by garbage collector/).to_stderr end else it "can be configured" do - client = new_client(:automatic_close => false) + client = new_client(automatic_close: false) expect(client.automatic_close?).to be(false) end @@ -270,9 +275,9 @@ def run_gc database = 1235 @client.query "CREATE DATABASE IF NOT EXISTS `#{database}`" - expect { + expect do new_client('database' => database) - }.not_to raise_error + end.not_to raise_error @client.query "DROP DATABASE IF EXISTS `#{database}`" end @@ -283,9 +288,9 @@ def run_gc it "should be able to close properly" do expect(@client.close).to be_nil - expect { + expect do @client.query "SELECT 1" - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end context "#closed?" do @@ -300,11 +305,11 @@ def run_gc end it "should not try to query closed mysql connection" do - client = new_client(:reconnect => true) + client = new_client(reconnect: true) expect(client.close).to be_nil - expect { + expect do client.query "SELECT 1" - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "should respond to #query" do @@ -353,7 +358,7 @@ def run_gc # # Note that mysql_info() returns a non-NULL value for INSERT ... VALUES only for the multiple-row form of the statement (that is, only if multiple value lists are specified). @client.query("INSERT INTO infoTest (blah) VALUES (1234),(4535)") - expect(@client.query_info).to eql(:records => 2, :duplicates => 0, :warnings => 0) + expect(@client.query_info).to eql(records: 2, duplicates: 0, warnings: 0) expect(@client.query_info_string).to eq('Records: 2 Duplicates: 0 Warnings: 0') @client.query "DROP TABLE infoTest" @@ -363,7 +368,7 @@ def run_gc context ":local_infile" do before(:all) do - new_client(:local_infile => true) do |client| + new_client(local_infile: true) do |client| local = client.query "SHOW VARIABLES LIKE 'local_infile'" local_enabled = local.any? { |x| x['Value'] == 'ON' } skip("DON'T WORRY, THIS TEST PASSES - but LOCAL INFILE is not enabled in your MySQL daemon.") unless local_enabled @@ -385,24 +390,24 @@ def run_gc end it "should raise an error when local_infile is disabled" do - client = new_client(:local_infile => false) - expect { + client = new_client(local_infile: false) + expect do client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest" - }.to raise_error(Mysql2::Error, /command is not allowed/) + end.to raise_error(Mysql2::Error, /command is not allowed/) end it "should raise an error when a non-existent file is loaded" do - client = new_client(:local_infile => true) - expect { + client = new_client(local_infile: true) + expect do client.query "LOAD DATA LOCAL INFILE 'this/file/is/not/here' INTO TABLE infileTest" - }.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here') + end.to raise_error(Mysql2::Error, 'No such file or directory: this/file/is/not/here') end it "should LOAD DATA LOCAL INFILE" do - client = new_client(:local_infile => true) + client = new_client(local_infile: true) client.query "LOAD DATA LOCAL INFILE 'spec/test_data' INTO TABLE infileTest" info = client.query_info - expect(info).to eql(:records => 1, :deleted => 0, :skipped => 0, :warnings => 0) + expect(info).to eql(records: 1, deleted: 0, skipped: 0, warnings: 0) result = client.query "SELECT * FROM infileTest" expect(result.first).to eql('id' => 1, 'foo' => 'Hello', 'bar' => 'World') @@ -410,25 +415,25 @@ def run_gc end it "should expect connect_timeout to be a positive integer" do - expect { - new_client(:connect_timeout => -1) - }.to raise_error(Mysql2::Error) + expect do + new_client(connect_timeout: -1) + end.to raise_error(Mysql2::Error) end it "should expect read_timeout to be a positive integer" do - expect { - new_client(:read_timeout => -1) - }.to raise_error(Mysql2::Error) + expect do + new_client(read_timeout: -1) + end.to raise_error(Mysql2::Error) end it "should expect write_timeout to be a positive integer" do - expect { - new_client(:write_timeout => -1) - }.to raise_error(Mysql2::Error) + expect do + new_client(write_timeout: -1) + end.to raise_error(Mysql2::Error) end it "should allow nil read_timeout" do - client = new_client(:read_timeout => nil) + client = new_client(read_timeout: nil) expect(client.read_timeout).to be_nil end @@ -443,7 +448,7 @@ def run_gc end it "should set custom connect_attrs" do - client = new_client(:connect_attrs => { :program_name => 'my_program_name', :foo => 'fooval', :bar => 'barval' }) + client = new_client(connect_attrs: { program_name: 'my_program_name', foo: 'fooval', bar: 'barval' }) if Mysql2::Client.info[:version] < '5.6' || client.info[:version] < '5.6' pending('Both client and server versions must be MySQL 5.6 or later.') end @@ -455,32 +460,32 @@ def run_gc context "#query" do it "should let you query again if iterating is finished when streaming" do - @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false).each.to_a + @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).each.to_a - expect { - @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false) - }.to_not raise_error + expect do + @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false) + end.to_not raise_error end it "should not let you query again if iterating is not finished when streaming" do - @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false).first + @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false).first - expect { - @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false) - }.to raise_exception(Mysql2::Error) + expect do + @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false) + end.to raise_exception(Mysql2::Error) end it "should only accept strings as the query parameter" do - expect { + expect do @client.query ["SELECT 'not right'"] - }.to raise_error(TypeError) + end.to raise_error(TypeError) end it "should not retain query options set on a query for subsequent queries, but should retain it in the result" do - result = @client.query "SELECT 1", :something => :else + result = @client.query "SELECT 1", something: :else expect(@client.query_options[:something]).to be_nil - expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(:something => :else)) - expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(:something => :else)) + expect(result.instance_variable_get('@query_options')).to eql(@client.query_options.merge(something: :else)) + expect(@client.instance_variable_get('@current_query_options')).to eql(@client.query_options.merge(something: :else)) result = @client.query "SELECT 1" expect(result.instance_variable_get('@query_options')).to eql(@client.query_options) @@ -488,7 +493,7 @@ def run_gc end it "should allow changing query options for subsequent queries" do - @client.query_options.merge!(:something => :else) + @client.query_options[:something] = :else result = @client.query "SELECT 1" expect(@client.query_options[:something]).to eql(:else) expect(result.instance_variable_get('@query_options')[:something]).to eql(:else) @@ -503,19 +508,19 @@ def run_gc end it "should be able to return results as an array" do - expect(@client.query("SELECT 1", :as => :array).first).to be_an_instance_of(Array) - @client.query("SELECT 1").each(:as => :array) + expect(@client.query("SELECT 1", as: :array).first).to be_an_instance_of(Array) + @client.query("SELECT 1").each(as: :array) end it "should be able to return results with symbolized keys" do - expect(@client.query("SELECT 1", :symbolize_keys => true).first.keys[0]).to be_an_instance_of(Symbol) + expect(@client.query("SELECT 1", symbolize_keys: true).first.keys[0]).to be_an_instance_of(Symbol) end it "should require an open connection" do @client.close - expect { + expect do @client.query "SELECT 1" - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "should detect closed connection on query read error" do @@ -526,37 +531,37 @@ def run_gc supervisor.query("KILL #{connection_id}") end.close end - expect { + expect do @client.query("SELECT SLEEP(1)") - }.to raise_error(Mysql2::Error, /Lost connection to MySQL server/) + end.to raise_error(Mysql2::Error, /Lost connection to MySQL server/) if RUBY_PLATFORM !~ /mingw|mswin/ - expect { + expect do @client.socket - }.to raise_error(Mysql2::Error, 'MySQL client is not connected') + end.to raise_error(Mysql2::Error, 'MySQL client is not connected') end end if RUBY_PLATFORM !~ /mingw|mswin/ it "should not allow another query to be sent without fetching a result first" do - @client.query("SELECT 1", :async => true) - expect { + @client.query("SELECT 1", async: true) + expect do @client.query("SELECT 1") - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "should describe the thread holding the active query" do - thr = Thread.new { @client.query("SELECT 1", :async => true) } + thr = Thread.new { @client.query("SELECT 1", async: true) } thr.join expect { @client.query('SELECT 1') }.to raise_error(Mysql2::Error, Regexp.new(Regexp.escape(thr.inspect))) end it "should timeout if we wait longer than :read_timeout" do - client = new_client(:read_timeout => 0) - expect { + client = new_client(read_timeout: 0) + expect do client.query('SELECT SLEEP(0.1)') - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end # XXX this test is not deterministic (because Unix signal handling is not) @@ -596,9 +601,9 @@ def run_gc it "#socket should require an open connection" do @client.close - expect { + expect do @client.socket - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it 'should be impervious to connection-corrupting timeouts in #execute' do @@ -626,7 +631,7 @@ def run_gc pending('MySQL 5.5 on OSX is afflicted by an unknown bug that breaks this test. See #633 and #634.') end - client = new_client(:reconnect => true) + client = new_client(reconnect: true) expect { Timeout.timeout(0.1, ArgumentError) { client.query('SELECT SLEEP(1)') } }.to raise_error(ArgumentError) expect { client.query('SELECT 1') }.to_not raise_error @@ -653,7 +658,7 @@ def run_gc sleep_time = 0.5 # Note that each thread opens its own database connection - threads = 5.times.map do + threads = Array.new(5) do Thread.new do new_client do |client| client.query("SELECT SLEEP(#{sleep_time})") @@ -672,17 +677,11 @@ def run_gc it "evented async queries should be supported" do skip("ruby 1.8 doesn't support IO.for_fd options") if RUBY_VERSION.start_with?("1.8.") # should immediately return nil - expect(@client.query("SELECT sleep(0.1)", :async => true)).to eql(nil) + expect(@client.query("SELECT sleep(0.1)", async: true)).to eql(nil) - io_wrapper = IO.for_fd(@client.socket, :autoclose => false) + io_wrapper = IO.for_fd(@client.socket, autoclose: false) loops = 0 - loop do - if IO.select([io_wrapper], nil, nil, 0.05) - break - else - loops += 1 - end - end + loops += 1 until IO.select([io_wrapper], nil, nil, 0.05) # make sure we waited some period of time expect(loops >= 1).to be true @@ -694,15 +693,15 @@ def run_gc context "Multiple results sets" do before(:each) do - @multi_client = new_client(:flags => Mysql2::Client::MULTI_STATEMENTS) + @multi_client = new_client(flags: Mysql2::Client::MULTI_STATEMENTS) end it "should raise an exception when one of multiple statements fails" do result = @multi_client.query("SELECT 1 AS 'set_1'; SELECT * FROM invalid_table_name; SELECT 2 AS 'set_2';") expect(result.first['set_1']).to be(1) - expect { + expect do @multi_client.next_result - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) expect(@multi_client.next_result).to be false end @@ -724,17 +723,17 @@ def run_gc it "will raise on query if there are outstanding results to read" do @multi_client.query("SELECT 1; SELECT 2; SELECT 3") - expect { + expect do @multi_client.query("SELECT 4") - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "#abandon_results! should work" do @multi_client.query("SELECT 1; SELECT 2; SELECT 3") @multi_client.abandon_results! - expect { + expect do @multi_client.query("SELECT 4") - }.not_to raise_error + end.not_to raise_error end it "#more_results? should work" do @@ -770,9 +769,9 @@ def run_gc if RUBY_PLATFORM =~ /mingw|mswin/ it "#socket should raise as it's not supported" do - expect { + expect do @client.socket - }.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/) + end.to raise_error(Mysql2::Error, /Raw access to the mysql file descriptor isn't supported on Windows/) end end @@ -791,15 +790,15 @@ def run_gc end it "should not overflow the thread stack" do - expect { + expect do Thread.new { Mysql2::Client.escape("'" * 256 * 1024) }.join - }.not_to raise_error + end.not_to raise_error end it "should not overflow the process stack" do - expect { + expect do Thread.new { Mysql2::Client.escape("'" * 1024 * 1024 * 4) }.join - }.not_to raise_error + end.not_to raise_error end it "should carry over the original string's encoding" do @@ -828,26 +827,26 @@ def run_gc end it "should not overflow the thread stack" do - expect { + expect do Thread.new { @client.escape("'" * 256 * 1024) }.join - }.not_to raise_error + end.not_to raise_error end it "should not overflow the process stack" do - expect { + expect do Thread.new { @client.escape("'" * 1024 * 1024 * 4) }.join - }.not_to raise_error + end.not_to raise_error end it "should require an open connection" do @client.close - expect { + expect do @client.escape "" - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end context 'when mysql encoding is not utf8' do - let(:client) { new_client(:encoding => "ujis") } + let(:client) { new_client(encoding: "ujis") } it 'should return a internal encoding string if Encoding.default_internal is set' do with_internal_encoding Encoding::UTF_8 do @@ -900,9 +899,9 @@ def run_gc it "#server_info should require an open connection" do @client.close - expect { + expect do @client.server_info - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end context "strings returned by #server_info" do @@ -910,7 +909,7 @@ def run_gc with_internal_encoding nil do expect(@client.server_info[:version].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') expect(client2.server_info[:version].encoding).to eql(Encoding::ASCII) end end @@ -927,13 +926,13 @@ def run_gc end it "should raise a Mysql2::Error exception upon connection failure" do - expect { - new_client(:host => "localhost", :username => 'asdfasdf8d2h', :password => 'asdfasdfw42') - }.to raise_error(Mysql2::Error) + expect do + new_client(host: "localhost", username: 'asdfasdf8d2h', password: 'asdfasdfw42') + end.to raise_error(Mysql2::Error) - expect { + expect do new_client(DatabaseCredentials['root']) - }.not_to raise_error + end.not_to raise_error end context 'write operations api' do @@ -1018,9 +1017,9 @@ def run_gc end it "should raise a Mysql2::Error when the database doesn't exist" do - expect { + expect do @client.select_db("nopenothere") - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) end it "should return the database switched to" do @@ -1035,7 +1034,7 @@ def run_gc end it "should be able to connect using plaintext password" do - client = new_client(:enable_cleartext_plugin => true) + client = new_client(enable_cleartext_plugin: true) client.query('SELECT 1') end diff --git a/spec/mysql2/result_spec.rb b/spec/mysql2/result_spec.rb index f3b5a9350..f1386b16c 100644 --- a/spec/mysql2/result_spec.rb +++ b/spec/mysql2/result_spec.rb @@ -1,4 +1,5 @@ # encoding: UTF-8 + require 'spec_helper' RSpec.describe Mysql2::Result do @@ -27,13 +28,13 @@ end it "should raise a Mysql2::Error exception upon a bad query" do - expect { + expect do @client.query "bad sql" - }.to raise_error(Mysql2::Error) + end.to raise_error(Mysql2::Error) - expect { + expect do @client.query "SELECT 1" - }.not_to raise_error + end.not_to raise_error end it "should respond to #count, which is aliased as #size" do @@ -62,13 +63,13 @@ end it "should yield rows as hash's with symbol keys if :symbolize_keys was set to true" do - @result.each(:symbolize_keys => true) do |row| + @result.each(symbolize_keys: true) do |row| expect(row.keys.first).to be_an_instance_of(Symbol) end end it "should be able to return results as an array" do - @result.each(:as => :array) do |row| + @result.each(as: :array) do |row| expect(row).to be_an_instance_of(Array) end end @@ -78,32 +79,32 @@ end it "should not cache previously yielded results if cache_rows is disabled" do - result = @client.query "SELECT 1", :cache_rows => false + result = @client.query "SELECT 1", cache_rows: false expect(result.first.object_id).not_to eql(result.first.object_id) end it "should be able to iterate a second time even if cache_rows is disabled" do - result = @client.query "SELECT 1 UNION SELECT 2", :cache_rows => false + result = @client.query "SELECT 1 UNION SELECT 2", cache_rows: false expect(result.to_a).to eql(result.to_a) end it "should yield different value for #first if streaming" do - result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false + result = @client.query "SELECT 1 UNION SELECT 2", stream: true, cache_rows: false expect(result.first).not_to eql(result.first) end it "should yield the same value for #first if streaming is disabled" do - result = @client.query "SELECT 1 UNION SELECT 2", :stream => false + result = @client.query "SELECT 1 UNION SELECT 2", stream: false expect(result.first).to eql(result.first) end it "should throw an exception if we try to iterate twice when streaming is enabled" do - result = @client.query "SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false + result = @client.query "SELECT 1 UNION SELECT 2", stream: true, cache_rows: false - expect { + expect do result.each.to_a result.each.to_a - }.to raise_exception(Mysql2::Error) + end.to raise_exception(Mysql2::Error) end end @@ -118,20 +119,20 @@ it "should return an array of field names in proper order" do result = @client.query "SELECT 'a', 'b', 'c'" - expect(result.fields).to eql(%w(a b c)) + expect(result.fields).to eql(%w[a b c]) end end context "streaming" do it "should maintain a count while streaming" do - result = @client.query('SELECT 1', :stream => true, :cache_rows => false) + result = @client.query('SELECT 1', stream: true, cache_rows: false) expect(result.count).to eql(0) result.each.to_a expect(result.count).to eql(1) end it "should retain the count when mixing first and each" do - result = @client.query("SELECT 1 UNION SELECT 2", :stream => true, :cache_rows => false) + result = @client.query("SELECT 1 UNION SELECT 2", stream: true, cache_rows: false) expect(result.count).to eql(0) result.first expect(result.count).to eql(1) @@ -140,13 +141,13 @@ end it "should not yield nil at the end of streaming" do - result = @client.query('SELECT * FROM mysql2_test', :stream => true, :cache_rows => false) + result = @client.query('SELECT * FROM mysql2_test', stream: true, cache_rows: false) result.each { |r| expect(r).not_to be_nil } end it "#count should be zero for rows after streaming when there were no results" do @client.query "USE test" - result = @client.query("SELECT * FROM mysql2_test WHERE null_test IS NOT NULL", :stream => true, :cache_rows => false) + result = @client.query("SELECT * FROM mysql2_test WHERE null_test IS NOT NULL", stream: true, cache_rows: false) expect(result.count).to eql(0) result.each.to_a expect(result.count).to eql(0) @@ -162,14 +163,14 @@ end @client.query "SET net_write_timeout = 1" - res = @client.query "SELECT * FROM streamingTest", :stream => true, :cache_rows => false + res = @client.query "SELECT * FROM streamingTest", stream: true, cache_rows: false - expect { + expect do res.each_with_index do |_, i| # Exhaust the first result packet then trigger a timeout sleep 2 if i > 0 && i % 1000 == 0 end - }.to raise_error(Mysql2::Error, /Lost connection/) + end.to raise_error(Mysql2::Error, /Lost connection/) end end @@ -179,7 +180,7 @@ end it "should return nil values for NULL and strings for everything else when :cast is false" do - result = @client.query('SELECT null_test, tiny_int_test, bool_cast_test, int_test, date_test, enum_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast => false).first + result = @client.query('SELECT null_test, tiny_int_test, bool_cast_test, int_test, date_test, enum_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', cast: false).first expect(result["null_test"]).to be_nil expect(result["tiny_int_test"]).to eql("1") expect(result["bool_cast_test"]).to eql("1") @@ -220,9 +221,9 @@ end it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do - result1 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id1} LIMIT 1", :cast_booleans => true - result2 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id2} LIMIT 1", :cast_booleans => true - result3 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id3} LIMIT 1", :cast_booleans => true + result1 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id1} LIMIT 1", cast_booleans: true + result2 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id2} LIMIT 1", cast_booleans: true + result3 = @client.query "SELECT bool_cast_test FROM mysql2_test WHERE id = #{id3} LIMIT 1", cast_booleans: true expect(result1.first['bool_cast_test']).to be true expect(result2.first['bool_cast_test']).to be false expect(result3.first['bool_cast_test']).to be true @@ -240,8 +241,8 @@ end it "should return TrueClass or FalseClass for a BIT(1) value if :cast_booleans is enabled" do - result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", :cast_booleans => true - result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", :cast_booleans => true + result1 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id1}", cast_booleans: true + result2 = @client.query "SELECT single_bit_test FROM mysql2_test WHERE id = #{id2}", cast_booleans: true expect(result1.first['single_bit_test']).to be true expect(result2.first['single_bit_test']).to be false end @@ -333,7 +334,7 @@ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['enum_test'].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['enum_test'].encoding).to eql(Encoding::ASCII) end @@ -363,7 +364,7 @@ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['set_test'].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['set_test'].encoding).to eql(Encoding::ASCII) end @@ -427,7 +428,7 @@ end context "string encoding for #{type} values" do - if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type) + if %w[VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB].include?(type) it "should default to binary if Encoding.default_internal is nil" do with_internal_encoding nil do result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first @@ -452,7 +453,7 @@ result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result[field].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result[field].encoding).to eql(Encoding::ASCII) end diff --git a/spec/mysql2/statement_spec.rb b/spec/mysql2/statement_spec.rb index 76e20b5bf..327d4eb5c 100644 --- a/spec/mysql2/statement_spec.rb +++ b/spec/mysql2/statement_spec.rb @@ -1,9 +1,10 @@ # encoding: UTF-8 + require './spec/spec_helper.rb' RSpec.describe Mysql2::Statement do before :each do - @client = new_client(:encoding => "utf8") + @client = new_client(encoding: "utf8") end def stmt_count @@ -195,7 +196,7 @@ def stmt_count end it "should warn but still work if cache_rows is set to false" do - @client.query_options.merge!(:cache_rows => false) + @client.query_options[:cache_rows] = false statement = @client.prepare 'SELECT 1' result = nil expect { result = statement.execute.to_a }.to output(/:cache_rows is forced for prepared statements/).to_stderr @@ -217,7 +218,7 @@ def stmt_count it "should be able to retrieve utf8 field names correctly" do stmt = @client.prepare 'SELECT * FROM `テーブル`' - expect(stmt.fields).to eq(%w(整数 文字列)) + expect(stmt.fields).to eq(%w[整数 文字列]) result = stmt.execute expect(result.to_a).to eq([{ "整数" => 1, "文字列" => "イチ" }, { "整数" => 2, "文字列" => "弐" }, { "整数" => 3, "文字列" => "さん" }]) @@ -248,7 +249,7 @@ def stmt_count n = 1 stmt = @client.prepare("SELECT 1 UNION SELECT 2") - @client.query_options.merge!(:stream => true, :cache_rows => false, :as => :array) + @client.query_options.merge!(stream: true, cache_rows: false, as: :array) stmt.execute.each do |r| case n @@ -323,10 +324,10 @@ def stmt_count result = @client.prepare("SELECT 1 UNION SELECT 2").execute - expect { + expect do result.each {} result.each {} - }.to raise_exception(Mysql2::Error) + end.to raise_exception(Mysql2::Error) @client.query_options[:stream] = false @client.query_options[:cache_rows] = true @@ -341,7 +342,7 @@ def stmt_count it "should return an array of field names in proper order" do stmt = @client.prepare("SELECT 'a', 'b', 'c'") - expect(stmt.fields).to eql(%w(a b c)) + expect(stmt.fields).to eql(%w[a b c]) end it "should return nil for statement with no result fields" do @@ -378,7 +379,7 @@ def stmt_count context "cast booleans for TINYINT if :cast_booleans is enabled" do # rubocop:disable Style/Semicolon - let(:client) { new_client(:cast_booleans => true) } + let(:client) { new_client(cast_booleans: true) } let(:id1) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 1)'; client.last_id } let(:id2) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES ( 0)'; client.last_id } let(:id3) { client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (-1)'; client.last_id } @@ -401,7 +402,7 @@ def stmt_count context "cast booleans for BIT(1) if :cast_booleans is enabled" do # rubocop:disable Style/Semicolon - let(:client) { new_client(:cast_booleans => true) } + let(:client) { new_client(cast_booleans: true) } let(:id1) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (1)'; client.last_id } let(:id2) { client.query 'INSERT INTO mysql2_test (single_bit_test) VALUES (0)'; client.last_id } # rubocop:enable Style/Semicolon @@ -505,7 +506,7 @@ def stmt_count result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['enum_test'].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['enum_test'].encoding).to eql(Encoding::US_ASCII) end @@ -535,7 +536,7 @@ def stmt_count result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['set_test'].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result['set_test'].encoding).to eql(Encoding::US_ASCII) end @@ -599,7 +600,7 @@ def stmt_count end context "string encoding for #{type} values" do - if %w(VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB).include?(type) + if %w[VARBINARY TINYBLOB BLOB MEDIUMBLOB LONGBLOB].include?(type) it "should default to binary if Encoding.default_internal is nil" do with_internal_encoding nil do result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first @@ -624,7 +625,7 @@ def stmt_count result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result[field].encoding).to eql(Encoding::UTF_8) - client2 = new_client(:encoding => 'ascii') + client2 = new_client(encoding: 'ascii') result = client2.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first expect(result[field].encoding).to eql(Encoding::US_ASCII) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 045e78374..32e3b0069 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -37,7 +37,9 @@ def new_client(option_overrides = {}) end def num_classes + # rubocop:disable Lint/UnifiedInteger 0.class == Integer ? [Integer] : [Fixnum, Bignum] + # rubocop:enable Lint/UnifiedInteger end config.before :each do diff --git a/support/mysql_enc_to_ruby.rb b/support/mysql_enc_to_ruby.rb index fbe1562c3..d0a5a4b81 100644 --- a/support/mysql_enc_to_ruby.rb +++ b/support/mysql_enc_to_ruby.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'mysql2' @@ -45,8 +47,8 @@ "eucjpms" => "eucJP-ms", } -client = Mysql2::Client.new(:username => user, :password => pass, :host => host, :port => port.to_i) -collations = client.query "SHOW COLLATION", :as => :array +client = Mysql2::Client.new(username: user, password: pass, host: host, port: port.to_i) +collations = client.query "SHOW COLLATION", as: :array encodings = Array.new(collations.to_a.last[2].to_i) encodings_with_nil = Array.new(encodings.size) diff --git a/support/ruby_enc_to_mysql.rb b/support/ruby_enc_to_mysql.rb index 52603b303..120431e6e 100644 --- a/support/ruby_enc_to_mysql.rb +++ b/support/ruby_enc_to_mysql.rb @@ -1,3 +1,5 @@ +# encoding: UTF-8 + mysql_to_rb = { "big5" => "Big5", "dec8" => nil, @@ -40,21 +42,21 @@ "eucjpms" => "eucJP-ms", } -puts <<-header -%readonly-tables -%enum -%define lookup-function-name mysql2_mysql_enc_name_to_rb -%define hash-function-name mysql2_mysql_enc_name_to_rb_hash -%struct-type -struct mysql2_mysql_enc_name_to_rb_map { const char *name; const char *rb_name; } -%% -header +puts <<-HEADER.strip_indent + %readonly-tables + %enum + %define lookup-function-name mysql2_mysql_enc_name_to_rb + %define hash-function-name mysql2_mysql_enc_name_to_rb_hash + %struct-type + struct mysql2_mysql_enc_name_to_rb_map { const char *name; const char *rb_name; } + %% +HEADER mysql_to_rb.each do |mysql, ruby| - if ruby.nil? - name = "NULL" + name = if ruby.nil? + "NULL" else - name = "\"#{ruby}\"" + "\"#{ruby}\"" end puts "#{mysql}, #{name}" diff --git a/tasks/benchmarks.rake b/tasks/benchmarks.rake index b587ecdc0..8302f62a3 100644 --- a/tasks/benchmarks.rake +++ b/tasks/benchmarks.rake @@ -1,3 +1,5 @@ +# encoding: UTF-8 + BENCHMARKS = Dir["#{File.dirname(__FILE__)}/../benchmark/*.rb"].map do |path| File.basename(path, '.rb') end - ['setup_db'] diff --git a/tasks/compile.rake b/tasks/compile.rake index fb339580e..ce33554f5 100644 --- a/tasks/compile.rake +++ b/tasks/compile.rake @@ -1,3 +1,5 @@ +# encoding: UTF-8 + require "rake/extensiontask" load File.expand_path('../../mysql2.gemspec', __FILE__) unless defined? Mysql2::GEMSPEC @@ -33,20 +35,20 @@ Rake::ExtensionTask.new("mysql2", Mysql2::GEMSPEC) do |ext| spec.files << 'lib/mysql2/mysql2.rb' spec.files << 'vendor/libmysql.dll' spec.files << 'vendor/README' - spec.post_install_message = <<-POST_INSTALL_MESSAGE + spec.post_install_message = <<-POST_INSTALL_MESSAGE.strip_indent -====================================================================================================== + ====================================================================================================== - You've installed the binary version of #{spec.name}. - It was built using MySQL Connector/C version #{CONNECTOR_VERSION}. - It's recommended to use the exact same version to avoid potential issues. + You've installed the binary version of #{spec.name}. + It was built using MySQL Connector/C version #{CONNECTOR_VERSION}. + It's recommended to use the exact same version to avoid potential issues. - At the time of building this gem, the necessary DLL files were retrieved from: - #{vendor_mysql_url(spec.platform)} + At the time of building this gem, the necessary DLL files were retrieved from: + #{vendor_mysql_url(spec.platform)} - This gem *includes* vendor/libmysql.dll with redistribution notice in vendor/README. + This gem *includes* vendor/libmysql.dll with redistribution notice in vendor/README. -====================================================================================================== + ====================================================================================================== POST_INSTALL_MESSAGE end @@ -64,9 +66,9 @@ end file 'lib/mysql2/mysql2.rb' do |t| name = Mysql2::GEMSPEC.name File.open(t.name, 'wb') do |f| - f.write <<-END_OF_RUBY -RUBY_VERSION =~ /(\\d+.\\d+)/ -require "#{name}/\#{$1}/#{name}" + f.write <<-END_OF_RUBY.strip_indent + RUBY_VERSION =~ /(\\d+.\\d+)/ + require "#{name}/\#{$1}/#{name}" END_OF_RUBY end end @@ -83,10 +85,8 @@ end if RUBY_PLATFORM =~ /mingw|mswin/ Rake::Task['compile'].prerequisites.unshift 'vendor:mysql' unless defined?(RubyInstaller) Rake::Task['compile'].prerequisites.unshift 'devkit' -else - if Rake::Task.tasks.map(&:name).include? 'cross' - Rake::Task['cross'].prerequisites.unshift 'vendor:mysql:cross' - end +elsif Rake::Task.tasks.map(&:name).include? 'cross' + Rake::Task['cross'].prerequisites.unshift 'vendor:mysql:cross' end desc "Build binary gems for Windows with rake-compiler-dock" diff --git a/tasks/generate.rake b/tasks/generate.rake index 6e5eebd99..2712eeaee 100644 --- a/tasks/generate.rake +++ b/tasks/generate.rake @@ -1,3 +1,5 @@ +# encoding: UTF-8 + task :encodings do sh "ruby support/mysql_enc_to_ruby.rb > ./ext/mysql2/mysql_enc_to_ruby.h" sh "ruby support/ruby_enc_to_mysql.rb | gperf > ./ext/mysql2/mysql_enc_name_to_ruby.h" diff --git a/tasks/rspec.rake b/tasks/rspec.rake index 4be4d63dc..a7bbfb098 100644 --- a/tasks/rspec.rake +++ b/tasks/rspec.rake @@ -1,3 +1,5 @@ +# encoding: UTF-8 + begin require 'rspec' require 'rspec/core/rake_task' @@ -5,13 +7,13 @@ begin desc " Run all examples with Valgrind" namespace :spec do task :valgrind do - VALGRIND_OPTS = %w( + VALGRIND_OPTS = %w[ --num-callers=50 --error-limit=no --partial-loads-ok=yes --undef-value-errors=no --trace-children=yes - ) + ].freeze cmdline = "valgrind #{VALGRIND_OPTS.join(' ')} bundle exec rake spec" puts cmdline system cmdline diff --git a/tasks/vendor_mysql.rake b/tasks/vendor_mysql.rake index d88b6f177..6d77be208 100644 --- a/tasks/vendor_mysql.rake +++ b/tasks/vendor_mysql.rake @@ -1,7 +1,9 @@ +# encoding: UTF-8 + require 'rake/clean' require 'rake/extensioncompiler' -CONNECTOR_VERSION = "6.1.11" # NOTE: Track the upstream version from time to time +CONNECTOR_VERSION = "6.1.11".freeze # NOTE: Track the upstream version from time to time def vendor_mysql_platform(platform = nil) platform ||= RUBY_PLATFORM