Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit01f60a5

Browse files
committed
chore: rework how multi-snapshots work
1 parent19b3ccf commit01f60a5

File tree

3 files changed

+111
-72
lines changed

3 files changed

+111
-72
lines changed

‎lib/migration_generator/migration_generator.ex‎

Lines changed: 101 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ defmodule AshPostgres.MigrationGenerator do
7474
|>group_into_phases()
7575
|>comment_out_phases()
7676
|>build_up_and_down()
77-
|>write_migration(snapshots,repo,opts,tenant?)
77+
|>write_migration!(snapshots,repo,opts,tenant?)
7878
end
7979
end)
8080
end
@@ -302,47 +302,9 @@ defmodule AshPostgres.MigrationGenerator do
302302
|>Enum.sort()
303303
end
304304

305-
defpwrite_migration({up,down},snapshots,repo,opts,tenant?)do
305+
defpwrite_migration!({up,down},snapshots,repo,opts,tenant?)do
306306
repo_name=repo|>Module.split()|>List.last()|>Macro.underscore()
307307

308-
unlessopts.dry_rundo
309-
Enum.each(snapshots,fnsnapshot->
310-
snapshot_binary=snapshot_to_binary(snapshot)
311-
312-
snapshot_table="#{timestamp()}_#{snapshot.table}"
313-
314-
snapshot_folder=
315-
iftenant?do
316-
opts.snapshot_path
317-
|>Path.join(repo_name)
318-
|>Path.join("tenants")
319-
else
320-
opts.snapshot_path
321-
|>Path.join(repo_name)
322-
end
323-
324-
snapshot_file=
325-
snapshot_folder
326-
|>Path.join(snapshot_table<>".json")
327-
328-
File.mkdir_p(Path.dirname(snapshot_file))
329-
File.write!(snapshot_file,snapshot_binary,[])
330-
331-
# create a new version file to track latest migration file
332-
version_file=
333-
snapshot_folder
334-
|>Path.join(snapshot.table<>".version.json")
335-
336-
version_binary=
337-
snapshot_to_binary(%{
338-
latest_version:snapshot_file
339-
})
340-
341-
File.mkdir_p(Path.dirname(version_file))
342-
File.write!(version_file,version_binary,[])
343-
end)
344-
end
345-
346308
migration_path=
347309
iftenant?do
348310
ifopts.tenant_migration_pathdo
@@ -438,10 +400,73 @@ defmodule AshPostgres.MigrationGenerator do
438400
end
439401
"""
440402

441-
ifopts.dry_rundo
442-
Mix.shell().info(format(contents,opts))
443-
else
444-
create_file(migration_file,format(contents,opts))
403+
trydo
404+
contents=format(contents,opts)
405+
406+
create_new_snapshot(snapshots,repo_name,opts,tenant?)
407+
408+
ifopts.dry_rundo
409+
Mix.shell().info(contents)
410+
else
411+
create_file(migration_file,contents)
412+
end
413+
rescue
414+
exception->
415+
reraise(
416+
"""
417+
Exception while formatting generated code:
418+
#{Exception.format(:error,exception,__STACKTRACE__)}
419+
420+
Code:
421+
422+
#{add_line_numbers(contents)}
423+
424+
To generate it unformatted anyway, but manually fix it, use the `--no-format` option.
425+
""",
426+
__STACKTRACE__
427+
)
428+
end
429+
end
430+
431+
defpadd_line_numbers(contents)do
432+
lines=String.split(contents,"\n")
433+
434+
digits=String.length(to_string(Enum.count(lines)))
435+
436+
lines
437+
|>Enum.with_index()
438+
|>Enum.map_join("\n",fn{line,index}->
439+
"#{String.pad_trailing(to_string(index),digits," ")} |#{line}"
440+
end)
441+
end
442+
443+
defpcreate_new_snapshot(snapshots,repo_name,opts,tenant?)do
444+
unlessopts.dry_rundo
445+
Enum.each(snapshots,fnsnapshot->
446+
snapshot_binary=snapshot_to_binary(snapshot)
447+
448+
snapshot_folder=
449+
iftenant?do
450+
opts.snapshot_path
451+
|>Path.join(repo_name)
452+
|>Path.join("tenants")
453+
else
454+
opts.snapshot_path
455+
|>Path.join(repo_name)
456+
end
457+
458+
snapshot_file=Path.join(snapshot_folder,"#{snapshot.table}/#{timestamp()}.json")
459+
460+
File.mkdir_p(Path.dirname(snapshot_file))
461+
File.write!(snapshot_file,snapshot_binary,[])
462+
463+
old_snapshot_folder=Path.join(snapshot_folder,"#{snapshot.table}.json")
464+
465+
ifFile.exists?(old_snapshot_folder)do
466+
new_snapshot_folder=Path.join(snapshot_folder,"#{snapshot.table}/initial.json")
467+
File.rename(old_snapshot_folder,new_snapshot_folder)
468+
end
469+
end)
445470
end
446471
end
447472

@@ -951,27 +976,42 @@ defmodule AshPostgres.MigrationGenerator do
951976
|>Path.join(repo_name)
952977
|>Path.join("tenants")
953978
else
954-
Path.join(opts.snapshot_path,repo_name)
979+
opts.snapshot_path
980+
|>Path.join(repo_name)
955981
end
956982

957-
# get name of latest version file.
958-
version_file=Path.join(folder,snapshot.table<>".version.json")
983+
snapshot_folder=Path.join(folder,snapshot.table)
959984

960-
file=
961-
ifFile.exists?(version_file)do
962-
file_content=
963-
version_file
964-
|>File.read!()
965-
|>Jason.decode!(keys::atoms!)
985+
ifFile.exists?(snapshot_folder)do
986+
snapshot_folder
987+
|>File.ls!()
988+
|>Enum.filter(&String.ends_with?(&1,".json"))
989+
|>Enum.map(&String.trim_trailing(&1,".json"))
990+
|>Enum.map(&Integer.parse/1)
991+
|>Enum.filter(fn{_int,remaining}->remaining==""end)
992+
|>Enum.map(&elem(&1,0))
993+
|>casedo
994+
[]->
995+
get_old_snapshot(folder,snapshot)
966996

967-
file_content.latest_version
968-
else
969-
version_file=Path.join(folder,snapshot.table<>".json")
970-
version_file
997+
timestamps->
998+
timestamp=Enum.max(timestamps)
999+
snapshot_file=Path.join(snapshot_folder,"#{timestamp}.json")
1000+
1001+
snapshot_file
1002+
|>File.read!()
1003+
|>load_snapshot()
9711004
end
1005+
else
1006+
get_old_snapshot(folder,snapshot)
1007+
end
1008+
end
9721009

973-
ifFile.exists?(file)do
974-
file
1010+
defpget_old_snapshot(folder,snapshot)do
1011+
old_snapshot_file=Path.join(folder,"#{snapshot.table}.json")
1012+
# This is adapter code for the old version, where migrations were stored in a flat directory
1013+
ifFile.exists?(old_snapshot_file)do
1014+
old_snapshot_file
9751015
|>File.read!()
9761016
|>load_snapshot()
9771017
end
@@ -1206,6 +1246,8 @@ defmodule AshPostgres.MigrationGenerator do
12061246
attribute
12071247
|>Map.update!(:type,&String.to_atom/1)
12081248
|>Map.update!(:name,&String.to_atom/1)
1249+
|>Map.put_new(:default,"nil")
1250+
|>Map.update!(:default,&(&1||"nil"))
12091251
|>Map.update!(:references,fn
12101252
nil->
12111253
nil

‎lib/mix/tasks/ash_postgres.generate_migrations.ex‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ defmodule Mix.Tasks.AshPostgres.GenerateMigrations do
1717
* `no_format` - files that are created will not be formatted with the code formatter
1818
* `dry_run` - no files are created, instead the new migration is printed
1919
20+
#### Snapshots
21+
22+
Snapshots are stored in a folder for each table that migrations are generated for. Each snapshot is
23+
stored in a file with a timestamp of when it was generated.
24+
This is important because it allows for simultaneous work to be done on separate branches, and for rolling back
25+
changes more easily, e.g removing a generated migration, and deleting the most recent snapshot, without having to redo
26+
all of it
2027
2128
#### Dropping columns
2229

‎test/migration_generator_test.exs‎

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,26 +79,16 @@ defmodule AshPostgres.MigrationGeneratorTest do
7979
end
8080

8181
test"it creates a snapshot for each resource"do
82-
assertFile.exists?(Path.wildcard("test_snapshots_path/test_repo/*_posts.json"))
83-
assertFile.exists?(Path.join(["test_snapshots_path","test_repo","posts.version.json"]))
82+
assertFile.exists?(Path.wildcard("test_snapshots_path/test_repo/posts/*.json"))
8483
end
8584

8685
test"the snapshots can be loaded"do
87-
assertFile.exists?(Path.wildcard("test_snapshots_path/test_repo/*_posts.json"))
88-
assertFile.exists?(Path.join(["test_snapshots_path","test_repo","posts.version.json"]))
86+
assertFile.exists?(Path.wildcard("test_snapshots_path/test_repo/posts/*.json"))
8987
end
9088

9189
test"the snapshots contain valid json"do
92-
assertFile.exists?(Path.join(["test_snapshots_path","test_repo","posts.version.json"]))
93-
94-
assertFile.read!(Path.wildcard("test_snapshots_path/test_repo/*_posts.json"))
90+
assertFile.read!(Path.wildcard("test_snapshots_path/test_repo/posts/*.json"))
9591
|>Jason.decode!(keys::atoms!)
96-
97-
version_file_content=
98-
File.read!(Path.join(["test_snapshots_path","test_repo","posts.version.json"]))
99-
|>Jason.decode!(keys::atoms!)
100-
101-
assertMap.get(version_file_content,:latest_version,nil)!=nil
10292
end
10393

10494
test"the migration creates the table"do

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp