Current section
Files
Jump to
Current section
Files
src/themis@internal@store.erl
-module(themis@internal@store).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/themis/internal/store.gleam").
-export([new_metric/4, find_metric/2, match_metrics/1, init/0, clear/0, increment_record_by/3, increment_record/2, insert_record/3, match_records/1, find_record/2]).
-export_type([store_error/0, store/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type store_error() :: metric_name_already_exists |
insert_error |
{decode_errors, list(gleam@dynamic@decode:decode_error())} |
table_error |
invalid_increment |
single_result_expected |
invalid_type |
metric_not_found.
-type store() :: {store,
themis@internal@erlang@ets:table(),
themis@internal@erlang@ets:table()}.
-file("src/themis/internal/store.gleam", 214).
?DOC(false).
-spec decode_metric(gleam@dynamic:dynamic_()) -> {ok,
{binary(), binary(), binary(), list(float())}} |
{error, list(gleam@dynamic@decode:decode_error())}.
decode_metric(Metric) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Metric,
gleam@dynamic@decode:at(
[0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Field_1) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Metric,
gleam@dynamic@decode:at(
[1],
{decoder, fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Field_2) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Metric,
gleam@dynamic@decode:at(
[2],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Field_3) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Metric,
gleam@dynamic@decode:at(
[3],
gleam@dynamic@decode:list(
{decoder,
fun gleam@dynamic@decode:decode_float/1}
)
)
),
fun(Field_4) ->
{ok, {Field_1, Field_2, Field_3, Field_4}}
end
)
end
)
end
)
end
).
-file("src/themis/internal/store.gleam", 227).
?DOC(false).
-spec decode_record(gleam@dynamic:dynamic_()) -> {ok,
{{binary(), list(binary())}, integer(), float(), binary()}} |
{error, list(gleam@dynamic@decode:decode_error())}.
decode_record(Record) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Record,
gleam@dynamic@decode:at(
[0, 0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Field_1_1) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Record,
gleam@dynamic@decode:at(
[0, 1],
gleam@dynamic@decode:list(
{decoder, fun gleam@dynamic@decode:decode_string/1}
)
)
),
fun(Field_1_2) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Record,
gleam@dynamic@decode:at(
[1],
{decoder, fun gleam@dynamic@decode:decode_int/1}
)
),
fun(Field_2) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Record,
gleam@dynamic@decode:at(
[2],
{decoder,
fun gleam@dynamic@decode:decode_float/1}
)
),
fun(Field_3) ->
gleam@result:'try'(
gleam@dynamic@decode:run(
Record,
gleam@dynamic@decode:at(
[3],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
fun(Field_4) ->
{ok,
{{Field_1_1, Field_1_2},
Field_2,
Field_3,
Field_4}}
end
)
end
)
end
)
end
)
end
).
-file("src/themis/internal/store.gleam", 247).
?DOC(false).
-spec parse_record(gleam@dynamic:dynamic_()) -> {ok,
{themis@internal@label:label_set(), themis@number:number_()}} |
{error, store_error()}.
parse_record(Record) ->
Record_result = begin
_pipe = decode_record(Record),
gleam@result:try_recover(
_pipe,
fun(E) -> {error, {decode_errors, E}} end
)
end,
gleam@result:'try'(
Record_result,
fun(Record@1) ->
{{_, Labels}, Int_value, Float_value, Flag} = Record@1,
Float_decimal@1 = case gleam@float:modulo(Float_value, 1.0) of
{ok, Float_decimal} -> Float_decimal;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"parse_record"/utf8>>,
line => 264,
value => _assert_fail,
start => 8022,
'end' => 8083,
pattern_start => 8033,
pattern_end => 8050})
end,
Numeric_value = case Float_decimal@1 =:= +0.0 of
false ->
themis@number:decimal(
begin
_pipe@1 = Int_value,
_pipe@2 = erlang:float(_pipe@1),
gleam@float:add(_pipe@2, Float_value)
end
);
true ->
themis@number:integer(Int_value)
end,
Value = case Flag of
<<"-Inf"/utf8>> ->
themis@number:negative_infinity();
<<"+Inf"/utf8>> ->
themis@number:positive_infinity();
<<"NaN"/utf8>> ->
themis@number:not_a_number();
_ ->
Numeric_value
end,
Labels@1 = begin
_pipe@3 = Labels,
_pipe@4 = gleam@list:map(
_pipe@3,
fun(Label_string) ->
{Key@1, Value@2} = case gleam@string:split_once(
Label_string,
<<":"/utf8>>
) of
{ok, {Key, Value@1}} -> {Key, Value@1};
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"parse_record"/utf8>>,
line => 278,
value => _assert_fail@1,
start => 8494,
'end' => 8561,
pattern_start => 8505,
pattern_end => 8522})
end,
{Key@1, Value@2}
end
),
maps:from_list(_pipe@4)
end,
Labels@3 = case themis@internal@label:from_dict(Labels@1) of
{ok, Labels@2} -> Labels@2;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"parse_record"/utf8>>,
line => 282,
value => _assert_fail@2,
start => 8613,
'end' => 8660,
pattern_start => 8624,
pattern_end => 8634})
end,
_pipe@5 = {Labels@3, Value},
{ok, _pipe@5}
end
).
-file("src/themis/internal/store.gleam", 52).
?DOC(false).
-spec new_metric(
themis@internal@metric:metric_name(),
binary(),
binary(),
list(float())
) -> {ok, nil} | {error, store_error()}.
new_metric(Name, Description, Kind, Buckets) ->
_pipe@2 = themis@internal@erlang@ets:insert_new_raw(
<<"themis_metrics"/utf8>>,
begin
_pipe@1 = {begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
Description,
Kind,
Buckets},
gleam_stdlib:identity(_pipe@1)
end
),
gleam@result:replace_error(_pipe@2, metric_name_already_exists).
-file("src/themis/internal/store.gleam", 68).
?DOC(false).
-spec find_metric(themis@internal@metric:metric_name(), binary()) -> {ok,
{binary(), binary(), list(float())}} |
{error, store_error()}.
find_metric(Name, Given_kind) ->
Name_string = themis@internal@metric:name_to_string(Name),
Metrics@1 = case themis@internal@erlang@ets:lookup(
<<"themis_metrics"/utf8>>,
Name_string
) of
{ok, Metrics} -> Metrics;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => (<<<<"could not find metric \""/utf8,
Name_string/binary>>/binary,
"\". should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>),
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"find_metric"/utf8>>,
line => 75,
value => _assert_fail,
start => 1894,
'end' => 1962,
pattern_start => 1905,
pattern_end => 1916})
end,
gleam@result:'try'(
case begin
_pipe = Metrics@1,
gleam@list:map(_pipe, fun(Found) -> decode_metric(Found) end)
end of
[{ok, {_, Description, Kind, Buckets}}] ->
{ok, {Description, Kind, Buckets}};
[] ->
{error, metric_not_found};
_ ->
{error, table_error}
end,
fun(_use0) ->
{Description@1, Kind@1, Buckets@1} = _use0,
case Kind@1 =:= Given_kind of
false ->
{error, invalid_type};
true ->
{ok, {Description@1, Kind@1, Buckets@1}}
end
end
).
-file("src/themis/internal/store.gleam", 98).
?DOC(false).
-spec match_metrics(binary()) -> {ok, list({binary(), binary(), list(float())})} |
{error, store_error()}.
match_metrics(Kind) ->
Metrics@1 = case themis@internal@erlang@ets:match_metric(
<<"themis_metrics"/utf8>>,
Kind
) of
{ok, Metrics} -> Metrics;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"match_metrics"/utf8>>,
line => 103,
value => _assert_fail,
start => 2751,
'end' => 2818,
pattern_start => 2762,
pattern_end => 2773})
end,
_pipe@2 = gleam@list:map(
Metrics@1,
fun(Found) ->
R = begin
_pipe = decode_metric(Found),
gleam@result:try_recover(
_pipe,
fun(E) -> {error, {decode_errors, E}} end
)
end,
gleam@result:'try'(
R,
fun(_use0) ->
{Name, Description, _, Buckets} = _use0,
_pipe@1 = {Name, Description, Buckets},
{ok, _pipe@1}
end
)
end
),
gleam@result:all(_pipe@2).
-file("src/themis/internal/store.gleam", 39).
?DOC(false).
-spec init() -> gleam@erlang@atom:atom_().
init() ->
_ = themis@internal@erlang@ets:new(
{table_builder, set, public},
<<"themis_metrics"/utf8>>
),
_ = themis@internal@erlang@ets:new(
{table_builder, set, public},
<<"themis_records"/utf8>>
).
-file("src/themis/internal/store.gleam", 47).
?DOC(false).
-spec clear() -> {ok, boolean()} |
{error, themis@internal@erlang@ets:table_error()}.
clear() ->
_ = themis@internal@erlang@ets:delete_table(<<"themis_metrics"/utf8>>),
_ = themis@internal@erlang@ets:delete_table(<<"themis_records"/utf8>>).
-file("src/themis/internal/store.gleam", 118).
?DOC(false).
-spec increment_record_by(
themis@internal@metric:metric_name(),
themis@internal@label:label_set(),
themis@number:number_()
) -> {ok, nil} | {error, store_error()}.
increment_record_by(Name, Labels, Value) ->
case Value of
{dec, _} ->
_pipe = begin
Labels@1 = themis@internal@label:to_strings(Labels),
Name@1 = themis@internal@metric:name_to_string(Name),
R@1 = case themis@internal@erlang@ets:counter_increment_by(
<<"themis_records"/utf8>>,
{Name@1, Labels@1},
Value
) of
{ok, R} -> R;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"increment_record_by"/utf8>>,
line => 130,
value => _assert_fail,
start => 3673,
'end' => 3770,
pattern_start => 3684,
pattern_end => 3689})
end,
R@1
end,
{ok, _pipe};
{int, _} ->
_pipe = begin
Labels@1 = themis@internal@label:to_strings(Labels),
Name@1 = themis@internal@metric:name_to_string(Name),
R@1 = case themis@internal@erlang@ets:counter_increment_by(
<<"themis_records"/utf8>>,
{Name@1, Labels@1},
Value
) of
{ok, R} -> R;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"increment_record_by"/utf8>>,
line => 130,
value => _assert_fail,
start => 3673,
'end' => 3770,
pattern_start => 3684,
pattern_end => 3689})
end,
R@1
end,
{ok, _pipe};
na_n ->
{error, invalid_increment};
neg_inf ->
{error, invalid_increment};
pos_inf ->
{error, invalid_increment}
end.
-file("src/themis/internal/store.gleam", 140).
?DOC(false).
-spec increment_record(
themis@internal@metric:metric_name(),
themis@internal@label:label_set()
) -> {ok, nil} | {error, store_error()}.
increment_record(Name, Labels) ->
increment_record_by(Name, Labels, themis@number:integer(1)).
-file("src/themis/internal/store.gleam", 148).
?DOC(false).
-spec insert_record(
themis@internal@metric:metric_name(),
themis@internal@label:label_set(),
themis@number:number_()
) -> {ok, nil} | {error, store_error()}.
insert_record(Name, Labels, Value) ->
Labels@1 = themis@internal@label:to_strings(Labels),
{Int_value, Float_value, Flag_value} = case Value of
{dec, Val} ->
{0, Val, <<""/utf8>>};
{int, Val@1} ->
{Val@1, +0.0, <<""/utf8>>};
pos_inf ->
{0, +0.0, <<"+Inf"/utf8>>};
neg_inf ->
{0, +0.0, <<"-Inf"/utf8>>};
na_n ->
{0, +0.0, <<"NaN"/utf8>>}
end,
R@1 = case themis@internal@erlang@ets:insert_raw(
<<"themis_records"/utf8>>,
{{begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
Labels@1},
Int_value,
Float_value,
Flag_value}
) of
{ok, R} -> R;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"insert_record"/utf8>>,
line => 163,
value => _assert_fail,
start => 4698,
'end' => 4867,
pattern_start => 4709,
pattern_end => 4714})
end,
case R@1 of
false ->
{error, insert_error};
true ->
{ok, nil}
end.
-file("src/themis/internal/store.gleam", 178).
?DOC(false).
-spec match_records(themis@internal@metric:metric_name()) -> {ok,
gleam@dict:dict(themis@internal@label:label_set(), themis@number:number_())} |
{error, store_error()}.
match_records(Name) ->
Records@1 = case themis@internal@erlang@ets:match_record(
<<"themis_records"/utf8>>,
begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end
) of
{ok, Records} -> Records;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"match_records"/utf8>>,
line => 183,
value => _assert_fail,
start => 5249,
'end' => 5345,
pattern_start => 5260,
pattern_end => 5271})
end,
_pipe@1 = Records@1,
_pipe@2 = gleam@list:map(_pipe@1, fun parse_record/1),
_pipe@3 = gleam@result:all(_pipe@2),
gleam@result:map(_pipe@3, fun maps:from_list/1).
-file("src/themis/internal/store.gleam", 193).
?DOC(false).
-spec find_record(
themis@internal@metric:metric_name(),
themis@internal@label:label_set()
) -> {ok, {themis@internal@label:label_set(), themis@number:number_()}} |
{error, store_error()}.
find_record(Name, Labels) ->
Entries@1 = case themis@internal@erlang@ets:lookup(
<<"themis_records"/utf8>>,
{begin
_pipe = Name,
themis@internal@metric:name_to_string(_pipe)
end,
begin
_pipe@1 = Labels,
themis@internal@label:to_strings(_pipe@1)
end}
) of
{ok, Entries} -> Entries;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"should only return an error if the given table name string is not found as an atom. Are you sure you initialized the Themis store ?"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"themis/internal/store"/utf8>>,
function => <<"find_record"/utf8>>,
line => 200,
value => _assert_fail,
start => 5776,
'end' => 5916,
pattern_start => 5787,
pattern_end => 5798})
end,
_pipe@2 = case Entries@1 of
[Entry] ->
{ok, Entry};
_ ->
{error, single_result_expected}
end,
gleam@result:'try'(_pipe@2, fun parse_record/1).