Packages

Aerospike driver for Elixir with an OTP-native cluster runtime

Current section

Files

Jump to
aerospike_driver lib aerospike op exp.ex
Raw

lib/aerospike/op/exp.ex

defmodule Aerospike.Op.Exp do
@moduledoc """
Expression operations for `Aerospike.operate/4`.
Expression operations evaluate an `Aerospike.Exp` on the server. Reads return
the expression result under the requested response bin name; writes store the
result into the target bin.
Aerospike.operate(cluster, key, [
Aerospike.Op.Exp.read("projected", Aerospike.Exp.int_bin("count")),
Aerospike.Op.Exp.write("computed", Aerospike.Exp.int(99))
])
This module accepts the expression builders exposed by `Aerospike.Exp`; it
does not accept arbitrary encoded payloads.
"""
alias Aerospike.Error
alias Aerospike.Exp
alias Aerospike.PolicyInteger
alias Aerospike.Protocol.AsmMsg.Operation
@typedoc """
Opaque expression operation for `Aerospike.operate/4`.
"""
@opaque t :: Aerospike.Op.t()
@typedoc """
Options accepted by expression operate builders.
Supported key:
* `:flags` - expression read or write flags. Defaults to `:default`.
"""
@type flags :: atom() | [atom()] | non_neg_integer() | {:raw, non_neg_integer()}
@type opts :: [flags: flags()]
@doc """
Reads the result of a server-side expression into `bin_name`.
The optional `:flags` value accepts `:default`, `:eval_no_fail`, or a list
of those atoms. Compatibility callers may pass a non-negative integer; use
`{:raw, integer}` when deliberately sending an unnamed server value.
Aerospike.Op.Exp.read("projected", Aerospike.Exp.int_bin("count"))
"""
@spec read(String.t() | atom(), Exp.t(), opts()) :: t()
def read(bin_name, %Exp{} = expression, opts \\ []) do
case Operation.exp_read(
normalize_bin_name(bin_name),
expression,
read_flags(opts)
) do
{:ok, op} -> op
{:error, %Error{} = err} -> raise ArgumentError, err.message
end
end
@doc """
Writes the result of a server-side expression to `bin_name`.
The optional `:flags` value accepts `:default`, `:create_only`,
`:update_only`, `:allow_delete`, `:policy_no_fail`, `:eval_no_fail`, or a
list of those atoms. Compatibility callers may pass a non-negative integer;
use `{:raw, integer}` when deliberately sending an unnamed server value.
Aerospike.Op.Exp.write("computed", Aerospike.Exp.int(99))
"""
@spec write(String.t() | atom(), Exp.t(), opts()) :: t()
def write(bin_name, %Exp{} = expression, opts \\ []) do
case Operation.exp_modify(
normalize_bin_name(bin_name),
expression,
write_flags(opts)
) do
{:ok, op} -> op
{:error, %Error{} = err} -> raise ArgumentError, err.message
end
end
defp read_flags(opts),
do: opts |> Keyword.get(:flags, :default) |> PolicyInteger.exp_read_flags()
defp write_flags(opts),
do: opts |> Keyword.get(:flags, :default) |> PolicyInteger.exp_write_flags()
defp normalize_bin_name(bin_name) when is_atom(bin_name), do: Atom.to_string(bin_name)
defp normalize_bin_name(bin_name), do: bin_name
end