Phoenix.Sync.Writer.Format behaviour (Phoenix.Sync v0.4.2)
View SourceDefines a behaviour that applications can implement in order to handle custom
data formats within a Phoenix.Sync.Writer
The exact format of the change messages coming from the client is
unimportant, however Phoenix.Sync.Writer requires certain essential
information that needs to be included.
operation- one ofinsert,updateordeleterelation- the table name that the operation applies to.data- the original data before the mutation was applied. Required forupdateordeleteoperationschanges- the changes to apply. Required forinsertandupdateoperations
However you choose to encode this information on the client, you simply need
to set the format of your write configuration using to a module that
implements this behaviour.
Implementation guide
Once you have parsed the data coming from the client, over HTTP or even raw
TCP, use Phoenix.Sync.Writer.Operation.new/4 (or
Phoenix.Sync.Writer.Transaction.operation/4) to validate the values and
create a %Phoenix.Sync.Writer.Operation{} struct.
Phoenix.Sync.Writer.Transaction.parse_operations/2 is a helper function for
error handling when mapping a list of encoded operation data using
Phoenix.Sync.Writer.Transaction.operation/4.
Example:
We use Protocol buffers to encode the incoming information using :protox
and implement this module's parse_transaction/1 callback using the Protox decode functions:
defmodule MyApp.Protocol do
use Protox,
namespace: __MODULE__,
schema: ~S[
syntax: "proto2";
message Operation {
enum Op {
INSERT = 0;
UPDATE = 1;
DELETE = 2;
}
required Op op = 1;
string table = 2;
map<string, string> original = 3;
map<string, string> modified = 4;
}
message Transaction {
repeated Operation operations = 1;
}
]
alias Phoenix.Sync.Writer
@behaviour Phoenix.Sync.Writer.Format
@impl Phoenix.Sync.Writer.Format
def parse_transaction(proto) when is_binary(proto) do
with {:ok, %{operations: ops}} <- MyApp.Protocol.Transaction.decode(proto),
{:ok, operations} <- Writer.Transaction.parse_operations(ops, &convert_operation/1) do
{:ok, %Writer.Transaction{operations: operations}
end
end
defp convert_operation(%MyApp.Protocol.Operation{} = operation) do
Writer.Transaction.operation(
operation.op,
operation.table,
operation.original,
operation.modified
)
end
endWe use our protocol module as the format when we apply/4 our transaction
data and we can just pass our serialized protobuf message as the mutation data:
{:ok, txid, _changes} =
Phoenix.Sync.Writer.new()
|> Phoenix.Sync.Writer.apply(protobuf_data, MyApp.Repo, format: MyApp.Protocol)
Summary
Types
Raw data from a client that will be parsed to a Phoenix.Sync.Writer.Format.Transaction by the Writer's format parser
Callbacks
Translate some data format into a Phoenix.Sync.Writer.Transaction with a
list of operations to apply.
Types
@type parse_transaction_result() :: {:ok, Phoenix.Sync.Writer.Transaction.t()} | {:error, term()}
@type parser_fun() :: (transaction_data() -> parse_transaction_result()) | mfa()
@type t() :: module()
@type transaction_data() :: term()
Raw data from a client that will be parsed to a Phoenix.Sync.Writer.Format.Transaction by the Writer's format parser
Callbacks
@callback parse_transaction(term()) :: parse_transaction_result()
Translate some data format into a Phoenix.Sync.Writer.Transaction with a
list of operations to apply.