1. 25 10月, 2014 1 次提交
    • D
      Use type column first in multi-column indexes · 9cdd0a1f
      Derek Prior 提交于
      `add_reference` can very helpfully add a multi-column index when you use
      it to add a polymorphic reference. However, the first column in the
      index is the `id` column, which is less than ideal.
      
      The [PostgreSQL docs][1] say:
      > A multicolumn B-tree index can be used with query conditions that
      > involve any subset of the index's columns, but the index is most
      > efficient when there are constraints on the leading (leftmost)
      > columns.
      
      The [MySQL docs][2] say:
      > MySQL can use multiple-column indexes for queries that test all the
      > columns in the index, or queries that test just the first column, the
      > first two columns, the first three columns, and so on. If you specify
      > the columns in the right order in the index definition, a single
      > composite index can speed up several kinds of queries on the same
      > table.
      
      In a polymorphic relationship, the type column is much more likely to be
      useful as the first column in an index than the id column. That is, I'm
      more likely to query on type without an id than I am to query on id
      without a type.
      
      [1]: http://www.postgresql.org/docs/9.3/static/indexes-multicolumn.html
      [2]: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html
      9cdd0a1f
  2. 21 10月, 2014 1 次提交
    • C
      Remove duplicate 'select' database statement · ec981aa1
      claudiob 提交于
      The `select` method has the same definition in almost all database
      adapters, so it can be moved from the database-specific adapters
      (PostgreSQl, MySQL, SQLite) to the abstract `database_statement`:
      
      ```ruby
      def select(sql, name = nil, binds = [])
        exec_query(sql, name, binds)
      end
      ```
      
      ---
      
      More details about this commit: the only two DB-specific adapters
      that have a different definition of `select` are MySQLAdapter and
      MySQL2Adapter.
      
      In MySQLAdapter, `select` invokes `exec_query(sql, name, binds)`, so
      calling `super` achieves the same goal with less repetition.
      
      In MySQL2Adapter, `select` invokes `exec_query(sql, name)`, that is,
      it does not pass the `binds` parameter like other methods do. However,
      [MySQL2Adapter's `exec_query`](https://github.com/rails/rails/blob/74a527cc63ef56f3d0a42cf638299958dc7cb08c/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L228L231)
      works exactly the same whether this parameters is passed or not, so the output
      does not change:
      
      ```ruby
      def exec_query(sql, name = 'SQL', binds = [])
        result = execute(sql, name)
        ActiveRecord::Result.new(result.fields, result.to_a)
      end
      ```
      ec981aa1
  3. 16 10月, 2014 3 次提交
  4. 01 10月, 2014 1 次提交
  5. 29 9月, 2014 1 次提交
    • P
      Reduce allocations when running AR callbacks. · 796cab45
      Pete Higgins 提交于
      Inspired by @tenderlove's work in
      c363fff2, this reduces the number of
      strings allocated when running callbacks for ActiveRecord instances. I
      measured that using this script:
      
      ```
      require 'objspace'
      require 'active_record'
      require 'allocation_tracer'
      
      ActiveRecord::Base.establish_connection adapter: "sqlite3",
                                              database: ":memory:"
      
      ActiveRecord::Base.connection.instance_eval do
        create_table(:articles) { |t| t.string :name }
      end
      
      class Article < ActiveRecord::Base; end
      a = Article.create name: "foo"
      a = Article.find a.id
      
      N = 10
      result = ObjectSpace::AllocationTracer.trace do
        N.times { Article.find a.id }
      end
      
      result.sort.each do |k,v|
        p k => v
      end
      puts "total: #{result.values.map(&:first).inject(:+)}"
      ```
      
      When I run this against master and this branch I get this output:
      
      ```
      pete@balloon:~/projects/rails/activerecord$ git checkout master
      M Gemfile
      Switched to branch 'master'
      pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_before
      pete@balloon:~/projects/rails/activerecord$ git checkout remove-dynamic-send-on-built-in-callbacks
      M Gemfile
      Switched to branch 'remove-dynamic-send-on-built-in-callbacks'
      pete@balloon:~/projects/rails/activerecord$ bundle exec ruby benchmark_allocation_with_callback_send.rb > allocations_after
      pete@balloon:~/projects/rails/activerecord$ diff allocations_before allocations_after
      39d38
      <
      {["/home/pete/projects/rails/activesupport/lib/active_support/callbacks.rb",
      81]=>[40, 0, 0, 0, 0, 0]}
      42c41
      < total: 630
      ---
      > total: 590
      
      ```
      
      In addition to this, there are two micro-optimizations present:
      
      * Using `block.call if block` vs `yield if block_given?` when the block was being captured already.
      
      ```
      pete@balloon:~/projects$ cat benchmark_block_call_vs_yield.rb
      require 'benchmark/ips'
      
      def block_capture_with_yield &block
        yield if block_given?
      end
      
      def block_capture_with_call &block
        block.call if block
      end
      
      def no_block_capture
        yield if block_given?
      end
      
      Benchmark.ips do |b|
        b.report("block_capture_with_yield") { block_capture_with_yield }
        b.report("block_capture_with_call") { block_capture_with_call }
        b.report("no_block_capture") { no_block_capture }
      end
      pete@balloon:~/projects$ ruby benchmark_block_call_vs_yield.rb
      Calculating -------------------------------------
      block_capture_with_yield
                              124979 i/100ms
      block_capture_with_call
                              138340 i/100ms
          no_block_capture    136827 i/100ms
      -------------------------------------------------
      block_capture_with_yield
                            5703108.9 (±2.4%) i/s -   28495212 in   4.999368s
      block_capture_with_call
                            6840730.5 (±3.6%) i/s -   34169980 in   5.002649s
          no_block_capture  5821141.4 (±2.8%) i/s -   29144151 in   5.010580s
      ```
      
      * Defining and calling methods instead of using send.
      
      ```
      pete@balloon:~/projects$ cat benchmark_method_call_vs_send.rb
      require 'benchmark/ips'
      
      class Foo
        def tacos
          nil
        end
      end
      
      my_foo = Foo.new
      
      Benchmark.ips do |b|
        b.report('send') { my_foo.send('tacos') }
        b.report('call') { my_foo.tacos }
      end
      pete@balloon:~/projects$ ruby benchmark_method_call_vs_send.rb
      Calculating -------------------------------------
                      send     97736 i/100ms
                      call    151142 i/100ms
      -------------------------------------------------
                      send  2683730.3 (±2.8%) i/s -   13487568 in   5.029763s
                      call  8005963.9 (±2.7%) i/s -   40052630 in   5.006604s
      ```
      
      The result of this is making typical ActiveRecord operations slightly faster:
      
      https://gist.github.com/phiggins/e46e51dcc7edb45b5f98
      796cab45
  6. 23 9月, 2014 2 次提交
    • S
      ar/connection_pool: honor overriden rack.test in middleware · cb598c21
      Simon Eskildsen 提交于
      Honoring an overidden `rack.test` allows testing closed connection between
      multiple requests. This is useful if you're working on database resiliency, to
      ensure the connection is in the expected state from one request to another on
      the same worker.
      cb598c21
    • A
      add a truncate method to the connection · 9a4e183f
      Aaron Patterson 提交于
      it doesn't work on SQLite3 since it doesn't support truncate, but that's
      OK.  If you call truncate on the connection, you're now bound to that
      database (same as if you use hstore or any other db specific feature).
      9a4e183f
  7. 18 9月, 2014 1 次提交
    • G
      Use #inject over #sum to build PG create DB statement · 707958b5
      Geoff Harcourt 提交于
      While investigating #16951 I found that another library's monkey-patching of
      `Enumerable` was causing the test migrations helper to break when trying to
      build the `CREATE DATABASE` statement. The prior approach used `#sum` to build
      the string from the options hash.
      
      As the code that combines the options to build the database statement is not
      user-facing, using `#inject` here instead will remove the only place where the
      database creation/migration code is dependent on ActiveSupport's monkey-patching
      of `Enumerable`.
      707958b5
  8. 17 9月, 2014 1 次提交
  9. 11 9月, 2014 3 次提交
  10. 09 9月, 2014 1 次提交
  11. 05 9月, 2014 1 次提交
  12. 03 9月, 2014 1 次提交
  13. 02 9月, 2014 1 次提交
  14. 31 8月, 2014 1 次提交
    • J
      MySQL: set connection collation along with the charset · d5ad2037
      Jeremy Kemper 提交于
      Sets the connection collation to the database collation configured
      in database.yml. Otherwise, `SET NAMES utf8mb4` will use the default
      collation for that charset (utf8mb4_general_ci) when you may have chosen
      a different collation, like utf8mb4_unicode_ci.
      
      This only applies to literal string comparisons, not column values, so
      it is unlikely to affect you.
      d5ad2037
  15. 29 8月, 2014 1 次提交
    • G
      Avoid using heredoc for user warnings · 8c52480b
      Godfrey Chan 提交于
      Using heredoc would enforce line wrapping to whatever column width we decided to
      use in the code, making it difficult for the users to read on some consoles.
      
      This does make the source code read slightly worse and a bit more error-prone,
      but this seems like a fair price to pay since the primary purpose for these
      messages are for the users to read and the code will not stick around for too
      long.
      8c52480b
  16. 25 8月, 2014 1 次提交
  17. 24 8月, 2014 2 次提交
  18. 22 8月, 2014 2 次提交
  19. 20 8月, 2014 1 次提交
  20. 19 8月, 2014 2 次提交
  21. 16 8月, 2014 2 次提交
    • A
      Fix regression on after_commit in nested transactions. · 2e90fe73
      Arthur Neves 提交于
      after_commit should not run in nested transactions, however they should
      run once the outermost transaction gets committed. This patch fixes the
      problem copying the records from the Savepoint to its parent. So the
      RealTransaction will have all records that needs to run callbacks on it.
      
      [fixes #16425]
      2e90fe73
    • A
      Use *_transaction methods in TransactionManager · 00029545
      Arthur Neves 提交于
      Use `commit_transaction`/`rollback_transaction` on
      `within_new_transaction` method, so they make sure they `pop` the
      transaction from the stack before calling the methods `commit`/`rollback`.
      00029545
  22. 15 8月, 2014 1 次提交
  23. 13 8月, 2014 2 次提交
    • Y
      `index_exists?` with `:name` checks specified columns. · ecfce561
      Yves Senn 提交于
      [Yves Senn & Matthew Draper]
      
      The column check was embodied in the defaul index name.
      If the :name option was used, the specified columns were not verified at all.
      
      Given:
      
      ```
      assert connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_yo_momma)
      ```
      
      That index could have been defined on any field, not necessarily on `:foo_id`.
      ecfce561
    • S
      Change the default `null` value for timestamps · ea3ba345
      Sean Griffin 提交于
      As per discussion, this changes the model generators to specify
      `null: false` for timestamp columns. A warning is now emitted if
      `timestamps` is called without a `null` option specified, so we can
      safely change the behavior when no option is specified in Rails 5.
      ea3ba345
  24. 08 8月, 2014 2 次提交
  25. 07 8月, 2014 1 次提交
    • T
      Tables existence check query is executed in large quantities · 8aead812
      tsukasaoishi 提交于
      When Rails starts, tables existence check query is executed
      number of models.
      In case of mysql,
      
          SHOW TABLES LIKE 'table1';
          SHOW TABLES LIKE 'table2';
          SHOW TABLES LIKE 'table3';
          ...
          SHOW TABLES LIKE 'table999';
      
      Add process to get the names of all tables by one query.
      8aead812
  26. 05 8月, 2014 2 次提交
    • A
      Cleanup Transaction inheritance. · 8298d3ad
      Arthur Neves 提交于
      Transaction class doesnt need to encapsulate the transaction state using
      inheritance.
      This removes all Transaction subclasses, and let the Transaction object
      controls different actions based on its own state. Basically the only
      actions would behave differently are `being`,`commit`,`rollback` as they
      could act in a savepoint or in a real transaction.
      8298d3ad
    • C
      Remove unused text? predicate method and delegation · d44702ee
      Carlos Antonio da Silva 提交于
      The method has been removed in 09206716
      (PR #16074), but the delegation was apparently missed, and one instance
      of the method was added back with the addition of OID::Xml in
      336be2bd (PR #16072), so we can safely
      rm both.
      d44702ee
  27. 01 8月, 2014 2 次提交