Commit Graph

239 Commits

Author SHA1 Message Date
eileencodes
10ca60a16b
Add option to disable schema dumb per-database
Dumping the schema is on by default for all databases in an application. To turn it off for a
specific database use the `schema_dump` option:

```yaml
  # config/database.yml

  production:
  schema_dump: false
```

Co-authored-by: Luis Vasconcellos <vasconcelloslf@gmail.com>
2021-07-19 07:58:49 -04:00
eileencodes
22cef24b6e
Fix migrations with the same timestamps in multiple databases
In #42604 we added functionality that would sort the migrations by
timestamp so that if there were 2 migrations in 2 databases that were
dependent on one another they would be run in timestamp order rather
than in cluster order.

While debugging another issue I realized that if the timestamps are the
same that only one of the migrations will get run. This fixes the issue
by collecting all the db configs for a version so that we get the entire
list.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2021-06-30 09:28:16 -04:00
eileencodes
45eb0f3bec
Fix migration ordering across databases
Previously if there were 2 migrations in one db and 1 migration in the
other db all the migrations for db one would run and then all migrations
for db two would run. If a migration in one database depended on a
migration in another database then it could fail. This is probably
pretty rare, however in a multi-db application that's moving tables from
one db to another, running them out of order could result in a migration
error.

In this this change we collect all the versions for each migration and
the corresponding db_config so we can run them in the order they are
created rather than per-db.

Closes #41664
Related #41538

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
Co-authored-by: Kiril Dokh <dsounded@gmail.com>
2021-06-25 11:54:00 -04:00
eileencodes
6ae78e964d
Fix test name
I wrote this test and apparently forgot to give it a decent name. Oops.
2021-06-25 10:05:38 -04:00
George Claghorn
00feff918e rails tmp:clear: clear tmp/storage 2021-05-28 22:34:49 -04:00
John Bampton
7260f79d7a chore: fix grammar and spelling in Markdown and Ruby files 2021-04-15 19:32:27 +10:00
John Bampton
13b1d9dc35 chore: fix grammar and spelling 2021-04-12 05:30:44 +10:00
Nick Borromeo
0f09dfca36
Guard against using VERSION with db:rollback (#41430)
* Guard against using VERSION with db:rollback

I recently ran a migration that I needed to rollback, and admittedly, I often forget the proper incantation for this 😅
so the first thing I tried was to run `bin/rake db:rollback VERSION=123454679`. I had hoped that this reverted my
migration back and at first glance I thought it worked. However on closer inspection I realized that it was a different
migration, which initially confused me.

So I looked over the docs and saw that I was using the rake task incorrectly, and promptly corrected my mistake.

Proposal

Looking at the how the `:down` task is defined we see

8dc7439058/activerecord/lib/active_record/railties/databases.rake (L206-L211)

This got me thinking that maybe it would be helpful to have the opposite of this guard defined in `rollback` so that if
`VERSION` is passed it will raise an exception instead of just negecting the extra argument. This could help the user
realize that something went wrong instead of just seeing output and assuming that the rollback happened.

Change

We now raise an execption if `VERSION` is passed when attempting to rollback a migration

* update test name and fix failing test

* remove byebug

[Nick Borromeo + Kate Travers + Rafael Mendonça França]
2021-02-15 19:30:05 -05:00
Rafael Mendonça França
1b455e2e9d
Rails 6.2 is now Rails 7.0
We have big plans for the next version of Rails and that
require big versions.
2021-02-04 16:47:16 +00:00
Rafael Mendonça França
936833fa3e
Make sure db:prepare works even the schema file doesn't exist
In this case it will try to run migrations again.
2020-12-29 21:58:21 +00:00
Yasuo Honda
3cafe4ad2f Revert "Avoid chdir error in Railties tests on Ruby master"
This reverts commit ae5ecfe26c8fdc194d5b3cd16fd13b64574bcfd3.
2020-12-26 15:01:24 +09:00
KapilSachdev
a908d06c85
feat(rubocop): Add Style/RedundantRegexpEscape
- This cop will help in removing unnecessary escaping inside Regexp literals.
2020-12-08 18:57:09 +00:00
Rafael Mendonça França
8992a7d0c2
Remove deprecated rake initializers tasks 2020-10-30 00:26:09 +00:00
Rafael Mendonça França
e152f83c64
Remove deprecated rake routes tasks 2020-10-30 00:26:08 +00:00
Rafael Mendonça França
01f0020a55
Remove deprecated rake dev:cache tasks 2020-10-30 00:26:08 +00:00
Rafael Mendonça França
227d04f46a
Remove depreated rake notes tasks 2020-10-30 00:26:04 +00:00
Eugene Kenny
ae5ecfe26c Avoid chdir error in Railties tests on Ruby master
5d7953f86b
https://buildkite.com/rails/rails/builds/71925#9839c015-e562-4145-932c-75b9c118bfca/1043-1055
2020-10-04 00:26:03 +01:00
eileencodes
ee9e308f68
Default db_config should be primary or first
The handling for single database applications has always set a schema.rb
or structure.sql files for loading the database schema. When we first
implemented multiple database support we intended to keep this for the
original, default database. Afterall Rails _has_ to connect to something
on boot. In development only one connection is connected on boot since
we don't eager load the app.

Originally we had thought that all applications should be required to
add a `primary` entry in the database configurations file. However,
this hasn't worked in practice and we have some code now that does not
assume there's a primary. The schema dumping/loading code however,
still assumed there was a "primary" in the configurations file.

We want the "default" database in any application to use the original
files even when converted to a multiple database application as this
reduces the need to make changes when implementing this functionality on
an existing application.

The changes here update Rails to ensure that we treat either "primary"
or the first database configuration for an environment as "default".
If there is a "primary" that will be used as the default configuration.
If there is no primary the configuration that is first for an
environment will be used as the default. For schema dump/load this means
that the default configuration (primary or first) will use `schema.rb`
as the filename and other configurations will use
`[CONFIGURATION_NAME]_schema.rb`.

This should also help us finish the pull request to infer migrations
paths since now we can say the first configuration is the default. This
is a natural assumption for application developers.

Followup to #39536
2020-09-03 15:55:46 -04:00
eileencodes
e4af759bf3
Use default argument in test
We should use a default argument so that when there is only one option
we can delete the arguments instead of updating all the callers.
2020-09-01 16:26:28 -04:00
fatkodima
5488686851 Combine and deprecate rails db:structure:{dump,load} tasks into rails db:schema:{dump,load} 2020-08-03 19:08:41 +03:00
André Luis Leal Cardoso Junior
a636aa940b Adds db:migrate:redo:NAME support for multidbs
On current master with multiple DBs configured, calling db:migrate:redo fails when trying to run db:rollback.

Before:

```
» bin/rails db:migrate:redo
rake aborted!
You're using a multiple database application. To use `db:rollback` you must run the namespaced task with a VERSION. Available tasks are db:rollback:primary and db:rollback:secondary.
Tasks: TOP => db:rollback
(See full trace by running task with --trace)
```

After:

```
» bin/rails db:migrate:redo
rake aborted!
You're using a multiple database application. To use `db:migrate:redo` you must run the namespaced task with a VERSION. Available tasks are db:migrate:redo:primary and db:migrate:redo:secondary.
Tasks: TOP => db:migrate:redo
(See full trace by running task with --trace)
```

Running the namespaced version:

```
» bin/rails db:migrate:redo:secondary
== 20200728162820 CreateAnimals: reverting ====================================
-- drop_table(:animals)
   -> 0.0025s
== 20200728162820 CreateAnimals: reverted (0.0047s) ===========================

== 20200728162820 CreateAnimals: migrating ====================================
-- create_table(:animals)
   -> 0.0028s
== 20200728162820 CreateAnimals: migrated (0.0029s) ===========================
```
2020-07-30 22:15:22 -03:00
eileencodes
e7b1e118b9
Fix schema cache load and corresponding test
This test was incorrect. `primary` was winning for the schema cache load
but when you boot an application it's actually the first configuration
that wins (in a multi db app).

The test didn't catch this because I forgot to add a migrations_paths to
the configuration.

We updated the schema cache loader railtie as well because any
application that didn't have a `primary` config would not be able to use
the schema cache. Originally we thought we'd enforce a `primary`
configuration but no longer feel that's correct. It's simpler to say
that the first wins in a 3-tier rather than implementing a solution to
require `primary` and / or allow aliases.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
Co-authored-by: John Hawthorn <john@hawthorn.email>
2020-06-04 15:12:12 -04:00
George Claghorn
e4b6c719cd Update Railties tests for 7e52d0a 2020-05-21 13:00:56 -04:00
Jonathan Fleckenstein
dfb5a82b25
Active Storage: allow serving files by proxying 2020-05-11 16:21:58 -04:00
Bill Cromie
fce29be335 Add a route to handle Mandrill's webhook URL check
Mandrill's Inbound API checks to see if a URL exists before it creates
the webhook. It sends a HEAD request, to which we now return a 200 OK
response to indicate that the route exists.

Now we can generate inbound API calls with ease on Mandrill, without
having to shuffle around tokens in production.

Fixes #37609.
2020-04-07 13:22:36 +01:00
David Heinemeier Hansson
d56d2e7406
Add a way to deliver inbound emails by source (#38849)
* Add a way to deliver inbound emails by source

Great for testing when you get an eml file and can just paste it in.

* Test updates

* Fix tests

* Fix spacing
2020-03-31 16:46:13 -07:00
David Heinemeier Hansson
3e0cdbeaf4
require, require_relative, load by double quotes (#38841)
* require, require_relative, load by double quotes

We're getting rid of all single quote usage, unless it serves a specific purpose, as per the general style guide.
2020-03-29 16:30:52 -07:00
eileencodes
e33075a0ef
Handle db:rollback and db:rollback:[NAME] for multi-db apps
With a multiple database application `db:rollback` becomes problematic.
We can't rollback just the primary, that doesn't match the behavior in
the other tasks. We can't rollback a migration for every database, that
is unexpected.

To solve this I handled `db:rollback` the same way I handled `:up` and
`:down`. If `db:rollback` is called for a multi-db application then it
will raise an error recommending you use `db:rollback:[NAME]` instead.
Calling `db:rollback:primary` or `db:rollback:animals` will rollback
the migration for the number of steps specified.

Closes: #38513
Follow-up to: #34078
2020-03-19 16:50:46 -04:00
eileencodes
67b102a57f
Add erb tests for multi-db
If I had had these tests previously I would have not created PR #38658
and then promptly realize I needed to revert it.

We need to load and parse the configurations twice. Once before the
environment is loaded to create the named tasks and once after the
environment is loaded to have the real configurations. The configs
loaded before the env have the ERB stripped out and aren't valid
configs.
2020-03-06 11:23:43 -05:00
eileencodes
2dcf07a53a
Fix test name
Wow this is embarrassing. I literally named this FIXME so I'd remember
to give it some name that made sense and then I totally did not.
2020-03-06 10:01:14 -05:00
Kyle Thompson
4b81e367ef
Dump the schema or structure of a database when calling db:migrate:name 2020-02-27 13:40:00 -05:00
Kyle Thompson
0366cbd742
Reset the ActiveRecord::Base connection after rails db:migrate:name 2020-02-27 13:10:54 -05:00
eileencodes
79ce7d9af6
Deprecate spec_name and use name for configurations
I have so. many. regrets. about using `spec_name` for database
configurations and now I'm finally putting this mistake to an end.

Back when I started multi-db work I assumed that eventually
`connection_specification_name` (sometimes called `spec_name`) and
`spec_name` for configurations would one day be the same thing. After
2 years I no longer believe they will ever be the same thing.

This PR deprecates `spec_name` on database configurations in favor of
`name`. It's the same behavior, just a better name, or at least a
less confusing name.

`connection_specification_name` refers to the parent class name (ie
ActiveRecord::Base, AnimalsBase, etc) that holds the connection for it's
models. In some places like ConnectionHandler it shortens this to
`spec_name`, hence the major confusion.

Recently I've been working with some new folks on database stuff and
connection management and realize how confusing it was to explain that
`db_config.spec_name` was not `spec_name` and
`connection_specification_name`. Worse than that one is a symbole while
the other is a class name. This was made even more complicated by the
fact that `ActiveRecord::Base` used `primary` as the
`connection_specification_name` until #38190.

After spending 2 years with connection management I don't believe that
we can ever use the symbols from the database configs as a way to
connect the database without the class name being _somewhere_ because
a db_config does not know who it's owner class is until it's been
connected and a model has no idea what db_config belongs to it until
it's connected. The model is the only way to tie a primary/writer config
to a replica/reader config. This could change in the future but I don't
see value in adding a class name to the db_configs before connection or
telling a model what config belongs to it before connection. That would
probably break a lot of application assumptions. If we do ever end up in
that world, we can use name, because tbh `spec_name` and
`connection_specification_name` were always confusing to me.
2020-02-24 13:27:07 -05:00
Kyle Thompson
e8c61b6bfd
Adds additional database-specific rake tasks for multi-database users 2020-02-24 12:05:44 -05:00
eileencodes
c1a215a06b
Add schema cache tests
The schema cache tests test the following scenarios:

1) The default case works (single db, primary spec name (dev is default
to primary in 2-tier config), standard default schema cache filename)
2) Primary always wins over other entries
3) A custom schema cache filename works when set in the configuration
4) A custom schema cache filename works when set in the ENV

Cases that don't work:

1) A non-primary database entry picks up a namespaced schema cache file

This can't work currently because there's no way of knowing which cache
we actually want. In this railtie we can only load ActiveRecord::Base's
schema cache. If we grab the first config we risk loading a cache for
another connection because order is not guaranteed.

2) Multi-db schema caches

The reasons are similar to above. In addition we can't loop through the
configs, establish a connection, and load the cache because we don't
know what parent class to establish a connection to. In that case AR
Base will always get the cache and it would cause the last one to win
and therefore be loaded on the wrong connection.

The real fix for these issues is to get rid of the railtie entirely, but
for now we needed to set this back to what the behavior was before
recent changes but with the ability to pass a custom key.

Co-authored-by: Katrina Owen <kytrinyx@github.com>
2020-02-13 09:06:18 -05:00
eileencodes
2a53fe638d
Deprecate and replace #default_hash and #[]
Database configurations are now objects almost everywhere, so we don't
need to fake access to a hash with `#default_hash` or it's alias `#[]`.
Applications should `configs_for` and pass `env_name` and `spec_name` to
get the database config object. If you're looking for the default for
the test environment you can pass `configs_for(env_name: "test", spec_name:
"primary")`. Change test to developement to get the dev config, etc.

`#default_hash` and `#[]` will be removed in 6.2.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-01-17 16:08:12 -05:00
Haroon Ahmed
db1ae8cbb4 remove reference to global rails command and replace with bin/rails 2019-12-27 19:32:37 +00:00
Ryuta Kamizono
5324f2cb09 Revert "Merge pull request #37215 from utilum/avoid_test_flunking_on_warning"
This reverts commit ed78e96408f3f83e779a71c65b86aeb1cfc5616e, reversing
changes made to eca6c273fe2729b9634907562c2717cf86443b6b.
2019-12-25 17:13:09 +09:00
Brian Buchalter
53e9438ef2 Ignore test env in DatabaseTasks when DATABASE_URL is present
Fixes https://github.com/rails/rails/issues/28827.

The steps to reproduce are as follows:

git clone git@github.com:bbuchalter/rails-issue-28827.git
cd rails-issue-28827
bundle install
bin/rails db:create

Observe that we create two databases when invoking db:create: development and test. Now observe what happens when we invoke our drop command while using DATABASE_URL.

DATABASE_URL=sqlite3://$(pwd)/db/database_url.sqlite3 bin/rails db:create

As expected, the development environment now uses the DATABASE_URL. What is unexpected is that the test environment does not.

It's unclear what the expected behavior should be in this case, but the cause of it is this: 9f2c74eda0/activerecord/lib/active_record/tasks/database_tasks.rb (L494)

Because of each_local_configuration, there seems to be no way invoke these database rake on only the development environment to ensure DATABASE_URL is respected.

The smallest scope of change I can think to make would be to conditionalize this behavior so it does not get applied when DATABASE_URL is present.
2019-12-20 14:22:31 -08:00
eileencodes
3dffacd16e Fix remaining connection_config calls
We missed these in rails/rails#38005 because deprecation warnings are
silently swallowed by these tests.

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2019-12-18 09:12:27 -05:00
Peter Zhu
fbb83d78c3 Use DiskController for both public and private files 2019-12-06 16:02:16 -05:00
Ryuta Kamizono
d558febe32 Auto-correct rubocop offences 2019-11-24 09:54:47 +09:00
eileencodes
042b6fec87 Appease rubocop
Rubocop wants double quoted strings, not single. I missed this when I
merged #37601
2019-11-01 15:43:43 -04:00
Edouard CHIN
c9e44d1a06 Reestablish connection to previous database after migrating:
- The migrate task iterates and establish a connection over each db
  resulting in the last one to be used by subsequent rake tasks.
  We should reestablish a connection to the connection that was
  established before the migrate tasks was run
- Fix #37578
2019-10-30 19:31:22 +01:00
Peter Zhu
feab7031b5 Permanent URLs for public storage blobs
Services can be configured in `config/storage.yml` with a new key
`public: true | false` to indicate whether a service holds public
blobs or private blobs. Public services will always return a
permanent URL.

Deprecates `Blob#service_url` in favor of `Blob#url`.
2019-10-11 15:14:43 -04:00
utilum
e0b8c918a0 Avoid flunking tests on warning in output 2019-09-28 12:52:31 +02:00
Jean Boussier
48c716bbfa Instantiate ConnectionPool with a DatabaseConfig rather than a ConnectionSpecification 2019-09-24 15:12:22 +02:00
John Crepezzi
b8b2d40659 Make all reads on configuration_hash use methods
Convert all uses of `db_config.configuration_hash[*]` to use methods
defined on an implementation of `DatabaseConfigurations::DatabaseConfig`.

Since we want to get away from accessing properties directly on the
underlying configuration hash, we'll move here to accessing those values
via the implementations on `DatabaseConfig` (or more specifically,
`HashConfig`).

There are still codepaths that are passing around `configuration_hash`,
and follow-on PRs will address those with the goal of using
configuration objects everywhere up until the point we pass a resolved
hash over to the underlying client.

Co-authored-by: eileencodes <eileencodes@gmail.com>
2019-09-23 16:46:05 -04:00
eileencodes
b8fc0150d6 Reduce surface area of ConnectionSpecification
Eventually we'd like to get rid of this class altogether but for now
this PR reduces the surface area by removing methods from the class and
moving classes out into their own files.

* `adapter_method` was moved into database configurations
* `initialize_dup` was removed because it was only used in tests
* Resolver is now it's own class under connection adapters
* ConnectionUrlResolver, only used by the configurations, is in a class
under DatabaseConfigurations

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2019-09-13 22:05:02 -04:00
eileencodes
ce9b197cc9 Use symbols everywhere for database configurations
Previously in some places we used symbol keys, and in some places we used
string keys. That made it pretty confusing to figure out in a particular
place what type of configuration object you were working with.

Now internally, all configuration hashes are keyed by symbols and
converted to such on the way in.

A few exceptions:

- `DatabaseConfigurations#to_h` still returns strings for backward compatibility
- Same for `legacy_hash`
- `default_hash` previously could return strings, but the associated
  comment mentions it returns symbol-key `Hash` and now it always does

Because this is a change in behavior, a few method renames have happened:

- `DatabaseConfig#config` is now `DatabaseConfig#configuration_hash` and returns a symbol-key `Hash`
- `ConnectionSpecification#config` is now `ConnectionSpecification#underlying_configuration_hash` and returns the `Hash` of the underlying `DatabaseConfig`
- `DatabaseConfig#config` was added back, returns `String`-keys for backward compatibility, and is deprecated in favor of the new `configuration_hash`

Co-authored-by: eileencodes <eileencodes@gmail.com>
2019-09-13 08:53:22 -04:00