Current section

Files

Jump to
barrel_ex_http lib barrel document.ex
Raw

lib/barrel/document.ex

defmodule BarrelEx.Document do
@moduledoc """
API for interacting with a BarrelDB document.
"""
alias BarrelEx.Request
## TODO: some header args like x-barrel-id-match and ETag
## are in headers, accept them too
## GET - ALL DOCUMENTS
@doc """
Get all documents from the database `db`, filtered by
a map of `options`.
Returns also the response status.
"""
@spec get(String.t(), list | map | none) :: {atom, map}
def get(db, options \\ []) do
case is_map(options) do
true ->
with options <- Map.to_list(options),
opts <- options |> atomize_keys() do
get(db, opts)
end
false ->
with url <- make_url(db) do
Request.get(url, [], params: options)
end
end
end
@doc """
Get all documents from the
database `db`, filtered by a map of options or
a list of `options` tuples.
"""
@spec get!(String.t(), list | map | none) :: map
def get!(db, options \\ []) do
case is_map(options) do
true ->
with options <- Map.to_list(options),
opts <- options |> atomize_keys() do
get!(db, opts)
end
false ->
with url <- make_url(db) do
Request.get!(url, [], params: options)
end
end
end
## GET - ONE DOCUMENT
@doc """
Get the document with a given `doc_id` from the
database `db`, filtered by an optional list of options.
Returns also the response status.
"""
@spec get_one(String.t(), String.t(), list | none) :: {atom, map}
def get_one(db, doc_id, options \\ []) do
with url <- make_url(db, doc_id) do
Request.get(url, [], options)
end
end
@doc """
Get the document with a given `doc_id` from the
database `db`, filtered by an optional list of options.
"""
@spec get_one!(String.t(), String.t(), list | none) :: map
def get_one!(db, doc_id, options \\ []) do
with url <- make_url(db, doc_id) do
Request.get!(url, [], options)
end
end
## CREATE
@doc """
Create a new document `doc` in the database `db`.
Returns also the response status.
"""
@spec create(String.t(), map | none) :: {atom, map}
def create(db, doc \\ %{}) do
with url <- make_url(db) do
Request.post(url, doc)
end
end
@doc """
Create a new document `doc` in the database `db`.
"""
@spec create!(String.t(), map | none) :: map
def create!(db, doc \\ %{}) do
with url <- make_url(db) do
Request.post!(url, doc)
end
end
## DELETE
@doc """
Delete a document `doc` in the database `db`.
Returns also the response status.
"""
@spec delete(String.t(), String.t(), String.t() | none) :: {atom, map}
def delete(db, doc_id, e_tag \\ "") do
with url <- make_url(db, doc_id),
headers <- make_e_tag(e_tag) do
Request.delete(url, headers)
end
end
@doc """
Delete a document `doc` in the database `db`.
"""
@spec delete!(String.t(), String.t(), String.t() | none) :: map
def delete!(db, doc_id, e_tag \\ "") do
with url <- make_url(db, doc_id),
headers <- make_e_tag(e_tag) do
Request.delete!(url, headers)
end
end
## UPDATE
@doc """
Update a document `doc` in the database `db`.
Returns also the response status.
"""
@spec update(String.t(), String.t(), map, String.t(), boolean) :: {atom, map}
def update(db, doc_id, doc, e_tag \\ "", edit \\ false) do
with url <- make_url(db, doc_id) do
# to add doc_id to body if doesn't exist
doc = Map.put_new(doc, "id", doc_id)
Request.put(url, doc, make_e_tag(e_tag), edit: edit)
end
end
@doc """
Update a document `doc` in the database `db`.
"""
@spec update!(String.t(), String.t(), map, String.t(), boolean) :: map
def update!(db, doc_id, doc, e_tag \\ "", edit \\ false) do
with url <- make_url(db, doc_id) do
# to add doc_id to body if doesn't exist
doc = Map.put_new(doc, "id", doc_id)
Request.put!(url, doc, make_e_tag(e_tag), edit: edit)
end
end
## HISTORY
@doc """
Check for differences in documents history in the
database `db`. Returns also the response status.
"""
@spec revsdiff(String.t(), map) :: {atom, map}
def revsdiff(db, doc) do
with url <- make_revsdiff_url(db) do
Request.post(url, doc)
end
end
@doc """
Check for differences in documents history in the
database `db`.
"""
@spec revsdiff!(String.t(), map) :: map
def revsdiff!(db, doc) do
with url <- make_revsdiff_url(db) do
Request.post!(url, doc)
end
end
## UTILS
defp make_e_tag(e_tag) do
case is_bitstring(e_tag) do
true -> ["ETag: " <> e_tag]
_ -> []
end
end
defp make_id_match(doc_ids) do
case is_list(doc_ids) do
# TODO: test this header
true ->
["x-barrel-id-match: " <> Enum.join(doc_ids, ", ")]
_ ->
[]
end
end
defp make_url(db) do
"dbs/" <> db <> "/docs/"
end
defp make_url(db, doc_id) do
make_url(db) <> doc_id
end
defp make_revsdiff_url(db) do
"dbs/" <> db <> "/revsdiff/"
end
defp atomize_keys(list) do
Enum.map(list, fn {k, v} -> {String.to_atom(k), v} end)
end
end