activerecord 5.0.6 → 6.0.1

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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/database_configurations"
2
4
 
3
5
  module ActiveRecord
4
6
  module Tasks # :nodoc:
@@ -8,7 +10,7 @@ module ActiveRecord
8
10
  # ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
9
11
  # logic behind common tasks used to manage database and migrations.
10
12
  #
11
- # The tasks defined here are used with Rake tasks provided by Active Record.
13
+ # The tasks defined here are used with Rails commands provided by Active Record.
12
14
  #
13
15
  # In order to use DatabaseTasks, a few config values need to be set. All the needed
14
16
  # config values are set by Rails already, so it's necessary to do it only if you
@@ -35,19 +37,29 @@ module ActiveRecord
35
37
  #
36
38
  # DatabaseTasks.create_current('production')
37
39
  module DatabaseTasks
40
+ ##
41
+ # :singleton-method:
42
+ # Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:structure:dump
43
+ mattr_accessor :structure_dump_flags, instance_accessor: false
44
+
45
+ ##
46
+ # :singleton-method:
47
+ # Extra flags passed to database CLI tool when calling db:structure:load
48
+ mattr_accessor :structure_load_flags, instance_accessor: false
49
+
38
50
  extend self
39
51
 
40
52
  attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
41
53
  attr_accessor :database_configuration
42
54
 
43
- LOCAL_HOSTS = ['127.0.0.1', 'localhost']
55
+ LOCAL_HOSTS = ["127.0.0.1", "localhost"]
44
56
 
45
57
  def check_protected_environments!
46
- unless ENV['DISABLE_DATABASE_ENVIRONMENT_CHECK']
47
- current = ActiveRecord::Migrator.current_environment
48
- stored = ActiveRecord::Migrator.last_stored_environment
58
+ unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
59
+ current = ActiveRecord::Base.connection.migration_context.current_environment
60
+ stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
49
61
 
50
- if ActiveRecord::Migrator.protected_environment?
62
+ if ActiveRecord::Base.connection.migration_context.protected_environment?
51
63
  raise ActiveRecord::ProtectedEnvironmentError.new(stored)
52
64
  end
53
65
 
@@ -63,24 +75,24 @@ module ActiveRecord
63
75
  @tasks[pattern] = task
64
76
  end
65
77
 
66
- register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
67
- register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
68
- register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
78
+ register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
79
+ register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
80
+ register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
69
81
 
70
82
  def db_dir
71
83
  @db_dir ||= Rails.application.config.paths["db"].first
72
84
  end
73
85
 
74
86
  def migrations_paths
75
- @migrations_paths ||= Rails.application.paths['db/migrate'].to_a
87
+ @migrations_paths ||= Rails.application.paths["db/migrate"].to_a
76
88
  end
77
89
 
78
90
  def fixtures_path
79
- @fixtures_path ||= if ENV['FIXTURES_PATH']
80
- File.join(root, ENV['FIXTURES_PATH'])
81
- else
82
- File.join(root, 'test', 'fixtures')
83
- end
91
+ @fixtures_path ||= if ENV["FIXTURES_PATH"]
92
+ File.join(root, ENV["FIXTURES_PATH"])
93
+ else
94
+ File.join(root, "test", "fixtures")
95
+ end
84
96
  end
85
97
 
86
98
  def root
@@ -91,28 +103,33 @@ module ActiveRecord
91
103
  @env ||= Rails.env
92
104
  end
93
105
 
106
+ def spec
107
+ @spec ||= "primary"
108
+ end
109
+
94
110
  def seed_loader
95
111
  @seed_loader ||= Rails.application
96
112
  end
97
113
 
98
114
  def current_config(options = {})
99
- options.reverse_merge! :env => env
115
+ options.reverse_merge! env: env
116
+ options[:spec] ||= "primary"
100
117
  if options.has_key?(:config)
101
118
  @current_config = options[:config]
102
119
  else
103
- @current_config ||= ActiveRecord::Base.configurations[options[:env]]
120
+ @current_config ||= ActiveRecord::Base.configurations.configs_for(env_name: options[:env], spec_name: options[:spec]).config
104
121
  end
105
122
  end
106
123
 
107
124
  def create(*arguments)
108
125
  configuration = arguments.first
109
- class_for_adapter(configuration['adapter']).new(*arguments).create
110
- $stdout.puts "Created database '#{configuration['database']}'"
126
+ class_for_adapter(configuration["adapter"]).new(*arguments).create
127
+ $stdout.puts "Created database '#{configuration['database']}'" if verbose?
111
128
  rescue DatabaseAlreadyExists
112
- $stderr.puts "Database '#{configuration['database']}' already exists"
129
+ $stderr.puts "Database '#{configuration['database']}' already exists" if verbose?
113
130
  rescue Exception => error
114
131
  $stderr.puts error
115
- $stderr.puts "Couldn't create database for #{configuration.inspect}"
132
+ $stderr.puts "Couldn't create '#{configuration['database']}' database. Please check your configuration."
116
133
  raise
117
134
  end
118
135
 
@@ -120,12 +137,51 @@ module ActiveRecord
120
137
  old_pool = ActiveRecord::Base.connection_handler.retrieve_connection_pool(ActiveRecord::Base.connection_specification_name)
121
138
  each_local_configuration { |configuration| create configuration }
122
139
  if old_pool
123
- ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec)
140
+ ActiveRecord::Base.connection_handler.establish_connection(old_pool.spec.to_hash)
124
141
  end
125
142
  end
126
143
 
127
- def create_current(environment = env)
128
- each_current_configuration(environment) { |configuration|
144
+ def setup_initial_database_yaml
145
+ return {} unless defined?(Rails)
146
+
147
+ begin
148
+ Rails.application.config.load_database_yaml
149
+ rescue
150
+ $stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
151
+
152
+ {}
153
+ end
154
+ end
155
+
156
+ def for_each(databases)
157
+ return {} unless defined?(Rails)
158
+
159
+ database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
160
+
161
+ # if this is a single database application we don't want tasks for each primary database
162
+ return if database_configs.count == 1
163
+
164
+ database_configs.each do |db_config|
165
+ yield db_config.spec_name
166
+ end
167
+ end
168
+
169
+ def raise_for_multi_db(environment = env, command:)
170
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: environment)
171
+
172
+ if db_configs.count > 1
173
+ dbs_list = []
174
+
175
+ db_configs.each do |db|
176
+ dbs_list << "#{command}:#{db.spec_name}"
177
+ end
178
+
179
+ raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
180
+ end
181
+ end
182
+
183
+ def create_current(environment = env, spec_name = nil)
184
+ each_current_configuration(environment, spec_name) { |configuration|
129
185
  create configuration
130
186
  }
131
187
  ActiveRecord::Base.establish_connection(environment.to_sym)
@@ -133,8 +189,8 @@ module ActiveRecord
133
189
 
134
190
  def drop(*arguments)
135
191
  configuration = arguments.first
136
- class_for_adapter(configuration['adapter']).new(*arguments).drop
137
- $stdout.puts "Dropped database '#{configuration['database']}'"
192
+ class_for_adapter(configuration["adapter"]).new(*arguments).drop
193
+ $stdout.puts "Dropped database '#{configuration['database']}'" if verbose?
138
194
  rescue ActiveRecord::NoDatabaseError
139
195
  $stderr.puts "Database '#{configuration['database']}' does not exist"
140
196
  rescue Exception => error
@@ -153,41 +209,86 @@ module ActiveRecord
153
209
  }
154
210
  end
155
211
 
212
+ def truncate_tables(configuration)
213
+ ActiveRecord::Base.connected_to(database: { truncation: configuration }) do
214
+ conn = ActiveRecord::Base.connection
215
+ table_names = conn.tables
216
+ table_names -= [
217
+ conn.schema_migration.table_name,
218
+ InternalMetadata.table_name
219
+ ]
220
+
221
+ ActiveRecord::Base.connection.truncate_tables(*table_names)
222
+ end
223
+ end
224
+ private :truncate_tables
225
+
226
+ def truncate_all(environment = env)
227
+ ActiveRecord::Base.configurations.configs_for(env_name: environment).each do |db_config|
228
+ truncate_tables db_config.config
229
+ end
230
+ end
231
+
156
232
  def migrate
157
- raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
233
+ check_target_version
158
234
 
159
- verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
160
- version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
161
- scope = ENV['SCOPE']
162
- verbose_was, Migration.verbose = Migration.verbose, verbose
163
- Migrator.migrate(migrations_paths, version) do |migration|
235
+ scope = ENV["SCOPE"]
236
+ verbose_was, Migration.verbose = Migration.verbose, verbose?
237
+
238
+ Base.connection.migration_context.migrate(target_version) do |migration|
164
239
  scope.blank? || scope == migration.scope
165
240
  end
241
+
166
242
  ActiveRecord::Base.clear_cache!
167
243
  ensure
168
244
  Migration.verbose = verbose_was
169
245
  end
170
246
 
171
- def charset_current(environment = env)
172
- charset ActiveRecord::Base.configurations[environment]
247
+ def migrate_status
248
+ unless ActiveRecord::Base.connection.schema_migration.table_exists?
249
+ Kernel.abort "Schema migrations table does not exist yet."
250
+ end
251
+
252
+ # output
253
+ puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
254
+ puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
255
+ puts "-" * 50
256
+ ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
257
+ puts "#{status.center(8)} #{version.ljust(14)} #{name}"
258
+ end
259
+ puts
260
+ end
261
+
262
+ def check_target_version
263
+ if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
264
+ raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
265
+ end
266
+ end
267
+
268
+ def target_version
269
+ ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
270
+ end
271
+
272
+ def charset_current(environment = env, specification_name = spec)
273
+ charset ActiveRecord::Base.configurations.configs_for(env_name: environment, spec_name: specification_name).config
173
274
  end
174
275
 
175
276
  def charset(*arguments)
176
277
  configuration = arguments.first
177
- class_for_adapter(configuration['adapter']).new(*arguments).charset
278
+ class_for_adapter(configuration["adapter"]).new(*arguments).charset
178
279
  end
179
280
 
180
- def collation_current(environment = env)
181
- collation ActiveRecord::Base.configurations[environment]
281
+ def collation_current(environment = env, specification_name = spec)
282
+ collation ActiveRecord::Base.configurations.configs_for(env_name: environment, spec_name: specification_name).config
182
283
  end
183
284
 
184
285
  def collation(*arguments)
185
286
  configuration = arguments.first
186
- class_for_adapter(configuration['adapter']).new(*arguments).collation
287
+ class_for_adapter(configuration["adapter"]).new(*arguments).collation
187
288
  end
188
289
 
189
290
  def purge(configuration)
190
- class_for_adapter(configuration['adapter']).new(configuration).purge
291
+ class_for_adapter(configuration["adapter"]).new(configuration).purge
191
292
  end
192
293
 
193
294
  def purge_all
@@ -206,60 +307,129 @@ module ActiveRecord
206
307
  def structure_dump(*arguments)
207
308
  configuration = arguments.first
208
309
  filename = arguments.delete_at 1
209
- class_for_adapter(configuration['adapter']).new(*arguments).structure_dump(filename)
310
+ class_for_adapter(configuration["adapter"]).new(*arguments).structure_dump(filename, structure_dump_flags)
210
311
  end
211
312
 
212
313
  def structure_load(*arguments)
213
314
  configuration = arguments.first
214
315
  filename = arguments.delete_at 1
215
- class_for_adapter(configuration['adapter']).new(*arguments).structure_load(filename)
316
+ class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
216
317
  end
217
318
 
218
- def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
219
- file ||= schema_file(format)
319
+ def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary") # :nodoc:
320
+ file ||= dump_filename(spec_name, format)
321
+
322
+ verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
323
+ check_schema_file(file)
324
+ ActiveRecord::Base.establish_connection(configuration)
220
325
 
221
326
  case format
222
327
  when :ruby
223
- check_schema_file(file)
224
- ActiveRecord::Base.establish_connection(configuration)
225
328
  load(file)
226
329
  when :sql
227
- check_schema_file(file)
228
330
  structure_load(configuration, file)
229
331
  else
230
332
  raise ArgumentError, "unknown format #{format.inspect}"
231
333
  end
232
334
  ActiveRecord::InternalMetadata.create_table
233
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
335
+ ActiveRecord::InternalMetadata[:environment] = environment
336
+ ActiveRecord::InternalMetadata[:schema_sha1] = schema_sha1(file)
337
+ ensure
338
+ Migration.verbose = verbose_was
339
+ end
340
+
341
+ def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary")
342
+ file ||= dump_filename(spec_name, format)
343
+
344
+ return true unless File.exist?(file)
345
+
346
+ ActiveRecord::Base.establish_connection(configuration)
347
+ return false unless ActiveRecord::InternalMetadata.table_exists?
348
+ ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
234
349
  end
235
350
 
236
- def load_schema_for(*args)
237
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
238
- This method was renamed to `#load_schema` and will be removed in the future.
239
- Use `#load_schema` instead.
240
- MSG
241
- load_schema(*args)
351
+ def reconstruct_from_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env, spec_name = "primary") # :nodoc:
352
+ file ||= dump_filename(spec_name, format)
353
+
354
+ check_schema_file(file)
355
+
356
+ ActiveRecord::Base.establish_connection(configuration)
357
+
358
+ if schema_up_to_date?(configuration, format, file, environment, spec_name)
359
+ truncate_tables(configuration)
360
+ else
361
+ purge(configuration)
362
+ load_schema(configuration, format, file, environment, spec_name)
363
+ end
364
+ rescue ActiveRecord::NoDatabaseError
365
+ create(configuration)
366
+ load_schema(configuration, format, file, environment, spec_name)
367
+ end
368
+
369
+ def dump_schema(configuration, format = ActiveRecord::Base.schema_format, spec_name = "primary") # :nodoc:
370
+ require "active_record/schema_dumper"
371
+ filename = dump_filename(spec_name, format)
372
+ connection = ActiveRecord::Base.connection
373
+
374
+ case format
375
+ when :ruby
376
+ File.open(filename, "w:utf-8") do |file|
377
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
378
+ end
379
+ when :sql
380
+ structure_dump(configuration, filename)
381
+ if connection.schema_migration.table_exists?
382
+ File.open(filename, "a") do |f|
383
+ f.puts connection.dump_schema_information
384
+ f.print "\n"
385
+ end
386
+ end
387
+ end
242
388
  end
243
389
 
244
390
  def schema_file(format = ActiveRecord::Base.schema_format)
391
+ File.join(db_dir, schema_file_type(format))
392
+ end
393
+
394
+ def schema_file_type(format = ActiveRecord::Base.schema_format)
245
395
  case format
246
396
  when :ruby
247
- File.join(db_dir, "schema.rb")
397
+ "schema.rb"
248
398
  when :sql
249
- File.join(db_dir, "structure.sql")
399
+ "structure.sql"
400
+ end
401
+ end
402
+
403
+ def dump_filename(namespace, format = ActiveRecord::Base.schema_format)
404
+ filename = if namespace == "primary"
405
+ schema_file_type(format)
406
+ else
407
+ "#{namespace}_#{schema_file_type(format)}"
408
+ end
409
+
410
+ ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
411
+ end
412
+
413
+ def cache_dump_filename(namespace)
414
+ filename = if namespace == "primary"
415
+ "schema_cache.yml"
416
+ else
417
+ "#{namespace}_schema_cache.yml"
250
418
  end
419
+
420
+ ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
251
421
  end
252
422
 
253
423
  def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
254
- each_current_configuration(environment) { |configuration|
255
- load_schema configuration, format, file
424
+ each_current_configuration(environment) { |configuration, spec_name, env|
425
+ load_schema(configuration, format, file, env, spec_name)
256
426
  }
257
427
  ActiveRecord::Base.establish_connection(environment.to_sym)
258
428
  end
259
429
 
260
430
  def check_schema_file(filename)
261
431
  unless File.exist?(filename)
262
- message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
432
+ message = +%{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
263
433
  message << %{ 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.} if defined?(::Rails.root)
264
434
  Kernel.abort message
265
435
  end
@@ -269,47 +439,68 @@ module ActiveRecord
269
439
  if seed_loader
270
440
  seed_loader.load_seed
271
441
  else
272
- raise "You tried to load seed data, but no seed loader is specified. Please specify seed " +
273
- "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" +
442
+ raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \
443
+ "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \
274
444
  "Seed loader should respond to load_seed method"
275
445
  end
276
446
  end
277
447
 
448
+ # Dumps the schema cache in YAML format for the connection into the file
449
+ #
450
+ # ==== Examples:
451
+ # ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, "tmp/schema_dump.yaml")
452
+ def dump_schema_cache(conn, filename)
453
+ conn.schema_cache.clear!
454
+ conn.data_sources.each { |table| conn.schema_cache.add(table) }
455
+ open(filename, "wb") { |f| f.write(YAML.dump(conn.schema_cache)) }
456
+ end
457
+
278
458
  private
459
+ def verbose?
460
+ ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
461
+ end
279
462
 
280
- def class_for_adapter(adapter)
281
- key = @tasks.keys.detect { |pattern| adapter[pattern] }
282
- unless key
283
- raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
463
+ def class_for_adapter(adapter)
464
+ _key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
465
+ unless task
466
+ raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
467
+ end
468
+ task.is_a?(String) ? task.constantize : task
284
469
  end
285
- @tasks[key]
286
- end
287
470
 
288
- def each_current_configuration(environment)
289
- environments = [environment]
290
- environments << 'test' if environment == 'development'
471
+ def each_current_configuration(environment, spec_name = nil)
472
+ environments = [environment]
473
+ environments << "test" if environment == "development"
291
474
 
292
- configurations = ActiveRecord::Base.configurations.values_at(*environments)
293
- configurations.compact.each do |configuration|
294
- yield configuration unless configuration['database'].blank?
475
+ environments.each do |env|
476
+ ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
477
+ next if spec_name && spec_name != db_config.spec_name
478
+
479
+ yield db_config.config, db_config.spec_name, env
480
+ end
481
+ end
295
482
  end
296
- end
297
483
 
298
- def each_local_configuration
299
- ActiveRecord::Base.configurations.each_value do |configuration|
300
- next unless configuration['database']
484
+ def each_local_configuration
485
+ ActiveRecord::Base.configurations.configs_for.each do |db_config|
486
+ configuration = db_config.config
487
+ next unless configuration["database"]
301
488
 
302
- if local_database?(configuration)
303
- yield configuration
304
- else
305
- $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
489
+ if local_database?(configuration)
490
+ yield configuration
491
+ else
492
+ $stderr.puts "This task only modifies local databases. #{configuration['database']} is on a remote host."
493
+ end
306
494
  end
307
495
  end
308
- end
309
496
 
310
- def local_database?(configuration)
311
- configuration['host'].blank? || LOCAL_HOSTS.include?(configuration['host'])
312
- end
497
+ def local_database?(configuration)
498
+ configuration["host"].blank? || LOCAL_HOSTS.include?(configuration["host"])
499
+ end
500
+
501
+ def schema_sha1(file)
502
+ Digest::SHA1.hexdigest(File.read(file))
503
+ end
313
504
  end
314
505
  end
315
506
  end