aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* MySQL 8.0.14 adds `ER_FK_INCOMPATIBLE_COLUMNS`Yasuo Honda2019-01-221-1/+2
| | | | | | | | | | | | https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-14.html > Error messages relating to creating and dropping foreign keys > were improved to be more specific and informative. (Bug #28526309, Bug #92087) https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html > Error number: 3780; Symbol: ER_FK_INCOMPATIBLE_COLUMNS; SQLSTATE: HY000 > Message: Referencing column '%s' and referenced column '%s' in foreign key constraint '%s' are incompatible. > ER_FK_INCOMPATIBLE_COLUMNS was added in 8.0.14.
* Fix type casting column default in `change_column`Ryuta Kamizono2019-01-202-24/+42
| | | | | | | | | | | | | | Since #31230, `change_column` is executed as a bulk statement. That caused incorrect type casting column default by looking up the before changed type, not the after changed type. In a bulk statement, we can't use `change_column_default_for_alter` if the statement changes the column type. This fixes the type casting to use the constructed target sql_type. Fixes #34938.
* Merge pull request #34969 from eileencodes/fix-error-message-for-multi-db-appsEileen M. Uchitelle2019-01-181-1/+20
|\ | | | | Fix error message when adapter is not specified
| * Fix error message when adapter is not specifiedEileen Uchitelle2019-01-171-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we added support for multiple databases through a 3-tiered config and configuration objects this error message got a bit convoluted. Previously if you had an application with a missing configuation and multiple databases the error message would look like this: ``` 'doesnexist' database is not configured. Available: development, development, test, test, production, production (ActiveRecord::AdapterNotSpecified) ``` That's not very descriptive since it duplicates the environments (because there are multiple databases per environment for this application). To fix this I've constructed a bit more readable error message which now reads like this if you have a multi db app: ``` The `doesntexist` database is not configured for the `production` environment. (ActiveRecord::AdapterNotSpecified) Available databases configurations are: development: primary, primary_readonly test: primary, primary_readonly production: primary, primary_readonly ``` And like this if you have a single db app: ``` The `doesntexist` database is not configured for the `production` environment. (ActiveRecord::AdapterNotSpecified) Available databases configurations are: development test ``` This makes the error message more readable and presents the user all available options for the database connections.
* | 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-172-21/+1
| |
* | Remove deprecated ↵Rafael Mendonça França2019-01-171-5/+0
| | | | | | | | `ActiveRecord::ConnectionAdapters::SQLite3Adapter#valid_alter_table_type?`
* | Change `SQLite3Adapter` to always represent boolean values as integersRafael Mendonça França2019-01-172-20/+13
|/
* Remove public `prevent_writes` writerRyuta Kamizono2019-01-151-5/+5
| | | | | | The `@prevent_writes` should be updated only in the `while_preventing_writes`, it is not necessary to expose the attr writer.
* Deprecate `connection.visitor = ...` which is not released internal usageRyuta Kamizono2019-01-151-2/+6
| | | | | | | | | This attr writer was introduced at 7db90aa, but the usage is already removed at bd2f5c0 before v3.2.0.rc1 is released. If we'd like to customize the visitor in the connection, `arel_visitor` which is implemented in all adapters (mysql2, postgresql, sqlite3, oracle-enhanced, sqlserver) could be used for the purpose #23515.
* Remove `id_value` argument which is no longer passed to `sql_for_insert`Ryuta Kamizono2019-01-112-3/+3
| | | | Since #26002, `id_value` is no longer passed to `sql_for_insert`.
* Refactor `build_relation` in the uniqueness validator to avoid low level ↵Ryuta Kamizono2019-01-112-7/+16
| | | | predicate construction
* Enable `Lint/UselessAssignment` cop to avoid unused variable warnings (#34904)Ryuta Kamizono2019-01-091-2/+2
| | | | | | | | | | | | | | * Enable `Lint/UselessAssignment` cop to avoid unused variable warnings Since we've addressed the warning "assigned but unused variable" frequently. 370537de05092aeea552146b42042833212a1acc 3040446cece8e7a6d9e29219e636e13f180a1e03 5ed618e192e9788094bd92c51255dda1c4fd0eae 76ebafe594fc23abc3764acc7a3758ca473799e5 And also, I've found the unused args in c1b14ad which raises no warnings by the cop, it shows the value of the cop.
* :recycle: Fix mysql type map for enum and setbannzai2019-01-081-2/+2
|
* 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 ```
* Merge pull request #33985 from eugeneius/attribute_methods_schema_cacheKasper Timm Hansen2019-01-031-0/+5
|\ | | | | Only define attribute methods from schema cache
| * Only define attribute methods from schema cacheEugene Kenny2018-09-281-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | To define the attribute methods for a model, Active Record needs to know the schema of the underlying table, which is usually achieved by making a request to the database. This is undesirable behaviour while the app is booting, for two reasons: it makes the boot process dependent on the availability of the database, and it means every new process will make one query for each table, which can cause issues for large applications. However, if the application is using the schema cache dump feature, then the schema cache already contains the necessary information, and we can define the attribute methods without causing any extra database queries.
* | MariaDB: Remove version checking lower the 5.5.8Ryuta Kamizono2019-01-021-10/+2
| | | | | | | | Since we already bumped the minimum version of MySQL to 5.5.8 at #33853.
* | Add test case for `preventing_writes?`Ryuta Kamizono2019-01-021-1/+1
| | | | | | | | Since the `preventing_writes?` is public API.
* | 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.
* | Merge pull request #34742 from kamipo/row_format_dynamic_by_defaultRyuta Kamizono2018-12-211-0/+18
|\ \ | | | | | | MySQL: `ROW_FORMAT=DYNAMIC` create table option by default
| * | MySQL: `ROW_FORMAT=DYNAMIC` create table option by defaultRyuta Kamizono2018-12-191-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since MySQL 5.7.9, the `innodb_default_row_format` option defines the default row format for InnoDB tables. The default setting is `DYNAMIC`. The row format is required for indexing on `varchar(255)` with `utf8mb4` columns. As long as using MySQL 5.6, CI won't be passed even if MySQL server setting is properly configured the same as MySQL 5.7 (`innodb_file_per_table = 1`, `innodb_file_format = 'Barracuda'`, and `innodb_large_prefix = 1`) since InnoDB table is created as the row format `COMPACT` by default on MySQL 5.6, therefore indexing on string with `utf8mb4` columns aren't succeeded. Making `ROW_FORMAT=DYNAMIC` create table option by default for legacy MySQL version would mitigate the indexing issue on the user side, and it makes CI would be passed on MySQL 5.6 which is configured properly.
* | | Enable `Style/RedundantBegin` cop to avoid newly adding redundant begin blockRyuta Kamizono2018-12-212-25/+21
|/ / | | | | | | | | | | | | | | | | | | 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.
* | Use `utf8mb4` charset for internal tables if the row format `DYNAMIC` by defaultRyuta Kamizono2018-12-192-10/+10
| | | | | | | | The indexing issue on `utf8mb4` columns is resolved since MySQL 5.7.9.
* | Ensure that preventing writes is invoked before `materialize_transactions` ↵Ryuta Kamizono2018-12-121-4/+2
| | | | | | | | consistently
* | An empty transaction does not raise the `ReadOnlyError` if preventing writesRyuta Kamizono2018-12-113-3/+3
| | | | | | | | | | | | BEGIN transaction would cause COMMIT or ROLLBACK, so unless COMMIT and ROLLBACK aren't treated as write queries as well as BEGIN, the `ReadOnlyError` would be raised.
* | An explain query does not raise the `ReadOnlyError` if preventing writesRyuta Kamizono2018-12-113-3/+3
| |
* | Don't treat begin and rollback transactions as write queriesRyuta Kamizono2018-12-113-3/+3
| | | | | | | | | | Otherwise `save` method would raise the `ReadOnlyError` against `BEGIN` and `ROLLBACK` queries.
* | Prevent write queries with prepared statements for mysql2 adapterRyuta Kamizono2018-12-111-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Without this change, mysql2 adapter with prepared statements won't pass `base_test.rb`. ``` % ARCONN=mysql2 be ruby -w -Itest test/cases/base_test.rb Using mysql2 Run options: --seed 27614 # Running: ....S..............................F Failure: BasicsTest#test_creating_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1493]: ActiveRecord::ReadOnlyError expected but nothing was raised. rails test test/cases/base_test.rb:1492 ...F Failure: BasicsTest#test_deleting_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1513]: ActiveRecord::ReadOnlyError expected but nothing was raised. rails test test/cases/base_test.rb:1510 ............................................................................................................F Failure: BasicsTest#test_updating_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1503]: ActiveRecord::ReadOnlyError expected but nothing was raised. rails test test/cases/base_test.rb:1500 .......... Finished in 2.534490s, 62.7345 runs/s, 149.5370 assertions/s. 159 runs, 379 assertions, 3 failures, 0 errors, 1 skips ```
* | Prevent write queries for `exec_query`Ryuta Kamizono2018-12-112-1/+9
| | | | | | | | Follow up #34505.
* | Rename error that occurs when writing on a readEileen Uchitelle2018-12-073-3/+3
| | | | | | | | | | | | | | I originally named this `StatementInvalid` because that's what we do in GitHub, but `@tenderlove` pointed out that this means apps can't test for or explitly rescue this error. `StatementInvalid` is pretty broad so I've renamed this to `ReadOnlyError`.
* | Fix join table column quoting with SQLite.Gannon McGibbon2018-12-051-0/+4
| |
* | Merge pull request #34602 from guizmaii/masterRafael França2018-12-031-1/+2
|\ \ | | | | | | Pass the `connection` to the `@instrumenter.instrument` method call
| * | Pass the `connection` to the `@instrumenter.instrument` method calljules Ivanic2018-12-031-1/+2
| | |
* | | Address "warning: shadowing outer local variable - parts"Ryuta Kamizono2018-12-034-7/+8
|/ / | | | | | | And hide the `READ_QUERY` internal constant.
* | Add ability to prevent writes to a databaseEileen Uchitelle2018-11-305-1/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ```
* | Allow spaces in postgres table namesGannon McGibbon2018-11-281-1/+1
| | | | | | | | | | Fixes issue where "user post" is misinterpreted as "\"user\".\"post\"" when quoting table names with the postgres adapter.
* | Merge pull request #34557 from sergioisidoro/sergio-patch-load-errorRafael França2018-11-281-2/+2
|\ \ | | | | | | Patch load error in case GemSpecError
| * | Patch load error in case GemSpecErrorsergioisidoro2018-11-281-2/+2
| | |
* | | `Mutable` helper is in `ActiveModel`Ryuta Kamizono2018-11-274-4/+4
| | | | | | | | | | | | It should be referenced by full qualified name from Active Record.
* | | Merge pull request #34520 from yahonda/bump_pg93Rafael França2018-11-262-19/+17
|\ \ \ | | | | | | | | Bump the minimum version of PostgreSQL to 9.3
| * | | Bump the minimum version of PostgreSQL to 9.3Yasuo Honda2018-11-252-19/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | https://www.postgresql.org/support/versioning/ - 9.1 EOLed on September 2016. - 9.2 EOLed on September 2017. 9.3 is also not supported since Nov 8, 2018. https://www.postgresql.org/about/news/1905/ I think it may be a little bit early to drop PostgreSQL 9.3 yet. * Deprecated `supports_ranges?` since no other databases support range data type * Add `supports_materialized_views?` to abstract adapter Materialized views itself is supported by other databases, other connection adapters may support them * Remove `with_manual_interventions` It was only necessary for PostgreSQL 9.1 or earlier * Drop CI against PostgreSQL 9.2
* | | | When running exec_query MySQL always returns ActiveRecord::ResultAlireza Bashiri2018-11-251-2/+10
|/ / / | | | | | | | | | | | | When running `exec_query` with `INSERT` (or other write commands), MySQL returns `ActiveRecord::Result`.
* | | Merge pull request #34468 from gmcgibbon/redact_sql_in_errorsRafael França2018-11-234-41/+41
|\ \ \ | | | | | | | | Redact SQL in errors