aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract
Commit message (Collapse)AuthorAgeFilesLines
* More exercise table name prefix and suffix testsRyuta Kamizono2019-02-113-7/+11
|
* Merge pull request #35203 from chiastolite/add_column_without_column_namesRyuta Kamizono2019-02-101-0/+1
|\ | | | | | | Do not allow to add column without column name
| * Do not allow to add column without column nameHiroyuki Morita2019-02-101-0/+1
|/
* Refactor to extract defining column methods as `define_column_methods`Ryuta Kamizono2019-02-091-21/+23
| | | | | It makes to ease to handle all short-hand methods (e.g. validates arguments etc).
* Fix elapsed time calculationsbogdanvlviv2019-02-081-4/+4
| | | | | | | | | | | | | | | | | | | I've found a few places in Rails code base where I think it makes sense to calculate elapsed time more precisely by using `Concurrent.monotonic_time`: - Fix calculation of elapsed time in `ActiveSupport::Cache::MemoryStore#prune` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::ConnectionPool::Queue#wait_poll` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::ConnectionPool#attempt_to_checkout_all_existing_connections` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::Mysql2Adapter#explain` See https://docs.ruby-lang.org/en/2.5.0/Process.html#method-c-clock_gettime https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way Related to 7c4542146f0dde962205e5a90839349631ae60fb
* Merge pull request #35089 from ↵Eileen M. Uchitelle2019-02-041-1/+1
|\ | | | | | | | | eileencodes/fix-query-cache-for-database-switching Invalidate all query caches for current thread
| * Invalidate query cache for all connections in the current threadEileen Uchitelle2019-02-011-1/+1
| | | | | | | | | | | | This change ensures that all query cahces are cleared across all connections per handler for the current thread so if you write on one connection the read will have the query cache cleared.
* | Merge pull request #35105 from olivierlacan/document-table-foreign-keyGannon McGibbon2019-02-021-1/+2
|\ \ | | | | | | Hint at advanced options for foreign_key
| * | Hint at advanced options for foreign_keyOlivier Lacan2019-01-301-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We sometimes display simple examples of additional parameters that can be supplied to table-wise methods like these and I found it particularly difficult to figure out which options `t.foreign_key` accepts without drilling very deep into the specific SchemaStatements docs. Since it's relatively common to create foreign keys with custom column names or primary keys, it seems like this should help quite a few people. [ci skip]
* | | Merge pull request #35082 from Shopify/eagerly-materialize-test-transactionsRafael França2019-02-011-2/+5
|\ \ \ | |_|/ |/| | Eagerly materialize the fixtures transaction
| * | Eagerly materialize the fixtures transactionJean Boussier2019-01-291-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The transaction used to restore fixtures is an implementation detail that should be abstracted away. Idealy a test should behave the same wether or not transactional fixtures are enabled. However since transactions have been made lazy, the fixture transaction started leaking into tests case. e.g. consider the following (oversimplified) test: ```ruby class SQLSubscriber attr_accessor :sql def initialize @sql = [] end def call(*, event) sql << event[:sql] end end subscriber = SQLSubscriber.new ActiveSupport::Notifications.subscribe("sql.active_record", subscriber) User.connection.execute('SELECT 1', 'Generic name') assert_equal ['SELECT 1'], subscriber.sql ``` On Rails 6 it starts to break because the `sql` array will be `['BEGIN', 'SELECT 1']`. Several things are wrong here: - That transaction is not generated by the tested code, so it shouldn't be visible. - The transaction is not even closed yet, which again doesn't reflect the reality.
* | | Remove unused attr_writers `visitor` and `indexes`Ryuta Kamizono2019-02-011-4/+0
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I deprecated two unused attr_writers `visitor` and `indexes` at 8056fe0 and f4bc364 conservatively, since those are accidentaly exposed in the docs. https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html But I've found that `view_renderer` attr_writer is removed without deprecation at #35093, that is also exposed in the doc. https://api.rubyonrails.org/v5.2/classes/ActionView/Base.html I'd like to also remove the deprecated attr_writers since I think that removing `visitor` and `indexes` attr_writers is as safe as removing `view_renderer` attr_writer.
* | Make `t.timestamps` with precision by defaultRyuta Kamizono2019-01-262-1/+11
| |
* | Allow `column_exists?` giving options without typeRyuta Kamizono2019-01-261-1/+1
| |
* | Fix error raised when handler doesn't existEileen Uchitelle2019-01-251-1/+10
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While working on another feature for multiple databases (auto-switching) I observed that in development the first request won't autoload the application record connection for the primary database and may not yet know about the replica connection. In my test application this caused the application to thrown an error if I tried to send the first request to the replica before the replica was connected. This wouldn't be an issue in production because the application is preloaded. In order to fix this I decided to leave the original error message and delete the new error message. I updated the original error message to include the `role` to make it a bit clearer that the connection isn't established for that particular role. The error now reads: ``` No connection pool with 'primary' found for the 'reading' role. ``` A single database application will continue uisng the original error message: ``` No connection pool with 'primary' found. ```
* Allow `column_exists?` to be passed `type` argument as a stringRyuta Kamizono2019-01-241-1/+1
| | | | | | | | | | | Currently `conn.column_exists?("testings", "created_at", "datetime")` returns false even if the table has the `created_at` column. That reason is that `column.type` is a symbol but passed `type` is not normalized to symbol unlike `column_name`, it is surprising behavior to me. I've improved that to normalize a value before comparison.
* Remove deprecated `#set_state` from the transaction objectRafael Mendonça França2019-01-171-18/+0
|
* Remove deprecated `#supports_statement_cache?` from the database adaptersRafael Mendonça França2019-01-171-7/+0
|
* Remove deprecated `#insert_fixtures` from the database adaptersRafael Mendonça França2019-01-171-13/+1
|
* Remove `id_value` argument which is no longer passed to `sql_for_insert`Ryuta Kamizono2019-01-111-2/+2
| | | | Since #26002, `id_value` is no longer passed to `sql_for_insert`.
* Merge the redundant `when Symbol` case to the `when String, ...`Ryuta Kamizono2019-01-041-2/+1
|
* 2x faster `connection.type_cast`Ryuta Kamizono2019-01-041-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `nil`, `Numeric`, and `String` are most basic objects which are passed to `type_cast`. But now each `when *types_which_need_no_typecasting` evaluation allocates extra two arrays, it makes `type_cast` slower. The `types_which_need_no_typecasting` was introduced at #15351, but the method isn't useful (never used any adapters) since all adapters (sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver) still overrides the `_type_cast`. Just expanding the method would make the `type_cast` 2x faster. ```ruby module ActiveRecord module TypeCastFast def type_cast_fast(value, column = nil) value = id_value_for_database(value) if value.is_a?(Base) if column value = type_cast_from_column(column, value) end _type_cast_fast(value) rescue TypeError to_type = column ? " to #{column.type}" : "" raise TypeError, "can't cast #{value.class}#{to_type}" end private def _type_cast_fast(value) case value when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data value.to_s when true then unquoted_true when false then unquoted_false # BigDecimals need to be put in a non-normalized form and quoted. when BigDecimal then value.to_s("F") when nil, Numeric, String then value when Type::Time::Value then quoted_time(value) when Date, Time then quoted_date(value) else raise TypeError end end end end conn = ActiveRecord::Base.connection conn.extend ActiveRecord::TypeCastFast Benchmark.ips do |x| x.report("type_cast") { conn.type_cast("foo") } x.report("type_cast_fast") { conn.type_cast_fast("foo") } x.compare! end ``` ``` Warming up -------------------------------------- type_cast 58.733k i/100ms type_cast_fast 101.364k i/100ms Calculating ------------------------------------- type_cast 708.066k (± 5.9%) i/s - 3.583M in 5.080866s type_cast_fast 1.424M (± 2.3%) i/s - 7.197M in 5.055860s Comparison: type_cast_fast: 1424240.0 i/s type_cast: 708066.0 i/s - 2.01x slower ```
* Use high level API on `migration_context` instead of using low level API ↵Ryuta Kamizono2018-12-281-4/+2
| | | | | | | | directly Since `migration_context` has `migrations_paths` itself and provides methods which returning values from parsed migration files, so there is no reason to use the `parse_migration_filename` low level API directly.
* Deprecate passing `migrations_paths` to ↵Ryuta Kamizono2018-12-281-2/+8
| | | | | | | `connection.assume_migrated_upto_version` Since #31727, `migrations_paths` in `assume_migrated_upto_version` is no longer used.
* Enable `Style/RedundantBegin` cop to avoid newly adding redundant begin blockRyuta Kamizono2018-12-211-19/+17
| | | | | | | | | | Currently we sometimes find a redundant begin block in code review (e.g. https://github.com/rails/rails/pull/33604#discussion_r209784205). I'd like to enable `Style/RedundantBegin` cop to avoid that, since rescue/else/ensure are allowed inside do/end blocks in Ruby 2.5 (https://bugs.ruby-lang.org/issues/12906), so we'd probably meets with that situation than before.
* Add ability to prevent writes to a databaseEileen Uchitelle2018-11-301-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This PR adds the ability to prevent writes to a database even if the database user is able to write (ie the database is a primary and not a replica). This is useful for a few reasons: 1) when converting your database from a single db to a primary/replica setup - you can fix all the writes on reads early on, 2) when we implement automatic database switching or when an app is manually switching connections this feature can be used to ensure reads are reading and writes are writing. We want to make sure we raise if we ever try to write in read mode, regardless of database type and 3) for local development if you don't want to set up multiple databases but do want to support rw/ro queries. This should be used in conjunction with `connected_to` in write mode. For example: ``` ActiveRecord::Base.connected_to(role: :writing) do Dog.connection.while_preventing_writes do Dog.create! # will raise because we're preventing writes end end ActiveRecord::Base.connected_to(role: :reading) do Dog.connection.while_preventing_writes do Dog.first # will not raise because we're not writing end end ```
* Add support for UNLOGGED Postgresql tablesJacob Evelyn2018-11-131-1/+6
| | | | | | | | | | | This commit adds support for the `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables` setting, which turns `CREATE TABLE` SQL statements into `CREATE UNLOGGED TABLE` statements. This can improve PostgreSQL performance but at the cost of data durability, and thus it is highly recommended that you *DO NOT* enable this in a production environment.
* Deprecate `t.indexes = [...]` which is not by designRyuta Kamizono2018-11-091-2/+5
| | | | Use `t.index ...` instead.
* Refactor to initialize `TableDefinition` by kwargsRyuta Kamizono2018-11-092-4/+14
|
* Add an :if_not_exists option to create_tablefatkodima2018-11-083-4/+10
| | | | [fatkodima & Stefan Kanev]
* Always add records to parent of nested transactionEugene Kenny2018-11-071-1/+1
| | | | | | | | | | | | | | | | | | | When a record with transactional callbacks is saved, it's attached to the current transaction so that the callbacks can be run when the transaction is committed. Records can also be added manually with `add_transaction_record`, even if they have no transactional callbacks. When a nested transaction is committed, its records are transferred to the parent transaction, as transactional callbacks should only be run when the outermost transaction is committed (the "real" transaction). However, this currently only happens when the record has transactional callbacks, and not when added manually with `add_transaction_record`. If a record is added to a nested transaction, we should always attach it to the parent transaction when the nested transaction is committed, regardless of whether it has any transactional callbacks. [Eugene Kenny & Ryuta Kamizono]
* Remove and flip `index: true` for `references` in the doc [ci skip]Ryuta Kamizono2018-10-172-8/+8
| | | | Follow up #32146.
* Move UPDATE/DELETE with JOIN handling to the Arel sideRyuta Kamizono2018-10-031-17/+0
|
* Merge pull request #23593 from meinac/add_index_option_for_change_tableRyuta Kamizono2018-10-011-0/+2
|\ | | | | | | index option added for change_table migrations
| * Index option added for change_table migrationsMehmet Emin INAC2018-09-221-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In case if we want to add a column into the existing table with index on it, we have to add column and index in two seperate lines. With this feature we don't need to write an extra line to add index for column. We can just use `index` option. Old behaviour in action: ``` change_table(:languages) do |t| t.string :country_code t.index: :country_code end ``` New behaviour in action: ``` change_table(:languages) do |t| t.string :country_code, index: true end ``` Exactly same behaviour is already exist for `create_table` migrations.
* | Merge pull request #32031 from yahonda/remove_redundant_freezeRyuta Kamizono2018-10-011-3/+3
|\ \ | | | | | | Add `Style/RedundantFreeze` to remove redudant `.freeze`
| * | Add `Style/RedundantFreeze` to remove redudant `.freeze`Yasuo Honda2018-09-291-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since Rails 6.0 will support Ruby 2.4.1 or higher `# frozen_string_literal: true` magic comment is enough to make string object frozen. This magic comment is enabled by `Style/FrozenStringLiteralComment` cop. * Exclude these files not to auto correct false positive `Regexp#freeze` - 'actionpack/lib/action_dispatch/journey/router/utils.rb' - 'activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb' It has been fixed by https://github.com/rubocop-hq/rubocop/pull/6333 Once the newer version of RuboCop released and available at Code Climate these exclude entries should be removed. * Replace `String#freeze` with `String#-@` manually if explicit frozen string objects are required - 'actionpack/test/controller/test_case_test.rb' - 'activemodel/test/cases/type/string_test.rb' - 'activesupport/lib/active_support/core_ext/string/strip.rb' - 'activesupport/test/core_ext/string_ext_test.rb' - 'railties/test/generators/actions_test.rb'
* | | Place `PartialQuery` and `PartialQueryCollector` in the same fileRyuta Kamizono2018-09-301-23/+1
|/ /
* / Enable `Performance/UnfreezeString` copyuuji.yaginuma2018-09-234-7/+7
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In Ruby 2.3 or later, `String#+@` is available and `+@` is faster than `dup`. ```ruby # frozen_string_literal: true require "bundler/inline" gemfile(true) do source "https://rubygems.org" gem "benchmark-ips" end Benchmark.ips do |x| x.report('+@') { +"" } x.report('dup') { "".dup } x.compare! end ``` ``` $ ruby -v benchmark.rb ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] Warming up -------------------------------------- +@ 282.289k i/100ms dup 187.638k i/100ms Calculating ------------------------------------- +@ 6.775M (± 3.6%) i/s - 33.875M in 5.006253s dup 3.320M (± 2.2%) i/s - 16.700M in 5.032125s Comparison: +@: 6775299.3 i/s dup: 3320400.7 i/s - 2.04x slower ```
* Use utf8mb4 in all tests and examplesRyuta Kamizono2018-09-211-2/+2
| | | | | Since #33875, Rails dropped supporting MySQL 5.1 which does not support utf8mb4. We no longer need to use legacy utf8 (utf8mb3) conservatively.
* Fallback to unprepared statement only when bind params limit is exceededRyuta Kamizono2018-09-142-0/+10
| | | | | | | | | | | This is a follow up and/or an alternative of #33844. Unlike #33844, this would attempt to construct unprepared statement only when bind params limit (mysql2 65535, pg 65535, sqlite3 249999) is exceeded. I only defined 65535 as the limit, not defined 249999 for sqlite3, since it is an edge case, I'm not excited to add less worth extra code.
* Consistently use `visitor.compile`Ryuta Kamizono2018-09-091-3/+3
|
* Merge pull request #33809 from fidalgo/improve-remove-column-documentationRichard Schneeman2018-09-061-0/+1
|\ | | | | [ci skip] Improve remove_column documentation
| * [ci skip] Improve remove_column documentationPaulo Fidalgo2018-09-061-0/+1
| | | | | | | | | | | | | | | | Since when we remove one column it will also remove the associated indexes, we must ensure this behaviour is properly documented. In this commit we add a line to the documentation mentioning this behaviour.
* | Deprecate most methods which were never used in `DatabaseLimits`Ryuta Kamizono2018-09-051-0/+9
| | | | | | | | | | | | | | | | | | `DatabaseLimits` and those methods were introduced at 3809c80, but most methods were never used and never tested from the beginning (except `table_alias_length`, `index_name_length`, and `in_clause_length` (since 66c09372)). There is no reason to maintain unused those methods for about 8 years.
* | Add documentation for `:collation` column option (#33733)Nate Pinsky2018-08-271-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | * Add documentation for `:collation` option The table definition supports a `:collation` option for string and text columns, but this is not documented anywhere that I could find. I'm not sure if the "If not specified" part is accurate. From [this PR](https://github.com/rails/rails/commit/1515c4d98da3f730ef971fa5a13cad828bd9bef4), it looks like it passes `nil` and lets the database handle the collation, but I'm happy to change it if I misread the code. [ci skip] * FIX remove whitespace [Nate Pinsky + Rafael Mendonça França]
* | Merge pull request #31696 from BrentWheeldon/bmw-connection-pool-load-deadlockMatthew Draper2018-08-241-1/+3
|\ \ | | | | | | Prevent deadlocks when waiting for connection from pool.
| * | Prevent deadlocks when waiting for connection from pool.Brent Wheeldon2018-03-231-1/+3
| | | | | | | | | | | | | | | When a thread that had the load interlock but was blocked waiting to check a connection out of the connection pool but all of the threads using the available connections were blocked waiting to obtain the load interlock an `ActiveRecord::ConnectionTimeoutError` exception was be thrown by the thread waiting for the connection. When waiting for the connection to check out we should allow loading to proceed to avoid this deadlock.
* | | Merge pull request #32647 from eugeneius/lazy_transactionsMatthew Draper2018-08-232-14/+66
|\ \ \ | | | | | | | | Omit BEGIN/COMMIT statements for empty transactions
| * | | Omit BEGIN/COMMIT statements for empty transactionsEugene Kenny2018-08-132-14/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a transaction is opened and closed without any queries being run, we can safely omit the `BEGIN` and `COMMIT` statements, as they only exist to modify the connection's behaviour inside the transaction. This removes the overhead of those statements when saving a record with no changes, which makes workarounds like `save if changed?` unnecessary. This implementation buffers transactions inside the transaction manager and materializes them the next time the connection is used. For this to work, the adapter needs to guard all connection use with a call to `materialize_transactions`. Because of this, adapters must opt in to get this new behaviour by implementing `supports_lazy_transactions?`. If `raw_connection` is used to get a reference to the underlying database connection, the behaviour is disabled and transactions are opened eagerly, as we can't know how the connection will be used. However when the connection is checked back into the pool, we can assume that the application won't use the reference again and reenable lazy transactions. This prevents a single `raw_connection` call from disabling lazy transactions for the lifetime of the connection.