activerecord 3.2.22.4 → 4.0.13
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 +2799 -617
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -32
- data/examples/performance.rb +1 -1
- data/lib/active_record/aggregations.rb +40 -34
- data/lib/active_record/association_relation.rb +22 -0
- data/lib/active_record/associations/alias_tracker.rb +4 -2
- data/lib/active_record/associations/association.rb +60 -46
- data/lib/active_record/associations/association_scope.rb +46 -40
- data/lib/active_record/associations/belongs_to_association.rb +17 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +81 -28
- data/lib/active_record/associations/builder/belongs_to.rb +73 -56
- data/lib/active_record/associations/builder/collection_association.rb +54 -40
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +23 -41
- data/lib/active_record/associations/builder/has_many.rb +8 -64
- data/lib/active_record/associations/builder/has_one.rb +13 -50
- data/lib/active_record/associations/builder/singular_association.rb +13 -13
- data/lib/active_record/associations/collection_association.rb +130 -96
- data/lib/active_record/associations/collection_proxy.rb +916 -63
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -13
- data/lib/active_record/associations/has_many_association.rb +35 -8
- data/lib/active_record/associations/has_many_through_association.rb +37 -17
- data/lib/active_record/associations/has_one_association.rb +42 -19
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -22
- data/lib/active_record/associations/join_dependency/join_base.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_part.rb +21 -8
- data/lib/active_record/associations/join_dependency.rb +30 -9
- data/lib/active_record/associations/join_helper.rb +1 -11
- data/lib/active_record/associations/preloader/association.rb +29 -33
- data/lib/active_record/associations/preloader/collection_association.rb +1 -1
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/preloader/has_many_through.rb +6 -2
- data/lib/active_record/associations/preloader/has_one.rb +1 -1
- data/lib/active_record/associations/preloader/through_association.rb +13 -17
- data/lib/active_record/associations/preloader.rb +20 -43
- data/lib/active_record/associations/singular_association.rb +11 -11
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +223 -282
- data/lib/active_record/attribute_assignment.rb +134 -154
- data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
- data/lib/active_record/attribute_methods/dirty.rb +36 -29
- data/lib/active_record/attribute_methods/primary_key.rb +45 -31
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +67 -90
- data/lib/active_record/attribute_methods/serialization.rb +133 -70
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +51 -45
- data/lib/active_record/attribute_methods/write.rb +34 -39
- data/lib/active_record/attribute_methods.rb +268 -108
- data/lib/active_record/autosave_association.rb +80 -73
- data/lib/active_record/base.rb +54 -451
- data/lib/active_record/callbacks.rb +60 -22
- data/lib/active_record/coders/yaml_column.rb +18 -21
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +347 -197
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +146 -138
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -19
- data/lib/active_record/connection_adapters/abstract/quoting.rb +19 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +151 -142
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +499 -217
- data/lib/active_record/connection_adapters/abstract/transaction.rb +208 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +209 -44
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +169 -61
- data/lib/active_record/connection_adapters/column.rb +67 -36
- data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +28 -29
- data/lib/active_record/connection_adapters/mysql_adapter.rb +200 -73
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +98 -0
- data/lib/active_record/connection_adapters/postgresql/cast.rb +160 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +240 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +374 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +183 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +508 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +544 -899
- data/lib/active_record/connection_adapters/schema_cache.rb +76 -16
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +595 -16
- data/lib/active_record/connection_handling.rb +98 -0
- data/lib/active_record/core.rb +472 -0
- data/lib/active_record/counter_cache.rb +107 -108
- data/lib/active_record/dynamic_matchers.rb +115 -63
- data/lib/active_record/errors.rb +36 -18
- data/lib/active_record/explain.rb +15 -63
- data/lib/active_record/explain_registry.rb +30 -0
- data/lib/active_record/explain_subscriber.rb +8 -4
- data/lib/active_record/fixture_set/file.rb +55 -0
- data/lib/active_record/fixtures.rb +159 -155
- data/lib/active_record/inheritance.rb +93 -59
- data/lib/active_record/integration.rb +8 -8
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +39 -43
- data/lib/active_record/locking/pessimistic.rb +4 -4
- data/lib/active_record/log_subscriber.rb +19 -9
- data/lib/active_record/migration/command_recorder.rb +102 -33
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/migration.rb +411 -173
- data/lib/active_record/model_schema.rb +81 -94
- data/lib/active_record/nested_attributes.rb +173 -131
- data/lib/active_record/null_relation.rb +67 -0
- data/lib/active_record/persistence.rb +254 -106
- data/lib/active_record/query_cache.rb +18 -36
- data/lib/active_record/querying.rb +19 -15
- data/lib/active_record/railtie.rb +113 -38
- data/lib/active_record/railties/console_sandbox.rb +3 -4
- data/lib/active_record/railties/controller_runtime.rb +4 -3
- data/lib/active_record/railties/databases.rake +115 -368
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +7 -3
- data/lib/active_record/reflection.rb +110 -61
- data/lib/active_record/relation/batches.rb +29 -29
- data/lib/active_record/relation/calculations.rb +155 -125
- data/lib/active_record/relation/delegation.rb +94 -18
- data/lib/active_record/relation/finder_methods.rb +151 -203
- data/lib/active_record/relation/merger.rb +188 -0
- data/lib/active_record/relation/predicate_builder.rb +85 -42
- data/lib/active_record/relation/query_methods.rb +793 -146
- data/lib/active_record/relation/spawn_methods.rb +43 -150
- data/lib/active_record/relation.rb +293 -173
- data/lib/active_record/result.rb +48 -7
- data/lib/active_record/runtime_registry.rb +17 -0
- data/lib/active_record/sanitization.rb +41 -54
- data/lib/active_record/schema.rb +19 -12
- data/lib/active_record/schema_dumper.rb +41 -41
- data/lib/active_record/schema_migration.rb +46 -0
- data/lib/active_record/scoping/default.rb +56 -52
- data/lib/active_record/scoping/named.rb +78 -103
- data/lib/active_record/scoping.rb +54 -124
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +9 -15
- data/lib/active_record/statement_cache.rb +26 -0
- data/lib/active_record/store.rb +131 -15
- data/lib/active_record/tasks/database_tasks.rb +204 -0
- data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +144 -0
- data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
- data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
- data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
- data/lib/active_record/test_case.rb +67 -38
- data/lib/active_record/timestamp.rb +16 -11
- data/lib/active_record/transactions.rb +73 -51
- data/lib/active_record/validations/associated.rb +19 -13
- data/lib/active_record/validations/presence.rb +65 -0
- data/lib/active_record/validations/uniqueness.rb +110 -57
- data/lib/active_record/validations.rb +18 -17
- data/lib/active_record/version.rb +7 -6
- data/lib/active_record.rb +63 -45
- data/lib/rails/generators/active_record/migration/migration_generator.rb +45 -8
- data/lib/rails/generators/active_record/{model/templates/migration.rb → migration/templates/create_table_migration.rb} +4 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/model/model_generator.rb +5 -4
- data/lib/rails/generators/active_record/model/templates/model.rb +4 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- data/lib/rails/generators/active_record.rb +3 -5
- metadata +43 -29
- data/examples/associations.png +0 -0
- data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -191
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -583
- data/lib/active_record/dynamic_finder_match.rb +0 -68
- data/lib/active_record/dynamic_scope_match.rb +0 -23
- data/lib/active_record/fixtures/file.rb +0 -65
- data/lib/active_record/identity_map.rb +0 -162
- data/lib/active_record/observer.rb +0 -121
- data/lib/active_record/session_store.rb +0 -360
- data/lib/rails/generators/active_record/migration.rb +0 -15
- data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
- data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
- data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
- data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,193 +1,42 @@
|
|
1
|
-
require 'active_support/core_ext/object/inclusion'
|
2
1
|
require 'active_record'
|
3
2
|
|
4
3
|
db_namespace = namespace :db do
|
5
|
-
def database_url_config
|
6
|
-
@database_url_config ||=
|
7
|
-
ActiveRecord::Base::ConnectionSpecification::Resolver.new(ENV["DATABASE_URL"], {}).spec.config.stringify_keys
|
8
|
-
end
|
9
|
-
|
10
|
-
def current_config(options = {})
|
11
|
-
options = { :env => Rails.env }.merge! options
|
12
|
-
|
13
|
-
if options[:config]
|
14
|
-
@current_config = options[:config]
|
15
|
-
else
|
16
|
-
@current_config ||= if ENV['DATABASE_URL']
|
17
|
-
database_url_config
|
18
|
-
else
|
19
|
-
ActiveRecord::Base.configurations[options[:env]]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
4
|
task :load_config do
|
25
|
-
ActiveRecord::Base.configurations =
|
26
|
-
ActiveRecord::Migrator.migrations_paths =
|
27
|
-
|
28
|
-
if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
|
29
|
-
if engine.paths['db/migrate'].existent
|
30
|
-
ActiveRecord::Migrator.migrations_paths += engine.paths['db/migrate'].to_a
|
31
|
-
end
|
32
|
-
end
|
5
|
+
ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
|
6
|
+
ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
33
7
|
end
|
34
8
|
|
35
9
|
namespace :create do
|
36
|
-
# desc 'Create all the local databases defined in config/database.yml'
|
37
10
|
task :all => :load_config do
|
38
|
-
ActiveRecord::
|
39
|
-
# Skip entries that don't have a database key, such as the first entry here:
|
40
|
-
#
|
41
|
-
# defaults: &defaults
|
42
|
-
# adapter: mysql
|
43
|
-
# username: root
|
44
|
-
# password:
|
45
|
-
# host: localhost
|
46
|
-
#
|
47
|
-
# development:
|
48
|
-
# database: blog_development
|
49
|
-
# *defaults
|
50
|
-
next unless config['database']
|
51
|
-
# Only connect to local databases
|
52
|
-
local_database?(config) { create_database(config) }
|
53
|
-
end
|
11
|
+
ActiveRecord::Tasks::DatabaseTasks.create_all
|
54
12
|
end
|
55
13
|
end
|
56
14
|
|
57
15
|
desc 'Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)'
|
58
|
-
task :create => [:load_config
|
16
|
+
task :create => [:load_config] do
|
59
17
|
if ENV['DATABASE_URL']
|
60
|
-
|
61
|
-
else
|
62
|
-
configs_for_environment.each { |config| create_database(config) }
|
63
|
-
ActiveRecord::Base.establish_connection(configs_for_environment.first)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# If neither encoding nor collation is specified, use the utf-8 defaults.
|
68
|
-
def mysql_creation_options(config)
|
69
|
-
default_charset = ENV['CHARSET'] || 'utf8'
|
70
|
-
default_collation = ENV['COLLATION'] || 'utf8_unicode_ci'
|
71
|
-
|
72
|
-
Hash.new.tap do |options|
|
73
|
-
options[:charset] = config['encoding'] if config.include? 'encoding'
|
74
|
-
options[:collation] = config['collation'] if config.include? 'collation'
|
75
|
-
|
76
|
-
# Set default charset only when collation isn't set.
|
77
|
-
options[:charset] ||= default_charset unless options[:collation]
|
78
|
-
|
79
|
-
# Set default collation only when charset is also default.
|
80
|
-
options[:collation] ||= default_collation if options[:charset] == default_charset
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def create_database(config)
|
85
|
-
begin
|
86
|
-
if config['adapter'] =~ /sqlite/
|
87
|
-
if File.exist?(config['database'])
|
88
|
-
$stderr.puts "#{config['database']} already exists"
|
89
|
-
else
|
90
|
-
begin
|
91
|
-
# Create the SQLite database
|
92
|
-
ActiveRecord::Base.establish_connection(config)
|
93
|
-
ActiveRecord::Base.connection
|
94
|
-
rescue Exception => e
|
95
|
-
$stderr.puts e, *(e.backtrace)
|
96
|
-
$stderr.puts "Couldn't create database for #{config.inspect}"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
return # Skip the else clause of begin/rescue
|
100
|
-
else
|
101
|
-
ActiveRecord::Base.establish_connection(config)
|
102
|
-
ActiveRecord::Base.connection
|
103
|
-
end
|
104
|
-
rescue
|
105
|
-
case config['adapter']
|
106
|
-
when /mysql/
|
107
|
-
if config['adapter'] =~ /jdbc/
|
108
|
-
#FIXME After Jdbcmysql gives this class
|
109
|
-
require 'active_record/railties/jdbcmysql_error'
|
110
|
-
error_class = ArJdbcMySQL::Error
|
111
|
-
else
|
112
|
-
error_class = config['adapter'] =~ /mysql2/ ? Mysql2::Error : Mysql::Error
|
113
|
-
end
|
114
|
-
access_denied_error = 1045
|
115
|
-
|
116
|
-
create_options = mysql_creation_options(config)
|
117
|
-
|
118
|
-
begin
|
119
|
-
ActiveRecord::Base.establish_connection(config.merge('database' => nil))
|
120
|
-
ActiveRecord::Base.connection.create_database(config['database'], create_options)
|
121
|
-
ActiveRecord::Base.establish_connection(config)
|
122
|
-
rescue error_class => sqlerr
|
123
|
-
if sqlerr.errno == access_denied_error
|
124
|
-
print "#{sqlerr.error}. \nPlease provide the root password for your mysql installation\n>"
|
125
|
-
root_password = $stdin.gets.strip
|
126
|
-
grant_statement = "GRANT ALL PRIVILEGES ON #{config['database']}.* " \
|
127
|
-
"TO '#{config['username']}'@'localhost' " \
|
128
|
-
"IDENTIFIED BY '#{config['password']}' WITH GRANT OPTION;"
|
129
|
-
ActiveRecord::Base.establish_connection(config.merge(
|
130
|
-
'database' => nil, 'username' => 'root', 'password' => root_password))
|
131
|
-
ActiveRecord::Base.connection.create_database(config['database'], mysql_creation_options(config))
|
132
|
-
ActiveRecord::Base.connection.execute grant_statement
|
133
|
-
ActiveRecord::Base.establish_connection(config)
|
134
|
-
else
|
135
|
-
$stderr.puts sqlerr.error
|
136
|
-
$stderr.puts "Couldn't create database for #{config.inspect}, charset: #{create_options[:charset]}, collation: #{create_options[:collation]}"
|
137
|
-
$stderr.puts "(if you set the charset manually, make sure you have a matching collation)" if config['encoding']
|
138
|
-
end
|
139
|
-
end
|
140
|
-
when /postgresql/
|
141
|
-
@encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
|
142
|
-
begin
|
143
|
-
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
144
|
-
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
145
|
-
ActiveRecord::Base.establish_connection(config)
|
146
|
-
rescue Exception => e
|
147
|
-
$stderr.puts e, *(e.backtrace)
|
148
|
-
$stderr.puts "Couldn't create database for #{config.inspect}"
|
149
|
-
end
|
150
|
-
end
|
18
|
+
ActiveRecord::Tasks::DatabaseTasks.create_database_url
|
151
19
|
else
|
152
|
-
|
153
|
-
$stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
|
20
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current
|
154
21
|
end
|
155
22
|
end
|
156
23
|
|
157
24
|
namespace :drop do
|
158
|
-
# desc 'Drops all the local databases defined in config/database.yml'
|
159
25
|
task :all => :load_config do
|
160
|
-
ActiveRecord::
|
161
|
-
# Skip entries that don't have a database key
|
162
|
-
next unless config['database']
|
163
|
-
begin
|
164
|
-
# Only connect to local databases
|
165
|
-
local_database?(config) { drop_database(config) }
|
166
|
-
rescue Exception => e
|
167
|
-
$stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
|
168
|
-
end
|
169
|
-
end
|
26
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
170
27
|
end
|
171
28
|
end
|
172
29
|
|
173
30
|
desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
|
174
|
-
task :drop => [:load_config
|
31
|
+
task :drop => [:load_config] do
|
175
32
|
if ENV['DATABASE_URL']
|
176
|
-
|
177
|
-
else
|
178
|
-
configs_for_environment.each { |config| drop_database_and_rescue(config) }
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def local_database?(config, &block)
|
183
|
-
if config['host'].in?(['127.0.0.1', 'localhost']) || config['host'].blank?
|
184
|
-
yield
|
33
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_database_url
|
185
34
|
else
|
186
|
-
|
35
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
187
36
|
end
|
188
37
|
end
|
189
38
|
|
190
|
-
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
|
39
|
+
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
191
40
|
task :migrate => [:environment, :load_config] do
|
192
41
|
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
193
42
|
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
|
@@ -246,13 +95,15 @@ db_namespace = namespace :db do
|
|
246
95
|
next # means "return" for rake task
|
247
96
|
end
|
248
97
|
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
98
|
+
db_list.map! { |version| ActiveRecord::SchemaMigration.normalize_migration_number(version) }
|
249
99
|
file_list = []
|
250
100
|
ActiveRecord::Migrator.migrations_paths.each do |path|
|
251
101
|
Dir.foreach(path) do |file|
|
252
|
-
#
|
253
|
-
if match_data = /^(\d{
|
254
|
-
|
255
|
-
|
102
|
+
# match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
|
103
|
+
if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
|
104
|
+
version = ActiveRecord::SchemaMigration.normalize_migration_number(match_data[1])
|
105
|
+
status = db_list.delete(version) ? 'up' : 'down'
|
106
|
+
file_list << [status, version, match_data[2].humanize]
|
256
107
|
end
|
257
108
|
end
|
258
109
|
end
|
@@ -292,31 +143,15 @@ db_namespace = namespace :db do
|
|
292
143
|
|
293
144
|
# desc "Retrieves the charset for the current environment's database"
|
294
145
|
task :charset => [:environment, :load_config] do
|
295
|
-
|
296
|
-
case config['adapter']
|
297
|
-
when /mysql/
|
298
|
-
ActiveRecord::Base.establish_connection(config)
|
299
|
-
puts ActiveRecord::Base.connection.charset
|
300
|
-
when /postgresql/
|
301
|
-
ActiveRecord::Base.establish_connection(config)
|
302
|
-
puts ActiveRecord::Base.connection.encoding
|
303
|
-
when /sqlite/
|
304
|
-
ActiveRecord::Base.establish_connection(config)
|
305
|
-
puts ActiveRecord::Base.connection.encoding
|
306
|
-
else
|
307
|
-
$stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
308
|
-
end
|
146
|
+
puts ActiveRecord::Tasks::DatabaseTasks.charset_current
|
309
147
|
end
|
310
148
|
|
311
149
|
# desc "Retrieves the collation for the current environment's database"
|
312
150
|
task :collation => [:environment, :load_config] do
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
puts ActiveRecord::Base.connection.collation
|
318
|
-
else
|
319
|
-
$stderr.puts 'sorry, your database adapter is not supported yet, feel free to submit a patch'
|
151
|
+
begin
|
152
|
+
puts ActiveRecord::Tasks::DatabaseTasks.collation_current
|
153
|
+
rescue NoMethodError
|
154
|
+
$stderr.puts 'Sorry, your database adapter is not supported yet. Feel free to submit a patch.'
|
320
155
|
end
|
321
156
|
end
|
322
157
|
|
@@ -326,11 +161,11 @@ db_namespace = namespace :db do
|
|
326
161
|
end
|
327
162
|
|
328
163
|
# desc "Raises an error if there are pending migrations"
|
329
|
-
task :abort_if_pending_migrations =>
|
330
|
-
pending_migrations = ActiveRecord::Migrator.
|
164
|
+
task :abort_if_pending_migrations => :environment do
|
165
|
+
pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations
|
331
166
|
|
332
167
|
if pending_migrations.any?
|
333
|
-
puts "You have #{pending_migrations.size} pending migrations:"
|
168
|
+
puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
|
334
169
|
pending_migrations.each do |pending_migration|
|
335
170
|
puts ' %4d %s' % [pending_migration.version, pending_migration.name]
|
336
171
|
end
|
@@ -344,7 +179,7 @@ db_namespace = namespace :db do
|
|
344
179
|
desc 'Load the seed data from db/seeds.rb'
|
345
180
|
task :seed do
|
346
181
|
db_namespace['abort_if_pending_migrations'].invoke
|
347
|
-
|
182
|
+
ActiveRecord::Tasks::DatabaseTasks.load_seed
|
348
183
|
end
|
349
184
|
|
350
185
|
namespace :fixtures do
|
@@ -352,11 +187,19 @@ db_namespace = namespace :db do
|
|
352
187
|
task :load => [:environment, :load_config] do
|
353
188
|
require 'active_record/fixtures'
|
354
189
|
|
355
|
-
base_dir
|
190
|
+
base_dir = if ENV['FIXTURES_PATH']
|
191
|
+
STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
|
192
|
+
"ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
|
193
|
+
"instead."
|
194
|
+
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
195
|
+
else
|
196
|
+
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
197
|
+
end
|
198
|
+
|
356
199
|
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
|
357
200
|
|
358
201
|
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
|
359
|
-
ActiveRecord::
|
202
|
+
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
|
360
203
|
end
|
361
204
|
end
|
362
205
|
|
@@ -367,13 +210,22 @@ db_namespace = namespace :db do
|
|
367
210
|
label, id = ENV['LABEL'], ENV['ID']
|
368
211
|
raise 'LABEL or ID required' if label.blank? && id.blank?
|
369
212
|
|
370
|
-
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::
|
213
|
+
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
|
214
|
+
|
215
|
+
base_dir = if ENV['FIXTURES_PATH']
|
216
|
+
STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
|
217
|
+
"ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
|
218
|
+
"instead."
|
219
|
+
File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
|
220
|
+
else
|
221
|
+
ActiveRecord::Tasks::DatabaseTasks.fixtures_path
|
222
|
+
end
|
223
|
+
|
371
224
|
|
372
|
-
base_dir = ENV['FIXTURES_PATH'] ? File.join(Rails.root, ENV['FIXTURES_PATH']) : File.join(Rails.root, 'test', 'fixtures')
|
373
225
|
Dir["#{base_dir}/**/*.yml"].each do |file|
|
374
226
|
if data = YAML::load(ERB.new(IO.read(file)).result)
|
375
227
|
data.keys.each do |key|
|
376
|
-
key_id = ActiveRecord::
|
228
|
+
key_id = ActiveRecord::FixtureSet.identify(key)
|
377
229
|
|
378
230
|
if key == label || key_id == id.to_i
|
379
231
|
puts "#{file}: #{key} (#{key_id})"
|
@@ -388,7 +240,7 @@ db_namespace = namespace :db do
|
|
388
240
|
desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
|
389
241
|
task :dump => [:environment, :load_config] do
|
390
242
|
require 'active_record/schema_dumper'
|
391
|
-
filename = ENV['SCHEMA'] ||
|
243
|
+
filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
|
392
244
|
File.open(filename, "w:utf-8") do |file|
|
393
245
|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
394
246
|
end
|
@@ -397,87 +249,59 @@ db_namespace = namespace :db do
|
|
397
249
|
|
398
250
|
desc 'Load a schema.rb file into the database'
|
399
251
|
task :load => [:environment, :load_config] do
|
400
|
-
file = ENV['SCHEMA'] ||
|
401
|
-
if File.
|
252
|
+
file = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
|
253
|
+
if File.exist?(file)
|
402
254
|
load(file)
|
403
255
|
else
|
404
|
-
abort %{#{file} doesn't exist yet. Run `rake db:migrate` to create it then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded}
|
256
|
+
abort %{#{file} doesn't exist yet. Run `rake db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.}
|
405
257
|
end
|
406
258
|
end
|
407
259
|
|
408
260
|
task :load_if_ruby => ['db:create', :environment] do
|
409
261
|
db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
|
410
262
|
end
|
263
|
+
|
264
|
+
namespace :cache do
|
265
|
+
desc 'Create a db/schema_cache.dump file.'
|
266
|
+
task :dump => [:environment, :load_config] do
|
267
|
+
con = ActiveRecord::Base.connection
|
268
|
+
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
|
269
|
+
|
270
|
+
con.schema_cache.clear!
|
271
|
+
con.tables.each { |table| con.schema_cache.add(table) }
|
272
|
+
open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) }
|
273
|
+
end
|
274
|
+
|
275
|
+
desc 'Clear a db/schema_cache.dump file.'
|
276
|
+
task :clear => [:environment, :load_config] do
|
277
|
+
filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
|
278
|
+
FileUtils.rm(filename) if File.exist?(filename)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
411
282
|
end
|
412
283
|
|
413
284
|
namespace :structure do
|
414
285
|
desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
|
415
286
|
task :dump => [:environment, :load_config] do
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
search_path = config['schema_search_path']
|
425
|
-
unless search_path.blank?
|
426
|
-
search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
|
287
|
+
filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
|
288
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
289
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
|
290
|
+
|
291
|
+
if ActiveRecord::Base.connection.supports_migrations? &&
|
292
|
+
ActiveRecord::SchemaMigration.table_exists?
|
293
|
+
File.open(filename, "a") do |f|
|
294
|
+
f.puts ActiveRecord::Base.connection.dump_schema_information
|
427
295
|
end
|
428
|
-
`pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(config['database'])}`
|
429
|
-
raise 'Error dumping database' if $?.exitstatus == 1
|
430
|
-
File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
|
431
|
-
when /sqlite/
|
432
|
-
dbfile = config['database']
|
433
|
-
`sqlite3 #{dbfile} .schema > #{filename}`
|
434
|
-
when 'sqlserver'
|
435
|
-
`smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
|
436
|
-
when "firebird"
|
437
|
-
set_firebird_env(config)
|
438
|
-
db_string = firebird_db_string(config)
|
439
|
-
sh "isql -a #{db_string} > #{filename}"
|
440
|
-
else
|
441
|
-
raise "Task not supported by '#{config['adapter']}'"
|
442
|
-
end
|
443
|
-
|
444
|
-
if ActiveRecord::Base.connection.supports_migrations?
|
445
|
-
File.open(filename, "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
|
446
296
|
end
|
447
297
|
db_namespace['structure:dump'].reenable
|
448
298
|
end
|
449
299
|
|
450
300
|
# desc "Recreate the databases from the structure.sql file"
|
451
301
|
task :load => [:environment, :load_config] do
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
when /mysql/
|
456
|
-
ActiveRecord::Base.establish_connection(config)
|
457
|
-
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
|
458
|
-
IO.read(filename).split("\n\n").each do |table|
|
459
|
-
ActiveRecord::Base.connection.execute(table)
|
460
|
-
end
|
461
|
-
when /postgresql/
|
462
|
-
set_psql_env(config)
|
463
|
-
`psql -f "#{filename}" #{config['database']}`
|
464
|
-
when /sqlite/
|
465
|
-
dbfile = config['database']
|
466
|
-
`sqlite3 #{dbfile} < "#{filename}"`
|
467
|
-
when 'sqlserver'
|
468
|
-
`sqlcmd -S #{config['host']} -d #{config['database']} -U #{config['username']} -P #{config['password']} -i #{filename}`
|
469
|
-
when 'oci', 'oracle'
|
470
|
-
ActiveRecord::Base.establish_connection(config)
|
471
|
-
IO.read(filename).split(";\n\n").each do |ddl|
|
472
|
-
ActiveRecord::Base.connection.execute(ddl)
|
473
|
-
end
|
474
|
-
when 'firebird'
|
475
|
-
set_firebird_env(config)
|
476
|
-
db_string = firebird_db_string(config)
|
477
|
-
sh "isql -i #{filename} #{db_string}"
|
478
|
-
else
|
479
|
-
raise "Task not supported by '#{config['adapter']}'"
|
480
|
-
end
|
302
|
+
filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
|
303
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
304
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
|
481
305
|
end
|
482
306
|
|
483
307
|
task :load_if_sql => ['db:create', :environment] do
|
@@ -497,93 +321,67 @@ db_namespace = namespace :db do
|
|
497
321
|
end
|
498
322
|
end
|
499
323
|
|
324
|
+
# desc "Recreate the test database from an existent schema.rb file"
|
325
|
+
task :load_schema => 'db:test:purge' do
|
326
|
+
begin
|
327
|
+
should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
|
328
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
329
|
+
ActiveRecord::Schema.verbose = false
|
330
|
+
db_namespace["schema:load"].invoke
|
331
|
+
ensure
|
332
|
+
if should_reconnect
|
333
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
500
338
|
# desc "Recreate the test database from an existent structure.sql file"
|
501
339
|
task :load_structure => 'db:test:purge' do
|
502
340
|
begin
|
503
|
-
current_config(:config => ActiveRecord::Base.configurations['test'])
|
341
|
+
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
|
504
342
|
db_namespace["structure:load"].invoke
|
505
343
|
ensure
|
506
|
-
current_config(:config => nil)
|
344
|
+
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
|
507
345
|
end
|
508
346
|
end
|
509
347
|
|
510
|
-
# desc "Recreate the test database from
|
511
|
-
task :
|
512
|
-
ActiveRecord::Base.
|
513
|
-
|
514
|
-
|
348
|
+
# desc "Recreate the test database from a fresh schema"
|
349
|
+
task :clone => :environment do
|
350
|
+
case ActiveRecord::Base.schema_format
|
351
|
+
when :ruby
|
352
|
+
db_namespace["test:clone_schema"].invoke
|
353
|
+
when :sql
|
354
|
+
db_namespace["test:clone_structure"].invoke
|
355
|
+
end
|
515
356
|
end
|
516
357
|
|
517
358
|
# desc "Recreate the test database from a fresh schema.rb file"
|
518
|
-
task :
|
359
|
+
task :clone_schema => ["db:schema:dump", "db:test:load_schema"]
|
519
360
|
|
520
361
|
# desc "Recreate the test database from a fresh structure.sql file"
|
521
362
|
task :clone_structure => [ "db:structure:dump", "db:test:load_structure" ]
|
522
363
|
|
523
364
|
# desc "Empty the test database"
|
524
365
|
task :purge => [:environment, :load_config] do
|
525
|
-
|
526
|
-
case abcs['test']['adapter']
|
527
|
-
when /mysql/
|
528
|
-
ActiveRecord::Base.establish_connection(:test)
|
529
|
-
ActiveRecord::Base.connection.recreate_database(abcs['test']['database'], mysql_creation_options(abcs['test']))
|
530
|
-
when /postgresql/
|
531
|
-
ActiveRecord::Base.clear_active_connections!
|
532
|
-
drop_database(abcs['test'])
|
533
|
-
create_database(abcs['test'])
|
534
|
-
when /sqlite/
|
535
|
-
dbfile = abcs['test']['database']
|
536
|
-
File.delete(dbfile) if File.exist?(dbfile)
|
537
|
-
when 'sqlserver'
|
538
|
-
test = abcs.deep_dup['test']
|
539
|
-
test_database = test['database']
|
540
|
-
test['database'] = 'master'
|
541
|
-
ActiveRecord::Base.establish_connection(test)
|
542
|
-
ActiveRecord::Base.connection.recreate_database!(test_database)
|
543
|
-
when "oci", "oracle"
|
544
|
-
ActiveRecord::Base.establish_connection(:test)
|
545
|
-
ActiveRecord::Base.connection.structure_drop.split(";\n\n").each do |ddl|
|
546
|
-
ActiveRecord::Base.connection.execute(ddl)
|
547
|
-
end
|
548
|
-
when 'firebird'
|
549
|
-
ActiveRecord::Base.establish_connection(:test)
|
550
|
-
ActiveRecord::Base.connection.recreate_database!
|
551
|
-
else
|
552
|
-
raise "Task not supported by '#{abcs['test']['adapter']}'"
|
553
|
-
end
|
366
|
+
ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
|
554
367
|
end
|
555
368
|
|
556
369
|
# desc 'Check for pending migrations and load the test schema'
|
557
|
-
task :prepare =>
|
370
|
+
task :prepare => [:environment, :load_config] do
|
558
371
|
unless ActiveRecord::Base.configurations.blank?
|
559
|
-
db_namespace[
|
372
|
+
db_namespace['test:load'].invoke
|
560
373
|
end
|
561
374
|
end
|
562
375
|
end
|
563
|
-
|
564
|
-
namespace :sessions do
|
565
|
-
# desc "Creates a sessions migration for use with ActiveRecord::SessionStore"
|
566
|
-
task :create => [:environment, :load_config] do
|
567
|
-
raise 'Task unavailable to this database (no migration support)' unless ActiveRecord::Base.connection.supports_migrations?
|
568
|
-
Rails.application.load_generators
|
569
|
-
require 'rails/generators/rails/session_migration/session_migration_generator'
|
570
|
-
Rails::Generators::SessionMigrationGenerator.start [ ENV['MIGRATION'] || 'add_sessions_table' ]
|
571
|
-
end
|
572
|
-
|
573
|
-
# desc "Clear the sessions table"
|
574
|
-
task :clear => [:environment, :load_config] do
|
575
|
-
ActiveRecord::Base.connection.execute "DELETE FROM #{session_table_name}"
|
576
|
-
end
|
577
|
-
end
|
578
376
|
end
|
579
377
|
|
580
378
|
namespace :railties do
|
581
379
|
namespace :install do
|
582
|
-
# desc "Copies missing migrations from Railties (e.g.
|
380
|
+
# desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
|
583
381
|
task :migrations => :'db:load_config' do
|
584
382
|
to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip }
|
585
|
-
railties =
|
586
|
-
Rails.application.
|
383
|
+
railties = {}
|
384
|
+
Rails.application.migration_railties.each do |railtie|
|
587
385
|
next unless to_load == :all || to_load.include?(railtie.railtie_name)
|
588
386
|
|
589
387
|
if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first)
|
@@ -595,7 +393,7 @@ namespace :railties do
|
|
595
393
|
puts "NOTE: Migration #{migration.basename} from #{name} has been skipped. Migration with the same name already exists."
|
596
394
|
end
|
597
395
|
|
598
|
-
on_copy = Proc.new do |name, migration
|
396
|
+
on_copy = Proc.new do |name, migration|
|
599
397
|
puts "Copied migration #{migration.basename} from #{name}"
|
600
398
|
end
|
601
399
|
|
@@ -605,55 +403,4 @@ namespace :railties do
|
|
605
403
|
end
|
606
404
|
end
|
607
405
|
|
608
|
-
task 'test:prepare' => 'db:test:prepare'
|
609
|
-
|
610
|
-
def drop_database(config)
|
611
|
-
case config['adapter']
|
612
|
-
when /mysql/
|
613
|
-
ActiveRecord::Base.establish_connection(config)
|
614
|
-
ActiveRecord::Base.connection.drop_database config['database']
|
615
|
-
when /sqlite/
|
616
|
-
require 'pathname'
|
617
|
-
path = Pathname.new(config['database'])
|
618
|
-
file = path.absolute? ? path.to_s : File.join(Rails.root, path)
|
619
|
-
|
620
|
-
FileUtils.rm(file)
|
621
|
-
when /postgresql/
|
622
|
-
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
623
|
-
ActiveRecord::Base.connection.drop_database config['database']
|
624
|
-
end
|
625
|
-
end
|
626
|
-
|
627
|
-
def drop_database_and_rescue(config)
|
628
|
-
begin
|
629
|
-
drop_database(config)
|
630
|
-
rescue Exception => e
|
631
|
-
$stderr.puts "Couldn't drop #{config['database']} : #{e.inspect}"
|
632
|
-
end
|
633
|
-
end
|
634
|
-
|
635
|
-
def configs_for_environment
|
636
|
-
environments = [Rails.env]
|
637
|
-
environments << 'test' if Rails.env.development?
|
638
|
-
ActiveRecord::Base.configurations.values_at(*environments).compact.reject { |config| config['database'].blank? }
|
639
|
-
end
|
640
|
-
|
641
|
-
def session_table_name
|
642
|
-
ActiveRecord::SessionStore::Session.table_name
|
643
|
-
end
|
644
|
-
|
645
|
-
def set_firebird_env(config)
|
646
|
-
ENV['ISC_USER'] = config['username'].to_s if config['username']
|
647
|
-
ENV['ISC_PASSWORD'] = config['password'].to_s if config['password']
|
648
|
-
end
|
649
|
-
|
650
|
-
def firebird_db_string(config)
|
651
|
-
FireRuby::Database.db_string_for(config.symbolize_keys)
|
652
|
-
end
|
653
|
-
|
654
|
-
def set_psql_env(config)
|
655
|
-
ENV['PGHOST'] = config['host'] if config['host']
|
656
|
-
ENV['PGPORT'] = config['port'].to_s if config['port']
|
657
|
-
ENV['PGPASSWORD'] = config['password'].to_s if config['password']
|
658
|
-
ENV['PGUSER'] = config['username'].to_s if config['username']
|
659
|
-
end
|
406
|
+
task 'test:prepare' => ['db:test:prepare', 'db:test:load', 'db:abort_if_pending_migrations']
|