defmodule Ravix.Documents.Session.SaveChangesData do
@moduledoc """
Defines all changes that will be executed in a session when calling the save_changes function
## Fields
- deferred_commands_count: How many command will be executed
- commands: List of commands to be executed
- entities: Entities in the current session
"""
defstruct deferred_commands_count: 0,
commands: [],
entities: []
alias Ravix.Documents.Session.SaveChangesData
alias Ravix.Documents.Commands.Data.DeleteDocument
alias Ravix.Documents.Commands.Data.PutDocument
@type t :: %SaveChangesData{
deferred_commands_count: non_neg_integer(),
commands: list(map()),
entities: list(map())
}
@doc """
Add the commands that will be deferred to be executed together with the save_changes call
## Parameters
- save_changes_data: this structure instance
- deferred_commands: Raven commands to be deferred
## Returns
- Updated `Ravix.Documents.Session.SaveChangesData`
"""
@spec add_deferred_commands(SaveChangesData.t(), list(map())) :: SaveChangesData.t()
def add_deferred_commands(%SaveChangesData{} = save_changes_data, deferred_commands) do
%SaveChangesData{
save_changes_data
| commands: save_changes_data.commands ++ deferred_commands,
deferred_commands_count: Enum.count(deferred_commands)
}
end
@doc """
Add the entities that will be deleted
## Parameters
- save_changes_data: this structure instance
- deleted_entities: Entities that will be deleted
## Returns
- Updated `Ravix.Documents.Session.SaveChangesData`
"""
@spec add_delete_commands(SaveChangesData.t(), list(map())) :: SaveChangesData.t()
def add_delete_commands(%SaveChangesData{} = save_changes_data, deleted_entities) do
delete_commands =
Enum.map(
deleted_entities,
fn entity ->
%DeleteDocument{Id: entity.key, ChangeVector: entity.change_vector}
end
)
%SaveChangesData{
save_changes_data
| entities: save_changes_data.entities ++ deleted_entities,
commands: save_changes_data.commands ++ delete_commands
}
end
@doc """
Adds the documents that will be created
## Parameters
- save_changes_data: this structure instance
- documents_by_id: Map with the documents that will be created
## Returns
- Updated `Ravix.Documents.Session.SaveChangesData`
"""
@spec add_put_commands(SaveChangesData.t(), map()) :: SaveChangesData.t()
def add_put_commands(%SaveChangesData{} = save_changes_data, documents_by_id) do
put_commands =
documents_by_id
|> Map.values()
|> documents_with_changes()
|> Enum.map(fn elmn ->
%PutDocument{Id: elmn.key, Document: elmn.entity, ChangeVector: elmn.change_vector}
end)
entities = put_commands |> Enum.map(fn cmnd -> Map.get(cmnd, "Document") end)
%SaveChangesData{
save_changes_data
| entities: save_changes_data.entities ++ entities,
commands: save_changes_data.commands ++ put_commands
}
end
defp documents_with_changes(documents_by_id) do
Enum.filter(documents_by_id, fn document ->
document.entity != document.original_value
end)
end
end