1. 02 11月, 2015 1 次提交
    • R
      Remove `DEFAULT_CHARSET` and `DEFAULT_COLLATION` in `MySQLDatabaseTasks` · 322068fe
      Ryuta Kamizono 提交于
      This reverts commit f6ca7e4e.
      
      The default collation of utf8 in MySQL is the `utf8_general_ci`, and
      this should not be changed. This is because, the better collation in the
      all locales is not exists, optimal collation in own application is not
      known other than themselves.
      
      The `utf8_unicode_ci` is known as Japanese killer in Japan, there are
      serious impacts in search of Japanese.
      
      MySQL implements the `utf8_unicode_ci` according to the Unicode
      Collation Algorithm (UCA) described at http://www.unicode.org/reports/tr10/,
      but the `utf8_unicode_ci` have only partial support for the UCA, only
      primary level key comparison implemented (also known as L1 (Base
      characters) comparison).
      
      Because L1 (Base characters) comparison does not distinguish between the
      presence or absence of the accent, if distinction of the accent is
      important there is a serious impact (e.g. Japanese).
      
      Example:
      
      ```
      > SHOW CREATE TABLE `dicts`\G
      *************************** 1. row ***************************
             Table: dicts
      Create Table: CREATE TABLE `dicts` (
        `word` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
        `meaning` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
      1 row in set (0.00 sec)
      
      > INSERT INTO `dicts` VALUES ('ハハ', 'mother'), ('パパ', 'father');
      Query OK, 2 rows affected (0.00 sec)
      
      > SELECT * FROM `dicts` WHERE `word` = 'ハハ';
      +--------+---------+
      | word   | meaning |
      +--------+---------+
      | ハハ   | mother  |
      | パパ   | father  |
      +--------+---------+
      2 rows in set (0.00 sec)
      
      > CREATE UNIQUE INDEX `unique_index_word` ON `dicts`(`word`);
      ERROR 1062 (23000): Duplicate entry 'ハハ' for key 'unique_index_word'
      ```
      
      We should omit the collation entirely rather than providing a default.
      Then the choice is the responsibility of the server and MySQL distribution.
      322068fe
  2. 31 10月, 2015 5 次提交
    • Y
      Move some AR test cases to inheritance_test.rb · 2fe8baf9
      yui-knk 提交于
      These methods are defined in inheritance.rb
      
      * `abstract_class?`
      * `descends_from_active_record?`
      * `compute_type`
      2fe8baf9
    • A
      don't sleep in tests · cb848c8d
      Aaron Patterson 提交于
      we should be using a countdown latch instead of rolling our own
      busy-loop.
      cb848c8d
    • S
      Use advisory locks to prevent concurrent migrations · 2c2a8755
      Sam Davies 提交于
      - Addresses issue #22092
      - Works on Postgres and MySQL
      - Uses advisory locks because of two important properties:
        1. The can be obtained outside of the context of a transaction
        2. They are automatically released when the session ends, so if a
        migration process crashed for whatever reason the lock is not left
        open perpetually
      - Adds get_advisory_lock and release_advisory_lock methods to database
        adapters
      - Attempting to run a migration while another one is in process will
        raise a ConcurrentMigrationError instead of attempting to run in
        parallel with undefined behavior. This could be rescued and
        the migration could exit cleanly instead. Perhaps as a configuration
        option?
      
      Technical Notes
      ==============
      
      The Migrator uses generate_migrator_advisory_lock_key to build the key
      for the lock. In order to be compatible across multiple adapters there
      are some constraints on this key.
      - Postgres limits us to 64 bit signed integers
      - MySQL advisory locks are server-wide so we have to scope to the
        database
      - To fulfil these requirements we use a Migrator salt (a randomly
        chosen signed integer with max length of 31 bits) that identifies
        the Rails migration process as the owner of the lock. We multiply
        this salt with a CRC32 unsigned integer hash of the database name to
        get a signed 64 bit integer that can also be converted to a string
        to act as a lock key in MySQL databases.
      - It is important for subsequent versions of the Migrator to use the
        same salt, otherwise different versions of the Migrator will not see
        each other's locks.
      2c2a8755
    • S
      Fix test failures caused by #12071 · 3cd49570
      Sean Griffin 提交于
      This assumes only one query was ever executed, but it appears to
      sometimes be loading schema information. We can just look at the array
      of queries, rather than the "first" one that was run
      3cd49570
    • T
      Alias left_joins to left_outer_joins · d3411ad3
      Takashi Kokubun 提交于
      d3411ad3
  3. 30 10月, 2015 5 次提交
    • S
      Ensure `has_and_belongs_to_many` works with `belongs_to_required_by_default` · 21a386bb
      Sean Griffin 提交于
      Before this commit, if
      `ActiveRecord::Base.belongs_to_required_by_default` is set to `true`,
      then creating a record through `has_and_belongs_to_many` fails with the
      cryptic error message `Left side must exist`. This is because
      `inverse_of` isn't working properly in this case, presumably since we're
      doing trickery with anonymous classes in the middle.
      
      Rather than following this rabbit hole to try and get `inverse_of` to
      work in a case that we know is not publicly supported, we can just turn
      off this validation to match the behavior of 4.2 and earlier.
      21a386bb
    • S
      Never pass `nil` to `order` · a59a4fbd
      Sean Griffin 提交于
      This is part of a refactoring to make it easier to allow `order` to use
      sanitize like just about everything else on relation. The deleted test
      doesn't give any reasoning as to why passing `nil` to `order` needs to
      be supported, and it's rather nonsensical. I can almost see allowing an
      empty string being passed (though I'm tempted to just disallow it...)
      a59a4fbd
    • J
      FixtureSet.fixture_class_names should have no default value · 0c843640
      Jamis Buck 提交于
      Look at `TestFixtures.set_fixture_class`. As documented, it
      accepts a mapping of fixture identifiers (string or symbol) to Classes
      (the model classes that implement the named fixture).
      
      Look now at the initialization of `TestFixtures.fixture_class_names`.
      It defines a Hash, which will return a string by default (where the
      string is the estimated class name of the given fixture identifier).
      
      Now look at TestFixtures.load_fixtures. It calls `FixtureSet.create_fixtures`,
      passing in the mapping of `fixture_class_names`.
      
      Following this on to `FixtureSet.create_fixtures`, this instantiates a
      `FixtureSet::ClassCache`, passing in the map of class names.
      
      `ClassCache`, in turn, calls `insert_class` for each value in the cache.
      (Recall that `set_fixture_class` puts Class objects in there, while the
      default proc for the mapping puts String objects.)
      
      Look finally at `insert_class`. If the value is present, it checks to
      see if the value is a subclass of `AR::Base`. Fair enough...but wait!
      What if the value is a String? You get an exception, because a String
      instance cannot be compared with a Class.
      
      Judging from the implementation, it seems like the expected behavior
      here is for `fixture_class_names` to have no default proc. Look-ups are
      supposed to happen via `ClassCache`, with `fixture_class_names` existing
      solely as a repository for explicitly-registered class mappings.
      
      That is what this change does.
      0c843640
    • Y
      Revert "Revert "Merge pull request #22026 from akihiro17/fix-preload-association"" · 857a34a4
      Yves Senn 提交于
      This reverts commit 52439460.
      
      This fixes an issue with the build where tests would fail on mysql and
      postgresql due to different ordering.
      857a34a4
    • S
      Revert "Merge pull request #22026 from akihiro17/fix-preload-association" · 52439460
      Sean Griffin 提交于
      This reverts commit 6dc6a0b1, reversing
      changes made to ec94f00b.
      
      This pull request broke the build.
      52439460
  4. 29 10月, 2015 3 次提交
    • S
      Fix test failures caused by #19501 · 42b9f3eb
      Sean Griffin 提交于
      The first one is quite straightforward. We want to give the proper error
      message in the case where a top level constant exists, but we're looking
      for a nested one. We just need to port over the change to use
      `subclass.name` into these changes.
      
      The second set of failures, which are only present in the mysql adapter
      tests, are stranger to me. The failure occurs because we were
      previously comparing `subclass.name == self.name` instead of `subclass
      == self`. However, I don't think that we need to support creating
      anonymous classes which share a table with a class that uses STI,
      overrides `name` to return the same name as athe class that we have no
      other relationship with, when not assigned to a constant so it could
      never be used anyway...
      
      The commits around why that exist give no context, and I think they're
      just poorly written tests (WTF does `test_schema` mean anyway, and why
      does calling `.first` on some anonymous class test it?). We'll just
      disable STI on that class.
      42b9f3eb
    • A
      Set `scope.reordering_value` to `true` if :reordering values are specified · 0fdc2dbe
      akihiro17 提交于
      We should call `scope.order!` and set `scope.reordering_value` to `true` if :reordering values are specified
      
      Fixes #21886
      0fdc2dbe
    • Y
      tests, no every adapter supports "connection.version" · 59ec8a59
      Yves Senn 提交于
      This solves the following issue:
      
      ```
      $ bin/test
      Using sqlite3
      /Users/senny/Projects/rails/activerecord/test/cases/adapters/mysql2/sp_test.rb:16:in `<class:Mysql2StoredProcedureTest>': undefined method `version' for #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x007f8bab4b5b70> (NoMethodError)
      	from /Users/senny/Projects/rails/activerecord/test/cases/adapters/mysql2/sp_test.rb:5:in `<top (required)>'
      	from /Users/senny/Projects/rails/activesupport/lib/active_support/dependencies.rb:302:in `require'
      	from /Users/senny/Projects/rails/activesupport/lib/active_support/dependencies.rb:302:in `block in require'
      	from /Users/senny/Projects/rails/activesupport/lib/active_support/dependencies.rb:268:in `load_dependency'
      	from /Users/senny/Projects/rails/activesupport/lib/active_support/dependencies.rb:302:in `require'
      	from /Users/senny/Projects/rails/railties/lib/rails/test_unit/test_requirer.rb:11:in `block in require_files'
      	from /Users/senny/Projects/rails/railties/lib/rails/test_unit/test_requirer.rb:10:in `each'
      	from /Users/senny/Projects/rails/railties/lib/rails/test_unit/test_requirer.rb:10:in `require_files'
      	from /Users/senny/Projects/rails/railties/lib/rails/test_unit/minitest_plugin.rb:69:in `plugin_rails_init'
      	from /Users/senny/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/minitest-5.3.3/lib/minitest.rb:73:in `block in init_plugins'
      	from /Users/senny/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/minitest-5.3.3/lib/minitest.rb:71:in `each'
      	from /Users/senny/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/minitest-5.3.3/lib/minitest.rb:71:in `init_plugins'
      	from /Users/senny/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/minitest-5.3.3/lib/minitest.rb:122:in `run'
      	from bin/test:19:in `<main>'
      ```
      59ec8a59
  5. 27 10月, 2015 2 次提交
  6. 25 10月, 2015 1 次提交
  7. 22 10月, 2015 3 次提交
    • R
      Refactor Calculations#execute_grouped_calculation and clean AR test case · 4f21d42f
      Rafael Sales 提交于
      * When tried to use `Company#accounts` test/models/company.rb I got:
      
      ```
      ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column:
      accounts.company_id: SELECT COUNT(*) AS count_all, "companies"."firm_id"
      AS companies_firm_id FROM "companies" INNER JOIN "accounts" ON
      "accounts"."company_id" = "companies"."id" GROUP BY "companies"."firm_id"
      ```
      
      * The refactor on Calculations class was just to simplify the code
      4f21d42f
    • R
      Fix generated projection fields in group by query · c2d33c4a
      Rafael Sales 提交于
      Closes #21922
      
      Let `Book(id, author_id)`, `Photo(id, book_id, author_id)` and `Author(id)`
      
      Running `Book.group(:author_id).joins(:photos).count` will produce:
      
      * Rails 4.2 - conflicts `author_id` in both projection and group by:
      ```sql
      SELECT COUNT(*) AS count_all, author_id AS author_id
        FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
       GROUP BY author_id
      ```
      
      * Master (9d02a25d) - conflicts `author_id` only in projection:
      ```sql
      SELECT COUNT(*) AS count_all, author_id AS author_id
        FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
       GROUP BY "books"."author_id"
      ```
      
      * With this fix:
      ```sql
      SELECT COUNT(*) AS count_all, "books"."author_id" AS books_author_id
        FROM "books" INNER JOIN "photos" ON "photos"."book_id" = "books"."id"
       GROUP BY "books"."author_id"
      ```
      c2d33c4a
    • R
      Remove `#tables` extra args again · edfb738b
      Ryuta Kamizono 提交于
      This issue was resolved by #21687 already. But re-add args by #18856.
      `#tables` extra args was only using by `#table_exists?`. This is for
      internal API. This commit will remove these extra args again.
      edfb738b
  8. 21 10月, 2015 5 次提交
    • J
      Exit with non-zero status when db:create fails · 2893e6c0
      Jay Hayes 提交于
      * If the create task fails for a reason other than the database already
        existing, processing should end. This is indicated by a non-zero exit
        status.
      * Since the backtrace is already printed to screen, we forgo printing it
        again by using an explicit call to `exit`.
      *  This modifies the behavior of the db:create task slightly in
        that the stack trace is no longer printed by default. If the `--trace`
        option is used, it will print the trace _after_ the error message.
      2893e6c0
    • S
      Fix test failures caused by d99db6b8 · 3e29d96e
      Sean Griffin 提交于
      I messed up the merge conflict, and accidentally removed a schema query
      that needed to be ignored.
      3e29d96e
    • S
      Qualify column names in calculation · a7628099
      Soutaro Matsumoto 提交于
      Column names inserted via `group` have to be qualified with table name.
      a7628099
    • S
      Do not cache prepared statements that are unlikely to have cache hits · cbcdecd2
      Sean Griffin 提交于
      Prior to this commit, Rails makes no differentiation between whether a
      query uses bind parameters, and whether or not we cache that query as a
      prepared statement. This leads to the cache populating extremely fast in
      some cases, with the statements never being reused.
      
      In particular, the two problematic cases are `where(foo: [1, 2, 3])` and
      `where("foo = ?", 1)`. In both cases we'll end up quoting the values
      rather than using a bind param, causing a cache entry for every value
      ever used in that query.
      
      It was noted that we can probably eventually change `where("foo = ?",
      1)` to use a bind param, which would resolve that case. Additionally, on
      PG we can change our generated query to be `WHERE foo = ANY($1)`, and
      pass an array for the bind param. I hope to accomplish both in the
      future.
      
      For SQLite and MySQL, we still end up preparing the statements anyway,
      we just don't cache it. The statement will be cleaned up after it is
      executed. On postgres, we skip the prepare step entirely, as an API is
      provided to execute with bind params without preparing the statement.
      
      I'm not 100% happy on the way this ended up being structured. I was
      hoping to use a decorator on the visitor, rather than mixing a module
      into the object, but the way Arel has it's visitor pattern set up makes
      it very difficult to extend without inheritance. I'd like to remove the
      duplication from the various places that are extending it, but that'll
      require a larger restructuring of that initialization logic. I'm going
      to take another look at the structure of it soon.
      
      This changes the signature of one of the adapter's internals, and will
      require downstream changes from third party adapters. I'm not too
      worried about this, as worst case they can simply add the parameter and
      always ignore it, and just keep their previous behavior.
      
      Fixes #21992.
      cbcdecd2
    • K
  9. 19 10月, 2015 1 次提交
    • J
      Reorder application of has_many association constraints. · d9bb13ba
      jbranchaud 提交于
      With `unscope!` called last, it undoes `where` constraints of the same
      value when the `where` is chained after the `unscope`. This is what a
      `rewhere` does. This is undesirable behavior.
      
      The included tests demonstrate both the `unscope(...).where(...)`
      behavior as well as the direct use of `rewhere(...)`.
      
      This is in reference to #21955.
      d9bb13ba
  10. 18 10月, 2015 1 次提交
  11. 17 10月, 2015 1 次提交
  12. 16 10月, 2015 2 次提交
    • J
      `where` raises ArgumentError on unsupported types. · 7663376f
      Jake Worth 提交于
      [#20473]
      7663376f
    • M
      fixes #21815 · 86d2924a
      Maarten Jacobs 提交于
      The default timestamp used for AR is `updated_at` in nanoseconds! (:nsec) This causes issues on any machine that runs an OS that supports nanoseconds timestamps, i.e. not-OS X, where the cache_key of the record persisted in the database (milliseconds precision) is out-of-sync with the cache_key in the ruby VM.
      
      This commit adds:
      
      A test that shows the issue, it can be found in the separate file `cache_key_test.rb`, because
      - model couldn't be defined inline
      - transactional testing needed to be turned off to get it to pass the MySQL tests
      This seemed cleaner than putting it in an existing testcase file.
      
      It adds :usec as a dateformat that calculates datetime in microseconds
      
      It sets precision of cache_key to :usec instead of :nsec, as no db supports nsec precision on timestamps
      86d2924a
  13. 15 10月, 2015 4 次提交
  14. 13 10月, 2015 1 次提交
    • Y
      `:to_table` when adding a fk through `add_reference`. · 5a14349b
      Yves Senn 提交于
      Closes #21563.
      
      The `name` argument of `add_references` was both used to generate the
      column name `<name>_id` and as the target table for the foreign key
      `name.pluralize`.
      
      It's primary purpose is to define the column name. In cases where the
      `to_table` of the foreign key is different than the column name we
      should be able to specify it individually.
      5a14349b
  15. 08 10月, 2015 2 次提交
  16. 06 10月, 2015 2 次提交
  17. 05 10月, 2015 1 次提交