Skip to content

Commit 37c7e80

Browse files
committed
Add Hierarch.Ecto.LTree to support comman primary key(bigint)
1 parent 3993069 commit 37c7e80

File tree

6 files changed

+102
-2
lines changed

6 files changed

+102
-2
lines changed

lib/ecto/ltree.ex

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
defmodule Hierarch.Ecto.LTree do
2+
@behaviour Ecto.Type
3+
4+
def type, do: :ltree
5+
6+
@doc false
7+
def cast(label), do: {:ok, label}
8+
9+
@doc false
10+
def dump(label), do: {:ok, to_string(label)}
11+
12+
@doc false
13+
def load(label), do: {:ok, label}
14+
end

lib/hierarch.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ defmodule Hierarch do
209209

210210
defp get_primary_key(schema) do
211211
[{id_column, value}] = Ecto.primary_key(schema)
212-
{id_column, value}
212+
{id_column, to_string(value)}
213213
end
214214
end
215215
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
defmodule Dummy.Repo.Migrations.CreateOrganizations do
2+
use Ecto.Migration
3+
4+
def change do
5+
execute "CREATE EXTENSION IF NOT EXISTS ltree" # Enables Ltree action
6+
7+
create table(:organizations) do
8+
add :name, :string
9+
add :ancestry, :ltree, null: false, default: ""
10+
end
11+
12+
create index(:organizations, [:ancestry], using: "GIST")
13+
end
14+
end
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
defmodule BigintPrimaryKeyTest do
2+
use Hierarch.TestCase
3+
4+
setup_all do
5+
organizations = create_organizations()
6+
7+
on_exit fn ->
8+
Repo.delete_all(Organization)
9+
end
10+
11+
{:ok, organizations}
12+
end
13+
14+
test "returns the parent", organizations do
15+
b = Map.get(organizations, "A.B")
16+
c = Map.get(organizations, "A.B.C")
17+
18+
discendants = c
19+
|> Organization.parent
20+
|> Repo.one
21+
assert discendants == b
22+
end
23+
24+
test "returns sbilings", organizations do
25+
b = Map.get(organizations, "A.B")
26+
d = Map.get(organizations, "A.D")
27+
28+
sblings = b
29+
|> Organization.sblings
30+
|> Repo.all
31+
assert sblings == [d]
32+
end
33+
34+
test "return discendants", organizations do
35+
a = Map.get(organizations, "A")
36+
b = Map.get(organizations, "A.B")
37+
c = Map.get(organizations, "A.B.C")
38+
d = Map.get(organizations, "A.D")
39+
40+
discendants = a
41+
|> Organization.discendants
42+
|> Repo.all
43+
assert discendants == [b, c, d]
44+
end
45+
end

test/support/organization.ex

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
defmodule Dummy.Organization do
2+
@moduledoc false
3+
use Ecto.Schema
4+
use Hierarch, path_column: :ancestry
5+
6+
schema "organizations" do
7+
field :name, :string
8+
field :ancestry, Hierarch.Ecto.LTree
9+
end
10+
end

test/test_helper.exs

+18-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Hierarch.TestCase do
44
using(opts) do
55
quote do
66
use ExUnit.Case, unquote(opts)
7-
alias Dummy.{Repo, Catelog}
7+
alias Dummy.{Repo, Catelog, Organization}
88

99
def create_catelogs do
1010
catelogs_list = [
@@ -31,6 +31,23 @@ defmodule Hierarch.TestCase do
3131
Map.put acc, name, catelog
3232
end)
3333
end
34+
35+
def create_organizations do
36+
organizations_list = [
37+
"A",
38+
"A.B",
39+
"A.B.C",
40+
"A.D",
41+
]
42+
43+
Enum.reduce(organizations_list, %{}, fn (name, acc) ->
44+
parent_name = Hierarch.LTree.parent_path(name)
45+
parent = Map.get(acc, parent_name)
46+
47+
organization = Organization.build_child_of(parent, %{name: name}) |> Repo.insert!
48+
Map.put acc, name, organization
49+
end)
50+
end
3451
end
3552
end
3653

0 commit comments

Comments
 (0)