Current section
Files
Jump to
Current section
Files
lib/aerospike/command/exists.ex
defmodule Aerospike.Command.Exists do
@moduledoc false
alias Aerospike.Command.UnaryCommand
alias Aerospike.Command.UnarySupport
alias Aerospike.Error
alias Aerospike.Key
alias Aerospike.Protocol.AsmMsg
alias Aerospike.Protocol.Message
alias Aerospike.Protocol.Response
alias Aerospike.Runtime.TxnSupport
@type option ::
{:timeout, non_neg_integer()}
| {:socket_timeout, non_neg_integer()}
| {:max_retries, non_neg_integer()}
| {:sleep_between_retries_ms, non_neg_integer()}
| {:replica_policy, :master | :sequence}
| {:filter, Aerospike.Exp.t() | nil}
| {:read_mode_ap, :one | :all}
| {:read_mode_sc, :session | :linearize | :allow_replica | :allow_unavailable}
| {:read_touch_ttl_percent, -1 | 0..100}
| {:send_key, boolean()}
| {:use_compression, boolean()}
@type result ::
{:ok, boolean()}
| {:error, Error.t()}
| {:error, :cluster_not_ready | :no_master | :unknown_node}
@spec execute(GenServer.server(), Key.t(), [option()]) :: result()
def execute(tender, %Key{} = key, opts \\ []) when is_list(opts) do
with {:ok, txn} <- TxnSupport.txn_from_opts(opts),
{:ok, policy} <- UnarySupport.read_policy(tender, opts),
:ok <- TxnSupport.prepare_txn_read(tender, txn, key) do
UnarySupport.run_command(
tender,
key,
policy,
command(),
%{key: key, conn: tender, txn: txn, opts: opts, policy: policy, filter: policy.filter}
)
end
end
defp command do
UnaryCommand.new!(
name: __MODULE__,
dispatch: :read,
build_request: &encode_exists/1,
parse_response: &parse_exists_response/2
)
end
defp encode_exists(%{
key: %Key{} = key,
conn: conn,
opts: opts,
policy: policy,
use_compression: use_compression,
filter: filter
}) do
key
|> AsmMsg.key_command(
[],
[read: true, read_header: true] ++ UnarySupport.read_header_opts(policy, use_compression)
)
|> AsmMsg.maybe_add_filter_exp(filter)
|> TxnSupport.maybe_add_mrt_fields(conn, key, opts, false)
|> AsmMsg.encode()
|> Message.encode_as_msg_iodata()
end
defp parse_exists_response(body, %{key: key, conn: conn, txn: txn}) do
UnarySupport.parse_as_msg(body, fn msg ->
case exists_result(msg) do
{:ok, _} = ok ->
TxnSupport.track_txn_response(conn, txn, key, :read, msg, ok)
ok
{:error, _} = err ->
err
end
end)
end
defp exists_result(msg) do
case Response.parse_record_metadata_response(msg) do
{:ok, _metadata} -> {:ok, true}
{:error, %Error{code: :key_not_found}} -> {:ok, false}
{:error, %Error{}} = err -> err
end
end
end