Current section

Files

Jump to
evoq src evoq_adapter.erl
Raw

src/evoq_adapter.erl

%% @doc Event store adapter behavior for evoq
%%
%% Defines the interface for event store operations. Implementations
%% provide the actual connection to an event store backend.
%%
%% == Implementing an Adapter ==
%%
%% ```
%% -module(my_adapter).
%% -behaviour(evoq_adapter).
%%
%% append(StoreId, StreamId, ExpectedVersion, Events) ->
%% %% Implementation here
%% {ok, NewVersion}.
%% '''
%%
%% == Configuration ==
%%
%% Set the adapter in application config:
%%
%% ```
%% {evoq, [
%% {event_store_adapter, my_adapter}
%% ]}
%% '''
%%
%% @author rgfaber
-module(evoq_adapter).
-include_lib("evoq/include/evoq_types.hrl").
%%====================================================================
%% Callback Definitions
%%====================================================================
%% Append events to a stream with expected version check.
%%
%% Expected version semantics:
%% -1 (NO_STREAM) - Stream must not exist (first write)
%% -2 (ANY_VERSION) - No version check, always append
%% N >= 0 - Stream version must equal N
%%
%% Returns {ok, NewVersion} on success or {error, Reason} on failure.
-callback append(StoreId :: atom(),
StreamId :: binary(),
ExpectedVersion :: integer(),
Events :: [map()]) ->
{ok, non_neg_integer()} | {error, term()}.
%% Read events from a stream.
%%
%% Parameters:
%% StoreId - The store identifier
%% StreamId - The stream identifier
%% StartVersion - Starting version (0-based)
%% Count - Maximum number of events to read
%% Direction - forward or backward
%%
%% Returns {ok, [Event]} or {error, Reason}
-callback read(StoreId :: atom(),
StreamId :: binary(),
StartVersion :: non_neg_integer(),
Count :: pos_integer(),
Direction :: forward | backward) ->
{ok, [evoq_event()]} | {error, term()}.
%% Read all events from a stream.
-callback read_all(StoreId :: atom(),
StreamId :: binary(),
Direction :: forward | backward) ->
{ok, [evoq_event()]} | {error, term()}.
%% Read events by event types across all streams.
%%
%% Uses native filtering capabilities to efficiently query events
%% by their type without loading all events into memory.
-callback read_by_event_types(StoreId :: atom(),
EventTypes :: [binary()],
BatchSize :: pos_integer()) ->
{ok, [evoq_event()]} | {error, term()}.
%% Get current version of a stream.
%%
%% Returns:
%% -1 - if stream doesn't exist or is empty
%% N >= 0 - representing the version of the latest event
-callback version(StoreId :: atom(), StreamId :: binary()) ->
integer().
%% Check if a stream exists.
-callback exists(StoreId :: atom(), StreamId :: binary()) ->
boolean().
%% List all streams in the store.
-callback list_streams(StoreId :: atom()) ->
{ok, [binary()]} | {error, term()}.
%% Delete a stream and all its events.
-callback delete_stream(StoreId :: atom(), StreamId :: binary()) ->
ok | {error, term()}.
%% Read all events across all streams in global order.
%%
%% Returns events sorted by epoch_us, starting from Offset.
%% Used for catch-up subscriptions and global event replay.
-callback read_all_global(StoreId :: atom(),
Offset :: non_neg_integer(),
BatchSize :: pos_integer()) ->
{ok, [evoq_event()]} | {error, term()}.
-optional_callbacks([read_all_global/3]).