jinrai 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +93 -0
- data/Rakefile +20 -0
- data/lib/jinrai.rb +11 -0
- data/lib/jinrai/active_record/core.rb +21 -0
- data/lib/jinrai/active_record/cursor_methods.rb +34 -0
- data/lib/jinrai/active_record/finder_methods.rb +83 -0
- data/lib/jinrai/active_record/result.rb +14 -0
- data/lib/jinrai/config.rb +25 -0
- data/lib/jinrai/configuration_methods.rb +32 -0
- data/lib/jinrai/version.rb +3 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a92fa21d25f7ac12d4a77d0ede116fb8712608c
|
4
|
+
data.tar.gz: 776eeeed260c5a79bfdbef5007042a84696602bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0d92800fd47ee98b909ea62d3405835afb274ab0ee0a4ea4c88df8809397401963bbfdc254c1f97917e6fe1868478cf7d959d00e774378ef66b9868f679fa9d7
|
7
|
+
data.tar.gz: 3afc42adc4c5ba2aad592df04e8f3082fa31ce1c49be6ba131c26e0cc4c8af15985c4eefac29a6f4b66ea3a9426cd75969d8f0101dd7e6383f43f44144652d18
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 atomiyama
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Jinrai
|
2
|
+
Jinrai is a awesome cursor based paginator
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
```ruby
|
6
|
+
# config/initializers/jinrai.rb
|
7
|
+
|
8
|
+
Jinrai.configure do |config|
|
9
|
+
config.default_cursor_per = 20 #=> User.cursor.count == 20
|
10
|
+
config.default_cursor_format = :id, :name #=> cursor format will be "#{user.id}_#{user.name}"
|
11
|
+
config.cursor_sort_order = :desc
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# app/model/user.rb
|
17
|
+
|
18
|
+
class User < ApplicationRecord
|
19
|
+
cursor_per 100
|
20
|
+
cursor_format :name, :age
|
21
|
+
cursor_order :asc # default: :desc
|
22
|
+
end
|
23
|
+
|
24
|
+
User.cursor.count #=> 100
|
25
|
+
User.cursor.since_format #=> generate cursor fomatted "#{user.name}_#{user.age}"
|
26
|
+
```
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
User.cursor #=> get latest 20 records.
|
30
|
+
User.cursor.count #=> 20
|
31
|
+
```
|
32
|
+
|
33
|
+
`.cursor` has two arguments, `till` and `since`, and by passing them we can get record collection of arbitrary interval.
|
34
|
+
```ruby
|
35
|
+
since_cursor = User.cursor.till_cursor
|
36
|
+
User.cursor(since: since_cursor) # return records older than the record pointed by the cursor
|
37
|
+
|
38
|
+
till_cursor = User.cursor.since_cursor
|
39
|
+
User.cursor(till: till_cursor) # return records newer than the record pointed by the cursor
|
40
|
+
|
41
|
+
User.cursor(since: since_cursor, till: till_cursor) # return records newer than the record pointed by the since cursor and older than the record pointed by the till cursor.
|
42
|
+
```
|
43
|
+
|
44
|
+
Get cursor by calling `since_cursor` or `till_cursor`.
|
45
|
+
```ruby
|
46
|
+
users = User.cursor
|
47
|
+
users.since_cursor # this cursor points first record of User collection
|
48
|
+
users.till_cursor # this cursor points last record of User collection
|
49
|
+
```
|
50
|
+
|
51
|
+
## Installation
|
52
|
+
Add this line to your application's Gemfile:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
gem 'jinrai'
|
56
|
+
```
|
57
|
+
|
58
|
+
And then execute:
|
59
|
+
```bash
|
60
|
+
$ bundle
|
61
|
+
```
|
62
|
+
|
63
|
+
Or install it yourself as:
|
64
|
+
```bash
|
65
|
+
$ gem install jinrai
|
66
|
+
```
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
1. Fork then clone this repo:
|
70
|
+
```bash
|
71
|
+
git clone git@github.com:YOUR_USERNAME/jinrai.git
|
72
|
+
```
|
73
|
+
|
74
|
+
1. setup dependencies via bundler:
|
75
|
+
```bash
|
76
|
+
bundle install
|
77
|
+
```
|
78
|
+
|
79
|
+
1. Make sure the spec pass:
|
80
|
+
```bash
|
81
|
+
bundle exec rspec
|
82
|
+
```
|
83
|
+
|
84
|
+
1. Make your change, and write spec, make sure test pass:
|
85
|
+
```bash
|
86
|
+
bandle exec rspec
|
87
|
+
```
|
88
|
+
|
89
|
+
1. write a good commit message, push to your fork, then submit PullRequest.
|
90
|
+
|
91
|
+
|
92
|
+
## License
|
93
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Jinrai'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'rspec/core/rake_task'
|
18
|
+
RSpec::Core::RakeTask.new(:spec)
|
19
|
+
task default: :spec
|
20
|
+
require 'bundler/gem_tasks'
|
data/lib/jinrai.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal:true
|
2
|
+
|
3
|
+
require 'jinrai/active_record/result'
|
4
|
+
require 'jinrai/config'
|
5
|
+
require 'jinrai/configuration_methods'
|
6
|
+
|
7
|
+
ActiveSupport.on_load :active_record do
|
8
|
+
require 'jinrai/active_record/core'
|
9
|
+
ActiveRecord::Relation.send(:prepend, Jinrai::ActiveRecord::Result)
|
10
|
+
ActiveRecord::Base.send(:include, Jinrai::ActiveRecord::Core)
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'jinrai/active_record/finder_methods'
|
2
|
+
|
3
|
+
module Jinrai::ActiveRecord
|
4
|
+
module Core
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def inherited(kls)
|
10
|
+
super
|
11
|
+
kls.send(:include, Jinrai::ActiveRecord::FinderMethods) if kls.superclass == ::ActiveRecord::Base
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
included do
|
16
|
+
descendants.each do |kls|
|
17
|
+
kls.send(:include, Jinrai::ActiveRecord::FinderMethods) if kls.superclass == ::ActiveRecord::Base
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'jinrai/config'
|
2
|
+
|
3
|
+
module Jinrai::ActiveRecord
|
4
|
+
module CursorMethods
|
5
|
+
include Jinrai::ConfigurationMethods
|
6
|
+
|
7
|
+
def since_cursor
|
8
|
+
encode_cursor(first)
|
9
|
+
end
|
10
|
+
|
11
|
+
def till_cursor
|
12
|
+
encode_cursor(last)
|
13
|
+
end
|
14
|
+
|
15
|
+
def per(num = nil)
|
16
|
+
num ||= default_cursor_per
|
17
|
+
if (n = num.to_i).negative? || !(/^\d/ =~ num.to_s)
|
18
|
+
self
|
19
|
+
else
|
20
|
+
self.is_cursored = true
|
21
|
+
limit(n)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def encode_cursor(record)
|
28
|
+
attributes = default_cursor_format.map do |attr|
|
29
|
+
record.send(attr)
|
30
|
+
end
|
31
|
+
Base64.urlsafe_encode64(attributes.join("_"))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'jinrai/active_record/cursor_methods'
|
2
|
+
|
3
|
+
module Jinrai::ActiveRecord #:nodoc:
|
4
|
+
module FinderMethods
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include Jinrai::ConfigurationMethods
|
9
|
+
|
10
|
+
def to_cursor
|
11
|
+
cursor_format = self.class.default_cursor_format
|
12
|
+
attributes = cursor_format.map do |attribute|
|
13
|
+
self.send(attribute)
|
14
|
+
end
|
15
|
+
Base64.urlsafe_encode64(attributes.join("_"))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
def cursor(**options)
|
22
|
+
relation =
|
23
|
+
if default_cursor_sort_order == :desc
|
24
|
+
cursoring(:lt, :gt, options[:since], options[:sort_at]).cursoring(:gt, :lt, options[:till], options[:sort_at])
|
25
|
+
elsif default_cursor_sort_order == :asc
|
26
|
+
cursoring(:gt, :lt, options[:since], options[:sort_at]).cursoring(:lt, :gt, options[:till], options[:sort_at])
|
27
|
+
end
|
28
|
+
relation.extending_cursor
|
29
|
+
end
|
30
|
+
|
31
|
+
def after(cursor, **options)
|
32
|
+
relation =
|
33
|
+
if default_cursor_sort_order == :desc
|
34
|
+
cursoring(:lt, :gt, cursor, options[:sort_at])
|
35
|
+
elsif default_cursor_sort_order == :asc
|
36
|
+
cursoring(:gt, :lt, cursor, options[:sort_at])
|
37
|
+
end
|
38
|
+
relation.extending_cursor
|
39
|
+
end
|
40
|
+
|
41
|
+
def before(cursor, **options)
|
42
|
+
relation =
|
43
|
+
if default_cursor_sort_order == :desc
|
44
|
+
cursoring(:gt, :lt, cursor, options[:sort_at])
|
45
|
+
elsif default_cursor_sort_order == :asc
|
46
|
+
cursoring(:lt, :gt, cursor, options[:sort_at])
|
47
|
+
end
|
48
|
+
relation.extending_cursor
|
49
|
+
end
|
50
|
+
|
51
|
+
def extending_cursor
|
52
|
+
extending { include Jinrai::ActiveRecord::CursorMethods }.per
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def cursoring(rank, rank_for_primary, cursor, sort_at)
|
57
|
+
sort_at ||= primary_key
|
58
|
+
if cursor
|
59
|
+
attributes = HashWithIndifferentAccess.new(decode_cursor(cursor))
|
60
|
+
id = find_by(attributes).id
|
61
|
+
|
62
|
+
if sort_at != primary_key
|
63
|
+
condition_1 = arel_table[sort_at].send(rank, attributes[sort_at])
|
64
|
+
condition_2 = arel_table.grouping(arel_table[sort_at].eq(attributes[sort_at]).and(arel_table[primary_key].send(rank_for_primary, id)))
|
65
|
+
relation = where(condition_1.or(condition_2))
|
66
|
+
else
|
67
|
+
relation = where(arel_table[primary_key].send(rank, id))
|
68
|
+
end
|
69
|
+
else
|
70
|
+
relation = all
|
71
|
+
end
|
72
|
+
relation.order(sort_at => default_cursor_sort_order)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def decode_cursor(cursor)
|
78
|
+
attributes = Base64.urlsafe_decode64(cursor).split("_")
|
79
|
+
default_cursor_format.zip(attributes).to_h
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal:true
|
2
|
+
|
3
|
+
module Jinrai #:nodoc:
|
4
|
+
class << self
|
5
|
+
def config
|
6
|
+
@config ||= Config.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure
|
10
|
+
yield config
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Config #:nodoc:
|
15
|
+
attr_accessor :default_cursor_per,
|
16
|
+
:default_cursor_format,
|
17
|
+
:default_cursor_sort_order
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@default_cursor_per = 20
|
21
|
+
@default_cursor_format = %i[created_at id]
|
22
|
+
@default_cursor_sort_order = :desc
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Jinrai #:nodoc:
|
2
|
+
module ConfigurationMethods #:nodoc:
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods #:nodoc:
|
6
|
+
|
7
|
+
def cursor_per(num)
|
8
|
+
@_default_cursor_per = num.to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def cursor_format(*attributes)
|
12
|
+
@_default_cursor_format = attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def cursor_sort_order(rank)
|
16
|
+
@_default_cursor_sort_order = rank.to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_cursor_per
|
20
|
+
@_default_cursor_per || Jinrai.config.default_cursor_per
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_cursor_format
|
24
|
+
@_default_cursor_format || Jinrai.config.default_cursor_format
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_cursor_sort_order
|
28
|
+
@_default_cursor_sort_order || Jinrai.config.default_cursor_sort_order
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jinrai
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- atomiyama
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mysql2
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Jinrai is a awesome Cursor type pagination Link.
|
70
|
+
email:
|
71
|
+
- akifumi.tomiyama@studyplus.jp
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- MIT-LICENSE
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- lib/jinrai.rb
|
80
|
+
- lib/jinrai/active_record/core.rb
|
81
|
+
- lib/jinrai/active_record/cursor_methods.rb
|
82
|
+
- lib/jinrai/active_record/finder_methods.rb
|
83
|
+
- lib/jinrai/active_record/result.rb
|
84
|
+
- lib/jinrai/config.rb
|
85
|
+
- lib/jinrai/configuration_methods.rb
|
86
|
+
- lib/jinrai/version.rb
|
87
|
+
homepage: https://github.com/studyplus/jinrai
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.6.13
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: A cursor type pagination plugin for Rails
|
111
|
+
test_files: []
|