defmodule Mix.Tasks.Dynamo.Gen.Migration do
use Mix.Task
import Macro, only: [camelize: 1, underscore: 1]
import Mix.Generator
@shortdoc "Generates a new migration file for DynamoDB"
@aliases [
t: :table,
e: :env_prefix
]
@switches [
table: :string,
env_prefix: :boolean,
change: :string
]
@spec run([String.t()]) :: integer()
def run(args) do
case OptionParser.parse!(args, strict: @switches, aliases: @aliases) do
{opts, [file_name]} ->
if opts[:table] do
process(file_name, opts)
else
Mix.raise(
"expected dynamo.gen.migration to receive the table name, " <>
"got: #{inspect(Enum.join(args, " "))}"
)
end
_ ->
Mix.raise(
"expected dynamo.gen.migration to receive the migration file name, " <>
"got: #{inspect(Enum.join(args, " "))}"
)
end
end
defp process(file_name, opts) do
table_name = opts[:table]
include_env_prefix = !!opts[:env_prefix]
change =
opts[:change] ||
"""
# ## You can freely write operations related to DynamoDB.
# ### Examples.
# ExAws.Dynamo.create_table(
# "Tests", # You may type `Mix.env() <> "table_name"` if want to use it properly want by environment.
# [id: :hash],
# %{id: :number},
# 1,
# 1,
# :provisioned
# )
# |> ExAws.request!()
"""
migrations_path = DynamoMigration.migration_file_path()
base_name = "#{underscore(file_name)}.exs"
current_timestamp = timestamp()
file = Path.join(migrations_path, "#{current_timestamp}_#{base_name}")
unless File.dir?(migrations_path), do: create_directory(migrations_path)
fuzzy_path = Path.join(migrations_path, "*_#{base_name}")
if Path.wildcard(fuzzy_path) != [],
do:
Mix.raise(
"migration can't be created, there is already a migration file with name #{file_name}."
)
assigns = [
mod: Module.concat([Dynamo, Migrations, camelize(file_name)]),
table:
(include_env_prefix && "\#{Mix.env()}.#{table_name}") ||
table_name,
change: change
]
create_file(file, migration_template(assigns))
current_timestamp |> String.to_integer()
end
defp timestamp do
{{y, m, d}, {hh, mm, ss}} = :calendar.universal_time()
"#{y}#{pad(m)}#{pad(d)}#{pad(hh)}#{pad(mm)}#{pad(ss)}"
end
defp pad(i) when i < 10, do: <<?0, ?0 + i>>
defp pad(i), do: to_string(i)
embed_template(:migration, """
defmodule <%= inspect @mod %> do
@table_name "<%=@table %>"
def table_name, do: @table_name
def change do
<%=@change %>
end
end
""")
end