1. 16 9月, 2015 2 次提交
  2. 15 9月, 2015 1 次提交
  3. 14 9月, 2015 1 次提交
  4. 11 9月, 2015 1 次提交
  5. 10 9月, 2015 2 次提交
  6. 09 9月, 2015 9 次提交
  7. 08 9月, 2015 10 次提交
    • Y
      Define `SchemaStatements#tables` as interface · 1fbd954e
      yui-knk 提交于
      These 3 methods expect `ConnectionAdapters` to have `tables` method,
      so make it clear that `tables` method is interface.
      
      * `ConnectionAdapters::SchemaCache#prepare_tables`
      * `db:schema:cache:dump` task
      * `SchemaDumper#tables`
      1fbd954e
    • A
      dad0c267
    • R
      💣 · b4f82efd
      Rafael Mendonça França 提交于
      b4f82efd
    • R
      Memoized reflections accessor · 0675210c
      Rafael Mendonça França 提交于
      Its value never change since associations are defined at class load time
      so there is no need to build the hash everytime the method is called.
      
      Before this change:
      
          Calculating -------------------------------------
                   reflections   804.000  i/100ms
          -------------------------------------------------
                   reflections      8.213k (±26.2%) i/s -     36.180k
      
      After this change:
      
          Calculating -------------------------------------
                   reflections    24.548k i/100ms
          -------------------------------------------------
                   reflections      1.591M (±25.7%) i/s -      7.364M
      
      Benchmark script:
      
          require 'bundler/setup'
      
          require 'active_record'
          require 'benchmark/ips'
      
          ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
          ActiveRecord::Migration.verbose = false
      
          ActiveRecord::Schema.define do
            100.times do |i|
              create_table "users#{i}", force: true
            end
      
            create_table :cars, force: true do |t|
              100.times do |i|
                t.references "users#{i}"
              end
            end
          end
      
          class Car < ActiveRecord::Base
            100.times do |i|
              belongs_to "users#{i}".to_sym
            end
          end
      
          Benchmark.ips do |x|
            x.report('reflections') { Car.reflections }
          end
      0675210c
    • G
      Reduce allocation in `resolve_column_aliases`. · 607a4482
      Guo Xiang Tan 提交于
      Benchmark Script Used:
      ```
      begin
        require 'bundler/inline'
      rescue LoadError => e
        $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
        raise e
      end
      
      gemfile(true) do
        source 'https://rubygems.org'
        gem 'rails', path: '~/rails' # master against ref "f1f0a3f8"
        gem 'arel', github: 'rails/arel', branch: 'master'
        gem 'rack', github: 'rack/rack', branch: 'master'
        gem 'sass'
        gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
        gem 'sprockets', github: 'rails/sprockets', branch: 'master'
        gem 'pg'
        gem 'benchmark-ips'
      end
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
      
      ActiveRecord::Migration.verbose = false
      
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name, :email
          t.timestamps null: false
        end
      end
      
      class User < ActiveRecord::Base; end
      
      attributes = {
        name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        email: "foobar@email.com",
      }
      
      1000.times { User.create!(attributes) }
      
      Benchmark.ips(5, 3) do |x|
        x.report('where with hash single') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.report('where with string single') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.report('where with hash double') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", email: "foobar@email.com") }
        x.report('where with string double') { User.where("users.name = ? AND users.email = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "foobar@email.com") }
        x.compare!
      end
      ```
      
      Before:
      ```
      Calculating -------------------------------------
      where with hash single
                               3.300k i/100ms
      where with string single
                               4.965k i/100ms
      where with hash double
                               2.594k i/100ms
      where with string double
                               4.400k i/100ms
      -------------------------------------------------
      where with hash single
                               35.161k (± 1.2%) i/s -    178.200k
      where with string single
                               53.368k (± 2.9%) i/s -    268.110k
      where with hash double
                               27.364k (± 1.1%) i/s -    137.482k
      where with string double
                               46.876k (± 2.1%) i/s -    237.600k
      
      Comparison:
      where with string single:    53368.1 i/s
      where with string double:    46875.5 i/s - 1.14x slower
      where with hash single:    35160.8 i/s - 1.52x slower
      where with hash double:    27364.0 i/s - 1.95x slower
      ```
      
      After:
      ```
      Calculating -------------------------------------
      where with hash single
                               3.403k i/100ms
      where with string single
                               5.167k i/100ms
      where with hash double
                               2.659k i/100ms
      where with string double
                               4.597k i/100ms
      -------------------------------------------------
      where with hash single
                               36.410k (± 1.3%) i/s -    183.762k
      where with string single
                               55.009k (± 2.6%) i/s -    279.018k
      where with hash double
                               27.951k (± 1.4%) i/s -    140.927k
      where with string double
                               48.362k (± 2.6%) i/s -    243.641k
      
      Comparison:
      where with string single:    55008.6 i/s
      where with string double:    48361.5 i/s - 1.14x slower
      where with hash single:    36410.1 i/s - 1.51x slower
      where with hash double:    27950.9 i/s - 1.97x slower
      ```
      607a4482
    • J
      Support mysql2 0.4.0, first release with prepared statements support · 5da5e377
      Jeremy Daer 提交于
      Known failure on Ruby 2.3/trunk: brianmario/mysql2#671
      5da5e377
    • D
      Validate multiple contexts on `valid?` and `invalid?` at once. · e3d99e23
      Dmitry Polushkin 提交于
      Example:
      
      ```ruby
      class Person
        include ActiveModel::Validations
      
        attr_reader :name, :title
        validates_presence_of :name, on: :create
        validates_presence_of :title, on: :update
      end
      
      person = Person.new
      person.valid?([:create, :update])    # => true
      person.errors.messages               # => {:name=>["can't be blank"], :title=>["can't be blank"]}
      ```
      e3d99e23
    • R
      Use Hash[] instead of Hash#dup in resolve_column_aliases · d1ce45cd
      Rafael Mendonça França 提交于
      Related with #20418
      d1ce45cd
    • R
      Revert "Merge pull request #21069 from dmitry/feature/validate-multiple-contexts-at-once" · 7b9b0b53
      Rafael Mendonça França 提交于
      This reverts commit 51dd2588, reversing
      changes made to ecb4e4b2.
      
      This broke Active Record tests
      7b9b0b53
    • M
      Correct query for PostgreSQL 8.2 · 8c34d106
      Matthew Draper 提交于
      Generic cast-to-text was only added in 8.3.
      8c34d106
  8. 07 9月, 2015 7 次提交
    • T
    • T
    • G
      PERF: Don't create a Relation when it is not needed. · 69de09c5
      Guo Xiang Tan 提交于
      Benchmark script used:
      ```
      begin
        require 'bundler/inline'
      rescue LoadError => e
        $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
        raise e
      end
      
      gemfile(true) do
        source 'https://rubygems.org'
        gem 'rails', path: '~/rails' # master against ref "f1f0a3f8"
        gem 'arel', github: 'rails/arel', branch: 'master'
        gem 'rack', github: 'rack/rack', branch: 'master'
        gem 'sass'
        gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
        gem 'sprockets', github: 'rails/sprockets', branch: 'master'
        gem 'pg'
        gem 'benchmark-ips'
      end
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
      
      ActiveRecord::Migration.verbose = false
      
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name, :email
          t.timestamps null: false
        end
      end
      
      class User < ActiveRecord::Base; end
      
      attributes = {
        name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        email: "foobar@email.com",
      }
      
      1000.times { User.create!(attributes) }
      
      Benchmark.ips(5, 3) do |x|
        x.report('all') { User.all }
      end
      
      key =
        if RUBY_VERSION < '2.2'
          :total_allocated_object
        else
          :total_allocated_objects
        end
      
      before = GC.stat[key]
      User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
      after = GC.stat[key]
      puts "Total Allocated Object: #{after - before}"
      
      ```
      
      Before:
      ```
      Calculating -------------------------------------
                       all    17.569k i/100ms
      -------------------------------------------------
                       all    190.854k (± 3.3%) i/s -    966.295k
      Total Allocated Object: 85
      ```
      
      After:
      ```
      Calculating -------------------------------------
                       all    22.237k i/100ms
      -------------------------------------------------
                       all    262.715k (± 5.5%) i/s -      1.312M
      Total Allocated Object: 80
      ```
      69de09c5
    • P
      Make ActiveRecordException descendants args optional · 4ff626ca
      Pavel Pravosud 提交于
      This change allows to instantiate all ActiveRecordError descendant
      execption classes without arguments, which might be useful in testing
      and is far less surprising than mandatory arguments.
      4ff626ca
    • G
      Cache check if `default_scope` has been overridden. · 52b2ab9e
      Guo Xiang Tan 提交于
      Benchmark Script:
      ```
      begin
        require 'bundler/inline'
      rescue LoadError => e
        $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
        raise e
      end
      
      gemfile(true) do
        source 'https://rubygems.org'
        # gem 'rails', github: 'rails/rails', ref: 'f1f0a3f8'
        gem 'rails', path: '~/rails'
        gem 'arel', github: 'rails/arel', branch: 'master'
        gem 'rack', github: 'rack/rack', branch: 'master'
        gem 'sass'
        gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
        gem 'sprockets', github: 'rails/sprockets', branch: 'master'
        gem 'pg'
        gem 'benchmark-ips'
      end
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
      
      ActiveRecord::Migration.verbose = false
      
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name, :email
          t.timestamps null: false
        end
      end
      
      class User < ActiveRecord::Base; end
      
      attributes = {
        name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        email: "foobar@email.com",
      }
      
      1000.times { User.create!(attributes) }
      
      Benchmark.ips(5, 3) do |x|
        x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.compare!
      end
      
      key =
        if RUBY_VERSION < '2.2'
          :total_allocated_object
        else
          :total_allocated_objects
        end
      
      before = GC.stat[key]
      User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
      after = GC.stat[key]
      puts "Total Allocated Object: #{after - before}"
      ```
      
      Stackprof output truncated.
      ```
      TOTAL    (pct)     SAMPLES    (pct)     FRAME
         52  (10.6%)          10   (2.0%)     ActiveRecord::Scoping::Default::ClassMethods#build_default_scope
      ```
      
      Before:
      ```
      Calculating -------------------------------------
           where with hash     2.789k i/100ms
         where with string     4.407k i/100ms
      -------------------------------------------------
           where with hash     29.170k (± 1.9%) i/s -    147.817k
         where with string     46.954k (± 2.7%) i/s -    237.978k
      
      Comparison:
         where with string:    46954.3 i/s
           where with hash:    29169.9 i/s - 1.61x slower
      
      Total Allocated Object: 85
      Calculating -------------------------------------
                       all    16.773k i/100ms
      -------------------------------------------------
                       all    186.102k (± 3.6%) i/s -    939.288k
      ```
      
      After:
      ```
      Calculating -------------------------------------
           where with hash     3.014k i/100ms
         where with string     4.623k i/100ms
      -------------------------------------------------
           where with hash     31.524k (± 1.3%) i/s -    159.742k
         where with string     49.948k (± 2.3%) i/s -    249.642k
      
      Comparison:
         where with string:    49948.3 i/s
           where with hash:    31524.3 i/s - 1.58x slower
      
      Total Allocated Object: 84
      Calculating -------------------------------------
                       all    20.139k i/100ms
      -------------------------------------------------
                       all    227.860k (± 2.5%) i/s -      1.148M
      ```
      52b2ab9e
    • G
      Reduce calls to stringify_keys. · 47e06c98
      Guo Xiang Tan 提交于
      Stackprof output truncated.
      ```
      TOTAL    (pct)     SAMPLES    (pct)     FRAME
        23   (4.7%)          12   (2.4%)     Hash#transform_keys
        11   (2.2%)          11   (2.2%)     block in Hash#transform_keys
        30   (6.1%)           7   (1.4%)     Hash#stringify_keys
      ```
      
      Benchmark Script:
      ```
      begin
        require 'bundler/inline'
      rescue LoadError => e
        $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
        raise e
      end
      
      gemfile(true) do
        source 'https://rubygems.org'
        gem 'rails', path: '~/rails' # master against ref "f1f0a3f8"
        gem 'arel', github: 'rails/arel', branch: 'master'
        gem 'rack', github: 'rack/rack', branch: 'master'
        gem 'sass'
        gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
        gem 'sprockets', github: 'rails/sprockets', branch: 'master'
        gem 'pg'
        gem 'benchmark-ips'
      end
      
      require 'active_record'
      require 'benchmark/ips'
      
      ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
      
      ActiveRecord::Migration.verbose = false
      
      ActiveRecord::Schema.define do
        create_table :users, force: true do |t|
          t.string :name, :email
          t.timestamps null: false
        end
      end
      
      class User < ActiveRecord::Base; end
      
      attributes = {
        name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        email: "foobar@email.com",
      }
      
      1000.times { User.create!(attributes) }
      
      Benchmark.ips(5, 3) do |x|
        x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
        x.compare!
      end
      
      key =
        if RUBY_VERSION < '2.2'
          :total_allocated_object
        else
          :total_allocated_objects
        end
      
      before = GC.stat[key]
      User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
      after = GC.stat[key]
      puts "Total Allocated Object: #{after - before}"
      ```
      
      Before:
      ```
      Calculating -------------------------------------
           where with hash     2.796k i/100ms
         where with string     4.338k i/100ms
      -------------------------------------------------
           where with hash     29.177k (± 1.5%) i/s -    148.188k
         where with string     47.419k (± 2.8%) i/s -    238.590k
      
      Comparison:
         where with string:    47419.0 i/s
           where with hash:    29176.6 i/s - 1.63x slower
      
      Total Allocated Object: 85
      ```
      
      After:
      ```
      Calculating -------------------------------------
           where with hash     2.895k i/100ms
         where with string     4.416k i/100ms
      -------------------------------------------------
           where with hash     30.758k (± 2.0%) i/s -    156.330k
         where with string     47.708k (± 2.6%) i/s -    238.464k
      
      Comparison:
         where with string:    47707.9 i/s
           where with hash:    30757.7 i/s - 1.55x slower
      
      Total Allocated Object: 84
      ```
      47e06c98
    • Y
      [ci skip] Replace `AR` with `Active Record` in task desc · 5adaa9dc
      yui-knk 提交于
      Many user look `desc` of rake task and they are not familiar with `AR`.
      `Active Record` is more familiar word.
      5adaa9dc
  9. 06 9月, 2015 3 次提交
  10. 05 9月, 2015 1 次提交
    • S
      #where fails if opts.responds_to?(:==) unexpectedly · c431f175
      Samuel Williams 提交于
      Sometimes opts passed in might respond to ==, e.g. `Arel::Nodes::Grouping`. In this case, `opts == :chain` returns `Arel::Nodes::Equality` which causes odd behaviour. Prefer `if :chain == opts` which guarantees that `Symbol#==` would be invoked. Alternatively consider `eql?`.
      c431f175
  11. 03 9月, 2015 2 次提交
    • B
      HasManyAssociation: moved half of counter cache code to reflection · 712fc8a5
      Bogdan Gusiev 提交于
      Current implementation has a lot of utility methods that accept
      reflection call a lot of methods on it and exit.
      
      E.g. has_counter_cache?(reflection)
      
      It causes confusion and inability to cache result of the method even
      through it always returns the same result for the same reflection
      object.
      It can be done easier without access to the association context
      by moving code into reflection itself.
      
      e.g. reflection.has_counter_cache?
      
      Reflection is less complex object than association so moving code there
      automatically makes it simplier to understand.
      712fc8a5
    • S
      Don't allocate a bunch of strings in `Relation::Merger` · 3dd7cecf
      Sean Griffin 提交于
      Since the strings are dynamically computed from a constant, the actual
      strings we're creating are a known set. We can compute them ahead of
      time, and reduce the number of allocations in that method.
      3dd7cecf
  12. 02 9月, 2015 1 次提交