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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ade5ee002558a00db5f98d1a9e51b05064b62d44
4
- data.tar.gz: 3bc4315dc5e20579e89949d5093ac199f41e5abd
3
+ metadata.gz: 09e4b81b186b62dd90281e0988e3edb48d11cbb8
4
+ data.tar.gz: 3b326f2c8b3a3c334cc1ec8805d78bc0655121ce
5
5
  SHA512:
6
- metadata.gz: 8b9275a695341df769badc8d29a2ac91c54e3bd776a366c143412854efebee09713ffdd9867dedb287f931aed53ce692800a1dcd64e609d2902a1a577656bdf3
7
- data.tar.gz: 3470d335585769075043a947ed574f7e456d4b68a6b301c8401106db1fdd1f086590ba2f6f23279877c578439af4eaa02536ade239c543f4d84af4a40d491d37
6
+ metadata.gz: 81cfcc14175b0582c735defe870f3a87e72d375779927b4f6b2aee992b77e31bee6034631818dec8ca872de232278d0c360f710a88777c7e5a30d83427a0dfdd
7
+ data.tar.gz: cf85cc29b54130eb54445010137d20f9d880540946829cf8a6503c26489f0dc721884de924a36138c8f6f5b01dc5fe582c6457b19395f9b5d9231cc6ec88b90f
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Criterion
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/activefx/criterion.png)](http://travis-ci.org/activefx/criterion)
4
+ [![Code Climate](https://codeclimate.com/github/activefx/criterion/badges/gpa.svg)](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.
@@ -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{Criterion is a small, simple library for searching Ruby arrays and collections with a chainable, Active Record style query interface.}
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"
@@ -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 do |record|
88
- keep = where_values.empty? ? true : where_values.all? do |method, value|
89
- value === record.send(method)
90
- end
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
@@ -1,3 +1,3 @@
1
1
  module Criterion
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
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.1.1
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-17 00:00:00.000000000 Z
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: Criterion is a small, simple library for searching Ruby arrays and collections
114
- with a chainable, Active Record style query interface.
113
+ summary: Search Ruby arrays and collections with a chainable, Active Record style
114
+ query interface.
115
115
  test_files: []