pg_trunk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +87 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +92 -0
  6. data/.yardopts +4 -0
  7. data/CHANGELOG.md +31 -0
  8. data/CONTRIBUTING.md +17 -0
  9. data/Gemfile +22 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +141 -0
  12. data/Rakefile +16 -0
  13. data/bin/console +8 -0
  14. data/bin/rake +19 -0
  15. data/bin/rspec +19 -0
  16. data/bin/setup +8 -0
  17. data/bin/yard +19 -0
  18. data/lib/pg_trunk/core/adapters/postgres.rb +80 -0
  19. data/lib/pg_trunk/core/dependencies_resolver.rb +101 -0
  20. data/lib/pg_trunk/core/generators.rb +140 -0
  21. data/lib/pg_trunk/core/operation/attributes.rb +78 -0
  22. data/lib/pg_trunk/core/operation/callbacks.rb +40 -0
  23. data/lib/pg_trunk/core/operation/generators.rb +51 -0
  24. data/lib/pg_trunk/core/operation/inversion.rb +70 -0
  25. data/lib/pg_trunk/core/operation/registration.rb +55 -0
  26. data/lib/pg_trunk/core/operation/ruby_builder.rb +112 -0
  27. data/lib/pg_trunk/core/operation/ruby_helpers.rb +99 -0
  28. data/lib/pg_trunk/core/operation/sql_helpers.rb +44 -0
  29. data/lib/pg_trunk/core/operation/validations.rb +21 -0
  30. data/lib/pg_trunk/core/operation.rb +78 -0
  31. data/lib/pg_trunk/core/qualified_name.rb +165 -0
  32. data/lib/pg_trunk/core/railtie/command_recorder.rb +30 -0
  33. data/lib/pg_trunk/core/railtie/custom_types.rb +37 -0
  34. data/lib/pg_trunk/core/railtie/migration.rb +50 -0
  35. data/lib/pg_trunk/core/railtie/migrator.rb +22 -0
  36. data/lib/pg_trunk/core/railtie/schema_dumper.rb +75 -0
  37. data/lib/pg_trunk/core/railtie/schema_migration.rb +22 -0
  38. data/lib/pg_trunk/core/railtie/statements.rb +21 -0
  39. data/lib/pg_trunk/core/railtie.rb +35 -0
  40. data/lib/pg_trunk/core/registry.rb +159 -0
  41. data/lib/pg_trunk/core/serializers/array_of_hashes_serializer.rb +28 -0
  42. data/lib/pg_trunk/core/serializers/array_of_strings_serializer.rb +29 -0
  43. data/lib/pg_trunk/core/serializers/array_of_symbols_serializer.rb +28 -0
  44. data/lib/pg_trunk/core/serializers/array_serializer.rb +22 -0
  45. data/lib/pg_trunk/core/serializers/lowercase_string_serializer.rb +21 -0
  46. data/lib/pg_trunk/core/serializers/multiline_text_serializer.rb +21 -0
  47. data/lib/pg_trunk/core/serializers/qualified_name_serializer.rb +27 -0
  48. data/lib/pg_trunk/core/serializers/symbol_serializer.rb +22 -0
  49. data/lib/pg_trunk/core/serializers.rb +16 -0
  50. data/lib/pg_trunk/core/validators/all_items_valid_validator.rb +15 -0
  51. data/lib/pg_trunk/core/validators/difference_validator.rb +19 -0
  52. data/lib/pg_trunk/core/validators.rb +10 -0
  53. data/lib/pg_trunk/core.rb +21 -0
  54. data/lib/pg_trunk/generators.rb +7 -0
  55. data/lib/pg_trunk/operations/check_constraints/add_check_constraint.rb +109 -0
  56. data/lib/pg_trunk/operations/check_constraints/base.rb +69 -0
  57. data/lib/pg_trunk/operations/check_constraints/drop_check_constraint.rb +60 -0
  58. data/lib/pg_trunk/operations/check_constraints/rename_check_constraint.rb +54 -0
  59. data/lib/pg_trunk/operations/check_constraints/validate_check_constraint.rb +39 -0
  60. data/lib/pg_trunk/operations/check_constraints.rb +14 -0
  61. data/lib/pg_trunk/operations/composite_types/base.rb +61 -0
  62. data/lib/pg_trunk/operations/composite_types/change_composite_type.rb +136 -0
  63. data/lib/pg_trunk/operations/composite_types/column.rb +118 -0
  64. data/lib/pg_trunk/operations/composite_types/create_composite_type.rb +99 -0
  65. data/lib/pg_trunk/operations/composite_types/drop_composite_type.rb +67 -0
  66. data/lib/pg_trunk/operations/composite_types/rename_composite_type.rb +44 -0
  67. data/lib/pg_trunk/operations/composite_types.rb +15 -0
  68. data/lib/pg_trunk/operations/domains/base.rb +46 -0
  69. data/lib/pg_trunk/operations/domains/change_domain.rb +140 -0
  70. data/lib/pg_trunk/operations/domains/constraint.rb +93 -0
  71. data/lib/pg_trunk/operations/domains/create_domain.rb +124 -0
  72. data/lib/pg_trunk/operations/domains/drop_domain.rb +65 -0
  73. data/lib/pg_trunk/operations/domains/rename_domain.rb +44 -0
  74. data/lib/pg_trunk/operations/domains.rb +15 -0
  75. data/lib/pg_trunk/operations/enums/base.rb +47 -0
  76. data/lib/pg_trunk/operations/enums/change.rb +55 -0
  77. data/lib/pg_trunk/operations/enums/change_enum.rb +119 -0
  78. data/lib/pg_trunk/operations/enums/create_enum.rb +83 -0
  79. data/lib/pg_trunk/operations/enums/drop_enum.rb +63 -0
  80. data/lib/pg_trunk/operations/enums/rename_enum.rb +44 -0
  81. data/lib/pg_trunk/operations/enums.rb +15 -0
  82. data/lib/pg_trunk/operations/foreign_keys/add_foreign_key.rb +174 -0
  83. data/lib/pg_trunk/operations/foreign_keys/base.rb +155 -0
  84. data/lib/pg_trunk/operations/foreign_keys/drop_foreign_key.rb +76 -0
  85. data/lib/pg_trunk/operations/foreign_keys/rename_foreign_key.rb +63 -0
  86. data/lib/pg_trunk/operations/foreign_keys.rb +16 -0
  87. data/lib/pg_trunk/operations/functions/base.rb +54 -0
  88. data/lib/pg_trunk/operations/functions/change_function.rb +108 -0
  89. data/lib/pg_trunk/operations/functions/create_function.rb +198 -0
  90. data/lib/pg_trunk/operations/functions/drop_function.rb +88 -0
  91. data/lib/pg_trunk/operations/functions/rename_function.rb +57 -0
  92. data/lib/pg_trunk/operations/functions.rb +14 -0
  93. data/lib/pg_trunk/operations/indexes/add_index.rb +68 -0
  94. data/lib/pg_trunk/operations/indexes.rb +10 -0
  95. data/lib/pg_trunk/operations/materialized_views/base.rb +79 -0
  96. data/lib/pg_trunk/operations/materialized_views/change_materialized_view.rb +139 -0
  97. data/lib/pg_trunk/operations/materialized_views/column.rb +94 -0
  98. data/lib/pg_trunk/operations/materialized_views/create_materialized_view.rb +170 -0
  99. data/lib/pg_trunk/operations/materialized_views/drop_materialized_view.rb +70 -0
  100. data/lib/pg_trunk/operations/materialized_views/refresh_materialized_view.rb +48 -0
  101. data/lib/pg_trunk/operations/materialized_views/rename_materialized_view.rb +61 -0
  102. data/lib/pg_trunk/operations/materialized_views.rb +17 -0
  103. data/lib/pg_trunk/operations/procedures/base.rb +42 -0
  104. data/lib/pg_trunk/operations/procedures/change_procedure.rb +107 -0
  105. data/lib/pg_trunk/operations/procedures/create_procedure.rb +146 -0
  106. data/lib/pg_trunk/operations/procedures/drop_procedure.rb +66 -0
  107. data/lib/pg_trunk/operations/procedures/rename_procedure.rb +57 -0
  108. data/lib/pg_trunk/operations/procedures.rb +14 -0
  109. data/lib/pg_trunk/operations/statistics/base.rb +94 -0
  110. data/lib/pg_trunk/operations/statistics/create_statistics.rb +181 -0
  111. data/lib/pg_trunk/operations/statistics/drop_statistics.rb +75 -0
  112. data/lib/pg_trunk/operations/statistics/rename_statistics.rb +48 -0
  113. data/lib/pg_trunk/operations/statistics.rb +13 -0
  114. data/lib/pg_trunk/operations/tables/create_table.rb +75 -0
  115. data/lib/pg_trunk/operations/tables.rb +10 -0
  116. data/lib/pg_trunk/operations/triggers/base.rb +119 -0
  117. data/lib/pg_trunk/operations/triggers/change_trigger.rb +82 -0
  118. data/lib/pg_trunk/operations/triggers/create_trigger.rb +208 -0
  119. data/lib/pg_trunk/operations/triggers/drop_trigger.rb +66 -0
  120. data/lib/pg_trunk/operations/triggers/rename_trigger.rb +71 -0
  121. data/lib/pg_trunk/operations/triggers.rb +14 -0
  122. data/lib/pg_trunk/operations/views/base.rb +38 -0
  123. data/lib/pg_trunk/operations/views/change_view.rb +90 -0
  124. data/lib/pg_trunk/operations/views/create_view.rb +115 -0
  125. data/lib/pg_trunk/operations/views/drop_view.rb +69 -0
  126. data/lib/pg_trunk/operations/views/rename_view.rb +58 -0
  127. data/lib/pg_trunk/operations/views.rb +14 -0
  128. data/lib/pg_trunk/operations.rb +23 -0
  129. data/lib/pg_trunk/version.rb +6 -0
  130. data/lib/pg_trunk.rb +27 -0
  131. data/pg_trunk.gemspec +34 -0
  132. data/spec/dummy/.gitignore +16 -0
  133. data/spec/dummy/Rakefile +15 -0
  134. data/spec/dummy/bin/bundle +6 -0
  135. data/spec/dummy/bin/rails +6 -0
  136. data/spec/dummy/bin/rake +6 -0
  137. data/spec/dummy/config/application.rb +18 -0
  138. data/spec/dummy/config/boot.rb +7 -0
  139. data/spec/dummy/config/database.yml +14 -0
  140. data/spec/dummy/config/environment.rb +7 -0
  141. data/spec/dummy/config.ru +6 -0
  142. data/spec/dummy/db/materialized_views/admin_users_v01.sql +1 -0
  143. data/spec/dummy/db/migrate/.keep +0 -0
  144. data/spec/dummy/db/schema.rb +18 -0
  145. data/spec/dummy/db/views/admin_users_v01.sql +1 -0
  146. data/spec/dummy/db/views/admin_users_v02.sql +1 -0
  147. data/spec/operations/check_constraints/add_check_constraint_spec.rb +85 -0
  148. data/spec/operations/check_constraints/drop_check_constraint_spec.rb +111 -0
  149. data/spec/operations/check_constraints/rename_check_constraint_spec.rb +90 -0
  150. data/spec/operations/composite_types/change_composite_type_spec.rb +257 -0
  151. data/spec/operations/composite_types/create_composite_type_spec.rb +55 -0
  152. data/spec/operations/composite_types/drop_composite_type_spec.rb +109 -0
  153. data/spec/operations/composite_types/rename_composite_type_spec.rb +74 -0
  154. data/spec/operations/dependency_resolver_spec.rb +177 -0
  155. data/spec/operations/domains/change_domain_spec.rb +287 -0
  156. data/spec/operations/domains/create_domain_spec.rb +69 -0
  157. data/spec/operations/domains/drop_domain_spec.rb +119 -0
  158. data/spec/operations/domains/rename_domain_spec.rb +70 -0
  159. data/spec/operations/enums/change_enum_spec.rb +157 -0
  160. data/spec/operations/enums/create_enum_spec.rb +40 -0
  161. data/spec/operations/enums/drop_enum_spec.rb +120 -0
  162. data/spec/operations/enums/rename_enum_spec.rb +72 -0
  163. data/spec/operations/foreign_keys/add_foreign_key_spec.rb +208 -0
  164. data/spec/operations/foreign_keys/drop_foreign_key_spec.rb +167 -0
  165. data/spec/operations/foreign_keys/rename_foreign_key_spec.rb +101 -0
  166. data/spec/operations/functions/change_function_spec.rb +166 -0
  167. data/spec/operations/functions/create_function_spec.rb +192 -0
  168. data/spec/operations/functions/drop_function_spec.rb +182 -0
  169. data/spec/operations/functions/rename_function_spec.rb +101 -0
  170. data/spec/operations/indexes/add_index_spec.rb +94 -0
  171. data/spec/operations/materialized_views/change_materialized_view_spec.rb +190 -0
  172. data/spec/operations/materialized_views/create_materialized_view_spec.rb +144 -0
  173. data/spec/operations/materialized_views/drop_materialized_view_spec.rb +145 -0
  174. data/spec/operations/materialized_views/refresh_materialized_view_spec.rb +79 -0
  175. data/spec/operations/materialized_views/rename_materialized_view_spec.rb +88 -0
  176. data/spec/operations/procedures/change_procedure_spec.rb +175 -0
  177. data/spec/operations/procedures/create_procedure_spec.rb +151 -0
  178. data/spec/operations/procedures/drop_procedure_spec.rb +159 -0
  179. data/spec/operations/procedures/rename_procedure_spec.rb +107 -0
  180. data/spec/operations/statistics/create_statistics_spec.rb +230 -0
  181. data/spec/operations/statistics/drop_statistics_spec.rb +106 -0
  182. data/spec/operations/statistics/rename_statistics_spec.rb +129 -0
  183. data/spec/operations/tables/create_table_spec.rb +53 -0
  184. data/spec/operations/tables/rename_table_spec.rb +37 -0
  185. data/spec/operations/triggers/change_trigger_spec.rb +195 -0
  186. data/spec/operations/triggers/create_trigger_spec.rb +104 -0
  187. data/spec/operations/triggers/drop_trigger_spec.rb +124 -0
  188. data/spec/operations/triggers/rename_trigger_spec.rb +160 -0
  189. data/spec/operations/views/change_view_spec.rb +144 -0
  190. data/spec/operations/views/create_view_spec.rb +134 -0
  191. data/spec/operations/views/drop_view_spec.rb +146 -0
  192. data/spec/operations/views/rename_view_spec.rb +85 -0
  193. data/spec/pg_trunk/dependencies_resolver_spec.rb +43 -0
  194. data/spec/spec_helper.rb +28 -0
  195. data/spec/support/migrations_helper.rb +376 -0
  196. metadata +348 -0
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe ActiveRecord::Migration, "#create_statistics" do
4
+ before_all do
5
+ run_migration <<~RUBY
6
+ create_table :users do |t|
7
+ t.string :name
8
+ t.string :family
9
+ end
10
+ RUBY
11
+ end
12
+
13
+ context "with an explicit name" do
14
+ let(:migration) do
15
+ <<~RUBY
16
+ create_statistics "my_stats" do |s|
17
+ s.table "users"
18
+ s.columns "family", "name"
19
+ s.kinds :dependencies, :ndistinct
20
+ s.comment "Collect all stats"
21
+ end
22
+ RUBY
23
+ end
24
+
25
+ its(:execution) { is_expected.to insert(migration).into_schema }
26
+ its(:inversion) { is_expected.not_to change_schema }
27
+ end
28
+
29
+ context "without a name" do
30
+ let(:migration) do
31
+ <<~RUBY
32
+ create_statistics do |s|
33
+ s.table "users"
34
+ s.columns "family", "name"
35
+ s.kinds :dependencies, :ndistinct
36
+ s.comment "Collect all stats"
37
+ end
38
+ RUBY
39
+ end
40
+
41
+ its(:execution) { is_expected.to insert(migration).into_schema }
42
+ its(:inversion) { is_expected.not_to change_schema }
43
+ end
44
+
45
+ context "with one column" do
46
+ let(:migration) do
47
+ <<~RUBY
48
+ create_statistics "my_stats" do |s|
49
+ s.table "users"
50
+ s.columns "family"
51
+ s.kinds :dependencies, :ndistinct
52
+ s.comment "Collect all stats"
53
+ end
54
+ RUBY
55
+ end
56
+
57
+ it { is_expected.to fail_validation.because(/add more columns/i) }
58
+ end
59
+
60
+ context "with several expressions", since_version: 14 do
61
+ let(:migration) do
62
+ <<~RUBY
63
+ create_statistics "my_stats" do |s|
64
+ s.table "users"
65
+ s.expression "length(family::text)"
66
+ s.expression "length(name::text)"
67
+ s.kinds :dependencies, :ndistinct
68
+ s.comment "Collect all stats"
69
+ end
70
+ RUBY
71
+ end
72
+
73
+ its(:execution) { is_expected.to insert(migration).into_schema }
74
+ its(:inversion) { is_expected.not_to change_schema }
75
+ end
76
+
77
+ context "with several columns and expressions", since_version: 14 do
78
+ let(:migration) do
79
+ <<~RUBY
80
+ create_statistics "my_stats" do |s|
81
+ s.table "users"
82
+ s.columns "name"
83
+ s.expression "length(family::text)"
84
+ s.kinds :dependencies, :ndistinct
85
+ s.comment "Collect all stats"
86
+ end
87
+ RUBY
88
+ end
89
+
90
+ its(:execution) { is_expected.to insert(migration).into_schema }
91
+ its(:inversion) { is_expected.not_to change_schema }
92
+ end
93
+
94
+ context "with mcv kind" do
95
+ let(:migration) do
96
+ <<~RUBY
97
+ create_statistics "my_stats" do |s|
98
+ s.table "users"
99
+ s.columns "family", "name"
100
+ s.kinds :dependencies, :mcv, :ndistinct
101
+ s.comment "Collect all stats"
102
+ end
103
+ RUBY
104
+ end
105
+
106
+ context "before version 12", before_version: 12 do
107
+ its(:execution) { is_expected.to raise_error(/supported in PostgreSQL v12+/i) }
108
+ end
109
+
110
+ context "since version 12", since_version: 12 do
111
+ its(:execution) { is_expected.to insert(migration).into_schema }
112
+ its(:inversion) { is_expected.not_to change_schema }
113
+ end
114
+ end
115
+
116
+ context "with one expression only", since_version: 14 do
117
+ context "without kinds" do
118
+ let(:migration) do
119
+ <<~RUBY
120
+ create_statistics "my_stats" do |s|
121
+ s.table "users"
122
+ s.expression "length(family::text)"
123
+ s.comment "Collect all stats"
124
+ end
125
+ RUBY
126
+ end
127
+
128
+ its(:execution) { is_expected.to insert(migration).into_schema }
129
+ its(:inversion) { is_expected.not_to change_schema }
130
+ end
131
+
132
+ context "with kinds" do
133
+ let(:migration) do
134
+ <<~RUBY
135
+ create_statistics "my_stats" do |s|
136
+ s.table "users"
137
+ s.expression "length(family::text)"
138
+ s.kinds :dependencies
139
+ s.comment "Collect all stats"
140
+ end
141
+ RUBY
142
+ end
143
+
144
+ it { is_expected.to fail_validation.because(/kinds must be blank/i) }
145
+ end
146
+ end
147
+
148
+ context "with expressions", before_version: 14 do
149
+ let(:migration) do
150
+ <<~RUBY
151
+ create_statistics "my_stats" do |s|
152
+ s.table "users"
153
+ s.columns "name"
154
+ s.expression "length(family::text)"
155
+ s.kinds :dependencies, :ndistinct
156
+ s.comment "Collect all stats"
157
+ end
158
+ RUBY
159
+ end
160
+
161
+ its(:execution) { is_expected.to raise_error(/supported in PostgreSQL v14+/i) }
162
+ end
163
+
164
+ context "when the statistics existed" do
165
+ before do
166
+ run_migration <<~RUBY
167
+ create_statistics "my_stats" do |s|
168
+ s.table "users"
169
+ s.columns "family", "name"
170
+ s.comment "Collect all stats"
171
+ end
172
+ RUBY
173
+ end
174
+
175
+ context "without the `if_not_exists` option" do
176
+ let(:migration) do
177
+ <<~RUBY
178
+ create_statistics "my_stats" do |s|
179
+ s.table "users"
180
+ s.columns "family", "name"
181
+ s.comment "Collect all stats"
182
+ end
183
+ RUBY
184
+ end
185
+
186
+ its(:execution) { is_expected.to raise_error(StandardError) }
187
+ end
188
+
189
+ context "with the `if_not_exists: true` option" do
190
+ let(:migration) do
191
+ <<~RUBY
192
+ create_statistics "my_stats", if_not_exists: true do |s|
193
+ s.table "users"
194
+ s.columns "family", "name"
195
+ s.comment "Collect all stats"
196
+ end
197
+ RUBY
198
+ end
199
+
200
+ its(:execution) { is_expected.not_to change_schema }
201
+ it { is_expected.to be_irreversible.because_of(/if_not_exists: true/i) }
202
+ end
203
+
204
+ context "without a table" do
205
+ let(:migration) do
206
+ <<~RUBY
207
+ create_statistics "my_stats" do |s|
208
+ s.columns "family", "name"
209
+ s.kinds :dependencies, :ndistinct
210
+ end
211
+ RUBY
212
+ end
213
+
214
+ it { is_expected.to fail_validation.because(/table can't be blank/i) }
215
+ end
216
+
217
+ context "without columns and expressions" do
218
+ let(:migration) do
219
+ <<~RUBY
220
+ create_statistics "my_stats" do |s|
221
+ s.table "users"
222
+ s.kinds :dependencies, :ndistinct
223
+ end
224
+ RUBY
225
+ end
226
+
227
+ it { is_expected.to fail_validation.because(/can't be blank/i) }
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe ActiveRecord::Migration, "#drop_statistics" do
4
+ before_all do
5
+ run_migration <<~RUBY
6
+ create_table :users do |t|
7
+ t.string :name
8
+ t.string :family
9
+ end
10
+ RUBY
11
+ end
12
+ before { run_migration(snippet) }
13
+
14
+ context "when the statistics was anonymous" do
15
+ let(:snippet) do
16
+ <<~RUBY
17
+ create_statistics do |s|
18
+ s.table "users"
19
+ s.columns "family", "name"
20
+ s.kinds :dependencies, :ndistinct
21
+ end
22
+ RUBY
23
+ end
24
+ let(:migration) do
25
+ <<~RUBY
26
+ drop_statistics do |s|
27
+ s.table "users"
28
+ s.columns "family", "name"
29
+ s.kinds :dependencies, :ndistinct
30
+ end
31
+ RUBY
32
+ end
33
+
34
+ its(:execution) { is_expected.to remove(snippet).from_schema }
35
+ its(:inversion) { is_expected.not_to change_schema }
36
+ end
37
+
38
+ context "when the statistics was named explicitly" do
39
+ let(:snippet) do
40
+ <<~RUBY
41
+ create_statistics "my_stats" do |s|
42
+ s.table "users"
43
+ s.columns "family", "name"
44
+ s.kinds :dependencies, :ndistinct
45
+ end
46
+ RUBY
47
+ end
48
+ let(:migration) do
49
+ <<~RUBY
50
+ drop_statistics "my_stats" do |s|
51
+ s.table "users"
52
+ s.columns "family", "name"
53
+ s.kinds :dependencies, :ndistinct
54
+ end
55
+ RUBY
56
+ end
57
+
58
+ its(:execution) { is_expected.to remove(snippet).from_schema }
59
+ its(:inversion) { is_expected.not_to change_schema }
60
+ end
61
+
62
+ context "without a full definition" do
63
+ let(:snippet) do
64
+ <<~RUBY
65
+ create_statistics "my_stats" do |s|
66
+ s.table "users"
67
+ s.columns "family", "name"
68
+ s.kinds :dependencies, :ndistinct
69
+ end
70
+ RUBY
71
+ end
72
+ let(:migration) do
73
+ <<~RUBY
74
+ drop_statistics "my_stats"
75
+ RUBY
76
+ end
77
+
78
+ its(:execution) { is_expected.to remove(snippet).from_schema }
79
+ it { is_expected.to be_irreversible.because(/table can't be blank/i) }
80
+ end
81
+
82
+ context "when a statistics was absent" do
83
+ let(:snippet) { "" }
84
+
85
+ context "without `if_exists` option" do
86
+ let(:migration) do
87
+ <<~RUBY
88
+ drop_statistics "my_stats"
89
+ RUBY
90
+ end
91
+
92
+ its(:execution) { is_expected.to raise_error(StandardError) }
93
+ end
94
+
95
+ context "with the `if_exists: true` option" do
96
+ let(:migration) do
97
+ <<~RUBY
98
+ drop_statistics "my_stats", if_exists: true
99
+ RUBY
100
+ end
101
+
102
+ its(:execution) { is_expected.not_to change_schema }
103
+ it { is_expected.to be_irreversible.because_of(/if_exists: true/i) }
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe ActiveRecord::Migration, "#rename_statistics" do
4
+ before_all do
5
+ run_migration <<~RUBY
6
+ create_table :users do |t|
7
+ t.string :name
8
+ t.string :family
9
+ end
10
+ RUBY
11
+ end
12
+ before { run_migration(old_snippet) }
13
+
14
+ context "when the constraint was anonymous" do
15
+ let(:old_snippet) do
16
+ <<~RUBY
17
+ create_statistics do |s|
18
+ s.table :users
19
+ s.kinds :dependencies, :ndistinct
20
+ s.columns "name", "family"
21
+ end
22
+ RUBY
23
+ end
24
+
25
+ context "with a new name" do
26
+ let(:migration) do
27
+ <<~RUBY
28
+ rename_statistics to: "my_stats" do |s|
29
+ s.table :users
30
+ s.kinds :dependencies, :ndistinct
31
+ s.columns "name", "family"
32
+ end
33
+ RUBY
34
+ end
35
+ let(:new_snippet) do
36
+ <<~RUBY
37
+ create_statistics "my_stats" do |s|
38
+ s.table "users"
39
+ s.columns "family", "name"
40
+ s.kinds :dependencies, :ndistinct
41
+ end
42
+ RUBY
43
+ end
44
+
45
+ its(:execution) { is_expected.to insert(new_snippet).into_schema }
46
+ its(:reversion) { is_expected.not_to change_schema }
47
+ end
48
+
49
+ context "without a new name" do
50
+ let(:migration) do
51
+ <<~RUBY
52
+ rename_statistics do |s|
53
+ s.table :users
54
+ s.kinds :dependencies, :ndistinct
55
+ s.columns "name", "family"
56
+ end
57
+ RUBY
58
+ end
59
+
60
+ it { is_expected.to fail_validation.because(/new name must be different/i) }
61
+ end
62
+ end
63
+
64
+ context "when the constraint was named explicitly" do
65
+ let(:old_snippet) do
66
+ <<~RUBY
67
+ create_statistics "my_old_name" do |s|
68
+ s.table "users"
69
+ s.kinds :dependencies, :ndistinct
70
+ s.columns "name", "family"
71
+ end
72
+ RUBY
73
+ end
74
+
75
+ context "with a new name" do
76
+ let(:migration) do
77
+ <<~RUBY
78
+ rename_statistics "my_old_name", to: "my_new_name"
79
+ RUBY
80
+ end
81
+ let(:new_snippet) do
82
+ <<~RUBY
83
+ create_statistics "my_new_name" do |s|
84
+ s.table "users"
85
+ s.columns "family", "name"
86
+ s.kinds :dependencies, :ndistinct
87
+ end
88
+ RUBY
89
+ end
90
+
91
+ its(:execution) { is_expected.to insert(new_snippet).into_schema }
92
+ its(:reversion) { is_expected.not_to change_schema }
93
+ end
94
+
95
+ context "when missed new name can be generated" do
96
+ let(:migration) do
97
+ <<~RUBY
98
+ rename_statistics "my_old_name" do |s|
99
+ s.table "users"
100
+ s.kinds :dependencies, :ndistinct
101
+ s.columns "name", "family"
102
+ end
103
+ RUBY
104
+ end
105
+ let(:snippet) do
106
+ <<~RUBY
107
+ create_statistics do |s|
108
+ s.table "users"
109
+ s.columns "family", "name"
110
+ s.kinds :dependencies, :ndistinct
111
+ end
112
+ RUBY
113
+ end
114
+
115
+ its(:execution) { is_expected.to insert(snippet).into_schema }
116
+ its(:reversion) { is_expected.not_to change_schema }
117
+ end
118
+
119
+ context "when missed new name can't be generated" do
120
+ let(:migration) do
121
+ <<~RUBY
122
+ rename_statistics "my_old_name"
123
+ RUBY
124
+ end
125
+
126
+ it { is_expected.to fail_validation.because(/new name can't be blank/i) }
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe ActiveRecord::Migration, "#create_table" do
4
+ context "with indexes and check constraints" do
5
+ let(:migration) do
6
+ <<~RUBY
7
+ create_table :roles
8
+ create_table :users do |t|
9
+ t.integer :role_id, index: true
10
+ t.string :name
11
+ t.check_constraint "length(name) > 2"
12
+ t.foreign_key :roles
13
+ end
14
+ RUBY
15
+ end
16
+ let(:snippet) do
17
+ <<~RUBY
18
+ create_table "roles", force: :cascade do |t|
19
+ end
20
+
21
+ create_table "users", force: :cascade do |t|
22
+ t.integer "role_id"
23
+ t.string "name"
24
+ end
25
+
26
+ add_index "users", ["role_id"], name: "index_users_on_role_id"
27
+
28
+ add_check_constraint "users", "length((name)::text) > 2"
29
+
30
+ add_foreign_key "users", "roles"
31
+ RUBY
32
+ end
33
+
34
+ its(:execution) { is_expected.to insert(snippet).into_schema }
35
+ end
36
+
37
+ context "with a custom id (primary key) definition" do
38
+ let(:migration) do
39
+ <<~RUBY
40
+ create_table :users, primary_key: :name do |t|
41
+ end
42
+ RUBY
43
+ end
44
+ let(:snippet) do
45
+ <<~RUBY
46
+ create_table "users", primary_key: "name", force: :cascade do |t|
47
+ end
48
+ RUBY
49
+ end
50
+
51
+ its(:execution) { is_expected.to insert(snippet).into_schema }
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe ActiveRecord::Migration, "#rename_table" do
4
+ let(:migration) do
5
+ <<~RUBY
6
+ create_table :roles
7
+ create_table :users do |t|
8
+ t.integer :role_id, index: true
9
+ t.string :name
10
+ t.foreign_key :roles
11
+ t.check_constraint "length(name) > 1"
12
+ end
13
+
14
+ rename_table :users, :customers
15
+ RUBY
16
+ end
17
+ let(:snippet) do
18
+ <<~RUBY
19
+ create_table "customers", force: :cascade do |t|
20
+ t.integer "role_id"
21
+ t.string "name"
22
+ end
23
+
24
+ create_table "roles", force: :cascade do |t|
25
+ end
26
+
27
+ add_index "customers", ["role_id"], name: "index_customers_on_role_id"
28
+
29
+ add_check_constraint "customers", "length((name)::text) > 1"
30
+
31
+ add_foreign_key "customers", "roles"
32
+ RUBY
33
+ end
34
+
35
+ its(:execution) { is_expected.to insert(snippet).into_schema }
36
+ its(:inversion) { is_expected.not_to change_schema }
37
+ end