Packages
electric
1.0.17
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.16
1.4.16-beta-1
1.4.15
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.14
1.1.13
1.1.12
1.1.11
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
retired
1.1.5
retired
1.1.4
retired
1.1.3
retired
1.1.2
1.1.1
1.1.0
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.15
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-beta.23
1.0.0-beta.22
1.0.0-beta.20
1.0.0-beta.19
1.0.0-beta.18
1.0.0-beta.17
1.0.0-beta.16
1.0.0-beta.15
1.0.0-beta.14
1.0.0-beta.13
1.0.0-beta.12
1.0.0-beta.11
1.0.0-beta.10
1.0.0-beta.9
1.0.0-beta.8
1.0.0-beta.7
1.0.0-beta.6
1.0.0-beta.5
1.0.0-beta.4
1.0.0-beta.3
1.0.0-beta.2
1.0.0-beta.1
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.5.2
0.4.4
Postgres sync engine. Sync little subsets of your Postgres data into local apps and services.
Current section
Files
Jump to
Current section
Files
lib/electric/replication/eval/expr.ex
defmodule Electric.Replication.Eval.Expr do
@moduledoc """
Parsed expression, available for evaluation using the runner
"""
alias Electric.Replication.Eval.Parser
alias Electric.Replication.Eval.Env
defstruct [:query, :eval, :used_refs, :returns]
@type used_refs :: %{required([String.t(), ...]) => Env.pg_type()}
@type t() :: %__MODULE__{
query: String.t(),
eval: term(),
used_refs: used_refs(),
returns: Env.pg_type()
}
@doc """
Returns a flat list of all used refs used in the expression
that point to the current table
## Examples
iex> used_refs = %{["id"] => :int8, ["created_at"] => :timestamp}
iex> unqualified_refs(%Expr{query: "id = 1", used_refs: used_refs})
["created_at", "id"]
iex> used_refs = %{["id"] => :int8, ["potato", "created_at"] => :timestamp}
iex> unqualified_refs(%Expr{query: "id = 1", used_refs: used_refs, returns: :int8})
["id"]
"""
@spec unqualified_refs(t()) :: [String.t()]
def unqualified_refs(%__MODULE__{used_refs: used_refs}) do
used_refs
# Keep only used refs that are pointing to current table
|> Enum.filter(&match?({[_], _}, &1))
|> Enum.map(fn {[key], _} -> key end)
end
@doc false
@spec to_json_safe(t()) :: map()
def to_json_safe(%__MODULE__{query: query, used_refs: used_refs}) do
%{
version: 1,
query: query,
used_refs:
Enum.map(used_refs, fn
{k, v} when is_tuple(v) -> [k, Tuple.to_list(v)]
{k, v} -> [k, v]
end)
}
end
@doc false
@spec from_json_safe(map()) :: {:ok, t()} | {:error, String.t()}
def from_json_safe(%{"version" => 1, "query" => query, "used_refs" => refs}) do
refs =
Map.new(refs, fn
[k, v] when is_list(v) -> {k, List.to_tuple(v)}
[k, v] when is_binary(v) -> {k, String.to_existing_atom(v)}
end)
Parser.parse_and_validate_expression(query, refs: refs)
end
def from_json_safe(_),
do: {:error, "Incorrect serialized format: keys must be `version`, `query`, `used_refs`"}
end
defimpl Jason.Encoder, for: Electric.Replication.Eval.Expr do
def encode(expr, opts) do
expr
|> Electric.Replication.Eval.Expr.to_json_safe()
|> Jason.Encode.map(opts)
end
end