Current section
Files
Jump to
Current section
Files
lib/couchdb_connector.ex
defmodule Couchdb.Connector do
@moduledoc """
Your primary interface for writing to and reading from CouchDB.
The exchange format here are Maps. If you want to go more low
level and deal with JSON strings instead, please consider using
Couchdb.Connector.Reader or Couchdb.Connector.Writer.
"""
import Couchdb.Connector.AsMap
import Couchdb.Connector.AsJson
alias Couchdb.Connector.Types
alias Couchdb.Connector.Reader
alias Couchdb.Connector.Writer
@doc """
Retrieve the document given by database properties and id, returning it
as a Map, using no authentication.
"""
@spec get(Types.db_properties, String.t) :: {:ok, map} | {:error, map}
def get(db_props, id) do
db_props
|> Reader.get(id)
|> as_map
end
@doc """
Retrieve the document given by database properties and id, returning it
as a Map, using the given basic auth credentials for authentication.
"""
@spec get(Types.db_properties, Types.basic_auth, String.t) :: {:ok, map} | {:error, map}
def get(db_props, basic_auth, id) do
db_props
|> Reader.get(basic_auth, id)
|> as_map
end
@doc """
Fetch a single uuid from CouchDB for use in a a subsequent create operation.
Clients can retrieve the returned List of UUIDs by getting the value for key
"uuids". The List contains only one element (UUID).
"""
@spec fetch_uuid(Types.db_properties) :: {:ok, map} | {:error, String.t}
def fetch_uuid(db_props) do
db_props
|> Reader.fetch_uuid()
|> as_map
end
@doc """
Create a new document from given map with given id, using no authentication.
Clients must make sure that the id has not been used for an existing document
in CouchDB.
Either provide a UUID or consider using create_generate in case uniqueness cannot
be guaranteed.
"""
@spec create(Types.db_properties, map, String.t) :: {:ok, map} | {:error, map}
def create(db_props, doc_map, id) do
response = Writer.create(db_props, as_json(doc_map), id)
response |> handle_write_response
end
defp handle_write_response({status, json}) do
{status, %{:payload => as_map(json), :headers => %{}}}
end
defp handle_write_response({status, json, headers}) do
{status, %{:payload => as_map(json), :headers => as_map(headers)}}
end
@doc """
Create a new document from given map with a CouchDB generated id, using no
authentication.
Fetching the uuid from CouchDB does of course incur a performance penalty as
compared to providing one.
"""
@spec create_generate(Types.db_properties, map) :: {:ok, map} | {:error, map}
def create_generate(db_props, doc_map) do
{:ok, uuid_json} = Reader.fetch_uuid(db_props)
uuid = hd(Poison.decode!(uuid_json)["uuids"])
create(db_props, doc_map, uuid)
end
@doc """
Update the given document, provided it contains an id field. Raise an error
if it does not. Does not use any authentication.
"""
@spec update(Types.db_properties, map) :: {:ok, map} | {:error, map}
def update(db_props, doc_map) do
case Map.fetch(doc_map, "_id") do
{:ok, id} ->
Writer.update(db_props, as_json(doc_map), id) |> handle_write_response
:error ->
raise RuntimeError, message:
"the document to be updated must contain an \"_id\" field"
end
end
@doc """
Create a new document from given map with given id, using the provided basic
authentication parameters.
Clients must make sure that the id has not been used for an existing document
in CouchDB.
Either provide a UUID or consider using create_generate in case uniqueness cannot
be guaranteed.
"""
@spec create(Types.db_properties, Types.basic_auth, map, String.t) :: {:ok, map} | {:error, map}
def create(db_props, auth, doc_map, id) do
response = Writer.create(db_props, auth, as_json(doc_map), id)
response |> handle_write_response
end
@doc """
Create a new document from given map with a CouchDB generated id, using the
provided basic authentication parameters.
Fetching the uuid from CouchDB does of course incur a performance penalty as
compared to providing one.
"""
@spec create_generate(Types.db_properties, Types.basic_auth, map) :: {:ok, map} | {:error, map}
def create_generate(db_props, auth, doc_map) do
{:ok, uuid_json} = Reader.fetch_uuid(db_props)
uuid = hd(Poison.decode!(uuid_json)["uuids"])
create(db_props, auth, doc_map, uuid)
end
@doc """
Update the given document, provided it contains an id field. Raise an error
if it does not. Makes use of the provided basic authentication parameters.
"""
@spec update(Types.db_properties, Types.basic_auth, map)
:: {:ok, map} | {:error, map}
def update(db_props, auth, doc_map) do
case Map.fetch(doc_map, "_id") do
{:ok, id} ->
response = Writer.update(db_props, auth, as_json(doc_map), id)
response |> handle_write_response
:error ->
raise RuntimeError, message:
"the document to be updated must contain an \"_id\" field"
end
end
def destroy(db_props, id, rev) do
Writer.destroy(db_props, id, rev) |> handle_write_response
end
def destroy(db_props, auth, id, rev) do
Writer.destroy(db_props, auth, id, rev) |> handle_write_response
end
end