Current section
12 Versions
Jump to
Current section
12 Versions
Compare versions
7
files changed
+57
additions
-140
deletions
| @@ -31,7 +31,7 @@ Declarative [`Ecto`](https://github.com/elixir-ecto/ecto) `embedded_schema`s for | |
| 31 31 | ```elixir |
| 32 32 | def deps do |
| 33 33 | [ |
| 34 | - {:flint, "~> 0.4"} |
| 34 | + {:flint, "~> 0.5"} |
| 35 35 | ] |
| 36 36 | end |
| 37 37 | ``` |
| @@ -1,6 +1,6 @@ | |
| 1 1 | {<<"links">>,[{<<"GitHub">>,<<"https://github.com/acalejos/flint">>}]}. |
| 2 2 | {<<"name">>,<<"flint">>}. |
| 3 | - {<<"version">>,<<"0.4.3">>}. |
| 3 | + {<<"version">>,<<"0.5.0">>}. |
| 4 4 | {<<"description">>, |
| 5 5 | <<"Declarative Ecto embedded schemas for data validation, coercion, and manipulation.">>}. |
| 6 6 | {<<"elixir">>,<<"~> 1.14">>}. |
| @@ -32,8 +32,7 @@ | |
| 32 32 | <<"lib/flint.ex">>,<<"lib/flint">>,<<"lib/flint/types">>, |
| 33 33 | <<"lib/flint/types/union.ex">>,<<"lib/flint/extension">>, |
| 34 34 | <<"lib/flint/extension/field.ex">>,<<"lib/flint/extension/dsl.ex">>, |
| 35 | - <<"lib/flint/extension/entity.ex">>,<<"lib/flint/extensions">>, |
| 36 | - <<"lib/flint/extensions/pre_transforms.ex">>, |
| 35 | + <<"lib/flint/extensions">>,<<"lib/flint/extensions/pre_transforms.ex">>, |
| 37 36 | <<"lib/flint/extensions/post_transforms.ex">>, |
| 38 37 | <<"lib/flint/extensions/ecto_validations.ex">>, |
| 39 38 | <<"lib/flint/extensions/when.ex">>,<<"lib/flint/extensions/json.ex">>, |
| @@ -99,14 +99,17 @@ defmodule Flint.Extension do | |
| 99 99 | ] |
| 100 100 | ``` |
| 101 101 | |
| 102 | - ## Default `field` and `field!` definitions |
| 102 | + ## Default `embedded_schema` definitions |
| 103 103 | |
| 104 104 | Sometimes you might want to always have one of more fields defined for a given schema type without having |
| 105 105 | to write it each time. Much in the same way that, by default, the `@prmimary_key` attribute will set an `:id` field |
| 106 106 | for the schema, you might wish to template out some fields and values. |
| 107 107 | |
| 108 | - If you want to define fields that are defined by default in a schema that uses your extension, just use the |
| 109 | - `field` and `field!` macros. These accept the same arguments as their counterparts in `Flint.Schema`, and will be |
| 108 | + If you want to define fields that are defined by default in a schema that uses your extension, you can use the |
| 109 | + `embedded_schema` macro within an extension and all `field`, `embeds_one` and `embeds_many` declarations will be |
| 110 | + merged into the target schema that uses your extension. |
| 111 | + |
| 112 | + These accept the same arguments as their counterparts in `Flint.Schema`, and will be |
| 110 113 | added at the end of the `embedded_schema` definition. |
| 111 114 | |
| 112 115 | > #### Duplicate Fields {: .info} |
| @@ -122,8 +125,10 @@ defmodule Flint.Extension do | |
| 122 125 | defmodule Event do |
| 123 126 | use Flint.Extension |
| 124 127 | |
| 125 | - field! :timestamp, :utc_datetime_usec |
| 126 | - field! :id, :binary_id |
| 128 | + embedded_schema do |
| 129 | + field! :timestamp, :utc_datetime_usec |
| 130 | + field! :id, :binary_id |
| 131 | + end |
| 127 132 | end |
| 128 133 | ``` |
| 129 134 | |
| @@ -172,34 +177,19 @@ defmodule Flint.Extension do | |
| 172 177 | many_extension_kinds: [:extensions], |
| 173 178 | default_extensions: [extensions: Flint.Extension.Dsl] |
| 174 179 | |
| 175 | - @doc """ |
| 176 | - Registers a default field to be added to any `embedded_schema` using this extension |
| 177 | - """ |
| 178 | - defmacro field(name, type \\ :string, opts \\ []) do |
| 179 | - quote do |
| 180 | - entity do |
| 181 | - name(unquote(name)) |
| 182 | - type(unquote(type)) |
| 183 | - opts(unquote(opts)) |
| 184 | - end |
| 185 | - end |
| 180 | + @doc false |
| 181 | + defmacro embedded_schema(do: {:__block__, _, contents}) do |
| 182 | + Module.put_attribute(__CALLER__.module, :embedded_schema, contents) |
| 186 183 | end |
| 187 184 | |
| 188 | - @doc """ |
| 189 | - Same as `field` but marks the field as required |
| 190 | - """ |
| 191 | - defmacro field!(name, type \\ :string, opts \\ []) do |
| 192 | - quote do |
| 193 | - entity do |
| 194 | - name(unquote(name)) |
| 195 | - type(unquote(type)) |
| 196 | - opts(unquote(opts)) |
| 197 | - required(true) |
| 198 | - end |
| 199 | - end |
| 185 | + @doc false |
| 186 | + defmacro embedded_schema(do: block) do |
| 187 | + Module.put_attribute(__CALLER__.module, :embedded_schema, [block]) |
| 200 188 | end |
| 201 189 | |
| 202 190 | defmacro __using__(opts) do |
| 191 | + Module.put_attribute(__CALLER__.module, :embedded_schema, []) |
| 192 | + |
| 203 193 | quote do |
| 204 194 | import Flint.Extension |
| 205 195 | unquote_splicing(super(opts)) |
| @@ -211,6 +201,10 @@ defmodule Flint.Extension do | |
| 211 201 | |
| 212 202 | defoverridable __using__: 1 |
| 213 203 | |
| 204 | + def template_schema() do |
| 205 | + @embedded_schema |
| 206 | + end |
| 207 | + |
| 214 208 | @doc false |
| 215 209 | def option_names(), |
| 216 210 | do: Spark.Dsl.Extension.get_entities(__MODULE__, :options) |> Enum.map(& &1.name) |
| @@ -218,9 +212,6 @@ defmodule Flint.Extension do | |
| 218 212 | @doc false |
| 219 213 | def attribute_names(), |
| 220 214 | do: Spark.Dsl.Extension.get_entities(__MODULE__, :attributes) |> Enum.map(& &1.name) |
| 221 | - |
| 222 | - def field_names(), |
| 223 | - do: Spark.Dsl.Extension.get_entities(__MODULE__, :fields) |> Enum.map(& &1.name) |
| 224 215 | end |
| 225 216 | end |
| 226 217 | end |
| @@ -41,43 +41,12 @@ defmodule Flint.Extension.Dsl do | |
| 41 41 | args: [:name], |
| 42 42 | schema: @common_schema |
| 43 43 | } |
| 44 | - @field %Spark.Dsl.Entity{ |
| 45 | - name: :entity, |
| 46 | - target: Flint.Extension.Entity, |
| 47 | - schema: [ |
| 48 | - name: [ |
| 49 | - type: :atom, |
| 50 | - required: true, |
| 51 | - doc: "The name as an atom." |
| 52 | - ], |
| 53 | - type: [ |
| 54 | - required: false, |
| 55 | - default: :string, |
| 56 | - # Let the call to `field` inside the schema handle validating |
| 57 | - type: :any |
| 58 | - ], |
| 59 | - opts: [ |
| 60 | - type: :keyword_list, |
| 61 | - default: [], |
| 62 | - required: false |
| 63 | - ], |
| 64 | - required: [ |
| 65 | - type: :boolean, |
| 66 | - default: false, |
| 67 | - doc: |
| 68 | - "Whether the field is required. If it is required and not provided there will be a compile time error thrown." |
| 69 | - ] |
| 70 | - ] |
| 71 | - } |
| 44 | + |
| 72 45 | @attributes %Spark.Dsl.Section{ |
| 73 46 | name: :attributes, |
| 74 47 | entities: [@attribute], |
| 75 48 | top_level?: true |
| 76 49 | } |
| 77 | - @fields %Spark.Dsl.Section{ |
| 78 | - name: :fields, |
| 79 | - entities: [@field], |
| 80 | - top_level?: true |
| 81 | - } |
| 82 | - use Spark.Dsl.Extension, sections: [@attributes, @options, @fields] |
| 50 | + |
| 51 | + use Spark.Dsl.Extension, sections: [@attributes, @options] |
| 83 52 | end |
| @@ -1,9 +0,0 @@ | |
| 1 | - defmodule Flint.Extension.Entity do |
| 2 | - @moduledoc false |
| 3 | - defstruct [ |
| 4 | - :name, |
| 5 | - type: :string, |
| 6 | - required: false, |
| 7 | - opts: [] |
| 8 | - ] |
| 9 | - end |
Loading more files…