EctoSync (EctoSync v0.1.2)

View Source

A Cache updater and router for events emitted when database entries are updated. Subscribers can provide a list of records that they want to receive updates on. Additionally, they can provide a function that will act as a means of authorization on the updates they should get.

Using the subscribe function a process can subscribe to all messages for a given struct.

Summary

Functions

Returns a specification to start this module under a supervisor.

Subscribe to Ecto.Schema(s) provided. The input can be one of following

See EctoSync.Subscriber.subscribe/2.

Returns a list of pids that are subscribed to the given watcher identifier.

Performs the actual syncing of a given value. Based on the input and the event, certain behaviour can be expected.

See EctoSync.Subscriber.unsubscribe/2.

Create watcher specifications for a given schema.

Types

schema_or_list_of_schemas()

@type schema_or_list_of_schemas() :: Ecto.Schema.t() | [Ecto.Schema.t()]

subscriptions()

@type subscriptions() :: [{EctoWatch.watcher_identifier(), term()}]

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(opts \\ [name: __MODULE__])

subscribe(values)

Subscribe to Ecto.Schema(s) provided. The input can be one of following:

  • an Ecto.Schema struct,
  • a list of Ecto.Schema struct,
  • an EctoWatch identifier.

When an Ecto.Schema struct or list of structs is provided, the process is subscribed to all :updated and :deleted events for the Ecto.Schema that represents the struct.

Examples

iex> defmodule Test do
...>   use Ecto.Schema
...>   schema do
...>     field :name, :string
...>   end
...> end

iex> EctoSync.subscribe(Test)
[{{Test, :inserted}, nil}, {{Test, :updated}, nil}, {{Test, :deleted}, nil}]

iex> EctoSync.subscribe(%Test{id: 1})
[{{Test, :updated}, 1}, {{Test, :deleted}, 1}]

subscribe(values, opts)

See EctoSync.Subscriber.subscribe/2.

subscriptions(watcher_identifier, id \\ nil)

@spec subscriptions(EctoWatch.watcher_identifier(), term()) :: [
  {pid(), Registry.value()}
]

Returns a list of pids that are subscribed to the given watcher identifier.

sync(value, sync_config)

Performs the actual syncing of a given value. Based on the input and the event, certain behaviour can be expected.

:inserted event

structinputoutput
%Post{id: 1}[][%Post{id: 1}]
%Post{id: 2}[%Post{id: 1}][%Post{id: 1}, %Post{id: 2}]
%Comment{id: 1, post_id: 1}[%Post{id: 1, comments: []}][%Post{id: 1, comments: [%Comment{id: 1}]}]

:updated event

structinputoutput
%Post{id: 1, name: "Updated name"}%Post{id:1, name: "Name"}%Post{id: 1}, name: "Updated name"}
%Post{id: 2}[%Post{id: 1}][%Post{id: 1}, %Post{id: 2}]
%Comment{id: 1, post_id: 1}[%Post{id: 1, comments: []}][%Post{id: 1, comments: [%Comment{id: 1}]}]
%Comment{id: 1, post_id: 2}[%Post{id: 1, comments: [%Comment{id: 1}]}, %Post{id: 2, comments: []}][%Post{id: 1, comments: []}, %Post{id: 2, comments: [%Comment{id: 1}]}]

:deleted event

structinputoutput
%Post{id: 1}[][]
%Post{id: 1}%Post{id: 1}%Post{id: 1}
%Post{id: 2}[%Post{id: 1}, %Post{id: 2}][%Post{id: 1}]
%Comment{id: 1, post_id: 1}[%Post{id: 1, comments: [%Comment{id: 1}]}][%Post{id: 1, comments: []}]

unsubscribe(watcher_identifier, id)

See EctoSync.Subscriber.unsubscribe/2.

watchers(watchers \\ [], schema)

Create watcher specifications for a given schema.

  • schema - The Ecto.Schema to subscribe to.

Options

  • :extra_columns, which extra columns should be included
  • :assocs, a preload like keyword list of associations to subscribe to. If assocs are specified in the options, the necessary extra_columns will be added or merged to the :extra_columns option.

Examples

Assuming the same schemas are present as in the Use Cases page.

# Generate events for a schema without associations
watchers(MyApp.User)
# => [
#      {MyApp.User, :inserted, []},
#      {MyApp.User, :updated, []},
#      {MyApp.User, :deleted, []}
#    ]

# Generate events for all associations
watchers(User, assocs: [posts: [:comments, :tags, :labels]])
# => Includes events for:
# [
#   {Label, :deleted, [extra_columns: []]},
#   {Label, :inserted, [extra_columns: []]},
#   {Label, :updated, [extra_columns: []]},
#   {Person, :deleted, [extra_columns: []]},
#   {Person, :inserted, [extra_columns: []]},
#   {Person, :updated, [extra_columns: []]},
#   {Post, :deleted, [extra_columns: [:person_id]]},
#   {Post, :deleted, [extra_columns: [:post_id]]},
#   {Post, :inserted, [extra_columns: [:person_id]]},
#   {Post, :inserted, [extra_columns: [:post_id]]},
#   {Post, :updated, [extra_columns: [:person_id]]},
#   {Post, :updated, [extra_columns: [:post_id]]},
#   {PostsTags, :deleted, [extra_columns: [:tag_id, :post_id]]},
#   {PostsTags, :inserted, [extra_columns: [:tag_id, :post_id]]},
#   {PostsTags, :updated, [extra_columns: [:tag_id, :post_id]]},
#   {Tag, :deleted, [extra_columns: []]},
#   {Tag, :inserted, [extra_columns: []]},
#   {Tag, :updated, [extra_columns: []]}
# ]

watchers(watchers, schema, opts)

@spec watchers(list(), module(), list()) :: list()

See watchers/2.