Skip to content

ETS match spec builder from a simple intuitive query language.

License

Notifications You must be signed in to change notification settings

maxohq/ets_select

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

ETS match spec builder from a simple intuitive query language.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages