defmodule Xmeta.South.Migrate.Template do def template do """ defmodule Repo.Migrations.Auto do use Ecto.Migration def change do <%= for i <- data do %> <%= if i.action != :drop do %><%= i.action %> table(:<%= i.table %>) do <%= for s <- i.schema do %> <%= s %><% end %> end <% else %>drop table(:<%= i.table %>) <% end %><% end %> end end """ end def get(data \\ []) do tpl_data = to_tpl(data) EEx.eval_string(template(), [data: tpl_data]) end def to_tpl(data) do for i <- data, do: to_block_data(i) end def to_block_data(data) do if data.action != :drop do action_change(data) else %{action: data.action, table: data.table} end end @timestamps_atom [:inserted_at, :updated_at] def action_change(data) do timestamps? = Enum.reduce(data.schema, [], fn(i, acc) -> if i.filed in @timestamps_atom do acc ++ [i.filed] else acc end end) schema_data = if timestamps? == @timestamps_atom do Enum.reduce(data.schema, [], fn(i, acc) -> if i.filed in @timestamps_atom || i[:type] == :id do acc else acc ++ [i] end end) else Enum.filter(data.schema, fn(i) -> i[:type] != :id end) end schema = for i <- schema_data do if i.action != :remove do "#{i.action} :#{i.filed}, #{format_type(i.type)}" else "#{i.action} :#{i.filed}" end end schema = if timestamps? == @timestamps_atom, do: schema ++ ["timestamps"], else: schema %{action: data.action, table: data.table, schema: schema} end @ecto_atom_type [:string, :integer, :id, :float, :boolean, :binary] def format_type(t) do type = Atom.to_string(t) cond do t in @ecto_atom_type -> ":#{t}" String.contains?(type, "ref__") -> [_, ref] = String.split(type, "ref__") "references(:#{ref})" t == Ecto.Date -> ":date" t == Ecto.DateTime -> ":naive_datetime" t == Ecto.Time -> ":time" true -> ":#{t}" end end end