Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3ef0e5f
Showing
22 changed files
with
546 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/_build | ||
/deps | ||
/doc | ||
erl_crash.dump | ||
*.ez |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
language: elixir | ||
otp_release: | ||
- 18.2 | ||
elixir: | ||
- 1.2.3 | ||
before_script: | ||
- export SCRIVENER_ECTO_DB_USER=postgres | ||
- MIX_ENV=test mix scrivener.ecto.db.reset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Changelog | ||
|
||
## 1.0.0 | ||
|
||
* Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2016 Andrew Olson | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Scrivener.Ecto | ||
|
||
[![Build Status](https://travis-ci.org/drewolson/scrivener_ecto.svg)](https://travis-ci.org/drewolson/scrivener_ecto) [![Hex Version](http://img.shields.io/hexpm/v/scrivener_ecto.svg?style=flat)](https://hex.pm/packages/scrivener_ecto) [![Hex docs](http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat)](https://hexdocs.pm/scrivener_ecto) | ||
|
||
Scrivener.Ecto allows you to paginate your Ecto queries with Scrivener. It gives you useful information such as the total number of pages, the current page, and the current page's entries. It works nicely with Phoenix as well. | ||
|
||
First, you'll want to `use` Scrivener in your application's Ecto Repo. This will add a `paginate` function to your Repo. This `paginate` function expects to be called with, at a minimum, an Ecto query. It will then paginate the query and execute it, returning a `Scrivener.Page`. Defaults for `page_size` can be configued when you `use` Scrivener. If no `page_size` is provided, Scrivener will use `10` by default. | ||
|
||
You may also want to call `paginate` with a params map along with your query. If provided with a params map, Scrivener will use the values in the keys `"page"` and `"page_size"` before using any configured defaults. | ||
|
||
## Example | ||
|
||
```elixir | ||
defmodule MyApp.Repo do | ||
use Ecto.Repo, otp_app: :my_app | ||
use Scrivener, page_size: 10 | ||
end | ||
``` | ||
|
||
```elixir | ||
defmodule MyApp.Person do | ||
use Ecto.Schema | ||
|
||
schema "people" do | ||
field :name, :string | ||
field :age, :integer | ||
|
||
has_many :friends, MyApp.Person | ||
end | ||
end | ||
``` | ||
|
||
```elixir | ||
def index(conn, params) do | ||
page = MyApp.Person | ||
|> where([p], p.age > 30) | ||
|> order_by([p], desc: p.age) | ||
|> preload(:friends) | ||
|> MyApp.Repo.paginate(params) | ||
|
||
render conn, :index, | ||
people: page.entries, | ||
page_number: page.page_number, | ||
page_size: page.page_size, | ||
total_pages: page.total_pages, | ||
total_entries: page.total_entries | ||
end | ||
``` | ||
|
||
```elixir | ||
page = MyApp.Person | ||
|> where([p], p.age > 30) | ||
|> order_by([p], desc: p.age) | ||
|> preload(:friends) | ||
|> MyApp.Repo.paginate(page: 2, page_size: 5) | ||
``` | ||
|
||
## Installation | ||
|
||
Add `scrivener_ecto` to your `mix.exs` dependencies. | ||
|
||
```elixir | ||
defp deps do | ||
[{:scrivener_ecto, "~> 1.0"}] | ||
end | ||
``` | ||
|
||
## Contributing | ||
|
||
First, you'll need to build the test database. | ||
|
||
```elixir | ||
MIX_ENV=test mix scrivener.ecto.db.reset | ||
``` | ||
|
||
This task assumes you have postgres installed and that your current user can create / drop databases. If you'd prefer to use a different user, you can specify it with the environment variable `SCRIVENER_ECTO_DB_USER`. | ||
|
||
With the database built, you can now run the tests. | ||
|
||
```elixir | ||
mix test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
use Mix.Config | ||
|
||
import_config "#{Mix.env}.exs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use Mix.Config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use Mix.Config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use Mix.Config | ||
|
||
config :scrivener_ecto, ScrivenerEcto.Repo, | ||
adapter: Ecto.Adapters.Postgres, | ||
pool: Ecto.Adapters.SQL.Sandbox, | ||
database: "scrivener_test", | ||
username: System.get_env("SCRIVENER_ECTO_DB_USER") || System.get_env("USER") | ||
|
||
config :logger, :console, | ||
level: :error |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule Mix.Tasks.Scrivener.Ecto.Db.Reset do | ||
use Mix.Task | ||
|
||
@moduledoc false | ||
|
||
def run(_args) do | ||
Logger.configure(level: :error) | ||
|
||
Mix.Task.run("ecto.drop", []) | ||
Mix.Task.run("ecto.create", []) | ||
Mix.Task.run("ecto.migrate", []) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
defimpl Scrivener.Paginater, for: Ecto.Query do | ||
import Ecto.Query | ||
|
||
alias Scrivener.Config | ||
alias Scrivener.Page | ||
|
||
@spec paginate(Ecto.Query.t, Scrivener.Config.t) :: Scrivener.Page.t | ||
def paginate(query, %Config{page_size: page_size, page_number: page_number, module: repo}) do | ||
total_entries = total_entries(query, repo) | ||
|
||
%Page{ | ||
page_size: page_size, | ||
page_number: page_number, | ||
entries: entries(query, repo, page_number, page_size), | ||
total_entries: total_entries, | ||
total_pages: total_pages(total_entries, page_size) | ||
} | ||
end | ||
|
||
defp ceiling(float) do | ||
t = trunc(float) | ||
|
||
case float - t do | ||
neg when neg < 0 -> | ||
t | ||
pos when pos > 0 -> | ||
t + 1 | ||
_ -> t | ||
end | ||
end | ||
|
||
defp entries(query, repo, page_number, page_size) do | ||
offset = page_size * (page_number - 1) | ||
|
||
query | ||
|> limit([_], ^page_size) | ||
|> offset([_], ^offset) | ||
|> repo.all | ||
end | ||
|
||
defp total_entries(query, repo) do | ||
stripped_query = query | ||
|> exclude(:order_by) | ||
|> exclude(:preload) | ||
|> exclude(:select) | ||
|
||
{query_sql, parameters} = Ecto.Adapters.SQL.to_sql(:all, repo, stripped_query) | ||
{:ok, %{num_rows: 1, rows: [[count]]}} = Ecto.Adapters.SQL.query(repo, "SELECT count(*) FROM (#{query_sql}) AS temp", parameters) | ||
|
||
count | ||
end | ||
|
||
defp total_pages(total_entries, page_size) do | ||
ceiling(total_entries / page_size) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
defmodule Scrivener.Ecto.Mixfile do | ||
use Mix.Project | ||
|
||
def project do | ||
[ | ||
app: :scrivener_ecto, | ||
version: "1.0.0-dev", | ||
elixir: "~> 1.0", | ||
elixirc_paths: elixirc_paths(Mix.env), | ||
package: package, | ||
description: "Paginate your Ecto queries with Scrivener", | ||
deps: deps, | ||
docs: [ | ||
main: "README.md", | ||
readme: "README.md" | ||
] | ||
] | ||
end | ||
|
||
def application do | ||
[ | ||
applications: applications(Mix.env) | ||
] | ||
end | ||
|
||
defp applications(:test), do: [:postgrex, :ecto, :logger] | ||
defp applications(_), do: [:logger] | ||
|
||
defp deps do | ||
[ | ||
{:scrivener, git: "https://github.com/drewolson/scrivener", branch: "v2"}, | ||
{:ecto, "~> 2.0.0-beta"}, | ||
{:dialyze, "~> 0.2.0", only: :dev}, | ||
{:earmark, ">= 0.0.0", only: :dev}, | ||
{:ex_doc, "~> 0.11.0", only: :dev}, | ||
{:ex_spec, "~> 1.0", only: :test}, | ||
{:postgrex, ">= 0.0.0", optional: true} | ||
] | ||
end | ||
|
||
defp elixirc_paths(:test), do: ["lib", "test/support"] | ||
defp elixirc_paths(_), do: ["lib"] | ||
|
||
defp package do | ||
[ | ||
maintainers: ["Drew Olson"], | ||
licenses: ["MIT"], | ||
links: %{"github" => "https://github.com/drewolson/scrivener_ecto"}, | ||
files: [ | ||
"lib/scrivener", | ||
"mix.exs", | ||
"README.md" | ||
] | ||
] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
%{"connection": {:hex, :connection, "1.0.2"}, | ||
"db_connection": {:hex, :db_connection, "0.2.5"}, | ||
"decimal": {:hex, :decimal, "1.1.1"}, | ||
"dialyze": {:hex, :dialyze, "0.2.1"}, | ||
"earmark": {:hex, :earmark, "0.2.1"}, | ||
"ecto": {:hex, :ecto, "2.0.0-beta.2"}, | ||
"ex_doc": {:hex, :ex_doc, "0.11.4"}, | ||
"ex_spec": {:hex, :ex_spec, "1.0.0"}, | ||
"poolboy": {:hex, :poolboy, "1.5.1"}, | ||
"postgrex": {:hex, :postgrex, "0.11.1"}, | ||
"scrivener": {:git, "https://github.com/drewolson/scrivener", "18fddf641b77d88ec7462e963198ed086601c2f0", [branch: "v2"]}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
defmodule TestRepo.Migrations.CreatePosts do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:posts) do | ||
add :title, :string | ||
add :body, :string | ||
add :published, :boolean | ||
|
||
timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
defmodule Scrivener.Repo.Migrations.CreateComments do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:comments) do | ||
add :body, :string | ||
add :post_id, :integer | ||
|
||
timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
defmodule TestRepo.Migrations.CreateKeyValues do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:key_values, primary_key: false) do | ||
add :key, :string, primary_key: true | ||
add :value, :string | ||
end | ||
end | ||
end |
Oops, something went wrong.