Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dockyard/inquisitor
Composable query builder for Ecto
https://github.com/dockyard/inquisitor
composable-queries elixir phoenix
Last synced: 4 days ago
JSON representation
Composable query builder for Ecto
- Host: GitHub
- URL: https://github.com/dockyard/inquisitor
- Owner: DockYard
- Created: 2016-02-03T18:29:57.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2020-07-04T09:14:04.000Z (over 4 years ago)
- Last Synced: 2024-10-08T00:29:59.230Z (28 days ago)
- Topics: composable-queries, elixir, phoenix
- Language: Elixir
- Homepage:
- Size: 48.8 KB
- Stars: 170
- Watchers: 13
- Forks: 13
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- freaking_awesome_elixir - Elixir - Composable query builder for Ecto. (ORM and Datamapping)
- fucking-awesome-elixir - inquisitor - Composable query builder for Ecto. (ORM and Datamapping)
- awesome-elixir - inquisitor - Composable query builder for Ecto. (ORM and Datamapping)
README
# Inquisitor [![Build Status](https://secure.travis-ci.org/DockYard/inquisitor.svg?branch=master)](http://travis-ci.org/DockYard/inquisitor)
Easily build composable queries for Ecto.
**[Inquisitor is built and maintained by DockYard, contact us for expert Elixir and Phoenix consulting](https://dockyard.com/phoenix-consulting)**.
## Usage
Adding Inquisitor to a project is simple:
```elixir
defmodule MyApp.PostController do
use Inquisitordef index(conn, params) do
posts =
App.Post
|> build_query(conn, params)
|> Repo.all()json(conn, posts)
end
end
```After `use Inquisitor` `build_query/3` is added to
the `MyApp.PostController`. It takes a queryable variable, the
`conn`, and the `params` as arguments.This sets up a key/value queryable API for the `Post` model. Any
combination of fields on the model can be queried against. For example,
requesting `[GET] /posts?foo=bar&baz=qux` could create the query:```sql
SELECT p0."foo", p0."baz" FROM posts as p0 WHERE (p0."foo" = $1) AND (p0."baz" = $1);
````$1` and `$2` will get the values of `"bar"` and `"qux"`,
### Security
By default, Inquisitor is an opt-in library. It will not provide any
querying access to any key/value pair. The params list will be iterated
over and a no-op function is called on each element. You must add custom
query handlers that have a higher matching order on a case by case
basis.If you'd like to add a catch-all for any key/value pair you can override
the default:```elixir
def build_query(query, attr, value, _conn) do
Ecto.Query.where(query, [r], field(r, ^String.to_existing_atom(attr)) == ^value)
end
```However, this is not recommended. Instead you should create a
`@whitelist` module attribute that contains all of they keys you
wish to allow access to:```elixir
@whitelist ["title", "bio"]def build_query(query, attr, value, _conn) when attr in @whitelist do
Ecto.Query.where(query, [r], field(r, ^String.to_existing_atom(attr)) == ^value)
end
```This will handle matching keys in the whitelist and all unmatched keys
will fall back to the pass-through without affecting the query.### Adding custom query handlers
Use `build_query/4` to add key/value pair handlers:
```elixir
defmodule MyApp.PostsController do
use Inquisitordef index(conn, params) do
posts =
App.Post
|> build_query(params)
|> Repo.all()json(conn, posts)
enddef build_query(query, "inserted_at", date, _conn) do
Ecto.Query.where(query, [p], p.inserted_at >= ^date)
end
end
```### Handing fields that don't exist on the model
The keys you query against don't need to exist on the model. Revisiting
the date example, let's say we want to find all posts inserted for a
given month and year:```elixir
def build_query(query, attr, value, _conn) when attr == "month" or attr == "year" do
Ecto.Query.where(query, [e], fragment("date_part(?, ?) = ?", ^attr, e.inserted_at, type(^value, :integer)))
end
```### Usage Outside of Phoenix Controllers
To use inside a module other than a Phoenix Controller, you'll need to import `Ecto.from/1` otherwise you may see an error like `cannot use ^value outside of match clauses`.
Note: we use `warn: false` to suppress an incorrect warning generated by Elixir thinking `from` is unused.
```elixir
defmodule MyApp.PlainModule do
import Ecto.Query, only: [from: 1], warn: false
use Inquisitor
end
```### Plugins
We collect all Inquisitor plugins that extend its behavior:
* [inquisitor\_jsonapi](https://github.com/dockyard/inquisitor_jsonapi) - implements query handling according to the JSON API spec
## Authors
* [Brian Cardarella](http://twitter.com/bcardarella)
[We are very thankful for the many contributors](https://github.com/dockyard/inquisitor/graphs/contributors).
## Versioning
This library follows [Semantic Versioning](http://semver.org)
## Want to help?
Please do! We are always looking to improve this library. Please see our
[Contribution Guidelines](https://github.com/dockyard/inquisitor/blob/master/CONTRIBUTING.md)
on how to properly submit issues and pull requests.## Legal
[DockYard](http://dockyard.com/), Inc. © 2016
[@dockyard](http://twitter.com/dockyard)
[Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)