activerecord 3.2.22.5 → 4.0.0.beta1
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 +1024 -543
- data/MIT-LICENSE +1 -1
- data/README.rdoc +20 -29
- data/examples/performance.rb +1 -1
- data/lib/active_record.rb +55 -44
- data/lib/active_record/aggregations.rb +40 -34
- data/lib/active_record/associations.rb +204 -276
- data/lib/active_record/associations/alias_tracker.rb +1 -1
- data/lib/active_record/associations/association.rb +30 -35
- data/lib/active_record/associations/association_scope.rb +40 -40
- data/lib/active_record/associations/belongs_to_association.rb +15 -2
- data/lib/active_record/associations/builder/association.rb +81 -28
- data/lib/active_record/associations/builder/belongs_to.rb +35 -57
- 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 +92 -88
- data/lib/active_record/associations/collection_proxy.rb +913 -63
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -10
- data/lib/active_record/associations/has_many_association.rb +35 -9
- data/lib/active_record/associations/has_many_through_association.rb +24 -14
- data/lib/active_record/associations/has_one_association.rb +33 -13
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -22
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_helper.rb +1 -11
- data/lib/active_record/associations/preloader.rb +14 -17
- 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 +1 -1
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- 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/singular_association.rb +11 -11
- data/lib/active_record/associations/through_association.rb +2 -2
- data/lib/active_record/attribute_assignment.rb +133 -153
- data/lib/active_record/attribute_methods.rb +196 -93
- data/lib/active_record/attribute_methods/before_type_cast.rb +44 -5
- data/lib/active_record/attribute_methods/dirty.rb +31 -28
- data/lib/active_record/attribute_methods/primary_key.rb +38 -30
- data/lib/active_record/attribute_methods/query.rb +5 -4
- data/lib/active_record/attribute_methods/read.rb +62 -91
- data/lib/active_record/attribute_methods/serialization.rb +97 -66
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -45
- data/lib/active_record/attribute_methods/write.rb +32 -39
- data/lib/active_record/autosave_association.rb +56 -70
- data/lib/active_record/base.rb +53 -450
- data/lib/active_record/callbacks.rb +53 -18
- data/lib/active_record/coders/yaml_column.rb +11 -9
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +353 -197
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -131
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -19
- data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +101 -91
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +59 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +225 -96
- data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +99 -46
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +114 -36
- data/lib/active_record/connection_adapters/column.rb +46 -24
- data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -32
- data/lib/active_record/connection_adapters/mysql_adapter.rb +181 -64
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
- data/lib/active_record/connection_adapters/postgresql/cast.rb +132 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +347 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +158 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +448 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +454 -885
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -16
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +574 -13
- data/lib/active_record/connection_handling.rb +98 -0
- data/lib/active_record/core.rb +428 -0
- data/lib/active_record/counter_cache.rb +106 -108
- data/lib/active_record/dynamic_matchers.rb +110 -63
- data/lib/active_record/errors.rb +25 -8
- data/lib/active_record/explain.rb +8 -58
- data/lib/active_record/explain_subscriber.rb +6 -3
- data/lib/active_record/fixture_set/file.rb +56 -0
- data/lib/active_record/fixtures.rb +146 -148
- data/lib/active_record/inheritance.rb +77 -59
- data/lib/active_record/integration.rb +5 -5
- data/lib/active_record/locale/en.yml +8 -1
- data/lib/active_record/locking/optimistic.rb +38 -42
- data/lib/active_record/locking/pessimistic.rb +4 -4
- data/lib/active_record/log_subscriber.rb +19 -9
- data/lib/active_record/migration.rb +318 -153
- data/lib/active_record/migration/command_recorder.rb +90 -31
- data/lib/active_record/migration/join_table.rb +15 -0
- data/lib/active_record/model_schema.rb +69 -92
- data/lib/active_record/nested_attributes.rb +113 -148
- data/lib/active_record/null_relation.rb +65 -0
- data/lib/active_record/persistence.rb +188 -97
- data/lib/active_record/query_cache.rb +18 -36
- data/lib/active_record/querying.rb +19 -15
- data/lib/active_record/railtie.rb +91 -36
- data/lib/active_record/railties/console_sandbox.rb +0 -2
- data/lib/active_record/railties/controller_runtime.rb +2 -2
- data/lib/active_record/railties/databases.rake +90 -309
- 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 +72 -56
- data/lib/active_record/relation.rb +241 -157
- data/lib/active_record/relation/batches.rb +25 -22
- data/lib/active_record/relation/calculations.rb +143 -121
- data/lib/active_record/relation/delegation.rb +96 -18
- data/lib/active_record/relation/finder_methods.rb +117 -183
- data/lib/active_record/relation/merger.rb +133 -0
- data/lib/active_record/relation/predicate_builder.rb +90 -42
- data/lib/active_record/relation/query_methods.rb +666 -136
- data/lib/active_record/relation/spawn_methods.rb +43 -150
- data/lib/active_record/result.rb +33 -6
- data/lib/active_record/sanitization.rb +24 -50
- data/lib/active_record/schema.rb +19 -12
- data/lib/active_record/schema_dumper.rb +31 -39
- data/lib/active_record/schema_migration.rb +36 -0
- data/lib/active_record/scoping.rb +0 -124
- data/lib/active_record/scoping/default.rb +48 -45
- data/lib/active_record/scoping/named.rb +74 -103
- data/lib/active_record/serialization.rb +6 -2
- data/lib/active_record/serializers/xml_serializer.rb +9 -15
- data/lib/active_record/store.rb +119 -15
- data/lib/active_record/tasks/database_tasks.rb +158 -0
- data/lib/active_record/tasks/mysql_database_tasks.rb +138 -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/test_case.rb +61 -38
- data/lib/active_record/timestamp.rb +8 -9
- data/lib/active_record/transactions.rb +65 -51
- data/lib/active_record/validations.rb +17 -15
- data/lib/active_record/validations/associated.rb +20 -14
- data/lib/active_record/validations/presence.rb +65 -0
- data/lib/active_record/validations/uniqueness.rb +93 -52
- data/lib/active_record/version.rb +4 -4
- data/lib/rails/generators/active_record.rb +3 -5
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -7
- data/lib/rails/generators/active_record/migration/templates/migration.rb +20 -15
- data/lib/rails/generators/active_record/model/model_generator.rb +4 -3
- data/lib/rails/generators/active_record/model/templates/model.rb +1 -6
- data/lib/rails/generators/active_record/model/templates/module.rb +1 -1
- metadata +53 -46
- 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,10 +1,10 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
1
|
|
3
2
|
module ActiveRecord
|
4
3
|
# = Active Record Query Cache
|
5
4
|
class QueryCache
|
6
5
|
module ClassMethods
|
7
6
|
# Enable the query cache within the block if Active Record is configured.
|
7
|
+
# If it's not, it will execute the given block.
|
8
8
|
def cache(&block)
|
9
9
|
if ActiveRecord::Base.connected?
|
10
10
|
connection.cache(&block)
|
@@ -14,6 +14,7 @@ module ActiveRecord
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# Disable the query cache within the block if Active Record is configured.
|
17
|
+
# If it's not, it will execute the given block.
|
17
18
|
def uncached(&block)
|
18
19
|
if ActiveRecord::Base.connected?
|
19
20
|
connection.uncached(&block)
|
@@ -27,48 +28,29 @@ module ActiveRecord
|
|
27
28
|
@app = app
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@connection_id = connection_id
|
35
|
-
end
|
36
|
-
|
37
|
-
def method_missing(method_sym, *arguments, &block)
|
38
|
-
@target.send(method_sym, *arguments, &block)
|
39
|
-
end
|
40
|
-
|
41
|
-
def respond_to?(method_sym, include_private = false)
|
42
|
-
super || @target.respond_to?(method_sym)
|
43
|
-
end
|
31
|
+
def call(env)
|
32
|
+
enabled = ActiveRecord::Base.connection.query_cache_enabled
|
33
|
+
connection_id = ActiveRecord::Base.connection_id
|
34
|
+
ActiveRecord::Base.connection.enable_query_cache!
|
44
35
|
|
45
|
-
|
46
|
-
|
36
|
+
response = @app.call(env)
|
37
|
+
response[2] = Rack::BodyProxy.new(response[2]) do
|
38
|
+
restore_query_cache_settings(connection_id, enabled)
|
47
39
|
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ActiveRecord::Base.connection.clear_query_cache
|
54
|
-
unless @original_cache_value
|
55
|
-
ActiveRecord::Base.connection.disable_query_cache!
|
56
|
-
end
|
57
|
-
end
|
41
|
+
response
|
42
|
+
rescue Exception => e
|
43
|
+
restore_query_cache_settings(connection_id, enabled)
|
44
|
+
raise e
|
58
45
|
end
|
59
46
|
|
60
|
-
|
61
|
-
old = ActiveRecord::Base.connection.query_cache_enabled
|
62
|
-
ActiveRecord::Base.connection.enable_query_cache!
|
47
|
+
private
|
63
48
|
|
64
|
-
|
65
|
-
|
66
|
-
rescue Exception => e
|
49
|
+
def restore_query_cache_settings(connection_id, enabled)
|
50
|
+
ActiveRecord::Base.connection_id = connection_id
|
67
51
|
ActiveRecord::Base.connection.clear_query_cache
|
68
|
-
unless
|
69
|
-
ActiveRecord::Base.connection.disable_query_cache!
|
70
|
-
end
|
71
|
-
raise e
|
52
|
+
ActiveRecord::Base.connection.disable_query_cache! unless enabled
|
72
53
|
end
|
54
|
+
|
73
55
|
end
|
74
56
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
2
|
-
|
3
1
|
module ActiveRecord
|
4
2
|
module Querying
|
5
|
-
delegate :find, :first, :first!, :last, :last!, :
|
6
|
-
delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :
|
7
|
-
delegate :
|
8
|
-
delegate :
|
3
|
+
delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :to => :all
|
4
|
+
delegate :first_or_create, :first_or_create!, :first_or_initialize, :to => :all
|
5
|
+
delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :to => :all
|
6
|
+
delegate :find_by, :find_by!, :to => :all
|
7
|
+
delegate :destroy, :destroy_all, :delete, :delete_all, :update, :update_all, :to => :all
|
8
|
+
delegate :find_each, :find_in_batches, :to => :all
|
9
9
|
delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins,
|
10
10
|
:where, :preload, :eager_load, :includes, :from, :lock, :readonly,
|
11
|
-
:having, :create_with, :uniq, :to => :
|
12
|
-
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :to => :
|
11
|
+
:having, :create_with, :uniq, :references, :none, :to => :all
|
12
|
+
delegate :count, :average, :minimum, :maximum, :sum, :calculate, :pluck, :ids, :to => :all
|
13
13
|
|
14
14
|
# Executes a custom SQL query against your database and returns all the results. The results will
|
15
15
|
# be returned as an array with columns requested encapsulated as attributes of the model you call
|
@@ -25,18 +25,24 @@ module ActiveRecord
|
|
25
25
|
# MySQL specific terms will lock you to using that particular database engine or require you to
|
26
26
|
# change your call if you switch engines.
|
27
27
|
#
|
28
|
-
# ==== Examples
|
29
28
|
# # A simple SQL query spanning multiple tables
|
30
29
|
# Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
|
31
|
-
#
|
30
|
+
# # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
|
32
31
|
#
|
33
32
|
# # You can use the same string replacement techniques as you can with ActiveRecord#find
|
34
33
|
# Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
|
35
|
-
#
|
34
|
+
# # => [#<Post:0x36bff9c @attributes={"title"=>"The Cheap Man Buys Twice"}>, ...]
|
36
35
|
def find_by_sql(sql, binds = [])
|
37
|
-
|
38
|
-
|
36
|
+
result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds)
|
37
|
+
column_types = {}
|
38
|
+
|
39
|
+
if result_set.respond_to? :column_types
|
40
|
+
column_types = result_set.column_types
|
41
|
+
else
|
42
|
+
ActiveSupport::Deprecation.warn "the object returned from `select_all` must respond to `column_types`"
|
39
43
|
end
|
44
|
+
|
45
|
+
result_set.map { |record| instantiate(record, column_types) }
|
40
46
|
end
|
41
47
|
|
42
48
|
# Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
|
@@ -47,8 +53,6 @@ module ActiveRecord
|
|
47
53
|
#
|
48
54
|
# * +sql+ - An SQL statement which should return a count query from the database, see the example below.
|
49
55
|
#
|
50
|
-
# ==== Examples
|
51
|
-
#
|
52
56
|
# Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
|
53
57
|
def count_by_sql(sql)
|
54
58
|
sql = sanitize_conditions(sql)
|
@@ -10,7 +10,7 @@ require "action_controller/railtie"
|
|
10
10
|
|
11
11
|
module ActiveRecord
|
12
12
|
# = Active Record Railtie
|
13
|
-
class Railtie < Rails::Railtie
|
13
|
+
class Railtie < Rails::Railtie # :nodoc:
|
14
14
|
config.active_record = ActiveSupport::OrderedOptions.new
|
15
15
|
|
16
16
|
config.app_generators.orm :active_record, :migration => true,
|
@@ -29,6 +29,11 @@ module ActiveRecord
|
|
29
29
|
'ActiveRecord::RecordNotSaved' => :unprocessable_entity
|
30
30
|
)
|
31
31
|
|
32
|
+
|
33
|
+
config.active_record.use_schema_cache_dump = true
|
34
|
+
|
35
|
+
config.eager_load_namespaces << ActiveRecord
|
36
|
+
|
32
37
|
rake_tasks do
|
33
38
|
require "active_record/base"
|
34
39
|
load "active_record/railties/databases.rake"
|
@@ -40,7 +45,8 @@ module ActiveRecord
|
|
40
45
|
console do |app|
|
41
46
|
require "active_record/railties/console_sandbox" if app.sandbox?
|
42
47
|
require "active_record/base"
|
43
|
-
|
48
|
+
console = ActiveSupport::Logger.new(STDERR)
|
49
|
+
Rails.logger.extend ActiveSupport::Logger.broadcast console
|
44
50
|
end
|
45
51
|
|
46
52
|
runner do |app|
|
@@ -58,16 +64,84 @@ module ActiveRecord
|
|
58
64
|
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
59
65
|
end
|
60
66
|
|
61
|
-
initializer "active_record.
|
62
|
-
config.
|
63
|
-
"
|
67
|
+
initializer "active_record.migration_error" do |app|
|
68
|
+
if config.active_record.delete(:migration_error) == :page_load
|
69
|
+
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
|
70
|
+
"ActiveRecord::Migration::CheckPending"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
initializer "active_record.check_schema_cache_dump" do
|
75
|
+
if config.active_record.delete(:use_schema_cache_dump)
|
76
|
+
config.after_initialize do |app|
|
77
|
+
ActiveSupport.on_load(:active_record) do
|
78
|
+
filename = File.join(app.config.paths["db"].first, "schema_cache.dump")
|
79
|
+
|
80
|
+
if File.file?(filename)
|
81
|
+
cache = Marshal.load File.binread filename
|
82
|
+
if cache.version == ActiveRecord::Migrator.current_version
|
83
|
+
self.connection.schema_cache = cache
|
84
|
+
else
|
85
|
+
warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
64
91
|
end
|
65
92
|
|
66
93
|
initializer "active_record.set_configs" do |app|
|
67
94
|
ActiveSupport.on_load(:active_record) do
|
68
|
-
|
69
|
-
|
95
|
+
begin
|
96
|
+
old_behavior, ActiveSupport::Deprecation.behavior = ActiveSupport::Deprecation.behavior, :stderr
|
97
|
+
whitelist_attributes = app.config.active_record.delete(:whitelist_attributes)
|
98
|
+
|
99
|
+
if respond_to?(:mass_assignment_sanitizer=)
|
100
|
+
mass_assignment_sanitizer = nil
|
101
|
+
else
|
102
|
+
mass_assignment_sanitizer = app.config.active_record.delete(:mass_assignment_sanitizer)
|
103
|
+
end
|
104
|
+
|
105
|
+
unless whitelist_attributes.nil? && mass_assignment_sanitizer.nil?
|
106
|
+
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
107
|
+
Model based mass assignment security has been extracted
|
108
|
+
out of Rails into a gem. Please use the new recommended protection model for
|
109
|
+
params or add `protected_attributes` to your Gemfile to use the old one.
|
110
|
+
|
111
|
+
To disable this message remove the `whitelist_attributes` option from your
|
112
|
+
`config/application.rb` file and any `mass_assignment_sanitizer` options
|
113
|
+
from your `config/environments/*.rb` files.
|
114
|
+
|
115
|
+
See http://guides.rubyonrails.org/security.html#mass-assignment for more information.
|
116
|
+
EOF
|
117
|
+
end
|
118
|
+
|
119
|
+
unless app.config.active_record.delete(:auto_explain_threshold_in_seconds).nil?
|
120
|
+
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
121
|
+
The Active Record auto explain feature has been removed.
|
122
|
+
|
123
|
+
To disable this message remove the `active_record.auto_explain_threshold_in_seconds`
|
124
|
+
option from the `config/environments/*.rb` config file.
|
125
|
+
|
126
|
+
See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
|
127
|
+
EOF
|
128
|
+
end
|
129
|
+
|
130
|
+
unless app.config.active_record.delete(:observers).nil?
|
131
|
+
ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
|
132
|
+
Active Record Observers has been extracted out of Rails into a gem.
|
133
|
+
Please use callbacks or add `rails-observers` to your Gemfile to use observers.
|
134
|
+
|
135
|
+
To disable this message remove the `observers` option from your
|
136
|
+
`config/application.rb` or from your initializers.
|
137
|
+
|
138
|
+
See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
|
139
|
+
EOF
|
140
|
+
end
|
141
|
+
ensure
|
142
|
+
ActiveSupport::Deprecation.behavior = old_behavior
|
70
143
|
end
|
144
|
+
|
71
145
|
app.config.active_record.each do |k,v|
|
72
146
|
send "#{k}=", v
|
73
147
|
end
|
@@ -78,13 +152,7 @@ module ActiveRecord
|
|
78
152
|
# and then establishes the connection.
|
79
153
|
initializer "active_record.initialize_database" do |app|
|
80
154
|
ActiveSupport.on_load(:active_record) do
|
81
|
-
|
82
|
-
unless ENV['DATABASE_URL']
|
83
|
-
db_connection_type = "database.yml"
|
84
|
-
self.configurations = app.config.database_configuration
|
85
|
-
end
|
86
|
-
Rails.logger.info "Connecting to database specified by #{db_connection_type}"
|
87
|
-
|
155
|
+
self.configurations = app.config.database_configuration
|
88
156
|
establish_connection
|
89
157
|
end
|
90
158
|
end
|
@@ -98,34 +166,21 @@ module ActiveRecord
|
|
98
166
|
end
|
99
167
|
|
100
168
|
initializer "active_record.set_reloader_hooks" do |app|
|
101
|
-
hook =
|
102
|
-
ActiveRecord::Base.clear_reloadable_connections!
|
103
|
-
ActiveRecord::Base.clear_cache!
|
104
|
-
end
|
169
|
+
hook = app.config.reload_classes_only_on_change ? :to_prepare : :to_cleanup
|
105
170
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
ActionDispatch::Reloader.to_cleanup(&hook)
|
171
|
+
ActiveSupport.on_load(:active_record) do
|
172
|
+
ActionDispatch::Reloader.send(hook) do
|
173
|
+
if ActiveRecord::Base.connected?
|
174
|
+
ActiveRecord::Base.clear_reloadable_connections!
|
175
|
+
ActiveRecord::Base.clear_cache!
|
176
|
+
end
|
113
177
|
end
|
114
178
|
end
|
115
179
|
end
|
116
180
|
|
117
181
|
initializer "active_record.add_watchable_files" do |app|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
config.after_initialize do
|
122
|
-
ActiveSupport.on_load(:active_record) do
|
123
|
-
instantiate_observers
|
124
|
-
|
125
|
-
ActionDispatch::Reloader.to_prepare do
|
126
|
-
ActiveRecord::Base.instantiate_observers
|
127
|
-
end
|
128
|
-
end
|
182
|
+
path = app.paths["db"].first
|
183
|
+
config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
|
129
184
|
end
|
130
185
|
end
|
131
186
|
end
|
@@ -2,7 +2,7 @@ require 'active_support/core_ext/module/attr_internal'
|
|
2
2
|
require 'active_record/log_subscriber'
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
|
-
module Railties
|
5
|
+
module Railties # :nodoc:
|
6
6
|
module ControllerRuntime #:nodoc:
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
@@ -37,7 +37,7 @@ module ActiveRecord
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
module ClassMethods
|
40
|
+
module ClassMethods # :nodoc:
|
41
41
|
def log_process_action(payload)
|
42
42
|
messages, db_runtime = super, payload[:db_runtime]
|
43
43
|
messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
|
@@ -1,26 +1,6 @@
|
|
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
5
|
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
|
26
6
|
ActiveRecord::Migrator.migrations_paths = Rails.application.paths['db/migrate'].to_a
|
@@ -33,161 +13,36 @@ db_namespace = namespace :db do
|
|
33
13
|
end
|
34
14
|
|
35
15
|
namespace :create do
|
36
|
-
# desc 'Create all the local databases defined in config/database.yml'
|
37
16
|
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
|
17
|
+
ActiveRecord::Tasks::DatabaseTasks.create_all
|
54
18
|
end
|
55
19
|
end
|
56
20
|
|
57
21
|
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
|
22
|
+
task :create => [:load_config] do
|
59
23
|
if ENV['DATABASE_URL']
|
60
|
-
|
24
|
+
ActiveRecord::Tasks::DatabaseTasks.create_database_url
|
61
25
|
else
|
62
|
-
|
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
|
151
|
-
else
|
152
|
-
# Bug with 1.9.2 Calling return within begin still executes else
|
153
|
-
$stderr.puts "#{config['database']} already exists" unless config['adapter'] =~ /sqlite/
|
26
|
+
ActiveRecord::Tasks::DatabaseTasks.create_current
|
154
27
|
end
|
155
28
|
end
|
156
29
|
|
157
30
|
namespace :drop do
|
158
|
-
# desc 'Drops all the local databases defined in config/database.yml'
|
159
31
|
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
|
32
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_all
|
170
33
|
end
|
171
34
|
end
|
172
35
|
|
173
36
|
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
|
37
|
+
task :drop => [:load_config] do
|
175
38
|
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
|
39
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_database_url
|
185
40
|
else
|
186
|
-
|
41
|
+
ActiveRecord::Tasks::DatabaseTasks.drop_current
|
187
42
|
end
|
188
43
|
end
|
189
44
|
|
190
|
-
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
|
45
|
+
desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
|
191
46
|
task :migrate => [:environment, :load_config] do
|
192
47
|
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
193
48
|
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
|
@@ -246,11 +101,12 @@ db_namespace = namespace :db do
|
|
246
101
|
next # means "return" for rake task
|
247
102
|
end
|
248
103
|
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
104
|
+
db_list.map! { |version| "%.3d" % version }
|
249
105
|
file_list = []
|
250
106
|
ActiveRecord::Migrator.migrations_paths.each do |path|
|
251
107
|
Dir.foreach(path) do |file|
|
252
|
-
#
|
253
|
-
if match_data = /^(\d{
|
108
|
+
# match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
|
109
|
+
if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
|
254
110
|
status = db_list.delete(match_data[1]) ? 'up' : 'down'
|
255
111
|
file_list << [status, match_data[1], match_data[2].humanize]
|
256
112
|
end
|
@@ -292,31 +148,15 @@ db_namespace = namespace :db do
|
|
292
148
|
|
293
149
|
# desc "Retrieves the charset for the current environment's database"
|
294
150
|
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
|
151
|
+
puts ActiveRecord::Tasks::DatabaseTasks.charset_current
|
309
152
|
end
|
310
153
|
|
311
154
|
# desc "Retrieves the collation for the current environment's database"
|
312
155
|
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'
|
156
|
+
begin
|
157
|
+
puts ActiveRecord::Tasks::DatabaseTasks.collation_current
|
158
|
+
rescue NoMethodError
|
159
|
+
$stderr.puts 'Sorry, your database adapter is not supported yet, feel free to submit a patch'
|
320
160
|
end
|
321
161
|
end
|
322
162
|
|
@@ -327,7 +167,7 @@ db_namespace = namespace :db do
|
|
327
167
|
|
328
168
|
# desc "Raises an error if there are pending migrations"
|
329
169
|
task :abort_if_pending_migrations => [:environment, :load_config] do
|
330
|
-
pending_migrations = ActiveRecord::Migrator.
|
170
|
+
pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations
|
331
171
|
|
332
172
|
if pending_migrations.any?
|
333
173
|
puts "You have #{pending_migrations.size} pending migrations:"
|
@@ -356,7 +196,7 @@ db_namespace = namespace :db do
|
|
356
196
|
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
|
357
197
|
|
358
198
|
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
|
359
|
-
ActiveRecord::
|
199
|
+
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
|
360
200
|
end
|
361
201
|
end
|
362
202
|
|
@@ -367,13 +207,13 @@ db_namespace = namespace :db do
|
|
367
207
|
label, id = ENV['LABEL'], ENV['ID']
|
368
208
|
raise 'LABEL or ID required' if label.blank? && id.blank?
|
369
209
|
|
370
|
-
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::
|
210
|
+
puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
|
371
211
|
|
372
212
|
base_dir = ENV['FIXTURES_PATH'] ? File.join(Rails.root, ENV['FIXTURES_PATH']) : File.join(Rails.root, 'test', 'fixtures')
|
373
213
|
Dir["#{base_dir}/**/*.yml"].each do |file|
|
374
214
|
if data = YAML::load(ERB.new(IO.read(file)).result)
|
375
215
|
data.keys.each do |key|
|
376
|
-
key_id = ActiveRecord::
|
216
|
+
key_id = ActiveRecord::FixtureSet.identify(key)
|
377
217
|
|
378
218
|
if key == label || key_id == id.to_i
|
379
219
|
puts "#{file}: #{key} (#{key_id})"
|
@@ -408,75 +248,81 @@ db_namespace = namespace :db do
|
|
408
248
|
task :load_if_ruby => ['db:create', :environment] do
|
409
249
|
db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
|
410
250
|
end
|
251
|
+
|
252
|
+
namespace :cache do
|
253
|
+
desc 'Create a db/schema_cache.dump file.'
|
254
|
+
task :dump => [:environment, :load_config] do
|
255
|
+
con = ActiveRecord::Base.connection
|
256
|
+
filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.dump")
|
257
|
+
|
258
|
+
con.schema_cache.clear!
|
259
|
+
con.tables.each { |table| con.schema_cache.add(table) }
|
260
|
+
open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) }
|
261
|
+
end
|
262
|
+
|
263
|
+
desc 'Clear a db/schema_cache.dump file.'
|
264
|
+
task :clear => [:environment, :load_config] do
|
265
|
+
filename = File.join(Rails.application.config.paths["db"].first, "schema_cache.dump")
|
266
|
+
FileUtils.rm(filename) if File.exists?(filename)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
411
270
|
end
|
412
271
|
|
413
272
|
namespace :structure do
|
273
|
+
def set_firebird_env(config)
|
274
|
+
ENV['ISC_USER'] = config['username'].to_s if config['username']
|
275
|
+
ENV['ISC_PASSWORD'] = config['password'].to_s if config['password']
|
276
|
+
end
|
277
|
+
|
278
|
+
def firebird_db_string(config)
|
279
|
+
FireRuby::Database.db_string_for(config.symbolize_keys)
|
280
|
+
end
|
281
|
+
|
414
282
|
desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
|
415
283
|
task :dump => [:environment, :load_config] do
|
416
|
-
config = current_config
|
417
284
|
filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
|
418
|
-
|
419
|
-
|
420
|
-
|
285
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
286
|
+
case current_config['adapter']
|
287
|
+
when 'oci', 'oracle'
|
288
|
+
ActiveRecord::Base.establish_connection(current_config)
|
421
289
|
File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump }
|
422
|
-
when /postgresql/
|
423
|
-
set_psql_env(config)
|
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(" ")
|
427
|
-
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
290
|
when 'sqlserver'
|
435
|
-
`smoscript -s #{
|
291
|
+
`smoscript -s #{current_config['host']} -d #{current_config['database']} -u #{current_config['username']} -p #{current_config['password']} -f #{filename} -A -U`
|
436
292
|
when "firebird"
|
437
|
-
set_firebird_env(
|
438
|
-
db_string = firebird_db_string(
|
293
|
+
set_firebird_env(current_config)
|
294
|
+
db_string = firebird_db_string(current_config)
|
439
295
|
sh "isql -a #{db_string} > #{filename}"
|
440
296
|
else
|
441
|
-
|
297
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
|
442
298
|
end
|
443
299
|
|
444
300
|
if ActiveRecord::Base.connection.supports_migrations?
|
445
|
-
File.open(filename, "a")
|
301
|
+
File.open(filename, "a") do |f|
|
302
|
+
f.puts ActiveRecord::Base.connection.dump_schema_information
|
303
|
+
end
|
446
304
|
end
|
447
305
|
db_namespace['structure:dump'].reenable
|
448
306
|
end
|
449
307
|
|
450
308
|
# desc "Recreate the databases from the structure.sql file"
|
451
309
|
task :load => [:environment, :load_config] do
|
452
|
-
|
310
|
+
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
453
311
|
filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
|
454
|
-
case
|
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}"`
|
312
|
+
case current_config['adapter']
|
467
313
|
when 'sqlserver'
|
468
|
-
`sqlcmd -S #{
|
314
|
+
`sqlcmd -S #{current_config['host']} -d #{current_config['database']} -U #{current_config['username']} -P #{current_config['password']} -i #{filename}`
|
469
315
|
when 'oci', 'oracle'
|
470
|
-
ActiveRecord::Base.establish_connection(
|
316
|
+
ActiveRecord::Base.establish_connection(current_config)
|
471
317
|
IO.read(filename).split(";\n\n").each do |ddl|
|
472
318
|
ActiveRecord::Base.connection.execute(ddl)
|
473
319
|
end
|
474
320
|
when 'firebird'
|
475
|
-
set_firebird_env(
|
476
|
-
db_string = firebird_db_string(
|
321
|
+
set_firebird_env(current_config)
|
322
|
+
db_string = firebird_db_string(current_config)
|
477
323
|
sh "isql -i #{filename} #{db_string}"
|
478
324
|
else
|
479
|
-
|
325
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
|
480
326
|
end
|
481
327
|
end
|
482
328
|
|
@@ -497,25 +343,35 @@ db_namespace = namespace :db do
|
|
497
343
|
end
|
498
344
|
end
|
499
345
|
|
346
|
+
# desc "Recreate the test database from an existent schema.rb file"
|
347
|
+
task :load_schema => 'db:test:purge' do
|
348
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
|
349
|
+
ActiveRecord::Schema.verbose = false
|
350
|
+
db_namespace["schema:load"].invoke
|
351
|
+
end
|
352
|
+
|
500
353
|
# desc "Recreate the test database from an existent structure.sql file"
|
501
354
|
task :load_structure => 'db:test:purge' do
|
502
355
|
begin
|
503
|
-
current_config(:config => ActiveRecord::Base.configurations['test'])
|
356
|
+
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
|
504
357
|
db_namespace["structure:load"].invoke
|
505
358
|
ensure
|
506
|
-
current_config(:config => nil)
|
359
|
+
ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
|
507
360
|
end
|
508
361
|
end
|
509
362
|
|
510
|
-
# desc "Recreate the test database from
|
511
|
-
task :
|
512
|
-
ActiveRecord::Base.
|
513
|
-
|
514
|
-
|
363
|
+
# desc "Recreate the test database from a fresh schema"
|
364
|
+
task :clone do
|
365
|
+
case ActiveRecord::Base.schema_format
|
366
|
+
when :ruby
|
367
|
+
db_namespace["test:clone_schema"].invoke
|
368
|
+
when :sql
|
369
|
+
db_namespace["test:clone_structure"].invoke
|
370
|
+
end
|
515
371
|
end
|
516
372
|
|
517
373
|
# desc "Recreate the test database from a fresh schema.rb file"
|
518
|
-
task :
|
374
|
+
task :clone_schema => ["db:schema:dump", "db:test:load_schema"]
|
519
375
|
|
520
376
|
# desc "Recreate the test database from a fresh structure.sql file"
|
521
377
|
task :clone_structure => [ "db:structure:dump", "db:test:load_structure" ]
|
@@ -524,16 +380,6 @@ db_namespace = namespace :db do
|
|
524
380
|
task :purge => [:environment, :load_config] do
|
525
381
|
abcs = ActiveRecord::Base.configurations
|
526
382
|
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
383
|
when 'sqlserver'
|
538
384
|
test = abcs.deep_dup['test']
|
539
385
|
test_database = test['database']
|
@@ -549,41 +395,26 @@ db_namespace = namespace :db do
|
|
549
395
|
ActiveRecord::Base.establish_connection(:test)
|
550
396
|
ActiveRecord::Base.connection.recreate_database!
|
551
397
|
else
|
552
|
-
|
398
|
+
ActiveRecord::Tasks::DatabaseTasks.purge abcs['test']
|
553
399
|
end
|
554
400
|
end
|
555
401
|
|
556
402
|
# desc 'Check for pending migrations and load the test schema'
|
557
403
|
task :prepare => 'db:abort_if_pending_migrations' do
|
558
404
|
unless ActiveRecord::Base.configurations.blank?
|
559
|
-
db_namespace[
|
405
|
+
db_namespace['test:load'].invoke
|
560
406
|
end
|
561
407
|
end
|
562
408
|
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
409
|
end
|
579
410
|
|
580
411
|
namespace :railties do
|
581
412
|
namespace :install do
|
582
|
-
# desc "Copies missing migrations from Railties (e.g.
|
413
|
+
# desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
|
583
414
|
task :migrations => :'db:load_config' do
|
584
415
|
to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip }
|
585
|
-
railties =
|
586
|
-
Rails.application.railties.
|
416
|
+
railties = {}
|
417
|
+
Rails.application.railties.each do |railtie|
|
587
418
|
next unless to_load == :all || to_load.include?(railtie.railtie_name)
|
588
419
|
|
589
420
|
if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first)
|
@@ -607,53 +438,3 @@ end
|
|
607
438
|
|
608
439
|
task 'test:prepare' => 'db:test:prepare'
|
609
440
|
|
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
|