{"id":13508854,"url":"https://github.com/dockyard/inquisitor","last_synced_at":"2025-04-05T20:07:39.290Z","repository":{"id":57506974,"uuid":"51020962","full_name":"DockYard/inquisitor","owner":"DockYard","description":"Composable query builder for Ecto","archived":false,"fork":false,"pushed_at":"2020-07-04T09:14:04.000Z","size":50,"stargazers_count":170,"open_issues_count":2,"forks_count":13,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-29T19:05:57.450Z","etag":null,"topics":["composable-queries","elixir","phoenix"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DockYard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-03T18:29:57.000Z","updated_at":"2024-06-23T04:33:44.000Z","dependencies_parsed_at":"2022-08-29T20:01:21.108Z","dependency_job_id":null,"html_url":"https://github.com/DockYard/inquisitor","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DockYard%2Finquisitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DockYard%2Finquisitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DockYard%2Finquisitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DockYard%2Finquisitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DockYard","download_url":"https://codeload.github.com/DockYard/inquisitor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393570,"owners_count":20931812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["composable-queries","elixir","phoenix"],"created_at":"2024-08-01T02:00:59.446Z","updated_at":"2025-04-05T20:07:39.274Z","avatar_url":"https://github.com/DockYard.png","language":"Elixir","funding_links":[],"categories":["ORM and Datamapping"],"sub_categories":[],"readme":"# Inquisitor [![Build Status](https://secure.travis-ci.org/DockYard/inquisitor.svg?branch=master)](http://travis-ci.org/DockYard/inquisitor)\n\nEasily build composable queries for Ecto.\n\n**[Inquisitor is built and maintained by DockYard, contact us for expert Elixir and Phoenix consulting](https://dockyard.com/phoenix-consulting)**.\n\n## Usage\n\nAdding Inquisitor to a project is simple:\n\n```elixir\ndefmodule MyApp.PostController do\n  use Inquisitor\n\n  def index(conn, params) do\n    posts =\n      App.Post\n      |\u003e build_query(conn, params)\n      |\u003e Repo.all()\n\n    json(conn, posts)\n  end\nend\n```\n\nAfter `use Inquisitor` `build_query/3` is added to\nthe `MyApp.PostController`. It takes a queryable variable, the\n`conn`, and the `params` as arguments.\n\nThis sets up a key/value queryable API for the `Post` model. Any\ncombination of fields on the model can be queried against. For example,\nrequesting `[GET] /posts?foo=bar\u0026baz=qux` could create the query:\n\n```sql\nSELECT p0.\"foo\", p0.\"baz\" FROM posts as p0 WHERE (p0.\"foo\" = $1) AND (p0.\"baz\" = $1);\n```\n\n`$1` and `$2` will get the values of `\"bar\"` and `\"qux\"`,\n\n### Security\n\nBy default, Inquisitor is an opt-in library. It will not provide any\nquerying access to any key/value pair. The params list will be iterated\nover and a no-op function is called on each element. You must add custom\nquery handlers that have a higher matching order on a case by case\nbasis.\n\nIf you'd like to add a catch-all for any key/value pair you can override\nthe default:\n\n```elixir\ndef build_query(query, attr, value, _conn) do\n  Ecto.Query.where(query, [r], field(r, ^String.to_existing_atom(attr)) == ^value)\nend\n```\n\nHowever, this is not recommended. Instead you should create a\n`@whitelist` module attribute that contains all of they keys you\nwish to allow access to:\n\n```elixir\n@whitelist [\"title\", \"bio\"]\n\ndef build_query(query, attr, value, _conn) when attr in @whitelist do\n  Ecto.Query.where(query, [r], field(r, ^String.to_existing_atom(attr)) == ^value)\nend\n```\n\nThis will handle matching keys in the whitelist and all unmatched keys\nwill fall back to the pass-through without affecting the query.\n\n### Adding custom query handlers\n\nUse `build_query/4` to add key/value pair handlers:\n\n```elixir\ndefmodule MyApp.PostsController do\n  use Inquisitor\n\n  def index(conn, params) do\n    posts =\n      App.Post\n      |\u003e build_query(params)\n      |\u003e Repo.all()\n\n    json(conn, posts)\n  end\n\n  def build_query(query, \"inserted_at\", date, _conn) do\n    Ecto.Query.where(query, [p], p.inserted_at \u003e= ^date)\n  end\nend\n```\n\n### Handing fields that don't exist on the model\n\nThe keys you query against don't need to exist on the model. Revisiting\nthe date example, let's say we want to find all posts inserted for a\ngiven month and year:\n\n```elixir\ndef build_query(query, attr, value, _conn) when attr == \"month\" or attr == \"year\" do\n  Ecto.Query.where(query, [e], fragment(\"date_part(?, ?) = ?\", ^attr, e.inserted_at, type(^value, :integer)))\nend\n```\n\n### Usage Outside of Phoenix Controllers\n\nTo 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`.\n\nNote: we use `warn: false` to suppress an incorrect warning generated by Elixir thinking `from` is unused.\n\n```elixir\ndefmodule MyApp.PlainModule do\n  import Ecto.Query, only: [from: 1], warn: false\n  use Inquisitor\nend\n```\n\n### Plugins\n\nWe collect all Inquisitor plugins that extend its behavior:\n\n* [inquisitor\\_jsonapi](https://github.com/dockyard/inquisitor_jsonapi) - implements query handling according to the JSON API spec\n\n## Authors\n\n* [Brian Cardarella](http://twitter.com/bcardarella)\n\n[We are very thankful for the many contributors](https://github.com/dockyard/inquisitor/graphs/contributors).\n\n## Versioning\n\nThis library follows [Semantic Versioning](http://semver.org)\n\n## Want to help?\n\nPlease do! We are always looking to improve this library. Please see our\n[Contribution Guidelines](https://github.com/dockyard/inquisitor/blob/master/CONTRIBUTING.md)\non how to properly submit issues and pull requests.\n\n## Legal\n\n[DockYard](http://dockyard.com/), Inc. \u0026copy; 2016\n\n[@dockyard](http://twitter.com/dockyard)\n\n[Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdockyard%2Finquisitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdockyard%2Finquisitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdockyard%2Finquisitor/lists"}