jylis_ex
An idiomatic library for connecting an Elixir project to a Jylis database.
Jylis is a distributed in-memory database for Conflict-free Replicated Data Types (CRDTs), built for speed, scalability, availability, and ease of use.
Installation
Add the :jylis_ex
dependency to your mix.exs
file:
defp deps() do
[{:jylis_ex, ">= 0.0.0"}]
end
Run mix deps.get
to get the new dependency.
Database Connection
The connection URI must be specified in the format: schema://host:port
, where
the schema is jylis
. The host
can be a host name, IP address, or domain name
of the database host to connect to. The port
is optional and defaults to
6379
unless otherwise specified.
{:ok, connection} = Jylis.start_link("jylis://host:port")
Queries
This library aims to be idiomatic with both Elixir and Jylis. Therefore, the syntax of the queries closely match the Jylis documentation and ideally it should feel natural to you, an Elixir programmer.
For example, take the case of a Jylis query to set a value for a
UJSON
key:
UJSON SET fruit apple '{"color": "red", "ripe": true}'
Using this library, the query looks like this:
connection |> Jylis.UJSON.set(["fruit", "apple"], %{color: "red", ripe: true})
The format for a query is:
Jylis.<data_type>.<function>(key(s), value?, timestamp?)
However, be sure to consult the API documentation or the Jylis documentation for the exact format of your particular query.
TREG
Timestamped Register [link]
{:ok, _} = connection |> Jylis.TREG.set("lamp_brightness", 80, 1528082143)
{:ok, result} = connection |> Jylis.TREG.get("lamp_brightness")
# {:ok, {"80", 1528082143}}
TLOG
Timestamped Log [link]
{:ok, _} = connection |> Jylis.TLOG.ins("temperature", 68.8, 1528082150)
{:ok, _} = connection |> Jylis.TLOG.ins("temperature", 70.1, 1528082160)
{:ok, _} = connection |> Jylis.TLOG.ins("temperature", 73.6, 1528082170)
{:ok, size} = connection |> Jylis.TLOG.size("temperature")
# {:ok, 3}
{:ok, items} = connection |> Jylis.TLOG.get("temperature")
# {:ok, [{"73.6", 1528082170}, {"70.1", 1528082160}, {"68.8", 1528082150}]}
{:ok, _} = connection |> Jylis.TLOG.trim("temperature", 1)
{:ok, items} = connection |> Jylis.TLOG.get("temperature")
# {:ok, [{"73.6", 1528082170}]}
{:ok, _} = connection |> Jylis.TLOG.cutoff("temperature")
# {:ok, 1528082170}
GCOUNT
Grow-Only Counter [link]
{:ok, _} = connection |> Jylis.GCOUNT.inc("mileage", 10)
{:ok, _} = connection |> Jylis.GCOUNT.inc("mileage", 5)
{:ok, value} = connection |> Jylis.GCOUNT.get("mileage")
# {:ok, 15}
PNCOUNT
Positive/Negative Counter [link]
{:ok, _} = connection |> Jylis.PNCOUNT.inc("subscribers", 3)
{:ok, _} = connection |> Jylis.PNCOUNT.dec("subscribers", 1)
{:ok, value} = connection |> Jylis.PNCOUNT.get("subscribers")
# {:ok, 2}
MVREG
Multi-Value Register [link]
{:ok, _} = connection |> Jylis.MVREG.set("thermostat", 68)
{:ok, value} = connection |> Jylis.MVREG.get("thermostat")
# {:ok, ["68"]}
UJSON
Unordered JSON [link]
{:ok, _} = connection |> Jylis.UJSON.set(["users", "alice"], %{admin: false})
{:ok, _} = connection |> Jylis.UJSON.set(["users", "brett"], %{admin: false})
{:ok, _} = connection |> Jylis.UJSON.set(["users", "carol"], %{admin: true})
{:ok, users} = connection |> Jylis.UJSON.get("users")
# {:ok,
# %{
# "alice" => %{"admin" => false},
# "brett" => %{"admin" => false},
# "carol" => %{"admin" => true}
# }}
{:ok, _} = connection |> Jylis.UJSON.ins(["users", "brett", "banned"], true)
{:ok, _} = connection |> Jylis.UJSON.clr(["users", "alice"])
{:ok, users} = connection |> Jylis.UJSON.get("users")
# {:ok,
# %{
# "brett" => %{"admin" => false, "banned" => true},
# "carol" => %{"admin" => true}
# }}
Raw Query
If this library doesn’t contain a function for the query you would like to
perform, you can construct the query yourself by calling Jylis.query
.
However, be aware that this function is non-idiomatic and may require you to
do your own pre/post processing on the data.
{:ok, _} = connection |> Jylis.query(["TLOG", "INS", "temperature", 72.6, 5])
# {:ok, "OK"}
{:ok, value} = connection |> Jylis.query(["TLOG", "GET", "temperature"])
# {:ok, [["73.6", 1528082170]]}
Timestamps
In addition to supporting integer timestamps as defined by the Jylis spec, this
library also has helpers to convert the Jylis Timestamped
data types to/from
ISO 8601. Functions that have a timestamp
parameter will automatically convert
an ISO 8601 string to a Unix timestamp.
{:ok, _} = connection |> Jylis.TREG.set("volume", 64, "2018-06-06T01:42:57Z")
{:ok, result} = connection |> Jylis.TREG.get("volume")
# {:ok, {"64", 1528249377}}
result |> Jylis.Result.to_iso8601
# {"64", "2018-06-06T01:42:57Z"}