aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/tasks/database_tasks.rb
Commit message (Collapse)AuthorAgeFilesLines
* Allow `truncate` for SQLite3 adapter and add `rails db:seed:replant` (#34779)Bogdan2019-03-041-0/+18
| | | | | | | | | | | | | * Add `ActiveRecord::Base.connection.truncate` for SQLite3 adapter. SQLite doesn't support `TRUNCATE TABLE`, but SQLite3 adapter can support `ActiveRecord::Base.connection.truncate` by using `DELETE FROM`. `DELETE` without `WHERE` uses "The Truncate Optimization", see https://www.sqlite.org/lang_delete.html. * Add `rails db:seed:replant` that truncates database tables and loads the seeds Closes #34765
* Add multi-db support to schema cache dump and clearGannon McGibbon2018-11-071-0/+10
| | | | | Adds support for multiple databases to `rails db:schema:cache:dump` and `rails db:schema:cache:clear`.
* Move db:migrate:status to DatabaseTasks methodGannon McGibbon2018-10-081-0/+15
|
* Enable `Performance/UnfreezeString` copyuuji.yaginuma2018-09-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ```
* Convert configs_for to kwargs, add include_replicasEileen Uchitelle2018-08-311-5/+5
| | | | | | | | | | | Changes the `configs_for` method from using traditional arguments to using kwargs. This is so I can add the `include_replicas` kwarg without having to always include `env_name` and `spec_name` in the method call. `include_replicas` defaults to false because everywhere internally in Rails we don't want replicas. `configs_for` is for iterating over configurations to create / run rake tasks, so we really don't ever need replicas in that case.
* Refactors Active Record connection managementEileen Uchitelle2018-08-301-9/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While the three-tier config makes it easier to define databases for multiple database applications, it quickly became clear to offer full support for multiple databases we need to change the way the connections hash was handled. A three-tier config means that when Rails needed to choose a default configuration (in the case a user doesn't ask for a specific configuration) it wasn't clear to Rails which the default was. I [bandaid fixed this so the rake tasks could work](#32271) but that fix wasn't correct because it actually doubled up the configuration hashes. Instead of attemping to manipulate the hashes @tenderlove and I decided that it made more sense if we converted the hashes to objects so we can easily ask those object questions. In a three tier config like this: ``` development: primary: database: "my_primary_db" animals: database; "my_animals_db" ``` We end up with an object like this: ``` @configurations=[ #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>, #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="development",@spec_name="animals", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}> ]> ``` The configurations setter takes the database configuration set by your application and turns them into an `ActiveRecord::DatabaseConfigurations` object that has one getter - `@configurations` which is an array of all the database objects. The configurations getter returns this object by default since it acts like a hash in most of the cases we need. For example if you need to access the default `development` database we can simply request it as we did before: ``` ActiveRecord::Base.configurations["development"] ``` This will return primary development database configuration hash: ``` { "database" => "my_primary_db" } ``` Internally all of Active Record has been converted to use the new objects. I've built this to be backwards compatible but allow for accessing the hash if needed for a deprecation period. To get the original hash instead of the object you can either add `to_h` on the configurations call or pass `legacy: true` to `configurations. ``` ActiveRecord::Base.configurations.to_h => { "development => { "database" => "my_primary_db" } } ActiveRecord::Base.configurations(legacy: true) => { "development => { "database" => "my_primary_db" } } ``` The new configurations object allows us to iterate over the Active Record configurations without losing the known environment or specification name for that configuration. You can also select all the configs for an env or env and spec. With this we can always ask any object what environment it belongs to: ``` db_configs = ActiveRecord::Base.configurations.configurations_for("development") => #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[ #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>, #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="development",@spec_name="animals", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}> ]> db_config.env_name => "development" db_config.spec_name => "primary" db_config.config => { "adapter"=>"sqlite3", "database"=>"db/development.sqlite3" } ``` The configurations object is more flexible than the configurations hash and will allow us to build on top of the connection management in order to add support for primary/replica connections, sharding, and constructing queries for associations that live in multiple databases.
* Merge pull request #33744 from bogdanvlviv/fixes-27852Ryuta Kamizono2018-08-301-1/+1
|\ | | | | Prevent leaking of user's DB credentials on `rails db:create` failure
| * Prevent leaking of user's DB credentials on `rails db:create` failurebogdanvlviv2018-08-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Issue #27852 reports that when `rails db:create` fails, it causes leaking of user's DB credentials to $stderr. We print a DB's configuration hash in order to help users more quickly to figure out what could be wrong with his configuration. This commit changes message from "Couldn't create database for #{configuration.inspect}" to "Couldn't create '#{configuration['database']}' database. Please check your configuration.". There are two PRs that fixing it #27878, #27879, but they need a bit more work. I decided help to finish this and added Author of those PRs credit in this commit. Since it is a security issue, I think we should backport it to `5-2-stable`, and `5-1-stable`. Guided by https://edgeguides.rubyonrails.org/maintenance_policy.html#security-issues Fixes #27852 Closes #27879 Related to #27878 [Alexander Marrs & bogdanvlviv]
* | Drop load_database_yaml and fix testEileen Uchitelle2018-08-291-1/+1
|/ | | | | | | | | | | | | | | | | | | | | | | | | | We originally did the whole `load_database_yaml` thing because this test wasn't cooperating and we needed to finish the namespaced rake tasks for multiple databases. However, it turns out that YAML can't eval ERB if you don't tell it it's ERB so you get Pysch parse errors if you're using multi-line ERB or ERB with conditionals. It's a hot mess. After trying a few things and thinking it over we decided that it wasn't worth bandaiding over, the test needed to be improved. The test was added in #31135 to test that the env is loaded in these tasks. But it was blowing up because we were trying to read a database name out of the configuration - however that's not the purpose of this change. We want to read environment files in the rake tasks, but not in the config file. In this PR we changed the test to test what the PR was actually fixing. We've also deleted the `load_database_yaml` because it caused more problems than it was worth. This should fix the issues described in https://github.com/rails/rails/pull/32274#issuecomment-384161057. We also had these problems at GitHub. Co-authored-by: alimi <aibrahim2k2@gmail.com>
* [ci skip] Change references from Rake task to Rails commandAlberto Almagro2018-08-011-1/+1
| | | | | This commit follows the path we started at commit #ea4f0e2 and continued at PR #33229.
* use load_schema instead of migrate for parallel testingBritni Alexander2018-07-311-0/+3
|
* Don't create namespaced tasks if single db applicationeileencodes2018-04-091-2/+7
| | | | | | This was causing single db applications to have rake tasks named `db:create:primary`. These tasks are only useful to multiple database applications so they shouldn't be generated.
* Allow schema/structure load for multiple databaseseileencodes2018-04-091-3/+3
| | | | | Pass the spec name to load_schema in order to load from the correct structure file when there are multiple databases
* Refactor configs_for and friendseileencodes2018-03-211-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Moves the configs_for and DatabaseConfig struct into it's own file. I was considering doing this in a future refactoring but our set up forced me to move it now. You see there are `mattr_accessor`'s on the Core module that have default settings. For example the `schema_format` defaults to Ruby. So if I call `configs_for` or any methods in the Core module it will reset the `schema_format` to `:ruby`. By moving it to it's own class we can keep the logic contained and avoid this unfortunate issue. The second change here does a double loop over the yaml files. Bear with me... Our tests dictate that we need to load an environment before our rake tasks because we could have something in an environment that the database.yml depends on. There are side-effects to this and I think there's a deeper bug that needs to be fixed but that's for another issue. The gist of the problem is when I was creating the dynamic rake tasks if the yaml that that rake task is calling evaluates code (like erb) that calls the environment configs the code will blow up because the environment is not loaded yet. To avoid this issue we added a new method that simply loads the yaml and does not evaluate the erb or anything in it. We then use that yaml to create the task name. Inside the task name we can then call `load_config` and load the real config to actually call the code internal to the task. I admit, this is gross, but refactoring can't all be pretty all the time and I'm working hard with `@tenderlove` to refactor much more of this code to get to a better place re connection management and rake tasks.
* Update schema/structure dump tasks for multi dbeileencodes2018-03-211-2/+16
| | | | | | | Adds the ability to dump the schema or structure files for mulitple databases. Loops through the configs for a given env and sets a filename based on the format, then establishes a connection for that config and dumps into the file.
* Add ability to create/drop/migrate all dbs for a given enveileencodes2018-03-211-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `each_current_configuration` is used by create, drop, and other methods to find the configs for a given environment and returning those to the method calling them. The change here allows for the database commands to operate on all the configs in the environment. Previously we couldn't slice the hashes and iterate over them becasue they could be two tier or could be three tier. By using the database config structs we don't need to care whether we're dealing with a three tier or two tier, we can just parse all the configs based on the environment. This makes it possible for us to run `bin/rails db:create` and it will create all the configs for the dev and test environment ust like it does for a two tier - it creates the db for dev and test. Now `db:create` will create `primary` for dev and test, and `animals` for dev and test if our database.yml looks like: ``` development: primary: etc animals: etc test: primary: etc animals: etc ``` This means that `bin/rails db:create`, `bin/rails db:drop`, and `bin/rails db:migrate` will operate on the dev and test env for both primary and animals ds.
* Don't expose `verbose?` helper methodRyuta Kamizono2018-03-021-6/+4
| | | | | | Follow up of b988ecb99ff6c8854e4b74ef8a7ade8d9ef5d954. This was added for internal usage, it doesn't need to be public.
* Revert "Merge pull request #32075 from eileencodes/delete-default-configuration"eileencodes2018-02-221-0/+4
| | | | | | | | | | This reverts commit 16f279ebd474626577ced858e3626ac4535a33df, reversing changes made to 6c6a30a7c357ce1eafa093d77d2b08684fe50887. The config can be named anything, not just default (although all generated apps will be named default). We can't just delete configs that don't have a database because that will break three-tier configs. Oh well.
* Delete default configurationeileencodes2018-02-211-4/+0
| | | | | | | Because of this default configuration we're constantly checking if the database exists when looping through configurations. This is unnecessary and we should just delete it before we need to loop through configurations.
* Don't output information on drop if not verboseeileencodes2018-02-051-1/+1
| | | | | Followup to b988ecb, when I cherry-picked from my parallel testing branch I didn't realize `drop` wasn't part of the commit.
* Add ability to turn off verbose for database taskseileencodes2018-02-051-3/+7
| | | | | | | | | | | | | | | You could use the `VERBOSE` env var to turn off output for migrations tasks but you couldn't use it for other tasks. This change moves the `verbose?` check to a method so we can also use it in create and drop respectively. tenderlove and I noticed this as part of the ongoing work in parallel testing. When the parallel tests boot the app needs to create new databases for each worker. The output from these is unnecessary but there was previously no way to turn it off. Now if `VERBOSE=false` is passes to `bin/rails db:create` the text "Created blah blah db" will no longer be output.
* Remove unused `migration_context` in `DatabaseTasks`Ryuta Kamizono2018-01-191-4/+0
| | | | This was added in #31727, but it is unused.
* Refactor migration to move migrations paths to connectioneileencodes2018-01-181-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rails has some support for multiple databases but it can be hard to handle migrations with those. The easiest way to implement multiple databases is to contain migrations into their own folder ("db/migrate" for the primary db and "db/seconddb_migrate" for the second db). Without this you would need to write code that allowed you to switch connections in migrations. I can tell you from experience that is not a fun way to implement multiple databases. This refactoring is a pre-requisite for implementing other features related to parallel testing and improved handling for multiple databases. The refactoring here moves the class methods from the `Migrator` class into it's own new class `MigrationContext`. The goal was to move the `migrations_paths` method off of the `Migrator` class and onto the connection. This allows users to do the following in their `database.yml`: ``` development: adapter: mysql2 username: root password: development_seconddb: adapter: mysql2 username: root password: migrations_paths: "db/second_db_migrate" ``` Migrations for the `seconddb` can now be store in the `db/second_db_migrate` directory. Migrations for the primary database are stored in `db/migrate`". The refactoring here drastically reduces the internal API for migrations since we don't need to pass `migrations_paths` around to every single method. Additionally this change does not require any Rails applications to make changes unless they want to use the new public API. All of the class methods from the `Migrator` class were `nodoc`'d except for the `migrations_paths` and `migrations_path` getter/setters respectively.
* Fix `bin/rails db:migrate` with specified `VERSION`bogdanvlviv2017-11-061-3/+12
| | | | | | Ensure that `bin/rails db:migrate` with specified `VERSION` reverts all migrations only if `VERSION` is `0`. Raise error if target migration doesn't exist.
* `ActiveRecord::Tasks::DatabaseTasks.load_schema` has always to establish ↵bogdanvlviv2017-10-151-3/+3
| | | | | | | | | | | | database connection When load schema from `structure.sql`, database connection isn't established. `ActiveRecord::Tasks::DatabaseTasks.load_schema` has to establish database connection since it executes ``` ActiveRecord::InternalMetadata.create_table ActiveRecord::InternalMetadata[:environment] = environment ```
* Fix `bin/rails db:setup` and `bin/rails db:test:prepare` create wrong ↵bogdanvlviv2017-10-151-7/+8
| | | | | | | | | | | | | | | | | | | | | | ar_internal_metadata's data for a test database. Before: ``` $ RAILS_ENV=test rails dbconsole > SELECT * FROM ar_internal_metadata; key|value|created_at|updated_at environment|development|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679 ``` After: ``` $ RAILS_ENV=test rails dbconsole > SELECT * FROM ar_internal_metadata; key|value|created_at|updated_at environment|test|2017-09-11 23:14:10.815679|2017-09-11 23:14:10.815679 ``` Fixes #26731.
* Avoid modifying frozen string in check_schema_fileEugene Kenny2017-07-231-1/+1
| | | | | | This was missed when the frozen string literal pragma was added to this file because the string is only modified when running in the context of a full Rails app, which wasn't covered by the test suite.
* Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|
* * Don't eagerly require Rails' minitest plugin.Kasper Timm Hansen2017-07-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | By making the Rails minitest behave like a standard minitest plugin we're much more likely to not break when people use other minitest plugins. Like minitest-focus and pride. To do this, we need to behave like minitest: require files up front and then perform the plugin behavior via the at_exit hook. This also saves us a fair bit of wrangling with test file loading. Finally, since the environment and warnings options have to be applied as early as possible, and since minitest loads plugins at_exit, they have to be moved to the test command. * Don't expect the root method. It's likely this worked because we eagerly loaded the Rails minitest plugin and that somehow defined a root method on `Rails`. * Assign a backtrace to failed exceptions. Otherwise Minitest pukes when attempting to filter the backtrace (which Rails' backtrace cleaner then removes). Means the exception message test has to be revised too. This is likely caused by the rails minitest plugin now being loaded for these tests and assigning a default backtrace cleaner.
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* Fix a RuboCop offences using `rubocop -a`Koichi ITO2017-05-241-3/+3
|
* Defer loading each DB Tasks class from AR DatabaseTasksAkira Matsuda2017-05-111-6/+6
| | | | | | Because we don't need to load tasks for DBs that we don't use for the current app. Also, these Tasks classes load AR::Base in their class level, and so immediately kick :active_record on_load hooks. This used to happen when we were loading tasks, not when we run a task.
* Refactor AR::Tasks::DatabaseTasks::migratebogdanvlviv2017-04-261-1/+1
| | | | | Set consistent type cast ENV["VERBOSE"]: ENV["VERBOSE"] is true if it not equal "false"
* Fixes #28359Philippe Guay2017-03-261-1/+3
| | | | | | | | | | | | | | | | Add stronger assertions to rake migration tasks to make sure the user is providing a numeric VERSION An empty string was getting converted to version = 0. This would in turn pass the presence check. Address linting warning Add test for rake task and refactor code to meet expectations In particular passing VERSION=0 should not raise an error. Addressed Comments for PR #28485. Trimmed empty lines + change of wording for error message Adjust test for change of wording in error message Change condition to follow rails idioms
* Reduce string objects by using \ instead of + or << for concatenating stringsAkira Matsuda2017-01-121-2/+2
| | | | (I personally prefer writing one string in one line no matter how long it is, though)
* Remove unneeded requires at active recordRafael Mendonça França2017-01-031-2/+0
|
* Dump schema cache for custom connectionKir Shatrov2017-01-011-0/+10
| | | | | | | | | Today `rake db:schema:cache:dump` only supports dumping cache for a single connection (`ActiveRecord::Base.connection`). This doesn't work for apps with multiple databases. This PR makes `DatabaseTasks` to provide an API for dumping schema cache for any connection.
* Remove deprecated #load_schema_forRafael Mendonça França2016-12-291-8/+0
|
* Make ActiveRecord structure load/dump configurableKir Shatrov2016-12-221-2/+12
| | | | | | | | Without this patch it's impossible to pass extra flags to mysqldump/pg_dump when running `rake db:structure:dump` or `load` The following config variables (`structure_load_flags` and `structure_dump_flags`) make it better configurable.
* Add more rubocop rules about whitespacesRafael Mendonça França2016-10-291-1/+1
|
* revises most Lint/EndAlignment offensesXavier Noria2016-08-071-3/+3
| | | | Some case expressions remain, need to think about those ones.
* normalizes indentation and whitespace across the projectXavier Noria2016-08-061-25/+25
|
* modernizes hash syntax in activerecordXavier Noria2016-08-061-1/+1
|
* applies new string literal convention in activerecord/libXavier Noria2016-08-061-19/+19
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* Add to_hash to specificationArthur Neves2016-05-251-1/+1
|
* Remove `name` from `establish_connection`Arthur Neves2016-05-241-1/+1
| | | | | Instead of passing a separete name variable, we can make the resolver merge a name on the config, and use that before creating the Specification.
* s/specification_name/connection_specification_nameArthur Neves2016-05-061-1/+1
|
* s/specification_id/specification_nameArthur Neves2016-05-051-1/+1
|
* Retrive the right pool for db tasksArthur Neves2016-05-051-2/+2
|