diff --git a/README.md b/README.md index 79f9150..68187e9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # Etso -## Overview - -Etso is an [ETS][erlang-ets] adapter, allowing you to use `Ecto` schemas with ETS tables. +**Etso** is an [ETS][erlang-ets] adapter, allowing you to use `Ecto` schemas with ETS tables. Within this library, a bare-bones Ecto Adapter is provided. The Adapter transparently spins up ETS tables for each Ecto Repo and Schema combination. The tables are publicly accessible to enable concurrency, and tracked by reference to ensure encapsulation. Each ETS table is spun up by a dedicated Table Server under a shared Dynamic Supervisor. @@ -54,18 +52,22 @@ The following features, for example, are missing: Using Etso is a two-step process. First, include it in your application’s dependencies: - defp deps do - [ - {:etso, "~> 0.1.1"} - ] - end +```elixir +defp deps do + [ + {:etso, "~> 0.1.2"} + ] +end +``` Afterwards, create a new `Ecto.Repo`, which uses `Etso.Adapter`: - defmodule MyApp.Repo do - @otp_app Mix.Project.config()[:app] - use Ecto.Repo, otp_app: @otp_app, adapter: Etso.Adapter - end +```elixir +defmodule MyApp.Repo do + @otp_app Mix.Project.config()[:app] + use Ecto.Repo, otp_app: @otp_app, adapter: Etso.Adapter +end +``` Once this is done, you can use any Schema against the Repo normally, as you would with any other Repo. Check out the [Northwind modules][northwind] for an example. @@ -75,9 +77,11 @@ Originally, Etso was created to answer the question of whether ETS and Ecto can *If you have other Use Cases for this library, please add it here with a Pull Request.* +- The [Erlef Website](https://github.com/erlef/website) is using Etso to cache and query news and event posts that are parsed and imported into the Repo on application startup. + ## Further Note -This repository is extracted from a prior project [ETS Playground][evadne-ets-playground], which was created to support my session at ElixirConf EU 2019, [*Leveraging ETS Effectively.*][evadne-ets-deck] +This repository is extracted from a prior project [ETS Playground][evadne-ets-playground], which was created to support a session at ElixirConf EU 2019, [*Leveraging ETS Effectively.*][evadne-ets-deck] Specifically, this library was created to illustrate the point that ETS can serve as a scalable storage layer for data which changes infrequently. Check out the [Northwind Importer][northwind-importer] for an example. @@ -95,6 +99,8 @@ The Author also wishes to thank the following individuals: - [David Schainker](https://github.com/schainks), for initial reviews, and for finding uses for this library. +- [Masanori Iwasaki][curi1119], for [support of `for…in` queries][pr-6]. + [erlang-ets]: http://erlang.org/doc/man/ets.html [northwind]: https://github.com/evadne/etso/tree/master/test/support/northwind [northwind-importer]: https://github.com/evadne/etso/tree/master/test/support/northwind/importer.ex @@ -102,3 +108,5 @@ The Author also wishes to thank the following individuals: [evadne-ets-playground]: https://github.com/evadne/ets-playground [evadne-ets-deck]: https://speakerdeck.com/evadne/leveraging-ets-effectively [wojtekmach]: https://github.com/wojtekmach +[curi1119]: https://github.com/curi1119 +[pr-6]: https://github.com/evadne/etso/pull/6 diff --git a/lib/etso/ets/match_specification.ex b/lib/etso/ets/match_specification.ex index d594a42..f1430fa 100644 --- a/lib/etso/ets/match_specification.ex +++ b/lib/etso/ets/match_specification.ex @@ -79,12 +79,16 @@ defmodule Etso.ETS.MatchSpecification do field_name end - defp resolve_field_values(params, {:^, [], indices}) do - for index <- indices do + defp resolve_field_values(params, {:^, [], [index, count]}) do + for index <- index..(index + count - 1) do Enum.at(params, index) end end + defp resolve_field_values(params, {:^, [], [index]}) do + Enum.at(params, index) + end + defp get_field_index(field_names, field_name) do 1 + Enum.find_index(field_names, fn x -> x == field_name end) end diff --git a/mix.exs b/mix.exs index b6a1b71..93153d4 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Etso.MixProject do def project do [ app: :etso, - version: "0.1.1", + version: "0.1.2", elixir: "~> 1.8", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, diff --git a/test/northwind/repo_test.exs b/test/northwind/repo_test.exs index 9bcb787..e32f70f 100644 --- a/test/northwind/repo_test.exs +++ b/test/northwind/repo_test.exs @@ -35,6 +35,52 @@ defmodule Northwind.RepoTest do |> Repo.all() end + test "Where In None" do + employee_ids = [] + + Model.Employee + |> where([x], x.employee_id in ^employee_ids) + |> select([x], x.employee_id) + |> Repo.all() + |> Enum.sort() + |> (&assert(&1 == employee_ids)).() + end + + test "Where In One" do + employee_ids = [3] + + Model.Employee + |> where([x], x.employee_id in ^employee_ids) + |> select([x], x.employee_id) + |> Repo.all() + |> Enum.sort() + |> (&assert(&1 == employee_ids)).() + end + + test "Where In Multiple" do + employee_ids = [3, 5, 7] + + Model.Employee + |> where([x], x.employee_id in ^employee_ids) + |> select([x], x.employee_id) + |> Repo.all() + |> Enum.sort() + |> (&assert(&1 == employee_ids)).() + end + + test "Where In Nested" do + employee_ids = [3, 5, 7] + employee_first_names = ["Janet"] + + Model.Employee + |> where([x], x.employee_id in ^employee_ids) + |> where([x], x.first_name in ^employee_first_names) + |> select([x], x.employee_id) + |> Repo.all() + |> Enum.sort() + |> (&assert(&1 == [3])).() + end + test "Select Where" do Model.Employee |> where([x], x.title == "Vice President Sales" and x.first_name == "Andrew") diff --git a/test/support/northwind/model/shipper.ex b/test/support/northwind/model/shipper.ex index 24bdf80..fd7fa9a 100644 --- a/test/support/northwind/model/shipper.ex +++ b/test/support/northwind/model/shipper.ex @@ -5,6 +5,7 @@ defmodule Northwind.Model.Shipper do schema "shippers" do field :company_name, :string field :phone, :string + # field :shipper_id, :integer has_many :orders, Model.Order, diff --git a/test/support/northwind/model/supplier.ex b/test/support/northwind/model/supplier.ex index 779ea8b..88df124 100644 --- a/test/support/northwind/model/supplier.ex +++ b/test/support/northwind/model/supplier.ex @@ -6,6 +6,7 @@ defmodule Northwind.Model.Supplier do field :company_name, :string field :contact_name, :string field :contact_title, :string + # field :supplier_id, :integer embeds_one :address, Model.Address