Skip to content

Latest commit

 

History

History
81 lines (51 loc) · 3.19 KB

README.md

File metadata and controls

81 lines (51 loc) · 3.19 KB

EtsSelect

A very simple and very useful little package to help you write non-trivial ETS match specs without fighting with the docs - Match Specifications in Erlang.

No macros, no huge ambitions, just a simple 50-lines long Elixir module. You use a simple and very familiar query syntax and get efficient ETS match specs to filter out your rows from ETS tables.

Assumptions / Limitations:

  • you store your data in maps / structs and look it up by a key
  • you select rows from simple flat maps (no support for nesting attributes) - YET

Example:

:ets.new(:my_table, [:set, :public, :named_table])

:ets.insert(:my_table, {:key1, %{status: :new, age: 30, name: "1", nested: %{a: 1}}})
:ets.insert(:my_table, {:key2, %{status: :old, age: 25, name: "2"}})
:ets.insert(:my_table, {:key3, %{status: :middle, age: 35, name: "3"}})
:ets.insert(:my_table, {:key4, %{status: :ancient, age: 100, name: "4"}})
:ets.insert(:my_table, {:key5, %{status: :old, age: 50, name: "5"}})

## find all items with status = :new or status = :old
query = %{or: [[:=, :status, :new], [:=, :status, :old]]}
match_spec = EtsSelect.build(query)
:ets.select(:my_table, match_spec)
#=> returns 1,2,5


query = %{and: [[:=, :status, :old], [:>, :age, 30]]}
match_spec = EtsSelect.build(query)
:ets.select(:my_table, match_spec)
#=> returns 5


query = %{age: 30}
match_spec = EtsSelect.build(query)
:ets.select(:my_table, match_spec)
#=> returns 1

Are there any other alternatives?

I have looked at matcha + Matcha - first-class match specifications for Elixir.

The package has a lot of code and the test suite has some failures. It has much more features, but feels also not quite complete and too complex for my needs.

There is also match_spec. But it uses macros that transforms elixir-style function into match specs. Not quite what I need. (https://elixirforum.com/t/matchspec-library-for-transforming-ets-matchspecs/52698/1)

I also saw ex2ms, it has a great test suite and is quite small. But again: macros + elixir-style functions.

Then there is active_memory, but it is much more full-featured and handles also queries on Mnesia. I liked it, but felt it could constrain me with some assumpions.

Etso requires Ecto, that is a bit too much for my needs.

Summary

So there you have it. It is a single module, that can be quickly vendored, adjusted or fixed. It wont break with any new Elixir versions and wont cause you any further headache.

Enjoy! 😎

Installation

If available in Hex, the package can be installed by adding ets_select to your list of dependencies in mix.exs:

def deps do
  [
    {:ets_select, "~> 0.1.0"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ets_select.