README.md

# DgraphEx 
[![Build Status](https://travis-ci.org/elbow-jason/dgraph_ex.svg?branch=master)](https://travis-ci.org/elbow-jason/dgraph_ex) [![Hex Version][hex-img]][hex] [![License][license-img]][license]

[hex-img]: https://img.shields.io/hexpm/v/dgraph_ex.svg
[hex]: https://hex.pm/packages/dgraph_ex
[license-img]: http://img.shields.io/badge/license-MIT-brightgreen.svg
[license]: http://opensource.org/licenses/MIT

An elixir database wrapper for dgraph database.

Works with dgraph v0.8.1 (most current release as of 16 AUG 2017)

[Docs](https://hexdocs.pm/dgraph_ex)

##### Installation: 

```elixir
def deps do
  [{:dgraph_ex, "~> 0.1.5"}]
end
```


## Usage 

#### define a model

```elixir

defmodule Person do
  use DgraphEx.Vertex

  vertex :person do
    field :name,    :string, index: [:exact, :term]
    field :address, :string, index: [:exact, :term]
  end
end

```

```elixir

defmodule Land do
  use Vertex

  vertex :land do
    field :address,             :string,  index: [:exact, :term],  count: true
    field :zipcode,             :string,  index: [:exact],         count: true
    field :city,                :string,  index: [:exact],         count: true
    field :land_size,           :int,     index: true
    field :living_space,        :int,     index: true
    field :zoning,              :string,  index: [:exact],         count: true
    field :floors,              :int
    field :construction_year,   :string
    field :geo_center,          :geo,     index: [:geo]
    field :geo_border,          :geo,     index: [:geo]
    field :owner,               :uid,     model: Person, reverse: true
  end
end

```

#### mutate the schema

```elixir
import DgraphEx
alias DgraphEx.Repo

{:ok, _} = Repo.request mutation(schema: Land)
{:ok, _} = Repo.request mutation(schema: Person)

```

#### define a changeset

```elixir

  alias DgraphEx.Changeset

  def changeset(%Person{} = model, changes) when is_map(changes) do
    model
    |> Changeset.cast(changes, _allowed_fields = [:name, :address])
    |> Changeset.validate_required(_required_fields = [:name, :address])
    |> Changeset.validate_type(_typed_fields = [:name, :address])
    |> Changeset.uncast
  end

```

#### insert a model

We apply the `changeset` function to ensure data consistency:

```elixir
{:ok, person} =
  %Person{} 
  |> Person.changeset(%{name: "jason", address: "221B Baker St. London, England 55555"})
```

And `person` is:

```elixir
  %Person{
    _uid_: nil,
    address: "221B Baker St. London, England 55555",
    name: "jason",
  }
```

Then we insert into the `Repo`:

```elixir
{:ok, person} = Repo.insert(person)
```

The resulting `person` is:

(notice the `_uid_` is populated)

```elixir
%Person{
  _uid_: "0x11c",
  address: "221B Baker St. London, England 55555",
  name: "jason",
}
```

#### update a model

Using the `person` from above:

```elixir
{:ok, person} = Person.changeset(person, %{name: "John Lakeman"})
person = Repo.update(person)
```

#### get a model by `_uid_`.

```elixir
Repo.get(Company, "0x11c")
```
returns `nil` or a populated `%Company{}` 


#### find anything

With function syntax:

```elixir

import DgraphEx

query()
|> func(:spy, eq(:name, "John Lakeman"))
|> select({
  :_uid_,
  :address,
  :name,
})
|> Repo.request

```

Again with keyword (kwargs) syntax:

```elixir
import DgraphEx
alias DgraphEx.Repo

query([
  get: :spy,
  func: eq(:name, "John Lakeman"),
  select: {
    :_uid_,
    :address,
    :name,
  },
]) |> Repo.request

```

Both of the above requests for "spy" result in the same response:

```elixir
{:ok, %{
  "spy" => [
    %{
      "_uid_" => "0x11c",
      "address" => "221B Baker St. London, England 55555",
      "name" => "John Lakeman",
    }
  ]
}}

```