defmodule Ravix.Documents.Commands.GetDocumentsCommand do
@moduledoc """
Command to fetch documents from RavenDB
## Fields
- ids: List of document ids
- includes: Path of the referenced documents that should be included
- metadata_only: If the response should contain only the metadata
- start: from which position should the returned documents start
- page_size: number of documents that should be returned
- counter_includes: List of counters to be returned
"""
use Ravix.Documents.Commands.RavenCommand,
ids: [],
includes: nil,
metadata_only: false,
start: nil,
page_size: nil,
counter_includes: []
import Ravix.Helpers.UrlBuilder
import Ravix.Documents.Commands.RavenCommand
alias Ravix.Documents.Protocols.CreateRequest
alias Ravix.Documents.Commands.GetDocumentsCommand
alias Ravix.Documents.Session.{SessionDocument, State}
alias Ravix.Connection.ServerNode
command_type(%{
ids: list(String.t()),
includes: list(String.t()) | nil,
metadata_only: boolean() | nil,
start: non_neg_integer() | nil,
page_size: non_neg_integer() | nil,
counter_includes: list(String.t()) | nil
})
@doc """
Parses the response of the GetCommand
## Parameters
- session_state: The session state where this command was called
- documents_response: Response from the database call
## Returns
- List of results and includes
"""
@spec parse_response(State.t(), map) :: [{:includes, list()} | {:results, list}]
def parse_response(session_state, documents_response) do
[
results: extract_results(session_state, Map.get(documents_response, "Results")),
includes: extract_includes(session_state, Map.get(documents_response, "Includes"))
]
end
defp extract_results(session_state, results) do
results
|> Enum.reject(fn batch_item -> batch_item == nil end)
|> Enum.map(fn batch_item ->
{:ok, :update_document, SessionDocument.upsert_document(session_state, batch_item)}
end)
end
defp extract_includes(session_state, includes) do
includes
|> Enum.map(fn {doc_id, document} ->
{:ok, :update_document, SessionDocument.upsert_document(session_state, doc_id, document)}
end)
end
defimpl CreateRequest, for: GetDocumentsCommand do
@spec create_request(GetDocumentsCommand.t(), ServerNode.t()) :: map()
def create_request(%GetDocumentsCommand{} = command, %ServerNode{} = server_node) do
base_url = server_node |> ServerNode.node_database_path()
%GetDocumentsCommand{
command
| method: :get,
is_read_request: true,
url:
"#{base_url}/docs?"
|> append_param("id", command.ids)
|> append_param("start", command.start)
|> append_param("pageSize", command.page_size)
|> append_param("metadataOnly", command.metadata_only)
|> append_param("include", command.includes)
}
end
end
end