_site/cover/pgsqlp_replication.COVER.html

1 %% Copyright (c) 2023 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(pgsqlp_replication).
17
18
19 -feature(maybe_expr, enable).
20
21
22 -export([expression/0]).
23 -import(pgsqlp, [t/1]).
24 -import(pgsqlp, [to_atom/1]).
25 -import(scran_branch, [alt/1]).
26 -import(scran_character_complete, [alpha1/0]).
27 -import(scran_character_complete, [hex_digit1/0]).
28 -import(scran_character_complete, [multispace0/0]).
29 -import(scran_character_complete, [multispace1/0]).
30 -import(scran_character_complete, [re/1]).
31 -import(scran_character_complete, [tag/1]).
32 -import(scran_character_complete, [tag_no_case/1]).
33 -import(scran_combinator, [ignore_result/1]).
34 -import(scran_combinator, [map_result/2]).
35 -import(scran_combinator, [opt/1]).
36 -import(scran_multi, [separated_list0/2]).
37 -import(scran_multi, [separated_list1/2]).
38 -import(scran_result, [kv/2]).
39 -import(scran_sequence, [delimited/3]).
40 -import(scran_sequence, [preceded/2]).
41 -import(scran_sequence, [separated_pair/3]).
42 -import(scran_sequence, [sequence/1]).
43
44
45 expression() ->
46 18 alt([identify_system(),
47 create_replication_slot(),
48 drop_replication_slot(),
49 start_replication()]).
50
51
52 identify_system() ->
53 18 sequence([kv(action, to_atom(tag_no_case("IDENTIFY_SYSTEM")))]).
54
55
56 create_replication_slot() ->
57 18 sequence(
58 [kv(action, to_atom(tag_no_case("CREATE_REPLICATION_SLOT"))),
59 slot_name(),
60 opt(t(preceded(multispace1(), tag_no_case("TEMPORARY")))),
61 alt([sequence(
62 [kv(mode, preceded(multispace1(), to_atom(tag_no_case("LOGICAL")))),
63 kv(output_plugin, preceded(multispace1(), alpha1()))]),
64 sequence(
65 [kv(mode, preceded(multispace1(), tag_no_case("PHYSICAL"))),
66 opt(preceded(multispace1(), tag_no_case("TEMPORARY")))])]),
67 alt([preceded(
68 multispace1(),
69 kv(
70 snapshot,
71 to_atom(
72 alt([tag_no_case("EXPORT_SNAPSHOT"),
73 tag_no_case("NOEXPORT_SNAPSHOT"),
74 tag_no_case("USE_SNAPSHOT")])))),
75
76 preceded(
77 multispace1(),
78 delimited(
79 tag("("),
80 separated_list1(
81 sequence([multispace0(), tag(","), multispace0()]),
82 alt([map_result(
83 separated_pair(
84 to_atom(tag_no_case("SNAPSHOT")),
85 multispace1(),
86 delimited(
87 tag("'"),
88 to_atom(
89 alt([tag_no_case("export"),
90 tag_no_case("use"),
91 tag_no_case("nothing")])),
92 tag("'"))),
93 fun erlang:list_to_tuple/1)])),
94 tag(")")))])]).
95
96
97 drop_replication_slot() ->
98 18 sequence(
99 [kv(action, to_atom(tag_no_case("DROP_REPLICATION_SLOT"))),
100 slot_name(),
101 opt(t(preceded(multispace1(), tag_no_case("WAIT"))))]).
102
103
104 start_replication() ->
105 18 sequence(
106 [kv(action, to_atom(tag_no_case("START_REPLICATION"))),
107 ignore_result(preceded(multispace1(), tag_no_case("SLOT"))),
108 slot_name(),
109 kv(mode, preceded(multispace1(), to_atom(tag_no_case("LOGICAL")))),
110 preceded(multispace1(), lsn()),
111 preceded(multispace1(), options())]).
112
113
114 options() ->
115 18 kv(?FUNCTION_NAME,
116 delimited(
117 tag("("),
118 map_result(
119 separated_list0(sequence([tag(","), multispace0()]),
120 option()),
121 fun maps:from_list/1),
122 tag(")"))).
123
124
125 option() ->
126 18 map_result(
127 separated_pair(to_atom(option_name()), multispace1(), option_value()),
128 fun erlang:list_to_tuple/1).
129
130
131 option_name() ->
132 18 re("[a-zA-Z_]+").
133
134
135 option_value() ->
136 18 delimited(tag("'"), re("[^']+"), tag("'")).
137
138
139 lsn() ->
140 18 kv(?FUNCTION_NAME,
141 map_result(
142 sequence([hex_digit1(), tag("/"), hex_digit1()]),
143 fun erlang:list_to_binary/1)).
144
145
146 slot_name() ->
147 54 kv(slot,
148 preceded(
149 multispace1(),
150 alt(
151 [quoted(re("[a-zA-Z0-9_]+")),
152 re("[a-zA-Z0-9_]+")]))).
153
154
155 quoted(Parser) ->
156 54 Quote = tag("\""),
157 54 delimited(Quote, Parser, Quote).
Line Hits Source