activerecord 6.0.0.rc1 → 6.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +11 -2
- data/lib/active_record/associations/preloader/association.rb +3 -1
- data/lib/active_record/attribute_methods.rb +0 -51
- data/lib/active_record/attribute_methods/dirty.rb +6 -1
- data/lib/active_record/autosave_association.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +93 -11
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -4
- data/lib/active_record/connection_adapters/abstract_adapter.rb +40 -20
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +10 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +8 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -2
- data/lib/active_record/connection_handling.rb +6 -2
- data/lib/active_record/database_configurations.rb +6 -6
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +2 -2
- data/lib/active_record/migration.rb +26 -23
- data/lib/active_record/railtie.rb +0 -1
- data/lib/active_record/railties/databases.rake +57 -23
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/relation/finder_methods.rb +4 -2
- data/lib/active_record/relation/merger.rb +6 -2
- data/lib/active_record/relation/query_methods.rb +32 -32
- data/lib/active_record/sanitization.rb +30 -2
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/table_metadata.rb +6 -10
- data/lib/active_record/tasks/database_tasks.rb +41 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -1
- data/lib/active_record/timestamp.rb +26 -16
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -10
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/arel/visitors/depth_first.rb +1 -1
- data/lib/arel/visitors/to_sql.rb +23 -26
- data/lib/arel/visitors/visitor.rb +9 -5
- metadata +8 -8
@@ -46,7 +46,7 @@ module ActiveRecord
|
|
46
46
|
conn = PG.connect(conn_params)
|
47
47
|
ConnectionAdapters::PostgreSQLAdapter.new(conn, logger, conn_params, config)
|
48
48
|
rescue ::PG::Error => error
|
49
|
-
if error.message.include?(
|
49
|
+
if error.message.include?(conn_params[:dbname])
|
50
50
|
raise ActiveRecord::NoDatabaseError
|
51
51
|
else
|
52
52
|
raise
|
@@ -259,6 +259,12 @@ module ActiveRecord
|
|
259
259
|
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
|
260
260
|
end
|
261
261
|
|
262
|
+
def self.database_exists?(config)
|
263
|
+
!!ActiveRecord::Base.postgresql_connection(config)
|
264
|
+
rescue ActiveRecord::NoDatabaseError
|
265
|
+
false
|
266
|
+
end
|
267
|
+
|
262
268
|
# Is this connection alive and ready for queries?
|
263
269
|
def active?
|
264
270
|
@lock.synchronize do
|
@@ -302,6 +308,7 @@ module ActiveRecord
|
|
302
308
|
end
|
303
309
|
|
304
310
|
def discard! # :nodoc:
|
311
|
+
super
|
305
312
|
@connection.socket_io.reopen(IO::NULL) rescue nil
|
306
313
|
@connection = nil
|
307
314
|
end
|
@@ -13,11 +13,11 @@ module ActiveRecord
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def quote_table_name(name)
|
16
|
-
|
16
|
+
self.class.quoted_table_names[name] ||= super.gsub(".", "\".\"").freeze
|
17
17
|
end
|
18
18
|
|
19
19
|
def quote_column_name(name)
|
20
|
-
|
20
|
+
self.class.quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}")
|
21
21
|
end
|
22
22
|
|
23
23
|
def quoted_time(value)
|
@@ -45,6 +45,42 @@ module ActiveRecord
|
|
45
45
|
0
|
46
46
|
end
|
47
47
|
|
48
|
+
def column_name_matcher
|
49
|
+
COLUMN_NAME
|
50
|
+
end
|
51
|
+
|
52
|
+
def column_name_with_order_matcher
|
53
|
+
COLUMN_NAME_WITH_ORDER
|
54
|
+
end
|
55
|
+
|
56
|
+
COLUMN_NAME = /
|
57
|
+
\A
|
58
|
+
(
|
59
|
+
(?:
|
60
|
+
# "table_name"."column_name" | function(one or no argument)
|
61
|
+
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
|
62
|
+
)
|
63
|
+
(?:\s+AS\s+(?:\w+|"\w+"))?
|
64
|
+
)
|
65
|
+
(?:\s*,\s*\g<1>)*
|
66
|
+
\z
|
67
|
+
/ix
|
68
|
+
|
69
|
+
COLUMN_NAME_WITH_ORDER = /
|
70
|
+
\A
|
71
|
+
(
|
72
|
+
(?:
|
73
|
+
# "table_name"."column_name" | function(one or no argument)
|
74
|
+
((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")) | \w+\((?:|\g<2>)\)
|
75
|
+
)
|
76
|
+
(?:\s+ASC|\s+DESC)?
|
77
|
+
)
|
78
|
+
(?:\s*,\s*\g<1>)*
|
79
|
+
\z
|
80
|
+
/ix
|
81
|
+
|
82
|
+
private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
|
83
|
+
|
48
84
|
private
|
49
85
|
|
50
86
|
def _type_cast(value)
|
@@ -98,6 +98,16 @@ module ActiveRecord
|
|
98
98
|
configure_connection
|
99
99
|
end
|
100
100
|
|
101
|
+
def self.database_exists?(config)
|
102
|
+
config = config.symbolize_keys
|
103
|
+
if config[:database] == ":memory:"
|
104
|
+
return true
|
105
|
+
else
|
106
|
+
database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
|
107
|
+
File.exist?(database_file)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
101
111
|
def supports_ddl_transactions?
|
102
112
|
true
|
103
113
|
end
|
@@ -485,9 +495,9 @@ module ActiveRecord
|
|
485
495
|
result = exec_query(sql, "SCHEMA").first
|
486
496
|
|
487
497
|
if result
|
488
|
-
# Splitting with left parentheses and
|
498
|
+
# Splitting with left parentheses and discarding the first part will return all
|
489
499
|
# columns separated with comma(,).
|
490
|
-
columns_string = result["sql"].split("(").last
|
500
|
+
columns_string = result["sql"].split("(", 2).last
|
491
501
|
|
492
502
|
columns_string.split(",").each do |column_string|
|
493
503
|
# This regex will match the column name and collation type and will save
|
@@ -173,7 +173,7 @@ module ActiveRecord
|
|
173
173
|
raise "Anonymous class is not allowed." unless name
|
174
174
|
|
175
175
|
config_or_env ||= DEFAULT_ENV.call.to_sym
|
176
|
-
pool_name =
|
176
|
+
pool_name = primary_class? ? "primary" : name
|
177
177
|
self.connection_specification_name = pool_name
|
178
178
|
|
179
179
|
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
|
@@ -204,11 +204,15 @@ module ActiveRecord
|
|
204
204
|
# Return the specification name from the current class or its parent.
|
205
205
|
def connection_specification_name
|
206
206
|
if !defined?(@connection_specification_name) || @connection_specification_name.nil?
|
207
|
-
return
|
207
|
+
return primary_class? ? "primary" : superclass.connection_specification_name
|
208
208
|
end
|
209
209
|
@connection_specification_name
|
210
210
|
end
|
211
211
|
|
212
|
+
def primary_class? # :nodoc:
|
213
|
+
self == Base || defined?(ApplicationRecord) && self == ApplicationRecord
|
214
|
+
end
|
215
|
+
|
212
216
|
# Returns the configuration of the associated connection as a hash:
|
213
217
|
#
|
214
218
|
# ActiveRecord::Base.connection_config
|
@@ -141,7 +141,7 @@ module ActiveRecord
|
|
141
141
|
config_without_url.delete "url"
|
142
142
|
|
143
143
|
ActiveRecord::DatabaseConfigurations::UrlConfig.new(env_name, spec_name, url, config_without_url)
|
144
|
-
elsif config["database"] ||
|
144
|
+
elsif config["database"] || config["adapter"] || ENV["DATABASE_URL"]
|
145
145
|
ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, spec_name, config)
|
146
146
|
else
|
147
147
|
config.each_pair.map do |sub_spec_name, sub_config|
|
@@ -153,11 +153,11 @@ module ActiveRecord
|
|
153
153
|
def build_url_config(url, configs)
|
154
154
|
env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s
|
155
155
|
|
156
|
-
if
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
156
|
+
if configs.find(&:for_current_env?)
|
157
|
+
configs.map do |config|
|
158
|
+
if config.url_config?
|
159
|
+
config
|
160
|
+
else
|
161
161
|
ActiveRecord::DatabaseConfigurations::UrlConfig.new(config.env_name, config.spec_name, url, config.config)
|
162
162
|
end
|
163
163
|
end
|
@@ -35,10 +35,10 @@ module ActiveRecord
|
|
35
35
|
# config.active_record.database_resolver = MyResolver
|
36
36
|
# config.active_record.database_resolver_context = MyResolver::MySession
|
37
37
|
class DatabaseSelector
|
38
|
-
def initialize(app, resolver_klass =
|
38
|
+
def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
|
39
39
|
@app = app
|
40
|
-
@resolver_klass = resolver_klass
|
41
|
-
@context_klass = context_klass
|
40
|
+
@resolver_klass = resolver_klass || Resolver
|
41
|
+
@context_klass = context_klass || Resolver::Session
|
42
42
|
@options = options
|
43
43
|
end
|
44
44
|
|
@@ -46,8 +46,8 @@ module ActiveRecord
|
|
46
46
|
private
|
47
47
|
|
48
48
|
def read_from_primary(&blk)
|
49
|
-
ActiveRecord::Base.
|
50
|
-
ActiveRecord::Base.
|
49
|
+
ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
|
50
|
+
ActiveRecord::Base.connection_handler.while_preventing_writes do
|
51
51
|
instrumenter.instrument("database_selector.active_record.read_from_primary") do
|
52
52
|
yield
|
53
53
|
end
|
@@ -494,9 +494,9 @@ module ActiveRecord
|
|
494
494
|
# This migration will create the horses table for you on the way up, and
|
495
495
|
# automatically figure out how to drop the table on the way down.
|
496
496
|
#
|
497
|
-
# Some commands
|
498
|
-
#
|
499
|
-
#
|
497
|
+
# Some commands cannot be reversed. If you care to define how to move up
|
498
|
+
# and down in these cases, you should define the +up+ and +down+ methods
|
499
|
+
# as before.
|
500
500
|
#
|
501
501
|
# If a command cannot be reversed, an
|
502
502
|
# <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
|
@@ -885,13 +885,14 @@ module ActiveRecord
|
|
885
885
|
|
886
886
|
def copy(destination, sources, options = {})
|
887
887
|
copied = []
|
888
|
+
schema_migration = options[:schema_migration] || ActiveRecord::SchemaMigration
|
888
889
|
|
889
890
|
FileUtils.mkdir_p(destination) unless File.exist?(destination)
|
890
891
|
|
891
|
-
destination_migrations = ActiveRecord::MigrationContext.new(destination).migrations
|
892
|
+
destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration).migrations
|
892
893
|
last = destination_migrations.last
|
893
894
|
sources.each do |scope, path|
|
894
|
-
source_migrations = ActiveRecord::MigrationContext.new(path).migrations
|
895
|
+
source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration).migrations
|
895
896
|
|
896
897
|
source_migrations.each do |migration|
|
897
898
|
source = File.binread(migration.filename)
|
@@ -1014,10 +1015,11 @@ module ActiveRecord
|
|
1014
1015
|
end
|
1015
1016
|
|
1016
1017
|
class MigrationContext #:nodoc:
|
1017
|
-
attr_reader :migrations_paths
|
1018
|
+
attr_reader :migrations_paths, :schema_migration
|
1018
1019
|
|
1019
|
-
def initialize(migrations_paths)
|
1020
|
+
def initialize(migrations_paths, schema_migration)
|
1020
1021
|
@migrations_paths = migrations_paths
|
1022
|
+
@schema_migration = schema_migration
|
1021
1023
|
end
|
1022
1024
|
|
1023
1025
|
def migrate(target_version = nil, &block)
|
@@ -1048,7 +1050,7 @@ module ActiveRecord
|
|
1048
1050
|
migrations
|
1049
1051
|
end
|
1050
1052
|
|
1051
|
-
Migrator.new(:up, selected_migrations, target_version).migrate
|
1053
|
+
Migrator.new(:up, selected_migrations, schema_migration, target_version).migrate
|
1052
1054
|
end
|
1053
1055
|
|
1054
1056
|
def down(target_version = nil)
|
@@ -1058,20 +1060,20 @@ module ActiveRecord
|
|
1058
1060
|
migrations
|
1059
1061
|
end
|
1060
1062
|
|
1061
|
-
Migrator.new(:down, selected_migrations, target_version).migrate
|
1063
|
+
Migrator.new(:down, selected_migrations, schema_migration, target_version).migrate
|
1062
1064
|
end
|
1063
1065
|
|
1064
1066
|
def run(direction, target_version)
|
1065
|
-
Migrator.new(direction, migrations, target_version).run
|
1067
|
+
Migrator.new(direction, migrations, schema_migration, target_version).run
|
1066
1068
|
end
|
1067
1069
|
|
1068
1070
|
def open
|
1069
|
-
Migrator.new(:up, migrations,
|
1071
|
+
Migrator.new(:up, migrations, schema_migration)
|
1070
1072
|
end
|
1071
1073
|
|
1072
1074
|
def get_all_versions
|
1073
|
-
if
|
1074
|
-
|
1075
|
+
if schema_migration.table_exists?
|
1076
|
+
schema_migration.all_versions.map(&:to_i)
|
1075
1077
|
else
|
1076
1078
|
[]
|
1077
1079
|
end
|
@@ -1108,12 +1110,12 @@ module ActiveRecord
|
|
1108
1110
|
end
|
1109
1111
|
|
1110
1112
|
def migrations_status
|
1111
|
-
db_list =
|
1113
|
+
db_list = schema_migration.normalized_versions
|
1112
1114
|
|
1113
1115
|
file_list = migration_files.map do |file|
|
1114
1116
|
version, name, scope = parse_migration_filename(file)
|
1115
1117
|
raise IllegalMigrationNameError.new(file) unless version
|
1116
|
-
version =
|
1118
|
+
version = schema_migration.normalize_migration_number(version)
|
1117
1119
|
status = db_list.delete(version) ? "up" : "down"
|
1118
1120
|
[status, version, (name + scope).humanize]
|
1119
1121
|
end.compact
|
@@ -1153,7 +1155,7 @@ module ActiveRecord
|
|
1153
1155
|
end
|
1154
1156
|
|
1155
1157
|
def move(direction, steps)
|
1156
|
-
migrator = Migrator.new(direction, migrations)
|
1158
|
+
migrator = Migrator.new(direction, migrations, schema_migration)
|
1157
1159
|
|
1158
1160
|
if current_version != 0 && !migrator.current_migration
|
1159
1161
|
raise UnknownMigrationVersionError.new(current_version)
|
@@ -1172,27 +1174,28 @@ module ActiveRecord
|
|
1172
1174
|
end
|
1173
1175
|
end
|
1174
1176
|
|
1175
|
-
class Migrator
|
1177
|
+
class Migrator # :nodoc:
|
1176
1178
|
class << self
|
1177
1179
|
attr_accessor :migrations_paths
|
1178
1180
|
|
1179
1181
|
# For cases where a table doesn't exist like loading from schema cache
|
1180
1182
|
def current_version
|
1181
|
-
MigrationContext.new(migrations_paths).current_version
|
1183
|
+
MigrationContext.new(migrations_paths, SchemaMigration).current_version
|
1182
1184
|
end
|
1183
1185
|
end
|
1184
1186
|
|
1185
1187
|
self.migrations_paths = ["db/migrate"]
|
1186
1188
|
|
1187
|
-
def initialize(direction, migrations, target_version = nil)
|
1189
|
+
def initialize(direction, migrations, schema_migration, target_version = nil)
|
1188
1190
|
@direction = direction
|
1189
1191
|
@target_version = target_version
|
1190
1192
|
@migrated_versions = nil
|
1191
1193
|
@migrations = migrations
|
1194
|
+
@schema_migration = schema_migration
|
1192
1195
|
|
1193
1196
|
validate(@migrations)
|
1194
1197
|
|
1195
|
-
|
1198
|
+
@schema_migration.create_table
|
1196
1199
|
ActiveRecord::InternalMetadata.create_table
|
1197
1200
|
end
|
1198
1201
|
|
@@ -1246,7 +1249,7 @@ module ActiveRecord
|
|
1246
1249
|
end
|
1247
1250
|
|
1248
1251
|
def load_migrated
|
1249
|
-
@migrated_versions = Set.new(
|
1252
|
+
@migrated_versions = Set.new(@schema_migration.all_versions.map(&:to_i))
|
1250
1253
|
end
|
1251
1254
|
|
1252
1255
|
private
|
@@ -1330,10 +1333,10 @@ module ActiveRecord
|
|
1330
1333
|
def record_version_state_after_migrating(version)
|
1331
1334
|
if down?
|
1332
1335
|
migrated.delete(version)
|
1333
|
-
|
1336
|
+
@schema_migration.delete_by(version: version.to_s)
|
1334
1337
|
else
|
1335
1338
|
migrated << version
|
1336
|
-
|
1339
|
+
@schema_migration.create!(version: version.to_s)
|
1337
1340
|
end
|
1338
1341
|
end
|
1339
1342
|
|
@@ -134,7 +134,6 @@ end_error
|
|
134
134
|
|
135
135
|
cache = YAML.load(File.read(filename))
|
136
136
|
if cache.version == current_version
|
137
|
-
connection.schema_cache = cache
|
138
137
|
connection_pool.schema_cache = cache.dup
|
139
138
|
else
|
140
139
|
warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "active_record"
|
4
4
|
|
5
|
+
databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
|
6
|
+
|
5
7
|
db_namespace = namespace :db do
|
6
8
|
desc "Set the environment value for the database"
|
7
9
|
task "environment:set" => :load_config do
|
@@ -23,7 +25,7 @@ db_namespace = namespace :db do
|
|
23
25
|
ActiveRecord::Tasks::DatabaseTasks.create_all
|
24
26
|
end
|
25
27
|
|
26
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
28
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
27
29
|
desc "Create #{spec_name} database for current environment"
|
28
30
|
task spec_name => :load_config do
|
29
31
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -42,7 +44,7 @@ db_namespace = namespace :db do
|
|
42
44
|
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
43
45
|
end
|
44
46
|
|
45
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
47
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
46
48
|
desc "Drop #{spec_name} database for current environment"
|
47
49
|
task spec_name => [:load_config, :check_protected_environments] do
|
48
50
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -101,7 +103,7 @@ db_namespace = namespace :db do
|
|
101
103
|
end
|
102
104
|
|
103
105
|
namespace :migrate do
|
104
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
106
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
105
107
|
desc "Migrate #{spec_name} database for current environment"
|
106
108
|
task spec_name => :load_config do
|
107
109
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -142,7 +144,7 @@ db_namespace = namespace :db do
|
|
142
144
|
end
|
143
145
|
|
144
146
|
namespace :up do
|
145
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
147
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
146
148
|
task spec_name => :load_config do
|
147
149
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
148
150
|
|
@@ -176,7 +178,7 @@ db_namespace = namespace :db do
|
|
176
178
|
end
|
177
179
|
|
178
180
|
namespace :down do
|
179
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
181
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
180
182
|
task spec_name => :load_config do
|
181
183
|
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
182
184
|
|
@@ -203,7 +205,7 @@ db_namespace = namespace :db do
|
|
203
205
|
end
|
204
206
|
|
205
207
|
namespace :status do
|
206
|
-
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
208
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
207
209
|
desc "Display status of migrations for #{spec_name} database"
|
208
210
|
task spec_name => :load_config do
|
209
211
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
@@ -250,7 +252,11 @@ db_namespace = namespace :db do
|
|
250
252
|
|
251
253
|
# desc "Raises an error if there are pending migrations"
|
252
254
|
task abort_if_pending_migrations: :load_config do
|
253
|
-
pending_migrations = ActiveRecord::Base.
|
255
|
+
pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
|
256
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
257
|
+
|
258
|
+
ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
259
|
+
end
|
254
260
|
|
255
261
|
if pending_migrations.any?
|
256
262
|
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
@@ -261,17 +267,56 @@ db_namespace = namespace :db do
|
|
261
267
|
end
|
262
268
|
end
|
263
269
|
|
270
|
+
namespace :abort_if_pending_migrations do
|
271
|
+
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
|
272
|
+
# desc "Raises an error if there are pending migrations for #{spec_name} database"
|
273
|
+
task spec_name => :load_config do
|
274
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
275
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
276
|
+
|
277
|
+
pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
|
278
|
+
|
279
|
+
if pending_migrations.any?
|
280
|
+
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
281
|
+
pending_migrations.each do |pending_migration|
|
282
|
+
puts " %4d %s" % [pending_migration.version, pending_migration.name]
|
283
|
+
end
|
284
|
+
abort %{Run `rails db:migrate:#{spec_name}` to update your database then try again.}
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
264
290
|
desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
|
265
291
|
task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
|
266
292
|
|
267
293
|
desc "Runs setup if database does not exist, or runs migrations if it does"
|
268
294
|
task prepare: :load_config do
|
295
|
+
seed = false
|
296
|
+
|
269
297
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
270
298
|
ActiveRecord::Base.establish_connection(db_config.config)
|
271
|
-
|
299
|
+
|
300
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
301
|
+
|
302
|
+
# Skipped when no database
|
303
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, ActiveRecord::Base.schema_format, db_config.spec_name)
|
304
|
+
|
272
305
|
rescue ActiveRecord::NoDatabaseError
|
273
|
-
|
306
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, db_config.spec_name)
|
307
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(
|
308
|
+
db_config.config,
|
309
|
+
ActiveRecord::Base.schema_format,
|
310
|
+
nil,
|
311
|
+
db_config.env_name,
|
312
|
+
db_config.spec_name
|
313
|
+
)
|
314
|
+
|
315
|
+
seed = true
|
274
316
|
end
|
317
|
+
|
318
|
+
ActiveRecord::Base.establish_connection
|
319
|
+
ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
|
275
320
|
end
|
276
321
|
|
277
322
|
desc "Loads the seed data from db/seeds.rb"
|
@@ -336,13 +381,9 @@ db_namespace = namespace :db do
|
|
336
381
|
namespace :schema do
|
337
382
|
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
|
338
383
|
task dump: :load_config do
|
339
|
-
require "active_record/schema_dumper"
|
340
384
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
341
|
-
|
342
|
-
|
343
|
-
ActiveRecord::Base.establish_connection(db_config.config)
|
344
|
-
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
345
|
-
end
|
385
|
+
ActiveRecord::Base.establish_connection(db_config.config)
|
386
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :ruby, db_config.spec_name)
|
346
387
|
end
|
347
388
|
|
348
389
|
db_namespace["schema:dump"].reenable
|
@@ -385,14 +426,7 @@ db_namespace = namespace :db do
|
|
385
426
|
task dump: :load_config do
|
386
427
|
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
387
428
|
ActiveRecord::Base.establish_connection(db_config.config)
|
388
|
-
|
389
|
-
ActiveRecord::Tasks::DatabaseTasks.structure_dump(db_config.config, filename)
|
390
|
-
if ActiveRecord::SchemaMigration.table_exists?
|
391
|
-
File.open(filename, "a") do |f|
|
392
|
-
f.puts ActiveRecord::Base.connection.dump_schema_information
|
393
|
-
f.print "\n"
|
394
|
-
end
|
395
|
-
end
|
429
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
|
396
430
|
end
|
397
431
|
|
398
432
|
db_namespace["structure:dump"].reenable
|