Skip to content
This repository was archived by the owner on Jun 11, 2023. It is now read-only.

Commit ad321e6

Browse files
Merge pull request #408 from renatomassaro/helix-id
Add new Helix.ID format
2 parents 264ce31 + 4a7d2b7 commit ad321e6

File tree

142 files changed

+1568
-688
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+1568
-688
lines changed

lib/account/http/controller/webhook.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ defmodule Helix.Account.HTTP.Controller.Webhook do
5858
nil ->
5959
# Account does not exists
6060
account = %Account{
61+
account_id: Account.ID.generate(%{}, :account),
6162
password: password,
6263
email: String.downcase(email),
6364
username: String.downcase(username),

lib/account/model/account.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
defmodule Helix.Account.Model.Account do
22

33
use Ecto.Schema
4-
use HELL.ID, field: :account_id, meta: [0x0001]
4+
use HELL.ID, field: :account_id
55

66
import Ecto.Changeset
7+
import HELL.Ecto.Macros
78
import HELL.Macros
89

910
alias Comeonin.Bcrypt
@@ -60,6 +61,7 @@ defmodule Helix.Account.Model.Account do
6061
|> cast(params, @creation_fields)
6162
|> generic_validations()
6263
|> prepare_changes()
64+
|> put_pk(%{}, :account)
6365
end
6466

6567
@spec update_changeset(t | Changeset.t, update_params) ::
@@ -159,10 +161,8 @@ defmodule Helix.Account.Model.Account do
159161
|| [username: "has invalid format"]
160162
end
161163

162-
defmodule Query do
163-
import Ecto.Query
164+
query do
164165

165-
alias Ecto.Queryable
166166
alias Helix.Account.Model.Account
167167

168168
@spec by_id(Queryable.t, Account.idtb) ::

lib/entity/model/entity.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
defmodule Helix.Entity.Model.Entity do
22

33
use Ecto.Schema
4-
use HELL.ID, field: :entity_id, autogenerate: false
4+
use HELL.ID, field: :entity_id
55

66
import Ecto.Changeset
7+
import HELL.Ecto.Macros
78

89
alias Ecto.Changeset
910
alias HELL.Constant
@@ -26,7 +27,7 @@ defmodule Helix.Entity.Model.Entity do
2627
entity_type: type
2728
}
2829

29-
@creation_fields ~w/entity_type entity_id/a
30+
@creation_fields [:entity_type]
3031

3132
schema "entities" do
3233
field :entity_id, ID,
@@ -51,12 +52,11 @@ defmodule Helix.Entity.Model.Entity do
5152
|> cast(params, @creation_fields)
5253
|> validate_required(@creation_fields)
5354
|> validate_inclusion(:entity_type, EntityType.possible_types())
55+
|> put_change(:entity_id, params.entity_id)
5456
end
5557

56-
defmodule Query do
57-
import Ecto.Query
58+
query do
5859

59-
alias Ecto.Queryable
6060
alias Helix.Server.Model.Server
6161
alias Helix.Entity.Model.Entity
6262
alias Helix.Entity.Model.EntityServer

lib/hell/hell/binary.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule HELL.Binary do
2+
3+
use EntropyString, charset: "01"
4+
end

lib/hell/hell/ecto_macros.ex

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,36 @@ defmodule HELL.Ecto.Macros do
3939

4040
end
4141
end
42+
43+
@doc """
44+
Generates and then inserts the Helix.ID into the changeset.
45+
46+
A custom ID module may be specified at `opts`, otherwise __CALLER__.ID shall
47+
be used.
48+
"""
49+
defmacro put_pk(changeset, heritage, domain, opts \\ unquote([])) do
50+
module = get_pk_module(opts, __CALLER__.module)
51+
52+
gen_pk(changeset, heritage, domain, module)
53+
end
54+
55+
defp gen_pk(changeset, heritage, domain, module) do
56+
quote do
57+
58+
if unquote(changeset).valid? do
59+
field = unquote(module).get_field()
60+
id = unquote(module).generate(unquote(heritage), unquote(domain))
61+
62+
put_change(unquote(changeset), field, id)
63+
else
64+
unquote(changeset)
65+
end
66+
67+
end
68+
end
69+
70+
defp get_pk_module([id: module], _),
71+
do: module
72+
defp get_pk_module([], parent_module),
73+
do: Module.concat(parent_module, :ID)
4274
end

lib/hell/hell/id.ex

Lines changed: 31 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,35 @@ defmodule HELL.ID do
22

33
defmacro __using__(params) do
44
model = __CALLER__.module
5-
65
field = Keyword.fetch!(params, :field)
7-
meta =
8-
params
9-
|> Keyword.get(:meta, [])
10-
|> List.wrap()
11-
|> pad()
12-
136
id_root = Keyword.get(params, :root, model)
147

15-
autogenerate = Keyword.get(params, :autogenerate, true)
16-
178
quote do
9+
10+
@type id :: __MODULE__.ID.t
11+
@type idt :: id | %__MODULE__{unquote(field) => id}
12+
@type idtb :: idt | String.t
13+
14+
@primary_key false
15+
1816
defmodule ID do
1917
@behaviour Ecto.Type
2018

2119
@type t ::
2220
%__MODULE__{}
2321
| %{:__struct__ => atom, root: unquote(id_root), id: tuple}
2422

25-
defstruct [
26-
id: nil,
27-
root: unquote(id_root)
28-
]
23+
defstruct [id: nil, root: unquote(id_root)]
24+
25+
@field unquote(field)
2926

3027
@doc false
3128
def type,
3229
do: :inet
3330

34-
def cast(id = %__MODULE__{}) do
35-
{:ok, id}
36-
end
31+
@doc false
32+
def cast(id = %__MODULE__{}),
33+
do: {:ok, id}
3734

3835
# HACK: use __struct__ to avoid mutual compilation dependency.
3936
# Extracts id from the input record as long as it is the model that
@@ -45,17 +42,14 @@ defmodule HELL.ID do
4542
{:ok, id}
4643
end
4744

48-
def cast(%Postgrex.INET{address: id}) do
49-
{:ok, %__MODULE__{id: id}}
50-
end
45+
def cast(%Postgrex.INET{address: id}),
46+
do: {:ok, %__MODULE__{id: id}}
5147

52-
def cast(%_{root: unquote(id_root), id: id}) when tuple_size(id) == 8 do
53-
{:ok, %__MODULE__{id: id}}
54-
end
48+
def cast(%_{root: unquote(id_root), id: id}) when tuple_size(id) == 8,
49+
do: {:ok, %__MODULE__{id: id}}
5550

56-
def cast(id = {_, _, _, _, _, _, _, _}) do
57-
{:ok, %__MODULE__{id: id}}
58-
end
51+
def cast(id = {_, _, _, _, _, _, _, _}),
52+
do: {:ok, %__MODULE__{id: id}}
5953

6054
def cast(string) when is_binary(string) do
6155
case HELL.IPv6.binary_to_address_tuple(string) do
@@ -66,10 +60,10 @@ defmodule HELL.ID do
6660
end
6761
end
6862

69-
def cast(_) do
70-
:error
71-
end
63+
def cast(_),
64+
do: :error
7265

66+
@doc false
7367
def cast!(term) do
7468
{:ok, id} = cast(term)
7569
id
@@ -87,9 +81,15 @@ defmodule HELL.ID do
8781
def dump(_),
8882
do: :error
8983

90-
def generate do
91-
%__MODULE__{id: HELL.IPv6.generate_address_tuple(unquote(meta))}
92-
end
84+
@doc false
85+
def generate(domain) when is_tuple(domain) or is_atom(domain),
86+
do: generate(%{}, domain)
87+
def generate(heritage, domain),
88+
do: %__MODULE__{id: Helix.ID.generate(heritage, domain)}
89+
90+
@doc false
91+
def get_field,
92+
do: @field
9393

9494
defimpl String.Chars do
9595
defdelegate to_string(struct),
@@ -100,33 +100,11 @@ defmodule HELL.ID do
100100
def encode(struct, _),
101101
do: "\"" <> HELL.ID.to_string(struct) <> "\""
102102
end
103-
end
104103

105-
# Inject the PK module as the PK autogenerator for the module
106-
alias __MODULE__.ID
107-
108-
@type id :: ID.t
109-
@type idt :: id | %__MODULE__{unquote(field) => id}
110-
@type idtb :: idt | String.t
111-
112-
@primary_key false
113-
114-
if unquote(autogenerate) do
115-
@ecto_autogenerate {unquote(field), {ID, :generate, []}}
116104
end
117105
end
118106
end
119107

120-
@doc false
121-
def pad([]),
122-
do: [0, 0, 0]
123-
def pad([x]),
124-
do: [x, 0, 0]
125-
def pad([x, y]),
126-
do: [x, y, 0]
127-
def pad(list = [_, _, _]),
128-
do: list
129-
130108
@doc false
131109
def to_string(%_{id: id, root: _}) when tuple_size(id) == 8 do
132110
id

lib/hell/hell/pk.ex

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@ defmodule HELL.PK do
44

55
@type t :: String.t
66

7-
@spec pk_for(atom) ::
8-
t
9-
defdelegate pk_for(atom),
10-
to: HELL.PK.Header
11-
127
def type,
138
do: :inet
149

lib/hell/hell/pk/header.ex

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)