Compare commits
2 Commits
d6a4dca5f6
...
6246f3f2e1
| Author | SHA1 | Date | |
|---|---|---|---|
| 6246f3f2e1 | |||
|
|
c6969238c7 |
54
src/mrdb.erl
54
src/mrdb.erl
@ -68,6 +68,7 @@
|
|||||||
, select/2 , select/3
|
, select/2 , select/3
|
||||||
, select_reverse/2, select_reverse/3
|
, select_reverse/2, select_reverse/3
|
||||||
, select/1
|
, select/1
|
||||||
|
, ms/2
|
||||||
, fold/3 , fold/4 , fold/5
|
, fold/3 , fold/4 , fold/5
|
||||||
, fold_reverse/3 , fold_reverse/4, fold_reverse/5
|
, fold_reverse/3 , fold_reverse/4, fold_reverse/5
|
||||||
, rdb_fold/4 , rdb_fold/5
|
, rdb_fold/4 , rdb_fold/5
|
||||||
@ -104,6 +105,7 @@
|
|||||||
, db_ref/0
|
, db_ref/0
|
||||||
, ref_or_tab/0
|
, ref_or_tab/0
|
||||||
, index_position/0
|
, index_position/0
|
||||||
|
, match_pattern/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-include("mnesia_rocksdb.hrl").
|
-include("mnesia_rocksdb.hrl").
|
||||||
@ -125,6 +127,9 @@
|
|||||||
-type outer() :: non_neg_integer().
|
-type outer() :: non_neg_integer().
|
||||||
-type retries() :: outer() | {inner(), outer()}.
|
-type retries() :: outer() | {inner(), outer()}.
|
||||||
|
|
||||||
|
-type matchpat_map() :: #{atom() => _}.
|
||||||
|
-type match_pattern() :: matchpat_map() | ets:match_pattern().
|
||||||
|
|
||||||
%% activity type 'ets' makes no sense in this context
|
%% activity type 'ets' makes no sense in this context
|
||||||
-type mnesia_activity_type() :: transaction
|
-type mnesia_activity_type() :: transaction
|
||||||
| sync_transaction
|
| sync_transaction
|
||||||
@ -1332,6 +1337,55 @@ select_reverse(Tab, Pat, Limit) when Limit == infinity; is_integer(Limit), Limit
|
|||||||
select(Cont) ->
|
select(Cont) ->
|
||||||
mrdb_select:select(Cont).
|
mrdb_select:select(Cont).
|
||||||
|
|
||||||
|
%% @doc Produce a match specification for select(), supporting map-based match patterns
|
||||||
|
%%
|
||||||
|
%% Using record syntax in match patterns tends to conflict with type checking. This
|
||||||
|
%% function offers an alternative approach, drawing on the fact that mnesia_rocksdb
|
||||||
|
%% keeps the record name and attribute names readily available as persistent terms.
|
||||||
|
%%
|
||||||
|
%% When using the map-based representation, the match pattern is built by matching
|
||||||
|
%% attribute names to map elements; any attribute not found in the map gets set to '_'.
|
||||||
|
%% Thus, ```[{#balance{key = {Acct,'$1'},_='_'},[{'>=','$1',Height}],['$_']}]''' can be
|
||||||
|
%% created as ```ms(balance,[{#{key => {Acct,'$1'}},[{'>=','$1',Height}],['$_']}])'''.
|
||||||
|
%%
|
||||||
|
%% This has the advantage over `ms_transform' that it can handle bound variables
|
||||||
|
%% in the match pattern. The function works on all mnesia table types.
|
||||||
|
%% @end
|
||||||
|
-spec ms(ref_or_tab(), [{match_pattern(), [_], [_]}]) -> ets:match_spec().
|
||||||
|
ms(Tab, Pat) ->
|
||||||
|
#{ attributes := Attrs
|
||||||
|
, record_name := RecName } = any_tab_props(Tab),
|
||||||
|
[{headpat(RecName, Attrs, Hd), Gs, Body}
|
||||||
|
|| {Hd, Gs, Body} <- Pat].
|
||||||
|
|
||||||
|
any_tab_props(Tab) ->
|
||||||
|
try mrdb_props(Tab)
|
||||||
|
catch
|
||||||
|
exit:{aborted,{bad_type,_}} ->
|
||||||
|
mnesia_props(Tab)
|
||||||
|
end.
|
||||||
|
|
||||||
|
mrdb_props(Tab) ->
|
||||||
|
#{properties := Props} = get_ref(Tab),
|
||||||
|
Props.
|
||||||
|
|
||||||
|
mnesia_props(Tab) ->
|
||||||
|
try mnesia_props_(Tab)
|
||||||
|
catch
|
||||||
|
exit:{aborted, _} ->
|
||||||
|
mnesia:abort({bad_type, Tab})
|
||||||
|
end.
|
||||||
|
|
||||||
|
mnesia_props_(Tab) ->
|
||||||
|
#{ record_name => mnesia:table_info(Tab, record_name)
|
||||||
|
, attributes => mnesia:table_info(Tab, attributes) }.
|
||||||
|
|
||||||
|
headpat(RecName, Attrs, Hd) when is_map(Hd) ->
|
||||||
|
list_to_tuple([RecName | [maps:get(A, Hd, '_')
|
||||||
|
|| A <- Attrs]]);
|
||||||
|
headpat(_, _, Hd) when is_tuple(Hd); is_atom(Hd) ->
|
||||||
|
Hd.
|
||||||
|
|
||||||
clear_table(Tab) ->
|
clear_table(Tab) ->
|
||||||
match_delete(Tab, '_').
|
match_delete(Tab, '_').
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user