/home/runner/work/pgec/pgec/_site/ct/ct_run.ct_pgec@fv-az651-965.2023-12-04_14.30.54/pgec_h.COVER.html

1 %% Copyright (c) 2022 Peter Morgan <peter.james.morgan@gmail.com>
2 %%
3 %% Licensed under the Apache License, Version 2.0 (the "License");
4 %% you may not use this file except in compliance with the License.
5 %% You may obtain a copy of the License at
6 %%
7 %% http://www.apache.org/licenses/LICENSE-2.0
8 %%
9 %% Unless required by applicable law or agreed to in writing, software
10 %% distributed under the License is distributed on an "AS IS" BASIS,
11 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 %% See the License for the specific language governing permissions and
13 %% limitations under the License.
14
15
16 -module(pgec_h).
17
18
19 -define(JSON, <<"application/json">>).
20 -export([init/2]).
21 -include_lib("kernel/include/logger.hrl").
22 -include_lib("stdlib/include/ms_transform.hrl").
23
24
25 init(Req, Opts) ->
26 4 ?FUNCTION_NAME(Req, Opts, cowboy_req:path_info(Req)).
27
28
29 init(#{bindings := #{publication := Publication,
30 table := Table} = Bindings} = Req,
31 Opts,
32 Keys) ->
33
34 4 ?LOG_DEBUG(#{req => Req, opts => Opts, keys => Keys}),
35
36 4 case pgec_storage_sync:metadata(Bindings) of
37 {ok, Metadata} ->
38 4 ?LOG_DEBUG(#{metadata => Metadata}),
39
40 4 try lookup(Metadata, Req) of
41 [_] = Row ->
42 2 ContentType = negotiate_content_type(Req),
43
44 2 {ok,
45 cowboy_req:reply(
46 200,
47 headers(ContentType),
48 [encode(
49 ContentType,
50 hd(lists:foldl(
51 pgec_kv:row(Metadata, ContentType),
52 [],
53 Row))),
54 "\n"],
55 Req),
56 Opts};
57
58 [] ->
59 2 {ok,
60 not_found(Req,
61 #{publication => Publication,
62 keys => Keys,
63 table => Table}),
64 Opts}
65
66 catch error:badarg ->
67
:-(
{ok,
68 not_found(Req,
69 #{publication => Publication,
70 keys => Keys,
71 table => Table}),
72 Opts}
73 end;
74
75 [] ->
76
:-(
?LOG_DEBUG(#{metadata => not_found}),
77
:-(
{ok,
78 not_found(Req,
79 #{publication => Publication,
80 keys => Keys,
81 table => Table}),
82 Opts}
83 end;
84
85 init(Req, Opts, _) ->
86
:-(
?LOG_DEBUG(#{req => Req, opts => Opts}),
87
88
:-(
{ok,
89 cowboy_req:reply(
90 200,
91 headers(),
92 [jsx:encode(#{publications => pgmp_config:replication(
93 logical,
94 publication_names)}),
95 "\n"],
96 Req),
97 Opts}.
98
99
100 %% Not much negotiation here, we only support JSON right now.
101 %%
102 negotiate_content_type(#{headers := #{}}) ->
103 2 ?JSON.
104
105
106 headers() ->
107 2 ?FUNCTION_NAME(?JSON).
108
109
110 headers(ContentType) ->
111 4 #{<<"content-type">> => ContentType}.
112
113
114 not_found(Req, Body) ->
115 2 cowboy_req:reply(404, headers(), [jsx:encode(Body), "\n"], Req).
116
117
118 lookup(Metadata,
119 #{bindings := Bindings} = Req) ->
120 4 ?LOG_DEBUG(#{metadata => Metadata, req => Req}),
121 4 Key = key(Metadata, Req),
122 4 case pgec_storage_sync:read(
123 maps:merge(
124 #{key => Key},
125 maps:with([publication, table], Bindings))) of
126
127 {ok, Value} ->
128 2 [pgec_storage_common:row(Key, Value, Metadata)];
129
130 not_found ->
131 2 []
132 end.
133
134
135 key(Metadata, Req) ->
136 4 ?LOG_DEBUG(#{metadata => Metadata, req => Req}),
137 4 pgec_kv:key(Metadata, cowboy_req:path_info(Req)).
138
139
140 encode(?JSON, Content) ->
141 2 jsx:encode(Content).
Line Hits Source