Documentation for Sofa.Doc, a test-driven idiomatic Apache CouchDB client.
If the only tool you have is CouchDB, then everything looks like
{:ok, :relax}
Attachments live in attachments, a map of name to %Sofa.Attachment{}.
from_map/1 and to_map/1 convert them to and from CouchDB's
_attachments stubs and inline content, so a document built with
attach/4 saves its attachments in the same request, and a fetched
document keeps the stubs CouchDB needs to retain them on update.
Examples
iex> Sofa.Doc.new("smol")
%Sofa.Doc{attachments: %{}, body: %{}, id: "smol", rev: nil, type: nil}
Summary
Functions
Attaches content to a document, to be saved inline with it. The content
type comes from the name unless given, see Sofa.Attachment.new/3.
Coerces a CouchDB "type" field to an existing atom. It is assumed that there will be a related Elixir Module Type of the same name. Elixir prefixes Module names with Elixir. and then elides this in iex, tests, and elsewhere, but here we need to make that explicit.
delete doc
Removes an attachment from a document. CouchDB deletes it when the document is next saved without its stub.
Check if doc exists via HEAD /:db/:doc and returns either
Check if doc exists via HEAD /:db/:doc and returns either true or false
Converts CouchDB-native JSON-friendly map to internal %Sofa.Doc{} format
GET doc and returns standard HTTP status, or the requested doc
Bang! version of get/3. Returns the document or raises Sofa.Error.
Lets a pipeline start from a fetched document.
Creates a new (empty) document
Optimistically write/update doc assuming rev matches
Saves a document, with the document first so it can end a pipeline that
builds it. The same as put/2 otherwise.
Bang! version of save/2. Returns the saved document, with its new rev,
or raises Sofa.Error. Lets a pipeline carry on with the saved document.
Converts internal %Sofa.Doc{} format to CouchDB-native JSON-friendly map
Types
Functions
Attaches content to a document, to be saved inline with it. The content
type comes from the name unless given, see Sofa.Attachment.new/3.
Sofa.Doc.new("recipe")
|> Sofa.Doc.attach("recipe.txt", "1. Cook spaghetti")
|> Sofa.Doc.attach("photo", photo_bytes, content_type: "image/jpeg")
|> Sofa.Doc.save(db)
Coerces a CouchDB "type" field to an existing atom. It is assumed that there will be a related Elixir Module Type of the same name. Elixir prefixes Module names with Elixir. and then elides this in iex, tests, and elsewhere, but here we need to make that explicit.
The "user" type is special-cased as it is already present in CouchDB /_users database.
This function is expected to be paired up with Ecto Schemas to properly manage the appropriate fields in your document body.
delete doc
Removes an attachment from a document. CouchDB deletes it when the document is next saved without its stub.
Check if doc exists via HEAD /:db/:doc and returns either:
{:error, not_found}# doc doesn't exist{:ok, %Sofa.Doc{}}# doc exists and has metadata
Check if doc exists via HEAD /:db/:doc and returns either true or false
Converts CouchDB-native JSON-friendly map to internal %Sofa.Doc{} format
Examples
iex> %{ "_id" => "smol", "_rev" => "1-cute", "yes" => true}
|> from_map()
%Sofa.Doc{
attachments: nil,
body: %{"yes" => true},
id: "smol",
rev: "1-cute",
type: nil
}
GET doc and returns standard HTTP status, or the requested doc
{:error, :not_found}# doc doesn't exist, or similar HTTP status%Sofa.Doc{}# doc exists and has metadata
Options
The attachment-related query parameters of the CouchDB document API:
attachments: truefetches attachment content inline, so each%Sofa.Attachment{}inattachmentscarries itsdataatt_encoding_info: trueaddsencodingandencoded_lengthto the stubs of attachments CouchDB stored compressedatts_since: [revs]fetches content only for attachments added after the given revisions, as used when syncingSofa.Doc.get(db, "SpaghettiWithMeatballs", attachments: true)
Bang! version of get/3. Returns the document or raises Sofa.Error.
Lets a pipeline start from a fetched document.
Sofa.Doc.get!(db, "SpaghettiWithMeatballs") |> Sofa.Doc.attach("photo.jpg", bytes) |> Sofa.Doc.save!(db)
Creates a new (empty) document
Optimistically write/update doc assuming rev matches
Saves a document, with the document first so it can end a pipeline that
builds it. The same as put/2 otherwise.
Sofa.Doc.new(%{id: "smol", body: %{"cute" => true}}) |> Sofa.Doc.save(db)
#=> {:ok, %Sofa.Doc{id: "smol", rev: "1-..."}}
Bang! version of save/2. Returns the saved document, with its new rev,
or raises Sofa.Error. Lets a pipeline carry on with the saved document.
doc = Sofa.Doc.new("smol") |> Sofa.Doc.save!(db)
Converts internal %Sofa.Doc{} format to CouchDB-native JSON-friendly map
Examples
iex> %Sofa.Doc{id: "smol", rev: "1-cute", body: %{"yes" => true}}
|> to_map()
%{ "_id" => "smol", "_rev" => "1-cute", "yes" => true}