Packages

Append-only (immutable) tables with version tracking for Ecto.

Current section

Files

Jump to
immu_table lib mix tasks immutable.gen.schema.ex
Raw

lib/mix/tasks/immutable.gen.schema.ex

defmodule Mix.Tasks.Immutable.Gen.Schema do
@shortdoc "Generates an ImmuTable schema"
@moduledoc """
Generates an ImmuTable schema.
$ mix immutable.gen.schema Blog.Post posts title:string body:text
The first argument is the schema module name followed by the table name
and a list of field definitions.
## Field types
The generator supports the following field types:
* `:string` - String type
* `:text` - Text (long string) type
* `:integer` - Integer type
* `:float` - Float type
* `:decimal` - Decimal type
* `:boolean` - Boolean type
* `:date` - Date type
* `:time` - Time type
* `:utc_datetime` - UTC DateTime type
* `:utc_datetime_usec` - UTC DateTime with microseconds
* `:uuid` - UUID type
* `:binary` - Binary type
* `:map` - Map/JSON type
* `references` - Foreign key reference (e.g., `user_id:references:users`)
## Example
$ mix immutable.gen.schema Accounts.User users name:string email:string age:integer
This will generate:
* `lib/my_app/accounts/user.ex` - The ImmuTable schema
"""
use Mix.Task
alias Mix.Immutable.Generator
alias Mix.Immutable.Templates
@impl true
def run(args) do
{schema, table, fields} = parse_args!(args)
Generator.validate_module!(schema, "schema")
Generator.validate_table!(table, "immutable.gen.schema")
parsed_fields = Generator.parse_fields(fields)
field_names = Generator.field_names(parsed_fields)
base_app = Generator.base_app()
inflections = Generator.inflect(schema)
schema_module = "#{base_app}.#{schema}"
schema_path = "lib/#{Generator.otp_app()}/#{inflections.path}.ex"
binding = [
app_module: base_app,
schema_module: schema_module,
table: table,
fields: parsed_fields,
field_names: field_names
]
File.mkdir_p!(Path.dirname(schema_path))
content = EEx.eval_string(Templates.schema_template(), binding)
Mix.Generator.create_file(schema_path, content)
end
defp parse_args!([]) do
Mix.raise("""
expected immutable.gen.schema to receive the schema module name and table name.
For example:
mix immutable.gen.schema Blog.Post posts title:string body:text
""")
end
defp parse_args!([_schema]) do
Mix.raise("""
expected immutable.gen.schema to receive the schema module name and table name.
For example:
mix immutable.gen.schema Blog.Post posts title:string body:text
""")
end
defp parse_args!([schema, table | fields]) do
{schema, table, fields}
end
end