-
Notifications
You must be signed in to change notification settings - Fork 138
/
Copy pathels_dt_functions.erl
139 lines (121 loc) · 4.05 KB
/
els_dt_functions.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
%%==============================================================================
%% The 'functions' table
%%==============================================================================
-module(els_dt_functions).
%%==============================================================================
%% Behaviour els_db_table
%%==============================================================================
-behaviour(els_db_table).
-export([
name/0,
opts/0
]).
%%==============================================================================
%% API
%%==============================================================================
-export([
insert/1,
versioned_insert/1,
lookup/1,
delete_by_uri/1,
versioned_delete_by_uri/2
]).
%%==============================================================================
%% Includes
%%==============================================================================
-include("els_lsp.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
%%==============================================================================
%% Item Definition
%%==============================================================================
-record(els_dt_functions, {
mfa :: mfa() | '_' | {atom(), '_', '_'},
version :: version() | '_',
is_exported :: boolean() | '_'
}).
-type els_dt_functions() :: #els_dt_functions{}.
-type version() :: null | integer().
-type item() :: #{
mfa := mfa(),
version := version(),
is_exported := boolean()
}.
-export_type([item/0]).
%%==============================================================================
%% Callbacks for the els_db_table Behaviour
%%==============================================================================
-spec name() -> atom().
name() -> ?MODULE.
-spec opts() -> proplists:proplist().
opts() ->
[set].
%%==============================================================================
%% API
%%==============================================================================
-spec from_item(item()) -> els_dt_functions().
from_item(#{
mfa := MFA,
version := Version,
is_exported := IsExported
}) ->
#els_dt_functions{
mfa = MFA,
version = Version,
is_exported = IsExported
}.
-spec to_item(els_dt_functions()) -> item().
to_item(#els_dt_functions{
mfa = MFA,
version = Version,
is_exported = IsExported
}) ->
#{
mfa => MFA,
version => Version,
is_exported => IsExported
}.
-spec insert(item()) -> ok | {error, any()}.
insert(Map) when is_map(Map) ->
Record = from_item(Map),
els_db:write(name(), Record).
-spec versioned_insert(item()) -> ok | {error, any()}.
versioned_insert(#{mfa := MFA, version := Version} = Map) ->
Record = from_item(Map),
Condition = fun(#els_dt_functions{version = CurrentVersion}) ->
CurrentVersion =:= null orelse Version >= CurrentVersion
end,
els_db:conditional_write(name(), MFA, Record, Condition).
-spec lookup(mfa()) -> {ok, [item()]}.
lookup(MFA) ->
{ok, Items} = els_db:lookup(name(), MFA),
{ok, [to_item(Item) || Item <- Items]}.
-spec delete_by_uri(uri()) -> ok.
delete_by_uri(Uri) ->
case filename:extension(Uri) of
<<".erl">> ->
Module = els_uri:module(Uri),
Pattern = #els_dt_functions{mfa = {Module, '_', '_'}, _ = '_'},
ok = els_db:match_delete(name(), Pattern);
_ ->
ok
end.
-spec versioned_delete_by_uri(uri(), version()) -> ok.
versioned_delete_by_uri(Uri, Version) ->
case filename:extension(Uri) of
<<".erl">> ->
Module = els_uri:module(Uri),
MS = ets:fun2ms(
fun
(#els_dt_functions{mfa = {M, _, _}, version = CurrentVersion}) when
M =:= Module,
CurrentVersion =:= null orelse CurrentVersion < Version
->
true;
(_) ->
false
end
),
ok = els_db:select_delete(name(), MS);
_ ->
ok
end.