criterion 0.1.1 → 0.2.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 +4 -4
- data/README.md +14 -0
- data/criterion.gemspec +1 -1
- data/lib/criterion.rb +61 -19
- data/lib/criterion/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09e4b81b186b62dd90281e0988e3edb48d11cbb8
|
4
|
+
data.tar.gz: 3b326f2c8b3a3c334cc1ec8805d78bc0655121ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81cfcc14175b0582c735defe870f3a87e72d375779927b4f6b2aee992b77e31bee6034631818dec8ca872de232278d0c360f710a88777c7e5a30d83427a0dfdd
|
7
|
+
data.tar.gz: cf85cc29b54130eb54445010137d20f9d880540946829cf8a6503c26489f0dc721884de924a36138c8f6f5b01dc5fe582c6457b19395f9b5d9231cc6ec88b90f
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Criterion
|
2
2
|
|
3
|
+
[](http://travis-ci.org/activefx/criterion)
|
4
|
+
[](https://codeclimate.com/github/activefx/criterion)
|
5
|
+
|
3
6
|
Criterion is a small, simple library for searching Ruby arrays and collections with a chainable, Active Record style query interface.
|
4
7
|
|
5
8
|
## Installation
|
@@ -96,6 +99,17 @@ collection.where(name: 'Matt', age: 40).empty?
|
|
96
99
|
#=> true
|
97
100
|
````
|
98
101
|
|
102
|
+
### Or
|
103
|
+
|
104
|
+
As #where calls must match all query values, calling #or allows for an alternative query that will return results if either the #where or #or arguments match.
|
105
|
+
|
106
|
+
````ruby
|
107
|
+
collection.where(name: 'Matt').or(name: 'John').to_a
|
108
|
+
#=> [{"name"=>"Matt", "age"=>30}, {"name"=>"John", "age"=>50}]
|
109
|
+
````
|
110
|
+
|
111
|
+
For #or to work, a #where query must also be performed.
|
112
|
+
|
99
113
|
### Not
|
100
114
|
|
101
115
|
The #not method negates the query, returning matches that do not match all of the specified values. Like #where, #not can search by exact value, regular expression, class, proc, and range.
|
data/criterion.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Matthew Solt"]
|
10
10
|
spec.email = ["mattsolt@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{
|
12
|
+
spec.summary = %q{Search Ruby arrays and collections with a chainable, Active Record style query interface.}
|
13
13
|
spec.description = %q{Criterion is a small, simple library for searching Ruby arrays and collections with a chainable, Active Record style query interface.}
|
14
14
|
spec.homepage = "https://github.com/activefx/criterion"
|
15
15
|
spec.license = "MIT"
|
data/lib/criterion.rb
CHANGED
@@ -5,7 +5,7 @@ module Criterion
|
|
5
5
|
extend Forwardable
|
6
6
|
|
7
7
|
def_delegators :criteria,
|
8
|
-
:where, :not, :order, :limit, :offset, :skip,
|
8
|
+
:where, :or, :not, :order, :limit, :offset, :skip,
|
9
9
|
:sum, :maximum, :minimum, :average
|
10
10
|
|
11
11
|
def criteria
|
@@ -16,17 +16,19 @@ module Criterion
|
|
16
16
|
extend Forwardable
|
17
17
|
include Enumerable
|
18
18
|
|
19
|
-
MULTI_VALUE_METHODS = [ :where, :not, :order ]
|
19
|
+
MULTI_VALUE_METHODS = [ :where, :or, :not, :order ]
|
20
20
|
SINGLE_VALUE_METHODS = [ :limit, :offset ]
|
21
|
+
RESULT_METHODS = [
|
22
|
+
:[], :at, :count, :empty?, :fetch, :first, :include?, :index,
|
23
|
+
:last, :length, :reverse, :rindex, :sample, :size, :sort,
|
24
|
+
:sort_by, :take, :take_while, :values_at
|
25
|
+
]
|
21
26
|
|
22
27
|
attr_accessor \
|
23
|
-
:where_values, :not_values, :order_values,
|
28
|
+
:where_values, :or_values, :not_values, :order_values,
|
24
29
|
:limit_value, :offset_value
|
25
30
|
|
26
|
-
def_delegators :to_a,
|
27
|
-
:[], :at, :count, :empty?, :fetch, :first, :include?, :index,
|
28
|
-
:last, :length, :reverse, :rindex, :sample, :size, :sort,
|
29
|
-
:sort_by, :take, :take_while, :values_at
|
31
|
+
def_delegators :to_a, *RESULT_METHODS
|
30
32
|
|
31
33
|
def initialize(records)
|
32
34
|
@records = records
|
@@ -40,6 +42,12 @@ module Criterion
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
45
|
+
def or(query = {})
|
46
|
+
clone.tap do |r|
|
47
|
+
r.or_values.merge!(query) unless query.empty?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
43
51
|
def not(query = {})
|
44
52
|
clone.tap do |r|
|
45
53
|
r.not_values.merge!(query) unless query.empty?
|
@@ -83,19 +91,35 @@ module Criterion
|
|
83
91
|
to_a.collect { |x| x.send(field) }.max
|
84
92
|
end
|
85
93
|
|
94
|
+
def where?
|
95
|
+
!where_values.empty?
|
96
|
+
end
|
97
|
+
|
98
|
+
def or?
|
99
|
+
!or_values.empty?
|
100
|
+
end
|
101
|
+
|
102
|
+
def not?
|
103
|
+
!not_values.empty?
|
104
|
+
end
|
105
|
+
|
106
|
+
def order?
|
107
|
+
!order_values.empty?
|
108
|
+
end
|
109
|
+
|
110
|
+
def offset?
|
111
|
+
valid_number?(offset_value)
|
112
|
+
end
|
113
|
+
|
114
|
+
def limit?
|
115
|
+
valid_number?(limit_value)
|
116
|
+
end
|
117
|
+
|
86
118
|
def to_a
|
87
|
-
results = @records.select
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
exclude = not_values.empty? ? false : not_values.all? do |method, value|
|
92
|
-
value === record.send(method)
|
93
|
-
end
|
94
|
-
keep && !exclude
|
95
|
-
end
|
96
|
-
results = results.sort_by(&ordering_args) unless order_values.empty?
|
97
|
-
results = results.drop(offset_value) if offset_value.is_a?(Integer)
|
98
|
-
results = results.take(limit_value) if limit_value.is_a?(Integer)
|
119
|
+
results = @records.select{ |record| keep?(record) }
|
120
|
+
results = results.sort_by(&ordering_args) if order?
|
121
|
+
results = results.drop(offset_value) if offset?
|
122
|
+
results = results.take(limit_value) if limit?
|
99
123
|
results
|
100
124
|
end
|
101
125
|
alias_method :all, :to_a
|
@@ -107,6 +131,19 @@ module Criterion
|
|
107
131
|
|
108
132
|
private
|
109
133
|
|
134
|
+
def criteria_matches?(record, values)
|
135
|
+
values.all? do |method, value|
|
136
|
+
value === record.send(method)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def keep?(record)
|
141
|
+
keep = where? ? criteria_matches?(record, where_values) : true
|
142
|
+
alt = or? ? criteria_matches?(record, or_values) : false
|
143
|
+
exclude = not? ? criteria_matches?(record, not_values) : false
|
144
|
+
(keep || alt) && !exclude
|
145
|
+
end
|
146
|
+
|
110
147
|
def ordering_args
|
111
148
|
Proc.new do |item|
|
112
149
|
order_values.map do |sort|
|
@@ -116,6 +153,11 @@ module Criterion
|
|
116
153
|
end
|
117
154
|
end
|
118
155
|
|
156
|
+
def valid_number?(value)
|
157
|
+
return false unless value.is_a?(Integer)
|
158
|
+
value >= 0
|
159
|
+
end
|
160
|
+
|
119
161
|
end
|
120
162
|
|
121
163
|
end
|
data/lib/criterion/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: criterion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Solt
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -110,6 +110,6 @@ rubyforge_project:
|
|
110
110
|
rubygems_version: 2.4.6
|
111
111
|
signing_key:
|
112
112
|
specification_version: 4
|
113
|
-
summary:
|
114
|
-
|
113
|
+
summary: Search Ruby arrays and collections with a chainable, Active Record style
|
114
|
+
query interface.
|
115
115
|
test_files: []
|