_site/cover/msc_mm_execute.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_execute).
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 := execute,
32 statement_id := StatementId} = Packet},
33 {execute, From},
34 #{prepared := Prepared,
35 client_flags := ClientFlags} = Data)
36 when is_map_key(StatementId, Prepared)->
37 2 #{StatementId := #{params := Params}} = Prepared,
38
39 2 {keep_state,
40 Data#{decoder := msmp_codec:decode(
41 scran_branch:alt(
42 [msmp_column_count:decode(),
43 msmp_packet_ok:decode(ClientFlags),
44 msmp_packet_error:decode(ClientFlags)])),
45 execute => #{columns => #{definitions => []},
46 rows => []},
47 encoder := msmp_codec:encode(
48 msmp_com_stmt_execute:encode(ClientFlags))},
49 nei({send,
50 #{packet => Packet#{flags => 0,
51 iteration_count => 1,
52 new_params_bind_flag => 1,
53 types => Params},
54 sequence => 0}})};
55
56 handle_event({call, _}, {request, _}, _, _) ->
57
:-(
{keep_state_and_data, postpone};
58
59 handle_event(internal,
60 {recv, #{packet := #{action := error} = Packet}},
61 {execute, From},
62 Data) ->
63
:-(
{next_state,
64 authenticated,
65 maps:without([execute], Data),
66 [pop_callback_module,
67 {reply,
68 From,
69 {error, maps:without([action], Packet)}}]};
70
71 handle_event(internal,
72 {recv, #{packet := #{action := ok} = Packet}},
73 {execute, From},
74 Data) ->
75 1 {next_state,
76 authenticated,
77 maps:without([execute], Data),
78 [pop_callback_module,
79 {reply,
80 From,
81 {ok, maps:without([action], Packet)}}]};
82
83 handle_event(
84 internal,
85 {recv,
86 #{packet := #{action := column_count, column_count := ColumnCount}}},
87 _,
88 #{execute := #{columns := Columns} = Execute} = Data) ->
89 1 {keep_state,
90 Data#{decoder := msmp_codec:decode(
91 msmp_column_definition:decode()),
92 execute := Execute#{columns := Columns#{count => ColumnCount}}}};
93
94 handle_event(
95 internal,
96 {recv, #{packet := #{action := column_definition} = Packet}},
97 _,
98 #{execute := #{columns := #{definitions := Definitions,
99 count := ColumnCount}}})
100 when length(Definitions) + 1 < ColumnCount ->
101
:-(
{keep_state_and_data, nei({add_definition, Packet})};
102
103 handle_event(
104 internal,
105 {recv, #{packet := #{action := column_definition} = Packet}},
106 _,
107 _) ->
108 1 {keep_state_and_data,
109 [nei({add_definition, Packet}), nei(ready_for_resultset)]};
110
111 handle_event(
112 internal,
113 ready_for_resultset,
114 _,
115 #{client_flags := ClientFlags,
116 execute := #{columns := #{definitions := Definitions}}} = Data) ->
117 1 {keep_state,
118 Data#{decoder := msmp_codec:decode(
119 scran_branch:alt(
120 [msmp_binary_resultset_row:decode(
121 lists:reverse(Definitions)),
122 msmp_packet_eof:decode(ClientFlags)]))}};
123
124 handle_event(
125 internal,
126 {add_definition, Packet},
127 _,
128 #{execute :=
129 #{columns :=
130 #{definitions := Definitions} = Columns} = Execute} = Data) ->
131 1 {keep_state,
132 Data#{execute :=
133 Execute#{columns :=
134 Columns#{definitions :=
135 [maps:without(
136 [action],
137 Packet) |
138 Definitions]}}}};
139
140 handle_event(
141 internal,
142 {recv, #{packet := #{action := binary_resultset_row, row := Row}}},
143 _,
144 #{execute := #{rows := Rows} = Execute} = Data) ->
145 1 {keep_state, Data#{execute := Execute#{rows := [Row | Rows]}}};
146
147 handle_event(internal,
148 {recv, #{packet := #{action := eof}}},
149 {execute, From},
150 #{execute := #{columns := #{definitions := Columns},
151 rows := Rows}} = Data) ->
152 1 {next_state,
153 authenticated,
154 maps:without([execute], Data),
155 [pop_callback_module,
156 {reply, From, {lists:reverse(Columns), lists:reverse(Rows)}}]};
157
158 handle_event(EventType, EventContent, State, Data) ->
159 38 msc_mm_common:handle_event(EventType,
160 EventContent,
161 State,
162 Data).
Line Hits Source