From af33d3aeade75d7176252aab6fdc151e18d1a2c0 Mon Sep 17 00:00:00 2001 From: David Boyer Date: Mon, 15 Jun 2020 12:08:14 -0400 Subject: [PATCH 1/2] Added an ecto recognizable type to the types_mapping --- lib/dlex/node.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dlex/node.ex b/lib/dlex/node.ex index 81c2391..c2e2321 100644 --- a/lib/dlex/node.ex +++ b/lib/dlex/node.ex @@ -238,7 +238,7 @@ defmodule Dlex.Node do float: "float", string: "string", geo: "geo", - datetime: "datetime", + utc_datetime: "datetime", uid: "[uid]" ] From 247426a498d0412cce61459a8e48ca76e64fddf3 Mon Sep 17 00:00:00 2001 From: David Boyer Date: Wed, 17 Jun 2020 06:50:10 -0400 Subject: [PATCH 2/2] Added Support to Repo for DateTime fields on Nodes on mutate/set and get --- lib/dlex/repo.ex | 9 +++++++++ mix.exs | 1 + test/dlex/node_test.exs | 6 ++++-- test/dlex/repo_test.exs | 8 ++++++++ test/test_helper.exs | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/dlex/repo.ex b/lib/dlex/repo.ex index 4f38a50..90f7e43 100644 --- a/lib/dlex/repo.ex +++ b/lib/dlex/repo.ex @@ -138,6 +138,7 @@ defmodule Dlex.Repo do end end + def encode(%DateTime{} = data), do: data def encode(%{__struct__: struct} = data) do data |> Map.from_struct() @@ -148,6 +149,7 @@ defmodule Dlex.Repo do def encode(data) when is_list(data), do: encode_list(data, []) def encode(data), do: data + defp encode_kv([], map, _struct), do: map defp encode_kv([{_key, nil} | kv], map, struct), do: encode_kv(kv, map, struct) @@ -227,6 +229,8 @@ defmodule Dlex.Repo do with %{} = map <- do_decode(map, lookup, strict?), do: {:ok, map} end + + defp do_decode(map, lookup, strict?) when is_map(map) and is_map(lookup) do with %{"dgraph.type" => [type_string]} <- map, type when type != nil <- Map.get(lookup, type_string) do @@ -264,6 +268,11 @@ defmodule Dlex.Repo do end) end + defp do_decode_field(struct, {field_name, :utc_datetime}, value, lookup, strict?) when not is_struct(value) do + {:ok, new_value} = Calendar.DateTime.Parse.rfc3339_utc(value) + do_decode_field(struct, {field_name, :utc_datetime}, new_value, lookup, strict?) + end + defp do_decode_field(struct, {field_name, field_type}, value, lookup, strict?) do case Ecto.Type.load(field_type, value) do {:ok, loaded_value} -> diff --git a/mix.exs b/mix.exs index a69effc..9e4d4b7 100644 --- a/mix.exs +++ b/mix.exs @@ -30,6 +30,7 @@ defmodule Dlex.MixProject do [ {:db_connection, "~> 2.1"}, {:grpc, "~> 0.3.1"}, + {:calendar, "~> 1.0.0"}, {:jason, "~> 1.0", optional: true}, {:mint, "~> 1.0", optional: true}, {:castore, "~> 0.1.4", optional: true}, diff --git a/test/dlex/node_test.exs b/test/dlex/node_test.exs index c5e4b68..18d8416 100644 --- a/test/dlex/node_test.exs +++ b/test/dlex/node_test.exs @@ -8,7 +8,7 @@ defmodule Dlex.NodeTest do assert "user" == User.__schema__(:source) assert :string == User.__schema__(:type, :name) assert :integer == User.__schema__(:type, :age) - assert [:name, :age, :friends, :location] == User.__schema__(:fields) + assert [:name, :age, :friends, :location, :modified] == User.__schema__(:fields) end test "alter" do @@ -22,11 +22,13 @@ defmodule Dlex.NodeTest do }, %{"predicate" => "user.age", "type" => "int"}, %{"predicate" => "user.friends", "type" => "[uid]"}, - %{"predicate" => "user.location", "type" => "geo"} + %{"predicate" => "user.location", "type" => "geo"}, + %{"predicate" => "user.modified", "type" => "datetime"} ], "types" => [ %{ "fields" => [ + %{"name" => "user.modified", "type" => "datetime"}, %{"name" => "user.location", "type" => "geo"}, %{"name" => "user.friends", "type" => "[uid]"}, %{"name" => "user.age", "type" => "int"}, diff --git a/test/dlex/repo_test.exs b/test/dlex/repo_test.exs index eb73bb3..728eea5 100644 --- a/test/dlex/repo_test.exs +++ b/test/dlex/repo_test.exs @@ -36,6 +36,14 @@ defmodule Dlex.RepoTest do assert {:ok, %{uid: _uid}} = TestRepo.set(valid_changeset) end + test "setting datetime field in Changeset" do + now = DateTime.utc_now() + changeset = Ecto.Changeset.cast(%User{}, %{name: "TimeTraveler", age: 20, modified: now}, [:name, :age, :modified]) + assert {:ok, %{uid: uid}} = TestRepo.set(changeset) + + assert {:ok, %User{name: "TimeTraveler", age: 20, modified: now}} = TestRepo.get(uid) + end + test "using custom types" do changes = %{name: "John", age: 30, location: %{lat: 15.5, lon: 10.2}} changeset = Changeset.cast(%User{}, changes, [:name, :age, :location]) diff --git a/test/test_helper.exs b/test/test_helper.exs index 1c8f127..cf9b2a2 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -48,6 +48,7 @@ defmodule Dlex.User do field :age, :integer field :friends, :uid field :location, Dlex.Geo + field :modified, :utc_datetime field :cache, :any, virtual: true end end