Packages
ex_esdb
0.3.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14-alpha
0.0.13-alpha
0.0.12-alpha
0.0.11-alpha
0.0.10-alpha
0.0.9-alpha
0.0.8-alpha
0.0.6-alpha
0.0.5-alpha
0.0.4-alpha
0.0.3-alpha
0.0.2-alfa
0.0.1-alfa
ExESDB is a reincarnation of rabbitmq/khepri, specialized for use as a BEAM-native event store.
Current section
Files
Jump to
Current section
Files
lib/ex_esdb/streams_helper.ex
defmodule ExESDB.StreamsHelper do
@moduledoc """
Provides helper functions for working with event store streams.
"""
import ExESDB.Khepri.Conditions
def calculate_versions(start_version, count, direction)
when is_integer(start_version) and is_integer(count) and count > 0 do
case direction do
:forward -> start_version..(start_version + count - 1)
:backward -> start_version..(start_version - count + 1)
end
end
# Handle invalid inputs gracefully
def calculate_versions(start_version, count, direction) do
require Logger
Logger.warning(
"Invalid parameters for calculate_versions: start_version=#{inspect(start_version)}, count=#{inspect(count)}, direction=#{inspect(direction)}"
)
# Return empty range for invalid inputs
0..-1
end
def stream_exists?(store, stream_id),
do:
store
|> :khepri.exists([:streams, stream_id])
def version_to_integer(padded_version)
when is_binary(padded_version) do
padded_version
|> String.trim_leading("0")
|> case do
# Handle all-zero case
"" -> 0
num_str -> String.to_integer(num_str)
end
end
def pad_version(version, length)
when is_integer(version) and
length > 0 do
version
|> Integer.to_string()
|> String.pad_leading(length, "0")
end
@doc """
Returns the version of the stream using 0-based indexing.
## Parameters
- `store` is the name of the store.
- `stream_id` is the name of the stream.
## Returns
- `version` (0-based) or `-1` if the stream does not exist.
This means:
- New stream (no events): -1
- Stream with 1 event: 0 (version of latest event)
- Stream with 2 events: 1 (version of latest event)
- etc.
"""
@spec get_version!(
store :: atom(),
stream_id :: String.t()
) :: integer
def get_version!(store, stream_id) do
case store
|> :khepri.count([
:streams,
stream_id,
if_node_exists(exists: true)
]) do
# No events in stream, so version is -1
{:ok, 0} -> -1
# Convert 1-based count to 0-based version
{:ok, count} -> count - 1
# Stream doesn't exist
_ -> -1
end
end
def to_event_record(
%ExESDB.Schema.NewEvent{} = new_event,
stream_id,
version,
created,
created_epoch
),
do: %ExESDB.Schema.EventRecord{
event_stream_id: stream_id,
event_number: version,
event_id: new_event.event_id,
event_type: new_event.event_type,
data_content_type: new_event.data_content_type,
metadata_content_type: new_event.metadata_content_type,
data: new_event.data,
metadata: new_event.metadata,
created: created,
created_epoch: created_epoch
}
end