activerecord 5.2.3

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 (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +937 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +217 -0
  5. data/examples/performance.rb +185 -0
  6. data/examples/simple.rb +15 -0
  7. data/lib/active_record.rb +188 -0
  8. data/lib/active_record/aggregations.rb +283 -0
  9. data/lib/active_record/association_relation.rb +40 -0
  10. data/lib/active_record/associations.rb +1860 -0
  11. data/lib/active_record/associations/alias_tracker.rb +81 -0
  12. data/lib/active_record/associations/association.rb +299 -0
  13. data/lib/active_record/associations/association_scope.rb +168 -0
  14. data/lib/active_record/associations/belongs_to_association.rb +130 -0
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +40 -0
  16. data/lib/active_record/associations/builder/association.rb +140 -0
  17. data/lib/active_record/associations/builder/belongs_to.rb +163 -0
  18. data/lib/active_record/associations/builder/collection_association.rb +82 -0
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +135 -0
  20. data/lib/active_record/associations/builder/has_many.rb +17 -0
  21. data/lib/active_record/associations/builder/has_one.rb +30 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +42 -0
  23. data/lib/active_record/associations/collection_association.rb +513 -0
  24. data/lib/active_record/associations/collection_proxy.rb +1131 -0
  25. data/lib/active_record/associations/foreign_association.rb +13 -0
  26. data/lib/active_record/associations/has_many_association.rb +144 -0
  27. data/lib/active_record/associations/has_many_through_association.rb +227 -0
  28. data/lib/active_record/associations/has_one_association.rb +120 -0
  29. data/lib/active_record/associations/has_one_through_association.rb +45 -0
  30. data/lib/active_record/associations/join_dependency.rb +262 -0
  31. data/lib/active_record/associations/join_dependency/join_association.rb +60 -0
  32. data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
  33. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  34. data/lib/active_record/associations/preloader.rb +193 -0
  35. data/lib/active_record/associations/preloader/association.rb +131 -0
  36. data/lib/active_record/associations/preloader/through_association.rb +107 -0
  37. data/lib/active_record/associations/singular_association.rb +73 -0
  38. data/lib/active_record/associations/through_association.rb +121 -0
  39. data/lib/active_record/attribute_assignment.rb +88 -0
  40. data/lib/active_record/attribute_decorators.rb +90 -0
  41. data/lib/active_record/attribute_methods.rb +492 -0
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +78 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +150 -0
  44. data/lib/active_record/attribute_methods/primary_key.rb +143 -0
  45. data/lib/active_record/attribute_methods/query.rb +42 -0
  46. data/lib/active_record/attribute_methods/read.rb +85 -0
  47. data/lib/active_record/attribute_methods/serialization.rb +90 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +91 -0
  49. data/lib/active_record/attribute_methods/write.rb +68 -0
  50. data/lib/active_record/attributes.rb +266 -0
  51. data/lib/active_record/autosave_association.rb +498 -0
  52. data/lib/active_record/base.rb +329 -0
  53. data/lib/active_record/callbacks.rb +353 -0
  54. data/lib/active_record/coders/json.rb +15 -0
  55. data/lib/active_record/coders/yaml_column.rb +50 -0
  56. data/lib/active_record/collection_cache_key.rb +53 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1068 -0
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +72 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +540 -0
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +145 -0
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +200 -0
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +146 -0
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +685 -0
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +95 -0
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1396 -0
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +283 -0
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +628 -0
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +887 -0
  70. data/lib/active_record/connection_adapters/column.rb +91 -0
  71. data/lib/active_record/connection_adapters/connection_specification.rb +287 -0
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
  73. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +129 -0
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +163 -0
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +56 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +111 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +168 -0
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +206 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +774 -0
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +863 -0
  118. data/lib/active_record/connection_adapters/schema_cache.rb +118 -0
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +573 -0
  127. data/lib/active_record/connection_adapters/statement_pool.rb +61 -0
  128. data/lib/active_record/connection_handling.rb +145 -0
  129. data/lib/active_record/core.rb +559 -0
  130. data/lib/active_record/counter_cache.rb +218 -0
  131. data/lib/active_record/define_callbacks.rb +22 -0
  132. data/lib/active_record/dynamic_matchers.rb +122 -0
  133. data/lib/active_record/enum.rb +244 -0
  134. data/lib/active_record/errors.rb +380 -0
  135. data/lib/active_record/explain.rb +50 -0
  136. data/lib/active_record/explain_registry.rb +32 -0
  137. data/lib/active_record/explain_subscriber.rb +34 -0
  138. data/lib/active_record/fixture_set/file.rb +82 -0
  139. data/lib/active_record/fixtures.rb +1065 -0
  140. data/lib/active_record/gem_version.rb +17 -0
  141. data/lib/active_record/inheritance.rb +283 -0
  142. data/lib/active_record/integration.rb +155 -0
  143. data/lib/active_record/internal_metadata.rb +45 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  145. data/lib/active_record/locale/en.yml +48 -0
  146. data/lib/active_record/locking/optimistic.rb +198 -0
  147. data/lib/active_record/locking/pessimistic.rb +89 -0
  148. data/lib/active_record/log_subscriber.rb +137 -0
  149. data/lib/active_record/migration.rb +1378 -0
  150. data/lib/active_record/migration/command_recorder.rb +240 -0
  151. data/lib/active_record/migration/compatibility.rb +217 -0
  152. data/lib/active_record/migration/join_table.rb +17 -0
  153. data/lib/active_record/model_schema.rb +521 -0
  154. data/lib/active_record/nested_attributes.rb +600 -0
  155. data/lib/active_record/no_touching.rb +58 -0
  156. data/lib/active_record/null_relation.rb +68 -0
  157. data/lib/active_record/persistence.rb +763 -0
  158. data/lib/active_record/query_cache.rb +45 -0
  159. data/lib/active_record/querying.rb +70 -0
  160. data/lib/active_record/railtie.rb +226 -0
  161. data/lib/active_record/railties/console_sandbox.rb +7 -0
  162. data/lib/active_record/railties/controller_runtime.rb +56 -0
  163. data/lib/active_record/railties/databases.rake +377 -0
  164. data/lib/active_record/readonly_attributes.rb +24 -0
  165. data/lib/active_record/reflection.rb +1044 -0
  166. data/lib/active_record/relation.rb +629 -0
  167. data/lib/active_record/relation/batches.rb +287 -0
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  169. data/lib/active_record/relation/calculations.rb +417 -0
  170. data/lib/active_record/relation/delegation.rb +147 -0
  171. data/lib/active_record/relation/finder_methods.rb +565 -0
  172. data/lib/active_record/relation/from_clause.rb +26 -0
  173. data/lib/active_record/relation/merger.rb +193 -0
  174. data/lib/active_record/relation/predicate_builder.rb +152 -0
  175. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  176. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  177. data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
  178. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
  179. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  180. data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
  181. data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
  182. data/lib/active_record/relation/query_attribute.rb +45 -0
  183. data/lib/active_record/relation/query_methods.rb +1231 -0
  184. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  185. data/lib/active_record/relation/spawn_methods.rb +77 -0
  186. data/lib/active_record/relation/where_clause.rb +186 -0
  187. data/lib/active_record/relation/where_clause_factory.rb +34 -0
  188. data/lib/active_record/result.rb +149 -0
  189. data/lib/active_record/runtime_registry.rb +24 -0
  190. data/lib/active_record/sanitization.rb +222 -0
  191. data/lib/active_record/schema.rb +70 -0
  192. data/lib/active_record/schema_dumper.rb +255 -0
  193. data/lib/active_record/schema_migration.rb +56 -0
  194. data/lib/active_record/scoping.rb +106 -0
  195. data/lib/active_record/scoping/default.rb +152 -0
  196. data/lib/active_record/scoping/named.rb +213 -0
  197. data/lib/active_record/secure_token.rb +40 -0
  198. data/lib/active_record/serialization.rb +22 -0
  199. data/lib/active_record/statement_cache.rb +121 -0
  200. data/lib/active_record/store.rb +211 -0
  201. data/lib/active_record/suppressor.rb +61 -0
  202. data/lib/active_record/table_metadata.rb +82 -0
  203. data/lib/active_record/tasks/database_tasks.rb +337 -0
  204. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  205. data/lib/active_record/tasks/postgresql_database_tasks.rb +143 -0
  206. data/lib/active_record/tasks/sqlite_database_tasks.rb +83 -0
  207. data/lib/active_record/timestamp.rb +153 -0
  208. data/lib/active_record/touch_later.rb +64 -0
  209. data/lib/active_record/transactions.rb +502 -0
  210. data/lib/active_record/translation.rb +24 -0
  211. data/lib/active_record/type.rb +79 -0
  212. data/lib/active_record/type/adapter_specific_registry.rb +136 -0
  213. data/lib/active_record/type/date.rb +9 -0
  214. data/lib/active_record/type/date_time.rb +9 -0
  215. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  216. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  217. data/lib/active_record/type/internal/timezone.rb +17 -0
  218. data/lib/active_record/type/json.rb +30 -0
  219. data/lib/active_record/type/serialized.rb +71 -0
  220. data/lib/active_record/type/text.rb +11 -0
  221. data/lib/active_record/type/time.rb +21 -0
  222. data/lib/active_record/type/type_map.rb +62 -0
  223. data/lib/active_record/type/unsigned_integer.rb +17 -0
  224. data/lib/active_record/type_caster.rb +9 -0
  225. data/lib/active_record/type_caster/connection.rb +33 -0
  226. data/lib/active_record/type_caster/map.rb +23 -0
  227. data/lib/active_record/validations.rb +93 -0
  228. data/lib/active_record/validations/absence.rb +25 -0
  229. data/lib/active_record/validations/associated.rb +60 -0
  230. data/lib/active_record/validations/length.rb +26 -0
  231. data/lib/active_record/validations/presence.rb +68 -0
  232. data/lib/active_record/validations/uniqueness.rb +238 -0
  233. data/lib/active_record/version.rb +10 -0
  234. data/lib/rails/generators/active_record.rb +19 -0
  235. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  236. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  237. data/lib/rails/generators/active_record/migration.rb +35 -0
  238. data/lib/rails/generators/active_record/migration/migration_generator.rb +78 -0
  239. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  240. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +46 -0
  241. data/lib/rails/generators/active_record/model/model_generator.rb +48 -0
  242. data/lib/rails/generators/active_record/model/templates/model.rb.tt +13 -0
  243. data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
  244. metadata +333 -0
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ # <tt>ActiveRecord::Migration::CommandRecorder</tt> records commands done during
6
+ # a migration and knows how to reverse those commands. The CommandRecorder
7
+ # knows how to invert the following commands:
8
+ #
9
+ # * add_column
10
+ # * add_foreign_key
11
+ # * add_index
12
+ # * add_reference
13
+ # * add_timestamps
14
+ # * change_column
15
+ # * change_column_default (must supply a :from and :to option)
16
+ # * change_column_null
17
+ # * create_join_table
18
+ # * create_table
19
+ # * disable_extension
20
+ # * drop_join_table
21
+ # * drop_table (must supply a block)
22
+ # * enable_extension
23
+ # * remove_column (must supply a type)
24
+ # * remove_columns (must specify at least one column name or more)
25
+ # * remove_foreign_key (must supply a second table)
26
+ # * remove_index
27
+ # * remove_reference
28
+ # * remove_timestamps
29
+ # * rename_column
30
+ # * rename_index
31
+ # * rename_table
32
+ class CommandRecorder
33
+ ReversibleAndIrreversibleMethods = [:create_table, :create_join_table, :rename_table, :add_column, :remove_column,
34
+ :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps,
35
+ :change_column_default, :add_reference, :remove_reference, :transaction,
36
+ :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension,
37
+ :change_column, :execute, :remove_columns, :change_column_null,
38
+ :add_foreign_key, :remove_foreign_key
39
+ ]
40
+ include JoinTable
41
+
42
+ attr_accessor :commands, :delegate, :reverting
43
+
44
+ def initialize(delegate = nil)
45
+ @commands = []
46
+ @delegate = delegate
47
+ @reverting = false
48
+ end
49
+
50
+ # While executing the given block, the recorded will be in reverting mode.
51
+ # All commands recorded will end up being recorded reverted
52
+ # and in reverse order.
53
+ # For example:
54
+ #
55
+ # recorder.revert{ recorder.record(:rename_table, [:old, :new]) }
56
+ # # same effect as recorder.record(:rename_table, [:new, :old])
57
+ def revert
58
+ @reverting = !@reverting
59
+ previous = @commands
60
+ @commands = []
61
+ yield
62
+ ensure
63
+ @commands = previous.concat(@commands.reverse)
64
+ @reverting = !@reverting
65
+ end
66
+
67
+ # Record +command+. +command+ should be a method name and arguments.
68
+ # For example:
69
+ #
70
+ # recorder.record(:method_name, [:arg1, :arg2])
71
+ def record(*command, &block)
72
+ if @reverting
73
+ @commands << inverse_of(*command, &block)
74
+ else
75
+ @commands << (command << block)
76
+ end
77
+ end
78
+
79
+ # Returns the inverse of the given command. For example:
80
+ #
81
+ # recorder.inverse_of(:rename_table, [:old, :new])
82
+ # # => [:rename_table, [:new, :old]]
83
+ #
84
+ # This method will raise an +IrreversibleMigration+ exception if it cannot
85
+ # invert the +command+.
86
+ def inverse_of(command, args, &block)
87
+ method = :"invert_#{command}"
88
+ raise IrreversibleMigration, <<-MSG.strip_heredoc unless respond_to?(method, true)
89
+ This migration uses #{command}, which is not automatically reversible.
90
+ To make the migration reversible you can either:
91
+ 1. Define #up and #down methods in place of the #change method.
92
+ 2. Use the #reversible method to define reversible behavior.
93
+ MSG
94
+ send(method, args, &block)
95
+ end
96
+
97
+ ReversibleAndIrreversibleMethods.each do |method|
98
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
99
+ def #{method}(*args, &block) # def create_table(*args, &block)
100
+ record(:"#{method}", args, &block) # record(:create_table, args, &block)
101
+ end # end
102
+ EOV
103
+ end
104
+ alias :add_belongs_to :add_reference
105
+ alias :remove_belongs_to :remove_reference
106
+
107
+ def change_table(table_name, options = {}) # :nodoc:
108
+ yield delegate.update_table_definition(table_name, self)
109
+ end
110
+
111
+ private
112
+
113
+ module StraightReversions # :nodoc:
114
+ private
115
+ { transaction: :transaction,
116
+ execute_block: :execute_block,
117
+ create_table: :drop_table,
118
+ create_join_table: :drop_join_table,
119
+ add_column: :remove_column,
120
+ add_timestamps: :remove_timestamps,
121
+ add_reference: :remove_reference,
122
+ enable_extension: :disable_extension
123
+ }.each do |cmd, inv|
124
+ [[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
125
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
126
+ def invert_#{method}(args, &block) # def invert_create_table(args, &block)
127
+ [:#{inverse}, args, block] # [:drop_table, args, block]
128
+ end # end
129
+ EOV
130
+ end
131
+ end
132
+ end
133
+
134
+ include StraightReversions
135
+
136
+ def invert_drop_table(args, &block)
137
+ if args.size == 1 && block == nil
138
+ raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
139
+ end
140
+ super
141
+ end
142
+
143
+ def invert_rename_table(args)
144
+ [:rename_table, args.reverse]
145
+ end
146
+
147
+ def invert_remove_column(args)
148
+ raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
149
+ super
150
+ end
151
+
152
+ def invert_rename_index(args)
153
+ [:rename_index, [args.first] + args.last(2).reverse]
154
+ end
155
+
156
+ def invert_rename_column(args)
157
+ [:rename_column, [args.first] + args.last(2).reverse]
158
+ end
159
+
160
+ def invert_add_index(args)
161
+ table, columns, options = *args
162
+ options ||= {}
163
+
164
+ options_hash = options.slice(:name, :algorithm)
165
+ options_hash[:column] = columns if !options_hash[:name]
166
+
167
+ [:remove_index, [table, options_hash]]
168
+ end
169
+
170
+ def invert_remove_index(args)
171
+ table, options_or_column = *args
172
+ if (options = options_or_column).is_a?(Hash)
173
+ unless options[:column]
174
+ raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option."
175
+ end
176
+ options = options.dup
177
+ [:add_index, [table, options.delete(:column), options]]
178
+ elsif (column = options_or_column).present?
179
+ [:add_index, [table, column]]
180
+ end
181
+ end
182
+
183
+ alias :invert_add_belongs_to :invert_add_reference
184
+ alias :invert_remove_belongs_to :invert_remove_reference
185
+
186
+ def invert_change_column_default(args)
187
+ table, column, options = *args
188
+
189
+ unless options && options.is_a?(Hash) && options.has_key?(:from) && options.has_key?(:to)
190
+ raise ActiveRecord::IrreversibleMigration, "change_column_default is only reversible if given a :from and :to option."
191
+ end
192
+
193
+ [:change_column_default, [table, column, from: options[:to], to: options[:from]]]
194
+ end
195
+
196
+ def invert_change_column_null(args)
197
+ args[2] = !args[2]
198
+ [:change_column_null, args]
199
+ end
200
+
201
+ def invert_add_foreign_key(args)
202
+ from_table, to_table, add_options = args
203
+ add_options ||= {}
204
+
205
+ if add_options[:name]
206
+ options = { name: add_options[:name] }
207
+ elsif add_options[:column]
208
+ options = { column: add_options[:column] }
209
+ else
210
+ options = to_table
211
+ end
212
+
213
+ [:remove_foreign_key, [from_table, options]]
214
+ end
215
+
216
+ def invert_remove_foreign_key(args)
217
+ from_table, to_table, remove_options = args
218
+ raise ActiveRecord::IrreversibleMigration, "remove_foreign_key is only reversible if given a second table" if to_table.nil? || to_table.is_a?(Hash)
219
+
220
+ reversed_args = [from_table, to_table]
221
+ reversed_args << remove_options if remove_options
222
+
223
+ [:add_foreign_key, reversed_args]
224
+ end
225
+
226
+ def respond_to_missing?(method, _)
227
+ super || delegate.respond_to?(method)
228
+ end
229
+
230
+ # Forwards any missing method call to the \target.
231
+ def method_missing(method, *args, &block)
232
+ if delegate.respond_to?(method)
233
+ delegate.public_send(method, *args, &block)
234
+ else
235
+ super
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Migration
5
+ module Compatibility # :nodoc: all
6
+ def self.find(version)
7
+ version = version.to_s
8
+ name = "V#{version.tr('.', '_')}"
9
+ unless const_defined?(name)
10
+ versions = constants.grep(/\AV[0-9_]+\z/).map { |s| s.to_s.delete("V").tr("_", ".").inspect }
11
+ raise ArgumentError, "Unknown migration version #{version.inspect}; expected one of #{versions.sort.join(', ')}"
12
+ end
13
+ const_get(name)
14
+ end
15
+
16
+ V5_2 = Current
17
+
18
+ class V5_1 < V5_2
19
+ def change_column(table_name, column_name, type, options = {})
20
+ if connection.adapter_name == "PostgreSQL"
21
+ super(table_name, column_name, type, options.except(:default, :null, :comment))
22
+ connection.change_column_default(table_name, column_name, options[:default]) if options.key?(:default)
23
+ connection.change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
24
+ connection.change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def create_table(table_name, options = {})
31
+ if connection.adapter_name == "Mysql2"
32
+ super(table_name, options: "ENGINE=InnoDB", **options)
33
+ else
34
+ super
35
+ end
36
+ end
37
+ end
38
+
39
+ class V5_0 < V5_1
40
+ module TableDefinition
41
+ def primary_key(name, type = :primary_key, **options)
42
+ type = :integer if type == :primary_key
43
+ super
44
+ end
45
+
46
+ def references(*args, **options)
47
+ super(*args, type: :integer, **options)
48
+ end
49
+ alias :belongs_to :references
50
+ end
51
+
52
+ def create_table(table_name, options = {})
53
+ if connection.adapter_name == "PostgreSQL"
54
+ if options[:id] == :uuid && !options.key?(:default)
55
+ options[:default] = "uuid_generate_v4()"
56
+ end
57
+ end
58
+
59
+ unless connection.adapter_name == "Mysql2" && options[:id] == :bigint
60
+ if [:integer, :bigint].include?(options[:id]) && !options.key?(:default)
61
+ options[:default] = nil
62
+ end
63
+ end
64
+
65
+ # Since 5.1 PostgreSQL adapter uses bigserial type for primary
66
+ # keys by default and MySQL uses bigint. This compat layer makes old migrations utilize
67
+ # serial/int type instead -- the way it used to work before 5.1.
68
+ unless options.key?(:id)
69
+ options[:id] = :integer
70
+ end
71
+
72
+ if block_given?
73
+ super do |t|
74
+ yield compatible_table_definition(t)
75
+ end
76
+ else
77
+ super
78
+ end
79
+ end
80
+
81
+ def change_table(table_name, options = {})
82
+ if block_given?
83
+ super do |t|
84
+ yield compatible_table_definition(t)
85
+ end
86
+ else
87
+ super
88
+ end
89
+ end
90
+
91
+ def create_join_table(table_1, table_2, column_options: {}, **options)
92
+ column_options.reverse_merge!(type: :integer)
93
+
94
+ if block_given?
95
+ super do |t|
96
+ yield compatible_table_definition(t)
97
+ end
98
+ else
99
+ super
100
+ end
101
+ end
102
+
103
+ def add_column(table_name, column_name, type, options = {})
104
+ if type == :primary_key
105
+ type = :integer
106
+ options[:primary_key] = true
107
+ end
108
+ super
109
+ end
110
+
111
+ def add_reference(table_name, ref_name, **options)
112
+ super(table_name, ref_name, type: :integer, **options)
113
+ end
114
+ alias :add_belongs_to :add_reference
115
+
116
+ private
117
+ def compatible_table_definition(t)
118
+ class << t
119
+ prepend TableDefinition
120
+ end
121
+ t
122
+ end
123
+ end
124
+
125
+ class V4_2 < V5_0
126
+ module TableDefinition
127
+ def references(*, **options)
128
+ options[:index] ||= false
129
+ super
130
+ end
131
+ alias :belongs_to :references
132
+
133
+ def timestamps(**options)
134
+ options[:null] = true if options[:null].nil?
135
+ super
136
+ end
137
+ end
138
+
139
+ def create_table(table_name, options = {})
140
+ if block_given?
141
+ super do |t|
142
+ yield compatible_table_definition(t)
143
+ end
144
+ else
145
+ super
146
+ end
147
+ end
148
+
149
+ def change_table(table_name, options = {})
150
+ if block_given?
151
+ super do |t|
152
+ yield compatible_table_definition(t)
153
+ end
154
+ else
155
+ super
156
+ end
157
+ end
158
+
159
+ def add_reference(*, **options)
160
+ options[:index] ||= false
161
+ super
162
+ end
163
+ alias :add_belongs_to :add_reference
164
+
165
+ def add_timestamps(_, **options)
166
+ options[:null] = true if options[:null].nil?
167
+ super
168
+ end
169
+
170
+ def index_exists?(table_name, column_name, options = {})
171
+ column_names = Array(column_name).map(&:to_s)
172
+ options[:name] =
173
+ if options[:name].present?
174
+ options[:name].to_s
175
+ else
176
+ connection.index_name(table_name, column: column_names)
177
+ end
178
+ super
179
+ end
180
+
181
+ def remove_index(table_name, options = {})
182
+ options = { column: options } unless options.is_a?(Hash)
183
+ options[:name] = index_name_for_remove(table_name, options)
184
+ super(table_name, options)
185
+ end
186
+
187
+ private
188
+ def compatible_table_definition(t)
189
+ class << t
190
+ prepend TableDefinition
191
+ end
192
+ super
193
+ end
194
+
195
+ def index_name_for_remove(table_name, options = {})
196
+ index_name = connection.index_name(table_name, options)
197
+
198
+ unless connection.index_name_exists?(table_name, index_name)
199
+ if options.is_a?(Hash) && options.has_key?(:name)
200
+ options_without_column = options.dup
201
+ options_without_column.delete :column
202
+ index_name_without_column = connection.index_name(table_name, options_without_column)
203
+
204
+ if connection.index_name_exists?(table_name, index_name_without_column)
205
+ return index_name_without_column
206
+ end
207
+ end
208
+
209
+ raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' does not exist"
210
+ end
211
+
212
+ index_name
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end