12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- %%% @doc Behaviour module for epgsql_sock commands.
- %%% @end
- %%% Copyright (C) 2017 - Sergey Prokhorov. All rights reserved.
- -module(epgsql_command).
- -export([init/2, execute/3, handle_message/5]).
- -export_type([command/0, state/0]).
- -type command() :: module().
- -type state() :: any().
- %% Initialize command's state. Called when command is received by epgsql_sock process.
- -callback init(any()) -> state().
- -type execute_return() ::
- {ok, epgsql_sock:pg_sock(), state()}
- | {stop, Reason :: any(), Response :: any(), epgsql_sock:pg_sock()}.
- %% Execute command. It should send commands to socket.
- %% May be called many times if 'handle_message' will return 'requeue'.
- -callback execute(epgsql_sock:pg_sock(), state()) -> execute_return().
- -type handle_message_return() ::
- {noaction, epgsql_sock:pg_sock()}
- %% Do nothing; remember changed state
- | {noaction, epgsql_sock:pg_sock(), state()}
- %% Add result to resultset (eg, `{ok, Count}' `{ok, Cols, Rows}', `{error, #error{}}'
- %% It may be returned many times for eg, `squery' with multiple
- %% queries separated by ';'
- %% See epgsql_sock:get_results/1
- | {add_result, Data :: any(), Notification :: any(), epgsql_sock:pg_sock(), state()}
- %% Add new row to current resultset;
- %% See epgsql_sock:get_rows/1
- | {add_row, tuple(), epgsql_sock:pg_sock(), state()}
- %% Finish command execution, reply to the client and go to next command
- | {finish, Result :: any(), Notification :: any(), epgsql_sock:pg_sock()}
- %% Stop `epgsql_sock' process
- | {stop, Reason :: any(), Response :: any(), epgsql_sock:pg_sock()}
- %% Call 'execute' and reschedule command.
- %% It's forbidden to call epgsql_sock:send from `handle_message'.
- %% If you need to do so, you should set some flag in state and
- %% reschedule command.
- %% See `epgsql_cmd_connect' for reference.
- | {requeue, epgsql_sock:pg_sock(), state()}
- %% Protocol synchronization error (eg, unexpected packet)
- %% Drop command queue and don't accept any command except 'sync'
- | {sync_required, Why :: any()}
- %% Unknown packet. Terminate `epgsql_sock' process
- | unknown.
- %% Handle incoming packet
- -callback handle_message(Type :: byte(), Payload :: binary() | epgsql:query_error(),
- epgsql_sock:pg_sock(), state()) -> handle_message_return().
- -spec init(command(), any()) -> state().
- init(Command, Args) ->
- Command:init(Args).
- -spec execute(command(), epgsql_sock:pg_sock(), state()) -> execute_return().
- execute(Command, PgSock, CmdState) ->
- Command:execute(PgSock, CmdState).
- -spec handle_message(command(), Type :: byte(), Payload :: binary() | epgsql:query_error(),
- epgsql_sock:pg_sock(), state()) -> handle_message_return().
- handle_message(Command, Type, Payload, PgSock, State) ->
- Command:handle_message(Type, Payload, PgSock, State).
|