@@ -24,15 +24,7 @@ defmodule AshPostgres.MigrationGenerator do
2424
2525def generate ( apis , opts \\ [ ] ) do
2626apis = List . wrap ( apis )
27-
28- opts =
29- case struct ( __MODULE__ , opts ) do
30- % { check_generated: true } = opts ->
31- % { opts | dry_run: true }
32-
33- opts ->
34- opts
35- end
27+ opts = opts ( opts )
3628
3729all_resources = Enum . flat_map ( apis , & Ash.Api . resources / 1 )
3830
@@ -184,7 +176,10 @@ defmodule AshPostgres.MigrationGenerator do
184176|> Enum . each ( fn { repo , snapshots } ->
185177deduped = deduplicate_snapshots ( snapshots , opts )
186178
187- snapshots_with_operations = fetch_operations ( deduped , opts )
179+ snapshots_with_operations =
180+ deduped
181+ |> fetch_operations ( opts )
182+ |> Enum . map ( & add_order_to_operations / 1 )
188183
189184snapshots = Enum . map ( snapshots_with_operations , & elem ( & 1 , 0 ) )
190185
@@ -217,6 +212,28 @@ defmodule AshPostgres.MigrationGenerator do
217212end )
218213end
219214
215+ defp add_order_to_operations ( { snapshot , operations } ) do
216+ operations_with_order = Enum . map ( operations , & add_order_to_operation ( & 1 , snapshot . attributes ) )
217+
218+ { snapshot , operations_with_order }
219+ end
220+
221+ defp add_order_to_operation ( % { attribute: attribute } = op , attributes ) do
222+ order = Enum . find_index ( attributes , & ( & 1 . name == attribute . name ) )
223+ attribute = Map . put ( attribute , :order , order )
224+
225+ % { op | attribute: attribute }
226+ end
227+
228+ defp add_order_to_operation ( % { new_attribute: attribute } = op , attributes ) do
229+ order = Enum . find_index ( attributes , & ( & 1 . name == attribute . name ) )
230+ attribute = Map . put ( attribute , :order , order )
231+
232+ % { op | new_attribute: attribute }
233+ end
234+
235+ defp add_order_to_operation ( op , _ ) , do: op
236+
220237defp organize_operations ( [ ] ) , do: [ ]
221238
222239defp organize_operations ( operations ) do
@@ -314,6 +331,8 @@ defmodule AshPostgres.MigrationGenerator do
314331
315332defp merge_attributes ( attributes , table , count ) do
316333attributes
334+ |> Enum . with_index ( )
335+ |> Enum . map ( fn { attr , i } -> Map . put ( attr , :order , i ) end )
317336|> Enum . group_by ( & & 1 . name )
318337|> Enum . map ( fn { name , attributes } ->
319338% {
@@ -323,9 +342,12 @@ defmodule AshPostgres.MigrationGenerator do
323342allow_nil?: Enum . any? ( attributes , & & 1 . allow_nil? ) || Enum . count ( attributes ) < count ,
324343generated?: Enum . any? ( attributes , & & 1 . generated? ) ,
325344references: merge_references ( Enum . map ( attributes , & & 1 . references ) , name , table ) ,
326- primary_key?: false
345+ primary_key?: false ,
346+ order: attributes |> Enum . map ( & & 1 . order ) |> Enum . min ( )
327347}
328348end )
349+ |> Enum . sort ( & ( & 1 . order < & 2 . order ) )
350+ |> Enum . map ( & Map . drop ( & 1 , [ :order ] ) )
329351end
330352
331353defp merge_references ( references , name , table ) do
@@ -834,6 +856,12 @@ defmodule AshPostgres.MigrationGenerator do
834856sort_operations ( rest , new_acc )
835857end
836858
859+ defp after? (
860+ % Operation.AddAttribute { attribute: % { order: l } , table: table } ,
861+ % Operation.AddAttribute { attribute: % { order: r } , table: table }
862+ ) ,
863+ do: l > r
864+
837865defp after? (
838866% Operation.RenameUniqueIndex {
839867table: table
@@ -1009,6 +1037,9 @@ defmodule AshPostgres.MigrationGenerator do
10091037when not is_nil ( references ) ,
10101038do: true
10111039
1040+ defp after? ( % Operation.AddCheckConstraint { } , _ ) , do: true
1041+ defp after? ( % Operation.RemoveCheckConstraint { } , _ ) , do: true
1042+
10121043defp after? ( _ , _ ) , do: false
10131044
10141045defp fetch_operations ( snapshots , opts ) do
@@ -1520,7 +1551,6 @@ defmodule AshPostgres.MigrationGenerator do
15201551
15211552resource
15221553|> Ash.Resource.Info . attributes ( )
1523- |> Enum . sort_by ( & & 1 . name )
15241554|> Enum . map ( & Map . take ( & 1 , [ :name , :type , :default , :allow_nil? , :generated? , :primary_key? ] ) )
15251555|> Enum . map ( fn attribute ->
15261556default = default ( attribute , repo )