Bandera. Store. Persistent. Ecto. Serializer
(bandera v0.1.0)
Copy Markdown
Pure mapping between Bandera.Gates and SQL table rows.
A row is a plain map %{flag_name, gate_type, target, enabled}. Both percentage
gate types collapse to gate_type: "percentage" (one percentage gate per flag),
with the ratio and kind encoded in target ("time/<r>" / "actors/<r>"). The
boolean gate's nil target is stored as the "_bandera_none" sentinel because SQL
unique indexes treat NULL values as distinct.
Flag names read back from storage are converted to atoms with String.to_atom/1
(so that listing flags created in a previous VM session works). Feature-flag
names must therefore be a bounded, developer-defined set — never untrusted user
input.
Summary
Functions
Rebuilds a Bandera.Flag from the rows stored for it.
Encodes a gate target for the target column.
Maps a flag name and gate to the row map persisted by the Ecto adapter.
Types
Functions
@spec deserialize_flag(atom() | String.t(), [map()]) :: Bandera.Flag.t()
Rebuilds a Bandera.Flag from the rows stored for it.
Rows are sorted for a stable gate order; the flag name is converted to an atom, so it must be a bounded, developer-defined value — never untrusted input.
Examples
iex> rows = [%{gate_type: "boolean", target: "_bandera_none", enabled: true}]
iex> flag = Bandera.Store.Persistent.Ecto.Serializer.deserialize_flag(:my_flag, rows)
iex> flag.name
:my_flag
iex> flag.gates
[%Bandera.Gate{type: :boolean, for: nil, enabled: true}]
Encodes a gate target for the target column.
nil becomes the "_bandera_none" sentinel; binaries pass through; everything
else is stringified.
Examples
iex> Bandera.Store.Persistent.Ecto.Serializer.serialize_target(nil)
"_bandera_none"
iex> Bandera.Store.Persistent.Ecto.Serializer.serialize_target("user-1")
"user-1"
iex> Bandera.Store.Persistent.Ecto.Serializer.serialize_target(0.5)
"0.5"
@spec to_row(atom(), Bandera.Gate.t()) :: row()
Maps a flag name and gate to the row map persisted by the Ecto adapter.
Percentage gates collapse to gate_type: "percentage" with the kind and ratio
encoded in target; a boolean gate's nil target becomes the "_bandera_none"
sentinel (SQL unique indexes treat NULLs as distinct).
Examples
iex> row = Bandera.Store.Persistent.Ecto.Serializer.to_row(:my_flag, Bandera.Gate.new(:boolean, true))
iex> {row.flag_name, row.gate_type, row.target, row.enabled}
{"my_flag", "boolean", "_bandera_none", true}
iex> row = Bandera.Store.Persistent.Ecto.Serializer.to_row(:my_flag, Bandera.Gate.new(:actor, "u1", true))
iex> {row.gate_type, row.target}
{"actor", "u1"}