A disk-based key-value storage built on top of dets
MIT License
A disk-based embedded key-value storage built on top of dets set. Inspired by CubDB's intuitive API.
A table has at most one entry with a given key. If an entry with a key already present in the table is inserted, the existing entry is overwritten by the new entry. The entries are not ordered. See dets manual for more info.
Documentation can be found at https://hexdocs.pm/dbkv.
iex> {:ok, t} = DBKV.open(name: :my_table, data_dir: "tmp")
{:ok, :my_table}
iex> DBKV.open?(t)
true
iex> DBKV.filename(t)
'tmp/my_table.db'
You could omit name
and data_dir
options. In such a case, they will default to DBKV
and "tmp"
respectively.
iex> DBKV.open()
iex> DBKV.put(t, "greeting", "Hi")
:ok
iex> DBKV.get(t, "greeting")
"Hi"
iex> DBKV.put_new(t, "greeting", "Hello")
{:error, :exists}
iex> DBKV.get(t, "greeting")
"Hi"
iex> DBKV.put_new(t, :temperature, 32)
:ok
iex> DBKV.get(t, :temperature)
32
iex> DBKV.update(t, "greeting", "default", &(&1 <> "!!!"))
:ok
iex> DBKV.get(t, "greeting")
"Hi!!!"
iex> DBKV.update(t, 123, "default", &(&1 <> "!!!"))
:ok
iex> DBKV.get(t, 123)
"default"
iex> DBKV.delete(t, "greeting")
:ok
iex> DBKV.get(t, "greeting")
nil
A table can be initialized with a list of two-element tulpes.
iex> DBKV.init_table(t, [{:a, 0}, {:b, 1}, {:c, 2}, {:d, 3}, {:e, 4}])
By key range
iex> DBKV.select_by_key_range(t, :b, :d)
[b: 1, c: 2, d: 3]
By value range
iex> DBKV.select_by_value_range(t, 2, 3)
[c: 2, d: 3]
By match spec
The Ex2ms.fun/2 macro is useful to build a match specification.
iex> require Ex2ms
iex> match_spec = Ex2ms.fun do {k, v} = kv when :b <= k and k <= :d -> kv end
[{{:"$1", :"$2"}, [{:andalso, {:"=<", :b, :"$1"}, {:"=<", :"$1", :d}}], [:"$_"]}]
iex> DBKV.select_by_match_spec(t, match_spec)
[b: 1, c: 2, d: 3]
:dets
functionsYou could mix and match with any dets functions if you wish.
iex> :dets.info(t)
[
type: :set,
keypos: 1,
size: 0,
file_size: 5464,
filename: 'tmp/my_table.db'
]
ArgumentError
When a table is not open, a function call results in ArgumentError
.
Make sure that the table is opened with a correct name.
iex> DBKV.get(:nonexistent_table, :temperature)
** (ArgumentError) argument error
(stdlib 3.15.1) dets.erl:1259: :dets.lookup(:nonexistent_table, :temperature)
(dbkv 0.2.0) lib/dvkv.ex:131: DBKV.get/3
DBKV
can be installed by adding dbkv
to your list of dependencies in mix.exs:
def deps do
[
{:dbkv, "~> 0.2"}
]
end
Using Mix.install/2
in IEx:
❯ iex
iex> Mix.install([{:dbkv, "~> 0.2"}])
There was a good discussion about Erlang/Elixir key-value stores in this Elixir Forum thread.