diff options
24 files changed, 119 insertions, 53 deletions
@@ -129,3 +129,4 @@ end # A gem necessary for Active Record tests with IBM DB. gem 'ibm_db' if ENV['IBM_DB'] gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] +gem 'wdm', '>= 0.1.0', platforms: [:mingw, :mswin, :x64_mingw, :mswin64] diff --git a/Gemfile.lock b/Gemfile.lock index ce854e6183..cb548862dd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -265,6 +265,7 @@ GEM w3c_validators (1.2) json nokogiri + wdm (0.1.1) websocket-driver (0.6.3) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) @@ -323,6 +324,7 @@ DEPENDENCIES tzinfo-data uglifier (>= 1.3.0) w3c_validators + wdm (>= 0.1.0) BUNDLED WITH 1.11.2 diff --git a/actioncable/lib/action_cable/remote_connections.rb b/actioncable/lib/action_cable/remote_connections.rb index aeef8abc72..a528024427 100644 --- a/actioncable/lib/action_cable/remote_connections.rb +++ b/actioncable/lib/action_cable/remote_connections.rb @@ -28,7 +28,7 @@ module ActionCable private # Represents a single remote connection found via <tt>ActionCable.server.remote_connections.where(*)</tt>. - # Exists for the solely for the purpose of calling #disconnect on that connection. + # Exists solely for the purpose of calling #disconnect on that connection. class RemoteConnection class InvalidIdentifiersError < StandardError; end diff --git a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb b/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb index 256876cf30..4735a4bfa8 100644 --- a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb +++ b/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb @@ -53,6 +53,10 @@ module ActionCable redis.on(:reconnect_failed) do @logger.error "[ActionCable] Redis reconnect failed." end + + redis.on(:failed) do + @logger.error "[ActionCable] Redis connection has failed." + end end end end diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 16dec31938..d4317399ed 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -76,7 +76,7 @@ module AbstractController end end - # action_methods are cached and there is sometimes need to refresh + # action_methods are cached and there is sometimes a need to refresh # them. ::clear_action_methods! allows you to do that, so next time # you run action_methods, they will be recalculated. def clear_action_methods! diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb index 59984a0028..6cd6130032 100644 --- a/actionpack/lib/action_controller/metal/data_streaming.rb +++ b/actionpack/lib/action_controller/metal/data_streaming.rb @@ -25,14 +25,13 @@ module ActionController #:nodoc: # * <tt>:filename</tt> - suggests a filename for the browser to use. # Defaults to <tt>File.basename(path)</tt>. # * <tt>:type</tt> - specifies an HTTP content type. - # You can specify either a string or a symbol for a registered type register with - # <tt>Mime::Type.register</tt>, for example :json - # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>. - # If no content type is registered for the extension, default type 'application/octet-stream' will be used. + # You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json. + # If omitted, the type will be inferred from the file extension specified in <tt>:filename</tt>. + # If no content type is registered for the extension, the default type 'application/octet-stream' will be used. # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded. # Valid values are 'inline' and 'attachment' (default). # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200. - # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from + # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser to guess the filename from # the URL, which is necessary for i18n filenames on certain browsers # (setting <tt>:filename</tt> overrides this option). # @@ -79,14 +78,14 @@ module ActionController #:nodoc: # <tt>render plain: data</tt>, but also allows you to specify whether # the browser should display the response as a file attachment (i.e. in a # download dialog) or as inline data. You may also set the content type, - # the apparent file name, and other things. + # the file name, and other things. # # Options: # * <tt>:filename</tt> - suggests a filename for the browser to use. - # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify - # either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json. - # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>. - # If no content type is registered for the extension, default type 'application/octet-stream' will be used. + # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. + # You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json. + # If omitted, type will be inferred from the file extension specified in <tt>:filename</tt>. + # If no content type is registered for the extension, the default type 'application/octet-stream' will be used. # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded. # Valid values are 'inline' and 'attachment' (default). # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200. diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb index e4d19e9dba..2775a24e56 100644 --- a/actionpack/lib/action_controller/renderer.rb +++ b/actionpack/lib/action_controller/renderer.rb @@ -45,7 +45,7 @@ module ActionController }.freeze # Create a new renderer instance for a specific controller class. - def self.for(controller, env = {}, defaults = DEFAULTS) + def self.for(controller, env = {}, defaults = DEFAULTS.dup) new(controller, env, defaults) end diff --git a/actionpack/test/controller/renderer_test.rb b/actionpack/test/controller/renderer_test.rb index 16d24fa82a..372c09bc23 100644 --- a/actionpack/test/controller/renderer_test.rb +++ b/actionpack/test/controller/renderer_test.rb @@ -87,6 +87,14 @@ class RendererTest < ActiveSupport::TestCase assert_equal "<p>1\n<br />2</p>", render[inline: '<%= simple_format "1\n2" %>'] end + test 'rendering with user specified defaults' do + ApplicationController.renderer.defaults.merge!({ hello: 'hello', https: true }) + renderer = ApplicationController.renderer.new + content = renderer.render inline: '<%= request.ssl? %>' + + assert_equal 'true', content + end + private def render @render ||= ApplicationController.renderer.method(:render) diff --git a/activejob/lib/active_job/queue_adapters.rb b/activejob/lib/active_job/queue_adapters.rb index 2c5039ef4d..71154d8785 100644 --- a/activejob/lib/active_job/queue_adapters.rb +++ b/activejob/lib/active_job/queue_adapters.rb @@ -33,7 +33,8 @@ module ActiveJob # # ==== Async # - # Yes: The Queue Adapter runs the jobs in a separate or forked process. + # Yes: The Queue Adapter has the ability to run the job in a non-blocking manner. + # It either runs on a separate or forked process, or on a different thread. # # No: The job is run in the same process. # diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 2fbecb7d04..5a973fa801 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -318,7 +318,7 @@ module ActiveRecord # create_other(attributes={}) | X | | X # create_other!(attributes={}) | X | | X # - # ===Collection associations (one-to-many / many-to-many) + # === Collection associations (one-to-many / many-to-many) # | | | has_many # generated methods | habtm | has_many | :through # ----------------------------------+-------+----------+---------- diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 104ca54793..105d9cde92 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -985,11 +985,23 @@ module ActiveRecord end def dump_schema_information #:nodoc: + versions = ActiveRecord::SchemaMigration.order('version').pluck(:version) + insert_versions_sql(versions) + end + + def insert_versions_sql(versions) sm_table = ActiveRecord::Migrator.schema_migrations_table_name - sql = "INSERT INTO #{sm_table} (version) VALUES " - sql << ActiveRecord::SchemaMigration.order('version').pluck(:version).map {|v| "('#{v}')" }.join(', ') - sql << ";\n\n" + if supports_multi_insert? + sql = "INSERT INTO #{sm_table} (version) VALUES " + sql << versions.map {|v| "('#{v}')" }.join(', ') + sql << ";\n\n" + sql + else + versions.map { |version| + "INSERT INTO #{sm_table} (version) VALUES ('#{version}');" + }.join "\n\n" + end end # Should not be called normally, but this operation is non-destructive. @@ -1026,7 +1038,7 @@ module ActiveRecord if (duplicate = inserting.detect {|v| inserting.count(v) > 1}) raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict." end - execute "INSERT INTO #{sm_table} (version) VALUES #{inserting.map {|v| "('#{v}')"}.join(', ') }" + execute insert_versions_sql(inserting) end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 20cc205b0d..2e18226a10 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -298,6 +298,11 @@ module ActiveRecord false end + # Does this adapter support multi-value insert + def supports_multi_insert? + true + end + # This is meant to be implemented by the adapters that support extensions def disable_extension(name) end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index 985cc06aa0..bf73d647c0 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -130,6 +130,10 @@ module ActiveRecord true end + def supports_multi_insert? + sqlite_version >= '3.7.11' + end + def active? @active != false end diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb index bbbc824b25..ca12a603da 100644 --- a/activerecord/lib/active_record/query_cache.rb +++ b/activerecord/lib/active_record/query_cache.rb @@ -44,8 +44,9 @@ module ActiveRecord executor.register_hook(self) executor.to_complete do - # FIXME: This should be skipped when env['rack.test'] - ActiveRecord::Base.clear_active_connections! + unless ActiveRecord::Base.connection.transaction_open? + ActiveRecord::Base.clear_active_connections! + end end end end diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb index c4c2c69d1c..1f9b6add7a 100644 --- a/activerecord/test/cases/connection_management_test.rb +++ b/activerecord/test/cases/connection_management_test.rb @@ -4,6 +4,8 @@ require "rack" module ActiveRecord module ConnectionAdapters class ConnectionManagementTest < ActiveRecord::TestCase + self.use_transactional_tests = false + class App attr_reader :calls def initialize @@ -46,8 +48,8 @@ module ActiveRecord assert !ActiveRecord::Base.connection_handler.active_connections? end - def test_active_connections_are_not_cleared_on_body_close_during_test - executor.wrap do + def test_active_connections_are_not_cleared_on_body_close_during_transaction + ActiveRecord::Base.transaction do _, _, body = @management.call(@env) body.close assert ActiveRecord::Base.connection_handler.active_connections? @@ -61,9 +63,9 @@ module ActiveRecord assert !ActiveRecord::Base.connection_handler.active_connections? end - def test_connections_not_closed_if_exception_and_test - executor.wrap do - app = Class.new(App) { def call(env); raise; end }.new + def test_connections_not_closed_if_exception_inside_transaction + ActiveRecord::Base.transaction do + app = Class.new(App) { def call(env); raise RuntimeError; end }.new explosive = middleware(app) assert_raises(RuntimeError) { explosive.call(@env) } assert ActiveRecord::Base.connection_handler.active_connections? diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index c7db77b426..7a304eab7f 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -29,6 +29,24 @@ class SchemaDumperTest < ActiveRecord::TestCase ActiveRecord::SchemaMigration.delete_all end + if current_adapter?(:SQLite3Adapter) + %w{3.7.8 3.7.11 3.7.12}.each do |version_string| + test "dumps schema version for sqlite version #{version_string}" do + version = ActiveRecord::ConnectionAdapters::SQLite3Adapter::Version.new(version_string) + ActiveRecord::Base.connection.stubs(:sqlite_version).returns(version) + + versions = %w{ 20100101010101 20100201010101 20100301010101 } + versions.reverse_each do |v| + ActiveRecord::SchemaMigration.create!(:version => v) + end + + schema_info = ActiveRecord::Base.connection.dump_schema_information + assert_match(/20100201010101.*20100301010101/m, schema_info) + ActiveRecord::SchemaMigration.delete_all + end + end + end + def test_magic_comment assert_match "# encoding: #{Encoding.default_external.name}", standard_dump end diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb index d6bad98376..b08321aeeb 100644 --- a/activesupport/lib/active_support/core_ext/object/blank.rb +++ b/activesupport/lib/active_support/core_ext/object/blank.rb @@ -115,7 +115,7 @@ class String # fallback. Penalty for the rest of strings is marginal. # # Double negation in the second operand is also a performance tweak, it is - # faster than the positive \A[[:space:]]*\z due to lack of backtracking. + # faster than the positive \A[[:space:]]*\z. empty? || !(/[[:^space:]]/ === self) end end diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb index 6a02a838b7..21fdf7bb80 100644 --- a/activesupport/lib/active_support/evented_file_update_checker.rb +++ b/activesupport/lib/active_support/evented_file_update_checker.rb @@ -86,16 +86,6 @@ module ActiveSupport end class PathHelper - using Module.new { - refine Pathname do - def ascendant_of?(other) - self != other && other.ascend do |ascendant| - break true if self == ascendant - end - end - end - } - def xpath(path) Pathname.new(path).expand_path end @@ -112,7 +102,7 @@ module ActiveSupport lcsp = Pathname.new(paths[0]) paths[1..-1].each do |path| - until lcsp.ascendant_of?(path) + until ascendant_of?(lcsp, path) if lcsp.root? # If we get here a root directory is not an ascendant of path. # This may happen if there are paths in different drives on @@ -145,13 +135,21 @@ module ActiveSupport dir = dirs_sorted_by_nparts.shift dirs_sorted_by_nparts.reject! do |possible_descendant| - dir.ascendant_of?(possible_descendant) && descendants << possible_descendant + ascendant_of?(dir, possible_descendant) && descendants << possible_descendant end end # Array#- preserves order. dirs - descendants end + + private + + def ascendant_of?(base, other) + base != other && other.ascend do |ascendant| + break true if base == ascendant + end + end end end end diff --git a/activesupport/test/file_update_checker_shared_tests.rb b/activesupport/test/file_update_checker_shared_tests.rb index 12e67a1e9f..40ae0c7617 100644 --- a/activesupport/test/file_update_checker_shared_tests.rb +++ b/activesupport/test/file_update_checker_shared_tests.rb @@ -9,7 +9,7 @@ module FileUpdateCheckerSharedTests end def tmpfile(name) - "#{tmpdir}/#{name}" + File.join(tmpdir, name) end def tmpfiles @@ -17,7 +17,9 @@ module FileUpdateCheckerSharedTests end def run(*args) - Dir.mktmpdir(nil, __dir__) { |dir| @tmpdir = dir; super } + capture_exceptions do + Dir.mktmpdir(nil, __dir__) { |dir| @tmpdir = dir; super } + end end test 'should not execute the block if no paths are given' do @@ -225,7 +227,7 @@ module FileUpdateCheckerSharedTests assert !checker.execute_if_updated assert_equal 0, i - touch("#{subdir}/nested.rb") + touch(File.join(subdir, "nested.rb")) assert checker.execute_if_updated assert_equal 1, i @@ -245,12 +247,12 @@ module FileUpdateCheckerSharedTests assert_equal 0, i # subdir does not look for Ruby files, but its parent tmpdir does. - touch("#{subdir}/nested.rb") + touch(File.join(subdir, "nested.rb")) assert checker.execute_if_updated assert_equal 1, i - touch("#{subdir}/nested.txt") + touch(File.join(subdir, "nested.txt")) assert checker.execute_if_updated assert_equal 2, i diff --git a/guides/source/3_0_release_notes.md b/guides/source/3_0_release_notes.md index 696493a3cf..70b0e89799 100644 --- a/guides/source/3_0_release_notes.md +++ b/guides/source/3_0_release_notes.md @@ -86,7 +86,7 @@ $ cd myapp ### Vendoring Gems -Rails now uses a `Gemfile` in the application root to determine the gems you require for your application to start. This `Gemfile` is processed by the [Bundler](http://github.com/carlhuda/bundler,) which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems. +Rails now uses a `Gemfile` in the application root to determine the gems you require for your application to start. This `Gemfile` is processed by the [Bundler](http://github.com/bundler/bundler,) which then installs all your dependencies. It can even install all the dependencies locally to your application so that it doesn't depend on the system gems. More information: - [bundler homepage](http://bundler.io/) @@ -213,7 +213,6 @@ Railties now deprecates: More information: * [Discovering Rails 3 generators](http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators) -* [Making Generators for Rails 3 with Thor](http://caffeinedd.com/guides/331-making-generators-for-rails-3-with-thor) * [The Rails Module (in Rails 3)](http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/) Action Pack @@ -250,7 +249,7 @@ Deprecations: More Information: -* [Render Options in Rails 3](http://www.engineyard.com/blog/2010/render-options-in-rails-3/) +* [Render Options in Rails 3](https://blog.engineyard.com/2010/render-options-in-rails-3) * [Three reasons to love ActionController::Responder](http://weblog.rubyonrails.org/2009/8/31/three-reasons-love-responder) diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md index e9f6275e55..9a13e3bda7 100644 --- a/guides/source/active_record_querying.md +++ b/guides/source/active_record_querying.md @@ -472,6 +472,12 @@ NOTE: Only equality, range and subset checking are possible with Hash conditions Client.where(locked: true) ``` +This will generate SQL like this: + +```sql +SELECT * FROM clients WHERE (clients.locked = 1) +``` + The field name can also be a string: ```ruby @@ -517,13 +523,17 @@ SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5)) ### NOT Conditions -`NOT` SQL queries can be built by `where.not`. +`NOT` SQL queries can be built by `where.not`: ```ruby -Article.where.not(author: author) +Client.where.not(locked: true) ``` -In other words, this query can be generated by calling `where` with no argument, then immediately chain with `not` passing `where` conditions. +In other words, this query can be generated by calling `where` with no argument, then immediately chain with `not` passing `where` conditions. This will generate SQL like this: + +```sql +SELECT * FROM clients WHERE (clients.locked != 1) +``` Ordering -------- diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile b/railties/lib/rails/generators/rails/plugin/templates/Rakefile index f1943644e4..383d2fb2d1 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile +++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile @@ -25,5 +25,5 @@ load 'rails/tasks/statistics.rake' <% unless options[:skip_gemspec] -%> -Bundler::GemHelper.install_tasks +require 'bundler/gem_tasks' <% end %> diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index decc4d138d..1ca6bbcecf 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1464,7 +1464,7 @@ module ApplicationTests assert_equal :api, Rails.configuration.debug_exception_response_format end - test "debug_exception_response_format can be overriden" do + test "debug_exception_response_format can be overridden" do add_to_config <<-RUBY config.api_only = true RUBY diff --git a/railties/test/application/rake/dev_test.rb b/railties/test/application/rake/dev_test.rb index deb9bc8dee..2330ad3535 100644 --- a/railties/test/application/rake/dev_test.rb +++ b/railties/test/application/rake/dev_test.rb @@ -34,7 +34,7 @@ module ApplicationTests Dir.chdir(app_path) do FileUtils.mkdir_p("tmp/pids") FileUtils.touch("tmp/pids/server.pid") - `rake dev:cache` + `rails dev:cache` assert_not File.exist?("tmp/pids/server.pid") end end |