_site/cover/msc_mm_prepare.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 %% @doc Middleman dealing with the query process.
16
17 -module(msc_mm_prepare).
18
19
20 -export([callback_mode/0]).
21 -export([handle_event/4]).
22 -import(msc_statem, [nei/1]).
23 -include_lib("kernel/include/logger.hrl").
24
25
26 callback_mode() ->
27 2 handle_event_function.
28
29
30 handle_event({call, From},
31 {request, #{action := prepare} = Packet},
32 {prepare, From},
33 #{client_flags := ClientFlags} = Data) ->
34 2 {keep_state,
35 Data#{decoder := msmp_codec:decode(
36 scran_branch:alt(
37 [msmp_com_stmt_prepare_ok:decode(ClientFlags),
38 msmp_packet_error:decode(ClientFlags)])),
39 encoder := msmp_codec:encode(
40 msmp_com_stmt_prepare:encode(ClientFlags))},
41 nei({send, #{packet => Packet, sequence => 0}})};
42
43 handle_event({call, _}, {request, _}, _, _) ->
44
:-(
{keep_state_and_data, postpone};
45
46 handle_event(internal,
47 {recv, #{packet := #{action := error} = Packet}},
48 {prepare, From},
49 Data) ->
50
:-(
{next_state,
51 authenticated,
52 Data,
53 [pop_callback_module,
54 {reply,
55 From,
56 {error, maps:without([action], Packet)}}]};
57
58 handle_event(
59 internal,
60 {recv,
61 #{packet := #{action := com_stmt_prepare_ok,
62 statement_id := StatementId,
63 num_params := 0,
64 num_columns := 0}}},
65 {prepare, From},
66 #{prepared := Prepared} = Data)
67 when not(is_map_key(StatementId, Prepared)) ->
68
:-(
{next_state,
69 authenticated,
70 Data#{prepared := Prepared#{StatementId => #{params => [],
71 columns => []}}},
72 [pop_callback_module, {reply, From, {ok, StatementId}}]};
73
74 handle_event(
75 internal,
76 {recv,
77 #{packet := #{action := com_stmt_prepare_ok,
78 statement_id := StatementId} = Packet}},
79 _,
80 #{prepared := Prepared} = Data)
81 when not(is_map_key(StatementId, Prepared)) ->
82 2 {keep_state,
83 Data#{decoder := msmp_codec:decode(
84 msmp_column_definition:decode()),
85 prepare => maps:with(
86 [statement_id,
87 num_params,
88 num_columns],
89 Packet),
90 prepared := Prepared#{StatementId => #{params => [],
91 columns => []}}}};
92
93 handle_event(
94 internal,
95 {recv, #{packet := #{action := column_definition} = Packet}},
96 {prepare, From},
97 #{prepare := #{statement_id := StatementId,
98 num_params := 1,
99 num_columns := 0},
100 prepared := Prepared} = Data) ->
101 1 #{StatementId := #{params := Params} = Definition} = Prepared,
102 1 {next_state,
103 authenticated,
104 maps:without(
105 [prepare],
106 Data#{prepared :=
107 Prepared#{StatementId :=
108 Definition#{params := lists:reverse(
109 [Packet | Params])}}}),
110 [pop_callback_module, {reply, From, {ok, StatementId}}]};
111
112 handle_event(
113 internal,
114 {recv, #{packet := #{action := column_definition} = Packet}},
115 _,
116 #{prepare := #{statement_id := StatementId,
117 num_params := NumParams} = Prepare,
118 prepared := Prepared} = Data)
119 when NumParams > 0 ->
120 1 #{StatementId := #{params := Params} = Definition} = Prepared,
121 1 {keep_state,
122 Data#{prepare := Prepare#{num_params := NumParams - 1},
123 prepared :=
124 Prepared#{StatementId :=
125 Definition#{params := [Packet | Params]}}}};
126
127 handle_event(
128 internal,
129 {recv, #{packet := #{action := column_definition} = Packet}},
130 _,
131 #{prepare := #{statement_id := StatementId,
132 num_columns := NumColumns} = Prepare,
133 prepared := Prepared} = Data)
134 when NumColumns > 1 ->
135
:-(
#{StatementId := #{columns := Columns} = Definition} = Prepared,
136
:-(
{keep_state,
137 Data#{prepare := Prepare#{num_columns := NumColumns - 1},
138 prepared :=
139 Prepared#{StatementId :=
140 Definition#{columns := [Packet | Columns]}}}};
141
142 handle_event(
143 internal,
144 {recv, #{packet := #{action := column_definition} = Packet}},
145 {prepare, From},
146 #{prepare := #{statement_id := StatementId,
147 num_columns := 1},
148 prepared := Prepared} = Data) ->
149 1 #{StatementId := #{columns := Columns,
150 params := Params} = Definition} = Prepared,
151 1 {next_state,
152 authenticated,
153 maps:without(
154 [prepare],
155 Data#{prepared :=
156 Prepared#{StatementId :=
157 Definition#{columns := lists:reverse(
158 [Packet | Columns]),
159 params := lists:reverse(Params)}}}),
160 [pop_callback_module, {reply, From, {ok, StatementId}}]};
161
162 handle_event(
163 internal,
164 {recv, #{packet := #{action := column_definition} = Packet}},
165 _,
166 #{client_flags := ClientFlags} = Data) ->
167
:-(
{keep_state,
168 Data#{decoder := msmp_codec:decode(
169 scran_branch:alt(
170 [msmp_packet_eof:decode(ClientFlags)]))},
171 nei({add_definition, Packet})};
172
173 handle_event(
174 internal,
175 {add_definition, Packet},
176 _,
177 #{prepare :=
178 #{columns :=
179 #{definitions := Definitions} = Columns} = Prepare} = Data) ->
180
:-(
{keep_state,
181 Data#{prepare :=
182 Prepare#{columns :=
183 Columns#{definitions :=
184 [maps:without(
185 [action],
186 Packet) |
187 Definitions]}}}};
188
189 handle_event(
190 internal,
191 {recv, #{packet := #{action := text_resultset, row := Row}}},
192 _,
193 #{prepare := #{rows := Rows} = Prepare} = Data) ->
194
:-(
{keep_state, Data#{prepare := Prepare#{rows := [Row | Rows]}}};
195
196 handle_event(internal,
197 {recv, #{packet := #{action := eof}}},
198 {prepare, From},
199 #{prepare := #{columns := #{definitions := Columns},
200 rows := Rows}} = Data) ->
201
:-(
{next_state,
202 authenticated,
203 maps:without([prepare], Data),
204 [pop_callback_module,
205 {reply, From, {lists:reverse(Columns), lists:reverse(Rows)}}]};
206
207 handle_event(EventType, EventContent, State, Data) ->
208 43 msc_mm_common:handle_event(EventType,
209 EventContent,
210 State,
211 Data).
Line Hits Source