Quarry (Quarry v0.1.0) View Source
A data-driven ecto query builder for nested associations.
Quarry allows you to interact with your database thinking only about your data, and generates queries for exactly what you need. You can specify all the filters, loads, and sorts with any level of granularity and at any association level, and Quarry will build a query for you that optimizes for joining just the data that is necessary and no more. To optimize has_many associations, subqueries are used for preloading the entity. This is generally more optimal than joining and selecting all the data because it avoids pulling n*m records into memory.
Link to this section Summary
Functions
Builds a query for an entity type from parameters
Link to this section Types
Specs
Specs
Specs
Specs
Link to this section Functions
Specs
build(atom(), opts()) :: Ecto.Query.t()
Builds a query for an entity type from parameters
Examples
# Top level attribute
iex> Quarry.build(Quarry.Post, filter: %{title: "Value"})
#Ecto.Query<from p0 in Quarry.Post, as: :post, where: as(:post).title == ^"Value">
# Field on nested belongs_to relationship
iex> Quarry.build(Quarry.Post, filter: %{author: %{publisher: "Publisher"}})
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, where: as(:post_author).publisher == ^"Publisher">
# Field on nested has_many relationship
Quarry.build(Post, filter: %{comments: %{body: "comment body"}})
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: c1 in assoc(p0, :comments), as: :post_comments, where: as(:post_comments).body == ^"comment body">
Load examples
# Single atom
iex> Quarry.build(Quarry.Post, load: :author)
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, preload: [author: a1]>
# List of atoms
iex> Quarry.build(Quarry.Post, load: [:author, :comments])
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, preload: [comments: #Ecto.Query<from c0 in Quarry.Comment, as: :post_comment>], preload: [author: a1]>
# Nested entities
iex> Quarry.build(Quarry.Post, load: [comments: :user])
#Ecto.Query<from p0 in Quarry.Post, as: :post, preload: [comments: #Ecto.Query<from c0 in Quarry.Comment, as: :post_comment, join: u1 in assoc(c0, :user), as: :post_comment_user, preload: [user: u1]>]>
# List of nested entities
iex> Quarry.build(Quarry.Post, load: [author: [:user, :posts]])
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, join: u2 in assoc(a1, :user), as: :post_author_user, preload: [author: [posts: #Ecto.Query<from p0 in Quarry.Post, as: :post_author_post>]], preload: [author: {a1, [user: u2]}]>
# Use Quarry on nested has_many association
iex> Quarry.build(Quarry.Post, load: [comments: [filter: %{body: "comment"}, load: :user]])
#Ecto.Query<from p0 in Quarry.Post, as: :post, preload: [comments: #Ecto.Query<from c0 in Quarry.Comment, as: :post_comment, join: u1 in assoc(c0, :user), as: :post_comment_user, where: as(:post_comment).body == ^"comment", preload: [user: u1]>]>
Sort examples
# Single field
iex> Quarry.build(Quarry.Post, sort: :title)
#Ecto.Query<from p0 in Quarry.Post, as: :post, order_by: [asc: as(:post).title]>
# Multiple fields
iex> Quarry.build(Quarry.Post, sort: [:title, :body])
#Ecto.Query<from p0 in Quarry.Post, as: :post, order_by: [asc: as(:post).title], order_by: [asc: as(:post).body]>
# Nested fields
iex> Quarry.build(Quarry.Post, sort: [[:author, :publisher], :title, [:author, :user, :name]])
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, join: u2 in assoc(a1, :user), as: :post_author_user, order_by: [asc: as(:post_author).publisher], order_by: [asc: as(:post).title], order_by: [asc: as(:post_author_user).name]>
# Descending sort
iex> Quarry.build(Quarry.Post, sort: [:title, desc: :body, desc: [:author, :publisher]])
#Ecto.Query<from p0 in Quarry.Post, as: :post, join: a1 in assoc(p0, :author), as: :post_author, order_by: [asc: as(:post).title], order_by: [desc: as(:post).body], order_by: [desc: as(:post_author).publisher]>
Limit example
iex> Quarry.build(Quarry.Post, limit: 10)
#Ecto.Query<from p0 in Quarry.Post, as: :post, limit: ^10>
Offset example
iex> Quarry.build(Quarry.Post, limit: 10, offset: 20)
#Ecto.Query<from p0 in Quarry.Post, as: :post, limit: ^10, offset: ^20>