activerecord 1.0.0 → 4.0.0

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.

Files changed (255) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2102 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +213 -0
  5. data/examples/performance.rb +172 -0
  6. data/examples/simple.rb +14 -0
  7. data/lib/active_record/aggregations.rb +180 -84
  8. data/lib/active_record/associations/alias_tracker.rb +76 -0
  9. data/lib/active_record/associations/association.rb +248 -0
  10. data/lib/active_record/associations/association_scope.rb +135 -0
  11. data/lib/active_record/associations/belongs_to_association.rb +92 -0
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +35 -0
  13. data/lib/active_record/associations/builder/association.rb +108 -0
  14. data/lib/active_record/associations/builder/belongs_to.rb +98 -0
  15. data/lib/active_record/associations/builder/collection_association.rb +89 -0
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +39 -0
  17. data/lib/active_record/associations/builder/has_many.rb +15 -0
  18. data/lib/active_record/associations/builder/has_one.rb +25 -0
  19. data/lib/active_record/associations/builder/singular_association.rb +32 -0
  20. data/lib/active_record/associations/collection_association.rb +608 -0
  21. data/lib/active_record/associations/collection_proxy.rb +986 -0
  22. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +58 -39
  23. data/lib/active_record/associations/has_many_association.rb +116 -85
  24. data/lib/active_record/associations/has_many_through_association.rb +197 -0
  25. data/lib/active_record/associations/has_one_association.rb +102 -0
  26. data/lib/active_record/associations/has_one_through_association.rb +36 -0
  27. data/lib/active_record/associations/join_dependency/join_association.rb +174 -0
  28. data/lib/active_record/associations/join_dependency/join_base.rb +24 -0
  29. data/lib/active_record/associations/join_dependency/join_part.rb +78 -0
  30. data/lib/active_record/associations/join_dependency.rb +235 -0
  31. data/lib/active_record/associations/join_helper.rb +45 -0
  32. data/lib/active_record/associations/preloader/association.rb +121 -0
  33. data/lib/active_record/associations/preloader/belongs_to.rb +17 -0
  34. data/lib/active_record/associations/preloader/collection_association.rb +24 -0
  35. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +60 -0
  36. data/lib/active_record/associations/preloader/has_many.rb +17 -0
  37. data/lib/active_record/associations/preloader/has_many_through.rb +19 -0
  38. data/lib/active_record/associations/preloader/has_one.rb +23 -0
  39. data/lib/active_record/associations/preloader/has_one_through.rb +9 -0
  40. data/lib/active_record/associations/preloader/singular_association.rb +21 -0
  41. data/lib/active_record/associations/preloader/through_association.rb +63 -0
  42. data/lib/active_record/associations/preloader.rb +178 -0
  43. data/lib/active_record/associations/singular_association.rb +64 -0
  44. data/lib/active_record/associations/through_association.rb +87 -0
  45. data/lib/active_record/associations.rb +1437 -431
  46. data/lib/active_record/attribute_assignment.rb +201 -0
  47. data/lib/active_record/attribute_methods/before_type_cast.rb +70 -0
  48. data/lib/active_record/attribute_methods/dirty.rb +118 -0
  49. data/lib/active_record/attribute_methods/primary_key.rb +122 -0
  50. data/lib/active_record/attribute_methods/query.rb +40 -0
  51. data/lib/active_record/attribute_methods/read.rb +107 -0
  52. data/lib/active_record/attribute_methods/serialization.rb +162 -0
  53. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -0
  54. data/lib/active_record/attribute_methods/write.rb +63 -0
  55. data/lib/active_record/attribute_methods.rb +393 -0
  56. data/lib/active_record/autosave_association.rb +426 -0
  57. data/lib/active_record/base.rb +268 -930
  58. data/lib/active_record/callbacks.rb +203 -230
  59. data/lib/active_record/coders/yaml_column.rb +38 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +638 -0
  61. data/lib/active_record/connection_adapters/abstract/database_limits.rb +67 -0
  62. data/lib/active_record/connection_adapters/abstract/database_statements.rb +390 -0
  63. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -0
  64. data/lib/active_record/connection_adapters/abstract/quoting.rb +129 -0
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +501 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +70 -0
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +873 -0
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +203 -0
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +389 -275
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +782 -0
  71. data/lib/active_record/connection_adapters/column.rb +318 -0
  72. data/lib/active_record/connection_adapters/connection_specification.rb +96 -0
  73. data/lib/active_record/connection_adapters/mysql2_adapter.rb +273 -0
  74. data/lib/active_record/connection_adapters/mysql_adapter.rb +517 -90
  75. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +97 -0
  76. data/lib/active_record/connection_adapters/postgresql/cast.rb +152 -0
  77. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +242 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid.rb +366 -0
  79. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -0
  80. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -0
  81. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +489 -0
  82. data/lib/active_record/connection_adapters/postgresql_adapter.rb +911 -138
  83. data/lib/active_record/connection_adapters/schema_cache.rb +129 -0
  84. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +624 -0
  85. data/lib/active_record/connection_adapters/statement_pool.rb +40 -0
  86. data/lib/active_record/connection_handling.rb +98 -0
  87. data/lib/active_record/core.rb +463 -0
  88. data/lib/active_record/counter_cache.rb +122 -0
  89. data/lib/active_record/dynamic_matchers.rb +131 -0
  90. data/lib/active_record/errors.rb +213 -0
  91. data/lib/active_record/explain.rb +38 -0
  92. data/lib/active_record/explain_registry.rb +30 -0
  93. data/lib/active_record/explain_subscriber.rb +29 -0
  94. data/lib/active_record/fixture_set/file.rb +55 -0
  95. data/lib/active_record/fixtures.rb +892 -138
  96. data/lib/active_record/inheritance.rb +200 -0
  97. data/lib/active_record/integration.rb +60 -0
  98. data/lib/active_record/locale/en.yml +47 -0
  99. data/lib/active_record/locking/optimistic.rb +181 -0
  100. data/lib/active_record/locking/pessimistic.rb +77 -0
  101. data/lib/active_record/log_subscriber.rb +82 -0
  102. data/lib/active_record/migration/command_recorder.rb +164 -0
  103. data/lib/active_record/migration/join_table.rb +15 -0
  104. data/lib/active_record/migration.rb +1015 -0
  105. data/lib/active_record/model_schema.rb +345 -0
  106. data/lib/active_record/nested_attributes.rb +546 -0
  107. data/lib/active_record/null_relation.rb +65 -0
  108. data/lib/active_record/persistence.rb +509 -0
  109. data/lib/active_record/query_cache.rb +56 -0
  110. data/lib/active_record/querying.rb +62 -0
  111. data/lib/active_record/railtie.rb +205 -0
  112. data/lib/active_record/railties/console_sandbox.rb +5 -0
  113. data/lib/active_record/railties/controller_runtime.rb +50 -0
  114. data/lib/active_record/railties/databases.rake +402 -0
  115. data/lib/active_record/railties/jdbcmysql_error.rb +16 -0
  116. data/lib/active_record/readonly_attributes.rb +30 -0
  117. data/lib/active_record/reflection.rb +544 -87
  118. data/lib/active_record/relation/batches.rb +93 -0
  119. data/lib/active_record/relation/calculations.rb +399 -0
  120. data/lib/active_record/relation/delegation.rb +125 -0
  121. data/lib/active_record/relation/finder_methods.rb +349 -0
  122. data/lib/active_record/relation/merger.rb +161 -0
  123. data/lib/active_record/relation/predicate_builder.rb +106 -0
  124. data/lib/active_record/relation/query_methods.rb +1044 -0
  125. data/lib/active_record/relation/spawn_methods.rb +73 -0
  126. data/lib/active_record/relation.rb +655 -0
  127. data/lib/active_record/result.rb +67 -0
  128. data/lib/active_record/runtime_registry.rb +17 -0
  129. data/lib/active_record/sanitization.rb +168 -0
  130. data/lib/active_record/schema.rb +65 -0
  131. data/lib/active_record/schema_dumper.rb +204 -0
  132. data/lib/active_record/schema_migration.rb +39 -0
  133. data/lib/active_record/scoping/default.rb +146 -0
  134. data/lib/active_record/scoping/named.rb +175 -0
  135. data/lib/active_record/scoping.rb +82 -0
  136. data/lib/active_record/serialization.rb +22 -0
  137. data/lib/active_record/serializers/xml_serializer.rb +197 -0
  138. data/lib/active_record/statement_cache.rb +26 -0
  139. data/lib/active_record/store.rb +156 -0
  140. data/lib/active_record/tasks/database_tasks.rb +203 -0
  141. data/lib/active_record/tasks/firebird_database_tasks.rb +56 -0
  142. data/lib/active_record/tasks/mysql_database_tasks.rb +143 -0
  143. data/lib/active_record/tasks/oracle_database_tasks.rb +45 -0
  144. data/lib/active_record/tasks/postgresql_database_tasks.rb +90 -0
  145. data/lib/active_record/tasks/sqlite_database_tasks.rb +51 -0
  146. data/lib/active_record/tasks/sqlserver_database_tasks.rb +48 -0
  147. data/lib/active_record/test_case.rb +96 -0
  148. data/lib/active_record/timestamp.rb +119 -0
  149. data/lib/active_record/transactions.rb +366 -69
  150. data/lib/active_record/translation.rb +22 -0
  151. data/lib/active_record/validations/associated.rb +49 -0
  152. data/lib/active_record/validations/presence.rb +65 -0
  153. data/lib/active_record/validations/uniqueness.rb +225 -0
  154. data/lib/active_record/validations.rb +64 -185
  155. data/lib/active_record/version.rb +11 -0
  156. data/lib/active_record.rb +149 -24
  157. data/lib/rails/generators/active_record/migration/migration_generator.rb +62 -0
  158. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +19 -0
  159. data/lib/rails/generators/active_record/migration/templates/migration.rb +39 -0
  160. data/lib/rails/generators/active_record/model/model_generator.rb +48 -0
  161. data/lib/rails/generators/active_record/model/templates/model.rb +10 -0
  162. data/lib/rails/generators/active_record/model/templates/module.rb +7 -0
  163. data/lib/rails/generators/active_record.rb +23 -0
  164. metadata +261 -161
  165. data/CHANGELOG +0 -581
  166. data/README +0 -361
  167. data/RUNNING_UNIT_TESTS +0 -36
  168. data/dev-utils/eval_debugger.rb +0 -9
  169. data/examples/associations.png +0 -0
  170. data/examples/associations.rb +0 -87
  171. data/examples/shared_setup.rb +0 -15
  172. data/examples/validation.rb +0 -88
  173. data/install.rb +0 -60
  174. data/lib/active_record/associations/association_collection.rb +0 -70
  175. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -107
  176. data/lib/active_record/deprecated_associations.rb +0 -70
  177. data/lib/active_record/observer.rb +0 -71
  178. data/lib/active_record/support/class_attribute_accessors.rb +0 -43
  179. data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
  180. data/lib/active_record/support/clean_logger.rb +0 -10
  181. data/lib/active_record/support/inflector.rb +0 -70
  182. data/lib/active_record/vendor/mysql.rb +0 -1117
  183. data/lib/active_record/vendor/simple.rb +0 -702
  184. data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
  185. data/lib/active_record/wrappings.rb +0 -59
  186. data/rakefile +0 -122
  187. data/test/abstract_unit.rb +0 -16
  188. data/test/aggregations_test.rb +0 -34
  189. data/test/all.sh +0 -8
  190. data/test/associations_test.rb +0 -477
  191. data/test/base_test.rb +0 -513
  192. data/test/class_inheritable_attributes_test.rb +0 -33
  193. data/test/connections/native_mysql/connection.rb +0 -24
  194. data/test/connections/native_postgresql/connection.rb +0 -24
  195. data/test/connections/native_sqlite/connection.rb +0 -24
  196. data/test/deprecated_associations_test.rb +0 -336
  197. data/test/finder_test.rb +0 -67
  198. data/test/fixtures/accounts/signals37 +0 -3
  199. data/test/fixtures/accounts/unknown +0 -2
  200. data/test/fixtures/auto_id.rb +0 -4
  201. data/test/fixtures/column_name.rb +0 -3
  202. data/test/fixtures/companies/first_client +0 -6
  203. data/test/fixtures/companies/first_firm +0 -4
  204. data/test/fixtures/companies/second_client +0 -6
  205. data/test/fixtures/company.rb +0 -37
  206. data/test/fixtures/company_in_module.rb +0 -33
  207. data/test/fixtures/course.rb +0 -3
  208. data/test/fixtures/courses/java +0 -2
  209. data/test/fixtures/courses/ruby +0 -2
  210. data/test/fixtures/customer.rb +0 -30
  211. data/test/fixtures/customers/david +0 -6
  212. data/test/fixtures/db_definitions/mysql.sql +0 -96
  213. data/test/fixtures/db_definitions/mysql2.sql +0 -4
  214. data/test/fixtures/db_definitions/postgresql.sql +0 -113
  215. data/test/fixtures/db_definitions/postgresql2.sql +0 -4
  216. data/test/fixtures/db_definitions/sqlite.sql +0 -85
  217. data/test/fixtures/db_definitions/sqlite2.sql +0 -4
  218. data/test/fixtures/default.rb +0 -2
  219. data/test/fixtures/developer.rb +0 -8
  220. data/test/fixtures/developers/david +0 -2
  221. data/test/fixtures/developers/jamis +0 -2
  222. data/test/fixtures/developers_projects/david_action_controller +0 -2
  223. data/test/fixtures/developers_projects/david_active_record +0 -2
  224. data/test/fixtures/developers_projects/jamis_active_record +0 -2
  225. data/test/fixtures/entrant.rb +0 -3
  226. data/test/fixtures/entrants/first +0 -3
  227. data/test/fixtures/entrants/second +0 -3
  228. data/test/fixtures/entrants/third +0 -3
  229. data/test/fixtures/fixture_database.sqlite +0 -0
  230. data/test/fixtures/fixture_database_2.sqlite +0 -0
  231. data/test/fixtures/movie.rb +0 -5
  232. data/test/fixtures/movies/first +0 -2
  233. data/test/fixtures/movies/second +0 -2
  234. data/test/fixtures/project.rb +0 -3
  235. data/test/fixtures/projects/action_controller +0 -2
  236. data/test/fixtures/projects/active_record +0 -2
  237. data/test/fixtures/reply.rb +0 -21
  238. data/test/fixtures/subscriber.rb +0 -5
  239. data/test/fixtures/subscribers/first +0 -2
  240. data/test/fixtures/subscribers/second +0 -2
  241. data/test/fixtures/topic.rb +0 -20
  242. data/test/fixtures/topics/first +0 -9
  243. data/test/fixtures/topics/second +0 -8
  244. data/test/fixtures_test.rb +0 -20
  245. data/test/inflector_test.rb +0 -104
  246. data/test/inheritance_test.rb +0 -125
  247. data/test/lifecycle_test.rb +0 -110
  248. data/test/modules_test.rb +0 -21
  249. data/test/multiple_db_test.rb +0 -46
  250. data/test/pk_test.rb +0 -57
  251. data/test/reflection_test.rb +0 -78
  252. data/test/thread_safety_test.rb +0 -33
  253. data/test/transactions_test.rb +0 -83
  254. data/test/unconnected_test.rb +0 -24
  255. data/test/validations_test.rb +0 -126
@@ -0,0 +1,205 @@
1
+ require "active_record"
2
+ require "rails"
3
+ require "active_model/railtie"
4
+
5
+ # For now, action_controller must always be present with
6
+ # rails, so let's make sure that it gets required before
7
+ # here. This is needed for correctly setting up the middleware.
8
+ # In the future, this might become an optional require.
9
+ require "action_controller/railtie"
10
+
11
+ module ActiveRecord
12
+ # = Active Record Railtie
13
+ class Railtie < Rails::Railtie # :nodoc:
14
+ config.active_record = ActiveSupport::OrderedOptions.new
15
+
16
+ config.app_generators.orm :active_record, :migration => true,
17
+ :timestamps => true
18
+
19
+ config.app_middleware.insert_after "::ActionDispatch::Callbacks",
20
+ "ActiveRecord::QueryCache"
21
+
22
+ config.app_middleware.insert_after "::ActionDispatch::Callbacks",
23
+ "ActiveRecord::ConnectionAdapters::ConnectionManagement"
24
+
25
+ config.action_dispatch.rescue_responses.merge!(
26
+ 'ActiveRecord::RecordNotFound' => :not_found,
27
+ 'ActiveRecord::StaleObjectError' => :conflict,
28
+ 'ActiveRecord::RecordInvalid' => :unprocessable_entity,
29
+ 'ActiveRecord::RecordNotSaved' => :unprocessable_entity
30
+ )
31
+
32
+
33
+ config.active_record.use_schema_cache_dump = true
34
+
35
+ config.eager_load_namespaces << ActiveRecord
36
+
37
+ rake_tasks do
38
+ require "active_record/base"
39
+
40
+ ActiveRecord::Tasks::DatabaseTasks.seed_loader = Rails.application
41
+ ActiveRecord::Tasks::DatabaseTasks.env = Rails.env
42
+
43
+ namespace :db do
44
+ task :load_config do
45
+ ActiveRecord::Tasks::DatabaseTasks.db_dir = Rails.application.config.paths["db"].first
46
+ ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
47
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths = Rails.application.paths['db/migrate'].to_a
48
+ ActiveRecord::Tasks::DatabaseTasks.fixtures_path = File.join Rails.root, 'test', 'fixtures'
49
+
50
+ if defined?(ENGINE_PATH) && engine = Rails::Engine.find(ENGINE_PATH)
51
+ if engine.paths['db/migrate'].existent
52
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths['db/migrate'].to_a
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ load "active_record/railties/databases.rake"
59
+ end
60
+
61
+ # When loading console, force ActiveRecord::Base to be loaded
62
+ # to avoid cross references when loading a constant for the
63
+ # first time. Also, make it output to STDERR.
64
+ console do |app|
65
+ require "active_record/railties/console_sandbox" if app.sandbox?
66
+ require "active_record/base"
67
+ console = ActiveSupport::Logger.new(STDERR)
68
+ Rails.logger.extend ActiveSupport::Logger.broadcast console
69
+ end
70
+
71
+ runner do
72
+ require "active_record/base"
73
+ end
74
+
75
+ initializer "active_record.initialize_timezone" do
76
+ ActiveSupport.on_load(:active_record) do
77
+ self.time_zone_aware_attributes = true
78
+ self.default_timezone = :utc
79
+ end
80
+ end
81
+
82
+ initializer "active_record.logger" do
83
+ ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
84
+ end
85
+
86
+ initializer "active_record.migration_error" do
87
+ if config.active_record.delete(:migration_error) == :page_load
88
+ config.app_middleware.insert_after "::ActionDispatch::Callbacks",
89
+ "ActiveRecord::Migration::CheckPending"
90
+ end
91
+ end
92
+
93
+ initializer "active_record.check_schema_cache_dump" do
94
+ if config.active_record.delete(:use_schema_cache_dump)
95
+ config.after_initialize do |app|
96
+ ActiveSupport.on_load(:active_record) do
97
+ filename = File.join(app.config.paths["db"].first, "schema_cache.dump")
98
+
99
+ if File.file?(filename)
100
+ cache = Marshal.load File.binread filename
101
+ if cache.version == ActiveRecord::Migrator.current_version
102
+ self.connection.schema_cache = cache
103
+ else
104
+ 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}."
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ initializer "active_record.set_configs" do |app|
113
+ ActiveSupport.on_load(:active_record) do
114
+ begin
115
+ old_behavior, ActiveSupport::Deprecation.behavior = ActiveSupport::Deprecation.behavior, :stderr
116
+ whitelist_attributes = app.config.active_record.delete(:whitelist_attributes)
117
+
118
+ if respond_to?(:mass_assignment_sanitizer=)
119
+ mass_assignment_sanitizer = nil
120
+ else
121
+ mass_assignment_sanitizer = app.config.active_record.delete(:mass_assignment_sanitizer)
122
+ end
123
+
124
+ unless whitelist_attributes.nil? && mass_assignment_sanitizer.nil?
125
+ ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
126
+ Model based mass assignment security has been extracted
127
+ out of Rails into a gem. Please use the new recommended protection model for
128
+ params or add `protected_attributes` to your Gemfile to use the old one.
129
+
130
+ To disable this message remove the `whitelist_attributes` option from your
131
+ `config/application.rb` file and any `mass_assignment_sanitizer` options
132
+ from your `config/environments/*.rb` files.
133
+
134
+ See http://guides.rubyonrails.org/security.html#mass-assignment for more information.
135
+ EOF
136
+ end
137
+
138
+ unless app.config.active_record.delete(:auto_explain_threshold_in_seconds).nil?
139
+ ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
140
+ The Active Record auto explain feature has been removed.
141
+
142
+ To disable this message remove the `active_record.auto_explain_threshold_in_seconds`
143
+ option from the `config/environments/*.rb` config file.
144
+
145
+ See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
146
+ EOF
147
+ end
148
+
149
+ unless app.config.active_record.delete(:observers).nil?
150
+ ActiveSupport::Deprecation.warn <<-EOF.strip_heredoc, []
151
+ Active Record Observers has been extracted out of Rails into a gem.
152
+ Please use callbacks or add `rails-observers` to your Gemfile to use observers.
153
+
154
+ To disable this message remove the `observers` option from your
155
+ `config/application.rb` or from your initializers.
156
+
157
+ See http://guides.rubyonrails.org/4_0_release_notes.html for more information.
158
+ EOF
159
+ end
160
+ ensure
161
+ ActiveSupport::Deprecation.behavior = old_behavior
162
+ end
163
+
164
+ app.config.active_record.each do |k,v|
165
+ send "#{k}=", v
166
+ end
167
+ end
168
+ end
169
+
170
+ # This sets the database configuration from Configuration#database_configuration
171
+ # and then establishes the connection.
172
+ initializer "active_record.initialize_database" do |app|
173
+ ActiveSupport.on_load(:active_record) do
174
+ self.configurations = app.config.database_configuration || {}
175
+ establish_connection
176
+ end
177
+ end
178
+
179
+ # Expose database runtime to controller for logging.
180
+ initializer "active_record.log_runtime" do
181
+ require "active_record/railties/controller_runtime"
182
+ ActiveSupport.on_load(:action_controller) do
183
+ include ActiveRecord::Railties::ControllerRuntime
184
+ end
185
+ end
186
+
187
+ initializer "active_record.set_reloader_hooks" do |app|
188
+ hook = app.config.reload_classes_only_on_change ? :to_prepare : :to_cleanup
189
+
190
+ ActiveSupport.on_load(:active_record) do
191
+ ActionDispatch::Reloader.send(hook) do
192
+ if ActiveRecord::Base.connected?
193
+ ActiveRecord::Base.clear_reloadable_connections!
194
+ ActiveRecord::Base.clear_cache!
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ initializer "active_record.add_watchable_files" do |app|
201
+ path = app.paths["db"].first
202
+ config.watchable_files.concat ["#{path}/schema.rb", "#{path}/structure.sql"]
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.begin_transaction(joinable: false)
2
+
3
+ at_exit do
4
+ ActiveRecord::Base.connection.rollback_transaction
5
+ end
@@ -0,0 +1,50 @@
1
+ require 'active_support/core_ext/module/attr_internal'
2
+ require 'active_record/log_subscriber'
3
+
4
+ module ActiveRecord
5
+ module Railties # :nodoc:
6
+ module ControllerRuntime #:nodoc:
7
+ extend ActiveSupport::Concern
8
+
9
+ protected
10
+
11
+ attr_internal :db_runtime
12
+
13
+ def process_action(action, *args)
14
+ # We also need to reset the runtime before each action
15
+ # because of queries in middleware or in cases we are streaming
16
+ # and it won't be cleaned up by the method below.
17
+ ActiveRecord::LogSubscriber.reset_runtime
18
+ super
19
+ end
20
+
21
+ def cleanup_view_runtime
22
+ if ActiveRecord::Base.connected?
23
+ db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
24
+ self.db_runtime = (db_runtime || 0) + db_rt_before_render
25
+ runtime = super
26
+ db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
27
+ self.db_runtime += db_rt_after_render
28
+ runtime - db_rt_after_render
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def append_info_to_payload(payload)
35
+ super
36
+ if ActiveRecord::Base.connected?
37
+ payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
38
+ end
39
+ end
40
+
41
+ module ClassMethods # :nodoc:
42
+ def log_process_action(payload)
43
+ messages, db_runtime = super, payload[:db_runtime]
44
+ messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
45
+ messages
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,402 @@
1
+ require 'active_record'
2
+
3
+ db_namespace = namespace :db do
4
+ task :load_config do
5
+ ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
6
+ ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
7
+ end
8
+
9
+ namespace :create do
10
+ task :all => :load_config do
11
+ ActiveRecord::Tasks::DatabaseTasks.create_all
12
+ end
13
+ end
14
+
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)'
16
+ task :create => [:load_config] do
17
+ if ENV['DATABASE_URL']
18
+ ActiveRecord::Tasks::DatabaseTasks.create_database_url
19
+ else
20
+ ActiveRecord::Tasks::DatabaseTasks.create_current
21
+ end
22
+ end
23
+
24
+ namespace :drop do
25
+ task :all => :load_config do
26
+ ActiveRecord::Tasks::DatabaseTasks.drop_all
27
+ end
28
+ end
29
+
30
+ desc 'Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)'
31
+ task :drop => [:load_config] do
32
+ if ENV['DATABASE_URL']
33
+ ActiveRecord::Tasks::DatabaseTasks.drop_database_url
34
+ else
35
+ ActiveRecord::Tasks::DatabaseTasks.drop_current
36
+ end
37
+ end
38
+
39
+ desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
40
+ task :migrate => [:environment, :load_config] do
41
+ ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
42
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
43
+ ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
44
+ end
45
+ db_namespace['_dump'].invoke
46
+ end
47
+
48
+ task :_dump do
49
+ case ActiveRecord::Base.schema_format
50
+ when :ruby then db_namespace["schema:dump"].invoke
51
+ when :sql then db_namespace["structure:dump"].invoke
52
+ else
53
+ raise "unknown schema format #{ActiveRecord::Base.schema_format}"
54
+ end
55
+ # Allow this task to be called as many times as required. An example is the
56
+ # migrate:redo task, which calls other two internally that depend on this one.
57
+ db_namespace['_dump'].reenable
58
+ end
59
+
60
+ namespace :migrate do
61
+ # desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
62
+ task :redo => [:environment, :load_config] do
63
+ if ENV['VERSION']
64
+ db_namespace['migrate:down'].invoke
65
+ db_namespace['migrate:up'].invoke
66
+ else
67
+ db_namespace['rollback'].invoke
68
+ db_namespace['migrate'].invoke
69
+ end
70
+ end
71
+
72
+ # desc 'Resets your database using your migrations for the current environment'
73
+ task :reset => ['db:drop', 'db:create', 'db:migrate']
74
+
75
+ # desc 'Runs the "up" for a given migration VERSION.'
76
+ task :up => [:environment, :load_config] do
77
+ version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
78
+ raise 'VERSION is required' unless version
79
+ ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version)
80
+ db_namespace['_dump'].invoke
81
+ end
82
+
83
+ # desc 'Runs the "down" for a given migration VERSION.'
84
+ task :down => [:environment, :load_config] do
85
+ version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
86
+ raise 'VERSION is required' unless version
87
+ ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
88
+ db_namespace['_dump'].invoke
89
+ end
90
+
91
+ desc 'Display status of migrations'
92
+ task :status => [:environment, :load_config] do
93
+ unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
94
+ puts 'Schema migrations table does not exist yet.'
95
+ next # means "return" for rake task
96
+ end
97
+ db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
98
+ db_list.map! { |version| "%.3d" % version }
99
+ file_list = []
100
+ ActiveRecord::Migrator.migrations_paths.each do |path|
101
+ Dir.foreach(path) do |file|
102
+ # match "20091231235959_some_name.rb" and "001_some_name.rb" pattern
103
+ if match_data = /^(\d{3,})_(.+)\.rb$/.match(file)
104
+ status = db_list.delete(match_data[1]) ? 'up' : 'down'
105
+ file_list << [status, match_data[1], match_data[2].humanize]
106
+ end
107
+ end
108
+ end
109
+ db_list.map! do |version|
110
+ ['up', version, '********** NO FILE **********']
111
+ end
112
+ # output
113
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
114
+ puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
115
+ puts "-" * 50
116
+ (db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
117
+ puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
118
+ end
119
+ puts
120
+ end
121
+ end
122
+
123
+ desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
124
+ task :rollback => [:environment, :load_config] do
125
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
126
+ ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
127
+ db_namespace['_dump'].invoke
128
+ end
129
+
130
+ # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
131
+ task :forward => [:environment, :load_config] do
132
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
133
+ ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step)
134
+ db_namespace['_dump'].invoke
135
+ end
136
+
137
+ # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
138
+ task :reset => [:environment, :load_config] do
139
+ db_namespace["drop"].invoke
140
+ db_namespace["setup"].invoke
141
+ end
142
+
143
+ # desc "Retrieves the charset for the current environment's database"
144
+ task :charset => [:environment, :load_config] do
145
+ puts ActiveRecord::Tasks::DatabaseTasks.charset_current
146
+ end
147
+
148
+ # desc "Retrieves the collation for the current environment's database"
149
+ task :collation => [:environment, :load_config] do
150
+ begin
151
+ puts ActiveRecord::Tasks::DatabaseTasks.collation_current
152
+ rescue NoMethodError
153
+ $stderr.puts 'Sorry, your database adapter is not supported yet. Feel free to submit a patch.'
154
+ end
155
+ end
156
+
157
+ desc 'Retrieves the current schema version number'
158
+ task :version => [:environment, :load_config] do
159
+ puts "Current version: #{ActiveRecord::Migrator.current_version}"
160
+ end
161
+
162
+ # desc "Raises an error if there are pending migrations"
163
+ task :abort_if_pending_migrations => :environment do
164
+ pending_migrations = ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations
165
+
166
+ if pending_migrations.any?
167
+ puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
168
+ pending_migrations.each do |pending_migration|
169
+ puts ' %4d %s' % [pending_migration.version, pending_migration.name]
170
+ end
171
+ abort %{Run `rake db:migrate` to update your database then try again.}
172
+ end
173
+ end
174
+
175
+ desc 'Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)'
176
+ task :setup => ['db:schema:load_if_ruby', 'db:structure:load_if_sql', :seed]
177
+
178
+ desc 'Load the seed data from db/seeds.rb'
179
+ task :seed do
180
+ db_namespace['abort_if_pending_migrations'].invoke
181
+ ActiveRecord::Tasks::DatabaseTasks.load_seed
182
+ end
183
+
184
+ namespace :fixtures do
185
+ desc "Load fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
186
+ task :load => [:environment, :load_config] do
187
+ require 'active_record/fixtures'
188
+
189
+ base_dir = if ENV['FIXTURES_PATH']
190
+ STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
191
+ "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
192
+ "instead."
193
+ File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
194
+ else
195
+ ActiveRecord::Tasks::DatabaseTasks.fixtures_path
196
+ end
197
+
198
+ fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
199
+
200
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
201
+ ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
202
+ end
203
+ end
204
+
205
+ # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
206
+ task :identify => [:environment, :load_config] do
207
+ require 'active_record/fixtures'
208
+
209
+ label, id = ENV['LABEL'], ENV['ID']
210
+ raise 'LABEL or ID required' if label.blank? && id.blank?
211
+
212
+ puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::FixtureSet.identify(label)}.) if label
213
+
214
+ base_dir = if ENV['FIXTURES_PATH']
215
+ STDERR.puts "Using FIXTURES_PATH env variable is deprecated, please use " +
216
+ "ActiveRecord::Tasks::DatabaseTasks.fixtures_path = '/path/to/fixtures' " +
217
+ "instead."
218
+ File.join [Rails.root, ENV['FIXTURES_PATH'] || %w{test fixtures}].flatten
219
+ else
220
+ ActiveRecord::Tasks::DatabaseTasks.fixtures_path
221
+ end
222
+
223
+
224
+ Dir["#{base_dir}/**/*.yml"].each do |file|
225
+ if data = YAML::load(ERB.new(IO.read(file)).result)
226
+ data.keys.each do |key|
227
+ key_id = ActiveRecord::FixtureSet.identify(key)
228
+
229
+ if key == label || key_id == id.to_i
230
+ puts "#{file}: #{key} (#{key_id})"
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ namespace :schema do
239
+ desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
240
+ task :dump => [:environment, :load_config] do
241
+ require 'active_record/schema_dumper'
242
+ filename = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
243
+ File.open(filename, "w:utf-8") do |file|
244
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
245
+ end
246
+ db_namespace['schema:dump'].reenable
247
+ end
248
+
249
+ desc 'Load a schema.rb file into the database'
250
+ task :load => [:environment, :load_config] do
251
+ file = ENV['SCHEMA'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, 'schema.rb')
252
+ if File.exists?(file)
253
+ load(file)
254
+ else
255
+ 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
+ end
257
+ end
258
+
259
+ task :load_if_ruby => ['db:create', :environment] do
260
+ db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
261
+ end
262
+
263
+ namespace :cache do
264
+ desc 'Create a db/schema_cache.dump file.'
265
+ task :dump => [:environment, :load_config] do
266
+ con = ActiveRecord::Base.connection
267
+ filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
268
+
269
+ con.schema_cache.clear!
270
+ con.tables.each { |table| con.schema_cache.add(table) }
271
+ open(filename, 'wb') { |f| f.write(Marshal.dump(con.schema_cache)) }
272
+ end
273
+
274
+ desc 'Clear a db/schema_cache.dump file.'
275
+ task :clear => [:environment, :load_config] do
276
+ filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.dump")
277
+ FileUtils.rm(filename) if File.exists?(filename)
278
+ end
279
+ end
280
+
281
+ end
282
+
283
+ namespace :structure do
284
+ desc 'Dump the database structure to db/structure.sql. Specify another file with DB_STRUCTURE=db/my_structure.sql'
285
+ task :dump => [:environment, :load_config] do
286
+ filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
287
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
288
+ ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
289
+
290
+ if ActiveRecord::Base.connection.supports_migrations?
291
+ File.open(filename, "a") do |f|
292
+ f.puts ActiveRecord::Base.connection.dump_schema_information
293
+ end
294
+ end
295
+ db_namespace['structure:dump'].reenable
296
+ end
297
+
298
+ # desc "Recreate the databases from the structure.sql file"
299
+ task :load => [:environment, :load_config] do
300
+ filename = ENV['DB_STRUCTURE'] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
301
+ current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
302
+ ActiveRecord::Tasks::DatabaseTasks.structure_load(current_config, filename)
303
+ end
304
+
305
+ task :load_if_sql => ['db:create', :environment] do
306
+ db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql
307
+ end
308
+ end
309
+
310
+ namespace :test do
311
+
312
+ # desc "Recreate the test database from the current schema"
313
+ task :load => 'db:test:purge' do
314
+ case ActiveRecord::Base.schema_format
315
+ when :ruby
316
+ db_namespace["test:load_schema"].invoke
317
+ when :sql
318
+ db_namespace["test:load_structure"].invoke
319
+ end
320
+ end
321
+
322
+ # desc "Recreate the test database from an existent schema.rb file"
323
+ task :load_schema => 'db:test:purge' do
324
+ begin
325
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
326
+ ActiveRecord::Schema.verbose = false
327
+ db_namespace["schema:load"].invoke
328
+ ensure
329
+ ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
330
+ end
331
+ end
332
+
333
+ # desc "Recreate the test database from an existent structure.sql file"
334
+ task :load_structure => 'db:test:purge' do
335
+ begin
336
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => ActiveRecord::Base.configurations['test'])
337
+ db_namespace["structure:load"].invoke
338
+ ensure
339
+ ActiveRecord::Tasks::DatabaseTasks.current_config(:config => nil)
340
+ end
341
+ end
342
+
343
+ # desc "Recreate the test database from a fresh schema"
344
+ task :clone do
345
+ case ActiveRecord::Base.schema_format
346
+ when :ruby
347
+ db_namespace["test:clone_schema"].invoke
348
+ when :sql
349
+ db_namespace["test:clone_structure"].invoke
350
+ end
351
+ end
352
+
353
+ # desc "Recreate the test database from a fresh schema.rb file"
354
+ task :clone_schema => ["db:schema:dump", "db:test:load_schema"]
355
+
356
+ # desc "Recreate the test database from a fresh structure.sql file"
357
+ task :clone_structure => [ "db:structure:dump", "db:test:load_structure" ]
358
+
359
+ # desc "Empty the test database"
360
+ task :purge => [:environment, :load_config] do
361
+ ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations['test']
362
+ end
363
+
364
+ # desc 'Check for pending migrations and load the test schema'
365
+ task :prepare => :load_config do
366
+ unless ActiveRecord::Base.configurations.blank?
367
+ db_namespace['test:load'].invoke
368
+ end
369
+ end
370
+ end
371
+ end
372
+
373
+ namespace :railties do
374
+ namespace :install do
375
+ # desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
376
+ task :migrations => :'db:load_config' do
377
+ to_load = ENV['FROM'].blank? ? :all : ENV['FROM'].split(",").map {|n| n.strip }
378
+ railties = {}
379
+ Rails.application.railties.each do |railtie|
380
+ next unless to_load == :all || to_load.include?(railtie.railtie_name)
381
+
382
+ if railtie.respond_to?(:paths) && (path = railtie.paths['db/migrate'].first)
383
+ railties[railtie.railtie_name] = path
384
+ end
385
+ end
386
+
387
+ on_skip = Proc.new do |name, migration|
388
+ puts "NOTE: Migration #{migration.basename} from #{name} has been skipped. Migration with the same name already exists."
389
+ end
390
+
391
+ on_copy = Proc.new do |name, migration|
392
+ puts "Copied migration #{migration.basename} from #{name}"
393
+ end
394
+
395
+ ActiveRecord::Migration.copy(ActiveRecord::Migrator.migrations_paths.first, railties,
396
+ :on_skip => on_skip, :on_copy => on_copy)
397
+ end
398
+ end
399
+ end
400
+
401
+ task 'test:prepare' => ['db:test:prepare', 'db:test:load', 'db:abort_if_pending_migrations']
402
+
@@ -0,0 +1,16 @@
1
+ #FIXME Remove if ArJdbcMysql will give.
2
+ module ArJdbcMySQL #:nodoc:
3
+ class Error < StandardError #:nodoc:
4
+ attr_accessor :error_number, :sql_state
5
+
6
+ def initialize msg
7
+ super
8
+ @error_number = nil
9
+ @sql_state = nil
10
+ end
11
+
12
+ # Mysql gem compatibility
13
+ alias_method :errno, :error_number
14
+ alias_method :error, :message
15
+ end
16
+ end