Sheetshow.Log.Event (Sheetshow v0.1.0)

Copy Markdown View Source

One row of a log: an id, what it says, and whether it says the row is gone.

iex> event = Sheetshow.Log.Event.new(%{item: "Rent", cost: "1000.00"})
iex> {byte_size(event.id), event.deleted, event.record.item}
{26, false, "Rent"}

An event is a value you hold on to. Writing one is Sheetshow.Log.plan/2; changing it later is the same id written again, and deleting it is the same id written again with deleted set. Nothing is edited in place, on the sheet or here, which is what makes a failed write safe to retry: the same id appended twice folds to one row.

row and errors are filled in by a read and are empty on an event you made yourself. errors is a map from column name to Sheetshow.Error: a cell a person typed that would not cast leaves the field nil and says so here, rather than taking the row or the read down with it.

Summary

Functions

The tombstone that takes a row out of the fold.

Whether a read left anything flagged on this event.

An event holding a record, with an id of its own unless you pass one.

Merges changes into the record, keeping the id: the update you append next.

Types

t()

@type t() :: %Sheetshow.Log.Event{
  deleted: boolean(),
  errors: %{optional(Sheetshow.Schema.name()) => Sheetshow.Error.t()},
  id: String.t() | nil,
  record: Sheetshow.Schema.fields(),
  row: non_neg_integer() | nil
}

Functions

delete(event)

@spec delete(t() | String.t()) :: t()

The tombstone that takes a row out of the fold.

Given an event, the record travels with it, so someone reading the tab sees what went; given a bare id, the tombstone is a row with nothing but that id and the flag.

iex> Sheetshow.Log.Event.delete("invoice-104")
%Sheetshow.Log.Event{id: "invoice-104", row: nil, record: %{}, deleted: true, errors: %{}}

errors?(event)

@spec errors?(t()) :: boolean()

Whether a read left anything flagged on this event.

iex> Sheetshow.Log.Event.new(%{item: "Rent"}) |> Sheetshow.Log.Event.errors?()
false

new(record, opts \\ [])

@spec new(Sheetshow.Schema.fields(), keyword()) :: t()

An event holding a record, with an id of its own unless you pass one.

Options: :id, any non-empty string, since a ULID is only the default, so an invoice number or a key your app already has is just as good; and :deleted, to make a tombstone in one step.

iex> Sheetshow.Log.Event.new(%{item: "Rent"}, id: "invoice-104").id
"invoice-104"

put(event, changes)

@spec put(t(), Sheetshow.Schema.fields()) :: t()

Merges changes into the record, keeping the id: the update you append next.

iex> Sheetshow.Log.Event.new(%{item: "Rent", cost: "1000.00"})
...> |> Sheetshow.Log.Event.put(%{cost: "1100.00"})
...> |> Map.fetch!(:record)
%{item: "Rent", cost: "1100.00"}