cursory 1.0.4 → 1.0.5
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 +4 -4
- data/lib/cursory/base.rb +116 -114
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bbbba609be8dd669f16a07b29e17622af6ea8b6
|
4
|
+
data.tar.gz: 7aa3758c6ff1f9eb96a9af76a10aa465418067af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e26cdde6e018c71848cd41810c3fb92d0e6838892a623765e5569c1e9034db860b40fba6baad7a091f0a0af4f11fc27020e34ab6f10f1cca950a58ef6358d3d6
|
7
|
+
data.tar.gz: 26b5e67ce33352c9f324d84d205b57ca0bab40705dbfe0719e8d1957d9528ebc19bcffa452737b598b8dcae19538eee148fa29ed5a1d51ee2507e4f9582fad53
|
data/lib/cursory/base.rb
CHANGED
@@ -1,155 +1,157 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'base64'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
module Cursory
|
5
|
+
class Base
|
6
|
+
attr_accessor *%i{criteria sort limit offset cursor}
|
7
|
+
|
8
|
+
MAX_LIMIT = 100
|
9
|
+
SORT_KEY, LIMIT_KEY, CURSOR_KEY, OFFSET_KEY = %i{sort limit cursor offset}
|
10
|
+
|
11
|
+
def initialize criteria, params
|
12
|
+
@criteria = criteria
|
13
|
+
@sort = params[SORT_KEY]
|
14
|
+
@limit = params[LIMIT_KEY]
|
15
|
+
@offset = params[OFFSET_KEY]
|
16
|
+
@cursor = params[CURSOR_KEY]
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def page
|
20
|
+
{ total_count: count, items: search_results, self: current_cursor }.tap do |p|
|
21
|
+
catch(:no_more_results) do
|
22
|
+
p[:next] = next_cursor
|
23
|
+
end
|
22
24
|
end
|
23
25
|
end
|
24
|
-
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def search
|
28
|
+
constrained_search.send(*search_type)
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def search_type
|
32
|
+
fail UnimplementedError
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def clamped_offset
|
36
|
+
[0, offset.to_i].max
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
def constrained_search
|
40
|
+
fail UnimplementedError
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
def search_results
|
44
|
+
@results ||= uncached_search
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
def uncached_search
|
48
|
+
fail UnimplementedError
|
49
|
+
end
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
def current_cursor
|
52
|
+
cursor || render_cursor
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
def record_for_next_cursor
|
56
|
+
search_results[clamped_limit-1] or throw(:no_more_results)
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
59
|
+
def next_cursor
|
60
|
+
if record_for_next_cursor
|
61
|
+
render_cursor cursor_data(id: record_for_next_cursor.id.to_s)
|
62
|
+
end
|
61
63
|
end
|
62
|
-
end
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
def count
|
66
|
+
@count ||= criteria.count
|
67
|
+
end
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
def uncached_count
|
70
|
+
fail UnimplementedError
|
71
|
+
end
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
def sort_keys
|
74
|
+
sort || model_sort || ''
|
75
|
+
end
|
75
76
|
|
76
|
-
|
77
|
-
|
78
|
-
|
77
|
+
def model
|
78
|
+
fail UnimplementedError
|
79
|
+
end
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
def model_sort
|
82
|
+
model.respond_to?(:default_sort_key) && model.default_sort_key
|
83
|
+
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
def order_keys
|
86
|
+
sort_keys.split(',').map{ |k| decompose_order_key(k) } + [[:id, 'asc']]
|
87
|
+
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
def decompose_order_key(k)
|
90
|
+
[ k.gsub(/\A[-+]?/,'').to_sym, k.start_with?('-') ? 'desc' : 'asc' ]
|
91
|
+
end
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
def order_clause
|
94
|
+
fail UnimplementedError
|
95
|
+
end
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
def clamped_limit
|
98
|
+
[1, limit.to_i, MAX_LIMIT].sort[1]
|
99
|
+
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
def cursor_clauses
|
102
|
+
fail UnimplementedError
|
103
|
+
end
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
105
|
+
def cursor_clause_set
|
106
|
+
keys = []
|
107
|
+
Enumerator.new do |y|
|
108
|
+
order_keys.each do |key|
|
109
|
+
y.yield cursor_clause(key, keys).reduce(&:merge)
|
110
|
+
keys << key
|
111
|
+
end
|
110
112
|
end
|
111
113
|
end
|
112
|
-
end
|
113
114
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
def cursor_clause(key, keys=[])
|
116
|
+
name, direction = key
|
117
|
+
Enumerator.new do |y|
|
118
|
+
keys.each do |name, direction|
|
119
|
+
y.yield clause_for_key(name, 'eq')
|
120
|
+
end
|
121
|
+
y.yield clause_for_key(name, direction)
|
119
122
|
end
|
120
|
-
y.yield clause_for_key(name, direction)
|
121
123
|
end
|
122
|
-
end
|
123
124
|
|
124
|
-
|
125
|
-
|
126
|
-
|
125
|
+
def clause_for_key key, direction
|
126
|
+
fail UnimplementedError
|
127
|
+
end
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
129
|
+
def cursor_object
|
130
|
+
@cursor_object ||= uncached_cursor_object
|
131
|
+
end
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
|
133
|
+
def uncached_cursor_object
|
134
|
+
fail UnimplementedError
|
135
|
+
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
def render_cursor(data={})
|
138
|
+
::Base64.urlsafe_encode64(JSON.dump(data))
|
139
|
+
end
|
139
140
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
141
|
+
def parsed_cursor
|
142
|
+
JSON.parse(::Base64.urlsafe_decode64(cursor || 'e30='))
|
143
|
+
rescue ArgumentError, JSON::ParserError
|
144
|
+
raise InvalidCursorError
|
145
|
+
end
|
145
146
|
|
146
|
-
|
147
|
-
|
148
|
-
|
147
|
+
def cursor_id
|
148
|
+
cursor_data['id']
|
149
|
+
end
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
151
|
+
def cursor_data(overrides={})
|
152
|
+
(parsed_cursor || {}).merge(overrides)
|
153
|
+
end
|
153
154
|
|
154
|
-
|
155
|
+
class InvalidCursorError < StandardError; end
|
156
|
+
end
|
155
157
|
end
|