Khepri high-level and cluster management API.
This module exposes the high-level API to manipulate data and the cluster management API.
The default store is based on Ra's default system. You need to change the Ra application configuration if you want to set settings. That said, it is recommended to start your own Ra system. This way, even though Ra is already running, you can choose where the Khepri data should be stored. This is also required if you need to run multiple database instances in parallel.
Here is a quick start example:
%% We start Khepri. Ra is also started because Khepri depends on it.
{ok, _} = application:ensure_all_started(khepri),
%% We define the configuration of the Ra system for our database. Here, we
%% only care about the directory where data will be written.
RaSystem = my_ra_system,
RaSystemDataDir = "/path/to/storage/dir",
DefaultSystemConfig = ra_system:default_config(),
RaSystemConfig = DefaultSystemConfig#{name => RaSystem,
data_dir => RaSystemDataDir,
wal_data_dir => RaSystemDataDir,
names => ra_system:derive_names(
RaSystem)},
%% The configuration is ready, let's start the Ra system.
{ok, _RaSystemPid} = ra_system:start(RaSystemConfig),
%% At last we can start Khepri! We need to choose a name for the Ra cluster
%% running in the Ra system started above. This must be an atom.
RaClusterName = my_khepri_db,
RaClusterFriendlyName = "My Khepri DB",
{ok, StoreId} = khepri:start(
RaSystem,
RaClusterName,
RaClusterFriendlyName),
%% The Ra cluster name is our "store ID" used everywhere in the Khepri API.
khepri:insert(StoreId, [stock, wood], 156).
Please refer to Ra documentation to learn more about Ra systems and Ra clusters.
To add a member to your Ra cluster:
khepri:add_member(
RaSystem,
RaClusterName,
RaClusterFriendlyName,
NewMemberErlangNodename).
To remove a member from your Ra cluster:
khepri:remove_member(
RaClusterName,
MemberErlangNodenameToRemove).
error(Type) = {error, Type}
Return value of a failed command or query.
error() = error(any())
ok(Type) = {ok, Type}
store_id() = ra:cluster_name()
ID of a Khepri store.
start/0 | |
start/1 | |
start/3 | |
add_member/2 | |
add_member/4 | |
remove_member/1 | |
remove_member/2 | |
reset/2 | |
members/1 | |
locally_known_members/1 | |
nodes/1 | |
locally_known_nodes/1 | |
get_store_ids/0 | |
create/2 | Creates a specific tree node in the tree structure only if it does not exist. |
create/3 | Creates a specific tree node in the tree structure only if it does not exist. |
insert/2 | Creates or modifies a specific tree node in the tree structure. |
insert/3 | Creates or modifies a specific tree node in the tree structure. |
update/2 | Updates a specific tree node in the tree structure only if it already exists. |
update/3 | Updates a specific tree node in the tree structure only if it already exists. |
compare_and_swap/3 | Updates a specific tree node in the tree structure only if it already
exists and its data matches the given DataPattern . |
compare_and_swap/4 | Updates a specific tree node in the tree structure only if it already
exists and its data matches the given DataPattern . |
clear_payload/1 | Clears the payload of an existing specific tree node in the tree structure. |
clear_payload/2 | Clears the payload of an existing specific tree node in the tree structure. |
delete/1 | Deletes all tree nodes matching the path pattern. |
delete/2 | Deletes all tree nodes matching the path pattern. |
get/1 | Returns all tree nodes matching the path pattern. |
get/2 | Returns all tree nodes matching the path pattern. |
get/3 | Returns all tree nodes matching the path pattern. |
exists/1 | Returns true if the tree node pointed to by the given path exists,
otherwise false . |
exists/2 | Returns true if the tree node pointed to by the given path exists,
otherwise false . |
has_data/1 | Returns true if the tree node pointed to by the given path has a data
payload, otherwise false . |
has_data/2 | Returns true if the tree node pointed to by the given path has a data
payload, otherwise false . |
list/1 | |
list/2 | |
find/2 | Finds tree nodes below Path which match the given Condition . |
find/3 | Finds tree nodes under Path which match the given Condition . |
transaction/1 | |
transaction/2 | |
transaction/3 | |
clear_store/0 | |
clear_store/1 | |
no_payload/0 | Returns ?NO_PAYLOAD . |
data_payload/1 | Returns ?DATA_PAYLOAD(Term) . |
info/0 | |
info/1 |
start() -> {ok, store_id()} | {error, any()}
start(RaSystem::atom()) -> {ok, store_id()} | {error, any()}
start(RaSystem::atom(), ClusterName::ra:cluster_name(), FriendlyName::string()) -> {ok, store_id()} | {error, any()}
add_member(RaSystem, NewNode) -> any()
add_member(RaSystem, ClusterName, FriendlyName, NewNode) -> any()
remove_member(NodeToRemove) -> any()
remove_member(ClusterName, NodeToRemove) -> any()
reset(RaSystem, ClusterName) -> any()
members(ClusterName) -> any()
locally_known_members(ClusterName) -> any()
nodes(ClusterName) -> any()
locally_known_nodes(ClusterName) -> any()
get_store_ids() -> [store_id()]
create(Path, Data) -> ok | error()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
Creates a specific tree node in the tree structure only if it does not exist.
Calling this function is the same as callingcreate(StoreId, Path, Data)
with the default store ID.
See also: create/3.
create(StoreId, Path, Data) -> ok | error()
StoreId = store_id()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:put/3
.
Creates a specific tree node in the tree structure only if it does not exist.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
The Path
is the modified to include a #if_node_exists{exists = false}
condition on its last component.
khepri_machine:put/3
.
See also: khepri_machine:put/3.
insert(Path, Data) -> ok | error()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
Creates or modifies a specific tree node in the tree structure.
Calling this function is the same as callinginsert(StoreId, Path, Data)
with the default store ID.
See also: insert/3.
insert(StoreId, Path, Data) -> ok | error()
StoreId = store_id()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:put/3
.
Creates or modifies a specific tree node in the tree structure.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
khepri_machine:put/3
.
See also: khepri_machine:put/3.
update(Path, Data) -> ok | error()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
Updates a specific tree node in the tree structure only if it already exists.
Calling this function is the same as callingupdate(StoreId, Path, Data)
with the default store ID.
See also: update/3.
update(StoreId, Path, Data) -> ok | error()
StoreId = store_id()
Path = khepri_path:pattern() | string()
Data = khepri_machine:data()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:put/3
.
Updates a specific tree node in the tree structure only if it already exists.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
The Path
is the modified to include a #if_node_exists{exists = true}
condition on its last component.
khepri_machine:put/3
.
See also: khepri_machine:put/3.
compare_and_swap(Path, DataPattern, Data) -> ok | error()
Path = khepri_path:pattern() | string()
DataPattern = ets:match_pattern()
Data = khepri_machine:data()
Updates a specific tree node in the tree structure only if it already
exists and its data matches the given DataPattern
.
compare_and_swap(StoreId, Path, DataPattern, Data)
with the default store
ID.
See also: create/3.
compare_and_swap(StoreId, Path, DataPattern, Data) -> ok | error()
StoreId = store_id()
Path = khepri_path:pattern() | string()
DataPattern = ets:match_pattern()
Data = khepri_machine:data()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:put/3
.
Updates a specific tree node in the tree structure only if it already
exists and its data matches the given DataPattern
.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
The Path
is the modified to include a
#if_data_matches{pattern = DataPattern}
condition on its last component.
khepri_machine:put/3
.
See also: khepri_machine:put/3.
clear_payload(Path) -> ok | error()
Path = khepri_path:pattern() | string()
Clears the payload of an existing specific tree node in the tree structure.
Calling this function is the same as callingclear_payload(StoreId, Path)
with the default store ID.
See also: create/3.
clear_payload(StoreId, Path) -> ok | error()
StoreId = store_id()
Path = khepri_path:pattern() | string()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:put/3
.
Clears the payload of an existing specific tree node in the tree structure.
In other words, the payload is set to ?NO_PAYLOAD
.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
khepri_machine:put/3
.
See also: khepri_machine:put/3.
delete(PathPattern) -> ok | error()
PathPattern = khepri_path:pattern() | string()
Deletes all tree nodes matching the path pattern.
Calling this function is the same as callingdelete(StoreId, PathPattern)
with
the default store ID.
See also: delete/2.
delete(StoreId, PathPattern) -> ok | error()
StoreId = store_id()
PathPattern = khepri_path:pattern() | string()
returns: a single "ok" atom or an "error" tuple, unlike
khepri_machine:delete/2
.
Deletes all tree nodes matching the path pattern.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
khepri_machine:delete/2
.
See also: delete/2.
get(PathPattern) -> Result
PathPattern = khepri_path:pattern() | string()
Result = khepri_machine:result()
Returns all tree nodes matching the path pattern.
Calling this function is the same as callingget(StoreId, PathPattern)
with the default store ID.
See also: get/3.
get(StoreId, PathPattern) -> Result
StoreId = store_id()
PathPattern = khepri_path:pattern() | string()
Result = khepri_machine:result()
get(PathPattern, Options) -> Result
PathPattern = khepri_path:pattern() | string()
Options = khepri_machine:operation_options()
Result = khepri_machine:result()
Returns all tree nodes matching the path pattern.
This function accepts the following two forms:get(StoreId, Path)
. Calling it is the same as calling
get(StoreId, PathPattern, #{})
.get(Path, Options
. Calling it is the same as calling
get(StoreId, PathPattern, #{})
with the default store ID.See also: get/3.
get(StoreId, PathPattern, Options) -> Result
StoreId = store_id()
PathPattern = khepri_path:pattern() | string()
Options = khepri_machine:operation_options()
Result = khepri_machine:result()
Returns all tree nodes matching the path pattern.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
khepri_machine:get/3
.
See also: khepri_machine:get/3.
exists(Path) -> Exists
Path = khepri_path:pattern() | string()
Exists = boolean()
Returns true
if the tree node pointed to by the given path exists,
otherwise false
.
exists(StoreId, Path)
with the default store ID.
See also: exists/2.
exists(StoreId, Path) -> Exists
StoreId = store_id()
Path = khepri_path:pattern() | string()
Exists = boolean()
Returns true
if the tree node pointed to by the given path exists,
otherwise false
.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
The Path
must point to a specific tree node and can't match multiple nodes.
get/3
and interpret its result.
See also: get/3.
has_data(Path) -> HasData
Path = khepri_path:pattern() | string()
HasData = boolean()
Returns true
if the tree node pointed to by the given path has a data
payload, otherwise false
.
has_data(StoreId, Path)
with the default store ID.
See also: has_data/2.
has_data(StoreId, Path) -> HasData
StoreId = store_id()
Path = khepri_path:pattern() | string()
HasData = boolean()
Returns true
if the tree node pointed to by the given path has a data
payload, otherwise false
.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
The Path
must point to a specific tree node and can't match multiple nodes.
get/3
and interpret its result.
See also: get/3.
list(Path::khepri_path:pattern() | string()) -> khepri_machine:result()
list(StoreId::store_id(), Path::khepri_path:pattern() | string()) -> khepri_machine:result()
find(Path, Condition) -> Result
Path = khepri_path:pattern() | string()
Condition = khepri_path:pattern_component()
Result = khepri_machine:result()
Finds tree nodes below Path
which match the given Condition
.
See also: find/3.
find(StoreId, Path, Condition) -> Result
StoreId = store_id()
Path = khepri_path:pattern() | string()
Condition = khepri_path:pattern_component()
Result = khepri_machine:result()
StoreId
: the name of the Ra cluster.
Path
: the path indicating where to start the search from.
Condition
: the condition nodes must match to be part of the result.
returns: an "ok" tuple with a map with zero, one or more entries, or an "error" tuple.
Finds tree nodes under Path
which match the given Condition
.
The Path
can be provided as a list of node names and conditions or as a
string. See khepri_path:from_string/1
.
Nodes are searched deeply under the given Path
, not only among direct
child nodes.
%% Find nodes with data under `/foo/bar'.
Result = khepri:find(
ra_cluster_name,
[foo, bar],
#if_has_data{has_data = true}),
%% Here is the content of `Result'.
{ok, #{[foo, bar, baz] => #{data => baz_value,
payload_version => 2,
child_list_version => 1,
child_list_length => 0},
[foo, bar, deep, under, qux] => #{data => qux_value,
payload_version => 1,
child_list_version => 1,
child_list_length => 0}}} = Result.
transaction(Fun) -> Ret
Fun = khepri_tx:tx_fun()
Ret = Atomic | Aborted
Atomic = {atomic, khepri_tx:tx_fun_result()}
Aborted = khepri_tx:tx_abort()
transaction(StoreId, Fun) -> Ret
StoreId = store_id()
Fun = khepri_tx:tx_fun()
Ret = Atomic | Aborted
Atomic = {atomic, khepri_tx:tx_fun_result()}
Aborted = khepri_tx:tx_abort()
transaction(Fun, ReadWrite) -> Ret
Fun = khepri_tx:tx_fun()
ReadWrite = ro | rw | auto
Ret = Atomic | Aborted
Atomic = {atomic, khepri_tx:tx_fun_result()}
Aborted = khepri_tx:tx_abort()
transaction(StoreId, Fun, ReadWrite) -> Ret
StoreId = store_id()
Fun = khepri_tx:tx_fun()
ReadWrite = ro | rw | auto
Ret = Atomic | Aborted
Atomic = {atomic, khepri_tx:tx_fun_result()}
Aborted = khepri_tx:tx_abort()
clear_store() -> ok | error()
clear_store(StoreId::store_id()) -> ok | error()
no_payload() -> none
Returns ?NO_PAYLOAD
.
data_payload(Term) -> {data, Term}
Term = khepri_machine:data()
Returns ?DATA_PAYLOAD(Term)
.
info() -> any()
info(StoreId::store_id()) -> ok
Generated by EDoc