meta_where 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ Changes since 1.0.1 (2011-01-18):
2
+ * Fix *_all behavior to not result in ORs when collapse_wheres is called
3
+ * Add support for NOT operator (-) on hashes, conditions, and compound
4
+ conditions. Unary NOTs the condition, binary does an AND NOT between
5
+ on the second condition.
6
+
1
7
  Changes since 1.0.0 (2011-01-17):
2
8
  * Update polymorphic join support to play nicely with MetaSearch
3
9
 
data/Rakefile CHANGED
@@ -19,9 +19,9 @@ begin
19
19
  gem.homepage = "http://metautonomo.us/projects/metawhere/"
20
20
  gem.authors = ["Ernie Miller"]
21
21
  gem.add_development_dependency "shoulda"
22
- gem.add_dependency "activerecord", "~> 3.0.2"
23
- gem.add_dependency "activesupport", "~> 3.0.2"
24
- gem.add_dependency "arel", "~> 2.0.2"
22
+ gem.add_dependency "activerecord", "~> 3.0.4"
23
+ gem.add_dependency "activesupport", "~> 3.0.4"
24
+ gem.add_dependency "arel", "~> 2.0.8"
25
25
  gem.post_install_message = <<END
26
26
 
27
27
  *** Thanks for installing MetaWhere! ***
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
data/lib/core_ext/hash.rb CHANGED
@@ -1,10 +1,5 @@
1
- class Hash
2
-
3
- def |(other)
4
- MetaWhere::Or.new(self, other)
5
- end
1
+ require 'meta_where/condition_operators'
6
2
 
7
- def &(other)
8
- MetaWhere::And.new(self, other)
9
- end
10
- end
3
+ class Hash
4
+ include MetaWhere::ConditionOperators
5
+ end
@@ -1,19 +1,15 @@
1
+ require 'meta_where/condition_operators'
2
+
1
3
  module MetaWhere
2
4
  class Compound
5
+ include ConditionOperators
6
+
3
7
  attr_reader :condition1, :condition2
4
8
 
5
9
  def initialize(condition1, condition2)
6
10
  @condition1 = condition1
7
11
  @condition2 = condition2
8
12
  end
9
-
10
- def |(other)
11
- Or.new(self, other)
12
- end
13
-
14
- def &(other)
15
- And.new(self, other)
16
- end
17
13
  end
18
14
 
19
15
  class Or < Compound
@@ -21,4 +17,4 @@ module MetaWhere
21
17
 
22
18
  class And < Compound
23
19
  end
24
- end
20
+ end
@@ -1,8 +1,10 @@
1
1
  require 'meta_where/utility'
2
+ require 'meta_where/condition_operators'
2
3
 
3
4
  module MetaWhere
4
5
  class Condition
5
- include MetaWhere::Utility
6
+ include ConditionOperators
7
+ include Utility
6
8
 
7
9
  attr_reader :column, :value, :method
8
10
 
@@ -21,18 +23,10 @@ module MetaWhere
21
23
 
22
24
  alias_method :eql?, :==
23
25
 
24
- def |(other)
25
- Or.new(self, other)
26
- end
27
-
28
- def &(other)
29
- And.new(self, other)
30
- end
31
-
32
26
  # Play "nicely" with expand_hash_conditions_for_aggregates
33
27
  def to_sym
34
28
  self
35
29
  end
36
30
  end
37
31
 
38
- end
32
+ end
@@ -0,0 +1,19 @@
1
+ module MetaWhere
2
+ module ConditionOperators
3
+ def |(other)
4
+ Or.new(self, other)
5
+ end
6
+
7
+ def &(other)
8
+ And.new(self, other)
9
+ end
10
+
11
+ def -(other)
12
+ And.new(self, Not.new(other))
13
+ end
14
+
15
+ def -@
16
+ Not.new(self)
17
+ end
18
+ end
19
+ end
@@ -23,7 +23,7 @@ module MetaWhere
23
23
  case associations
24
24
  when Symbol, String
25
25
  reflection = parent.reflections[associations.to_s.intern] or
26
- raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?"
26
+ raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it?"
27
27
  unless (association = find_join_association(reflection, parent)) && (!klass || association.active_record == klass)
28
28
  @reflections << reflection
29
29
  if reflection.options[:polymorphic]
@@ -0,0 +1,13 @@
1
+ require 'meta_where/condition_operators'
2
+
3
+ module MetaWhere
4
+ class Not
5
+ include ConditionOperators
6
+
7
+ attr_reader :expr
8
+
9
+ def initialize(expr)
10
+ @expr = expr
11
+ end
12
+ end
13
+ end
@@ -257,12 +257,7 @@ module MetaWhere
257
257
 
258
258
  def flatten_predicates(predicates, visitor)
259
259
  predicates.map {|p|
260
- predicate = visitor.can_accept?(p) ? visitor.accept(p) : p
261
- if predicate.is_a?(Arel::Nodes::Grouping) && predicate.expr.is_a?(Arel::Nodes::And)
262
- flatten_predicates([predicate.expr.left, predicate.expr.right], visitor)
263
- else
264
- predicate
265
- end
260
+ visitor.can_accept?(p) ? visitor.accept(p) : p
266
261
  }.flatten.uniq
267
262
  end
268
263
 
@@ -5,7 +5,7 @@ module MetaWhere
5
5
  class Predicate < Visitor
6
6
 
7
7
  def self.visitables
8
- [Hash, Array, MetaWhere::Or, MetaWhere::And, MetaWhere::Condition, MetaWhere::Function]
8
+ [Hash, Array, MetaWhere::Or, MetaWhere::And, MetaWhere::Not, MetaWhere::Condition, MetaWhere::Function]
9
9
  end
10
10
 
11
11
  def visit_Hash(o, parent)
@@ -16,7 +16,7 @@ module MetaWhere
16
16
  if value.is_a?(Hash)
17
17
  association = association_from_parent_and_column(parent, column)
18
18
  accept(value, association || column)
19
- elsif [MetaWhere::Condition, MetaWhere::And, MetaWhere::Or].include?(value.class)
19
+ elsif [MetaWhere::Condition, MetaWhere::And, MetaWhere::Or, MetaWhere::Not].include?(value.class)
20
20
  association = association_from_parent_and_column(parent, column)
21
21
  accept(value, association || column)
22
22
  elsif value.is_a?(Array) && !value.empty? && value.all? {|v| can_accept?(v)}
@@ -77,6 +77,10 @@ module MetaWhere
77
77
  accept(o.condition1, parent).and(accept(o.condition2, parent))
78
78
  end
79
79
 
80
+ def visit_MetaWhere_Not(o, parent)
81
+ accept(o.expr, parent).not
82
+ end
83
+
80
84
  def visit_MetaWhere_Condition(o, parent)
81
85
  table = tables[parent]
82
86
 
@@ -142,4 +146,4 @@ module MetaWhere
142
146
 
143
147
  end
144
148
  end
145
- end
149
+ end
data/lib/meta_where.rb CHANGED
@@ -26,11 +26,16 @@ module MetaWhere
26
26
  require 'core_ext/symbol_operators'
27
27
  end
28
28
  end
29
+
29
30
  require 'arel'
30
31
  require 'active_record'
31
32
  require 'active_support'
33
+
34
+ # TODO: Trim this down, as the individual files should be
35
+ # handling their requires.
32
36
  require 'meta_where/column'
33
37
  require 'meta_where/condition'
38
+ require 'meta_where/not'
34
39
  require 'meta_where/compound'
35
40
  require 'meta_where/function'
36
41
  require 'meta_where/join_type'
data/meta_where.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{meta_where}
8
- s.version = "1.0.1"
8
+ s.version = "1.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ernie Miller"]
12
- s.date = %q{2011-01-18}
12
+ s.date = %q{2011-02-09}
13
13
  s.description = %q{
14
14
  MetaWhere offers the ability to call any Arel predicate methods
15
15
  (with a few convenient aliases) on your Model's attributes instead
@@ -41,9 +41,11 @@ Gem::Specification.new do |s|
41
41
  "lib/meta_where/column.rb",
42
42
  "lib/meta_where/compound.rb",
43
43
  "lib/meta_where/condition.rb",
44
+ "lib/meta_where/condition_operators.rb",
44
45
  "lib/meta_where/function.rb",
45
46
  "lib/meta_where/join_dependency.rb",
46
47
  "lib/meta_where/join_type.rb",
48
+ "lib/meta_where/not.rb",
47
49
  "lib/meta_where/relation.rb",
48
50
  "lib/meta_where/utility.rb",
49
51
  "lib/meta_where/visitors/attribute.rb",
@@ -82,7 +84,7 @@ you're feeling especially appreciative. It'd help me justify this
82
84
 
83
85
  }
84
86
  s.require_paths = ["lib"]
85
- s.rubygems_version = %q{1.3.7}
87
+ s.rubygems_version = %q{1.5.0}
86
88
  s.summary = %q{ActiveRecord 3 query syntax on steroids.}
87
89
  s.test_files = [
88
90
  "test/fixtures/company.rb",
@@ -102,25 +104,24 @@ you're feeling especially appreciative. It'd help me justify this
102
104
  ]
103
105
 
104
106
  if s.respond_to? :specification_version then
105
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
106
107
  s.specification_version = 3
107
108
 
108
109
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
109
110
  s.add_development_dependency(%q<shoulda>, [">= 0"])
110
- s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.2"])
111
- s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.2"])
112
- s.add_runtime_dependency(%q<arel>, ["~> 2.0.2"])
111
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.4"])
112
+ s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.4"])
113
+ s.add_runtime_dependency(%q<arel>, ["~> 2.0.8"])
113
114
  else
114
115
  s.add_dependency(%q<shoulda>, [">= 0"])
115
- s.add_dependency(%q<activerecord>, ["~> 3.0.2"])
116
- s.add_dependency(%q<activesupport>, ["~> 3.0.2"])
117
- s.add_dependency(%q<arel>, ["~> 2.0.2"])
116
+ s.add_dependency(%q<activerecord>, ["~> 3.0.4"])
117
+ s.add_dependency(%q<activesupport>, ["~> 3.0.4"])
118
+ s.add_dependency(%q<arel>, ["~> 2.0.8"])
118
119
  end
119
120
  else
120
121
  s.add_dependency(%q<shoulda>, [">= 0"])
121
- s.add_dependency(%q<activerecord>, ["~> 3.0.2"])
122
- s.add_dependency(%q<activesupport>, ["~> 3.0.2"])
123
- s.add_dependency(%q<arel>, ["~> 2.0.2"])
122
+ s.add_dependency(%q<activerecord>, ["~> 3.0.4"])
123
+ s.add_dependency(%q<activesupport>, ["~> 3.0.4"])
124
+ s.add_dependency(%q<arel>, ["~> 2.0.8"])
124
125
  end
125
126
  end
126
127
 
@@ -115,6 +115,14 @@ class TestRelations < Test::Unit::TestCase
115
115
  assert_equal @r.where(:name.like % 'Advanced%').all, @r.where('name LIKE ?', 'Advanced%').all
116
116
  end
117
117
 
118
+ should "handle *_any predicates by creating or conditions" do
119
+ assert_match %r{ OR }, @r.where(:name.matches_any => ['%e%', '%a%']).to_sql
120
+ end
121
+
122
+ should "handle *_all predicates by creating AND conditions" do
123
+ assert_match %r{ AND }, @r.where(:name.matches_all => ['%e%', '%a%']).to_sql
124
+ end
125
+
118
126
  should "allow | and & for compound predicates" do
119
127
  assert_equal @r.where(:name.like % 'Advanced%' | :name.like % 'Init%').all,
120
128
  @r.where('name LIKE ? OR name LIKE ?', 'Advanced%', 'Init%').all
@@ -122,6 +130,16 @@ class TestRelations < Test::Unit::TestCase
122
130
  @r.where('name LIKE ? AND name LIKE ?', 'Mission%', '%Data').all
123
131
  end
124
132
 
133
+ should "create an AND NOT on binary minus between conditions" do
134
+ assert_equal @r.where(:name.like % 'Mission%' - :name.like % '%Data').all,
135
+ @r.where('name LIKE ? AND name NOT LIKE ?', 'Mission%', '%Data').all
136
+ end
137
+
138
+ should "create a NOT on unary minus on condition" do
139
+ assert_equal @r.where(-(:name.like % '%Data')).all,
140
+ @r.where('name NOT LIKE ?', '%Data').all
141
+ end
142
+
125
143
  should "allow nested conditions hashes to have array values" do
126
144
  assert_equal @r.joins(:data_types).where(:data_types => {:dec => 2..5}).all,
127
145
  @r.joins(:data_types).where(:data_types => [:dec >= 2, :dec <= 5]).all
@@ -142,6 +160,11 @@ class TestRelations < Test::Unit::TestCase
142
160
  @r.joins(:data_types).where(:data_types => ((:dec >= 2) | (:bln >> true))).all
143
161
  end
144
162
 
163
+ should "allow nested conditions hashes to have MetaWhere::Not values" do
164
+ assert_equal @r.joins(:data_types).where(:data_types => [:dec.gteq % 2 - :bln.eq % true]).all,
165
+ @r.joins(:data_types).where(:data_types => ((:dec >= 2) - (:bln >> true))).all
166
+ end
167
+
145
168
  should "allow combinations of options that no sane developer would ever try to use" do
146
169
  assert_equal @r.find_all_by_name('Initech'),
147
170
  @r.joins(:data_types, :developers => [:projects, :notes]).
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meta_where
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 1
9
- version: 1.0.1
4
+ prerelease:
5
+ version: 1.0.2
10
6
  platform: ruby
11
7
  authors:
12
8
  - Ernie Miller
@@ -14,7 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2011-01-18 00:00:00 -05:00
13
+ date: 2011-02-09 00:00:00 -05:00
18
14
  default_executable:
19
15
  dependencies:
20
16
  - !ruby/object:Gem::Dependency
@@ -25,8 +21,6 @@ dependencies:
25
21
  requirements:
26
22
  - - ">="
27
23
  - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
24
  version: "0"
31
25
  type: :development
32
26
  version_requirements: *id001
@@ -38,11 +32,7 @@ dependencies:
38
32
  requirements:
39
33
  - - ~>
40
34
  - !ruby/object:Gem::Version
41
- segments:
42
- - 3
43
- - 0
44
- - 2
45
- version: 3.0.2
35
+ version: 3.0.4
46
36
  type: :runtime
47
37
  version_requirements: *id002
48
38
  - !ruby/object:Gem::Dependency
@@ -53,11 +43,7 @@ dependencies:
53
43
  requirements:
54
44
  - - ~>
55
45
  - !ruby/object:Gem::Version
56
- segments:
57
- - 3
58
- - 0
59
- - 2
60
- version: 3.0.2
46
+ version: 3.0.4
61
47
  type: :runtime
62
48
  version_requirements: *id003
63
49
  - !ruby/object:Gem::Dependency
@@ -68,11 +54,7 @@ dependencies:
68
54
  requirements:
69
55
  - - ~>
70
56
  - !ruby/object:Gem::Version
71
- segments:
72
- - 2
73
- - 0
74
- - 2
75
- version: 2.0.2
57
+ version: 2.0.8
76
58
  type: :runtime
77
59
  version_requirements: *id004
78
60
  description: "\n MetaWhere offers the ability to call any Arel predicate methods\n (with a few convenient aliases) on your Model's attributes instead\n of the ones normally offered by ActiveRecord's hash parameters. It also\n adds convenient syntax for order clauses, smarter mapping of nested hash\n conditions, and a debug_sql method to see the real SQL your code is\n generating without running it against the database. If you like the new\n AR 3.0 query interface, you'll love it with MetaWhere.\n "
@@ -101,9 +83,11 @@ files:
101
83
  - lib/meta_where/column.rb
102
84
  - lib/meta_where/compound.rb
103
85
  - lib/meta_where/condition.rb
86
+ - lib/meta_where/condition_operators.rb
104
87
  - lib/meta_where/function.rb
105
88
  - lib/meta_where/join_dependency.rb
106
89
  - lib/meta_where/join_type.rb
90
+ - lib/meta_where/not.rb
107
91
  - lib/meta_where/relation.rb
108
92
  - lib/meta_where/utility.rb
109
93
  - lib/meta_where/visitors/attribute.rb
@@ -150,21 +134,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
134
  requirements:
151
135
  - - ">="
152
136
  - !ruby/object:Gem::Version
153
- segments:
154
- - 0
155
137
  version: "0"
156
138
  required_rubygems_version: !ruby/object:Gem::Requirement
157
139
  none: false
158
140
  requirements:
159
141
  - - ">="
160
142
  - !ruby/object:Gem::Version
161
- segments:
162
- - 0
163
143
  version: "0"
164
144
  requirements: []
165
145
 
166
146
  rubyforge_project:
167
- rubygems_version: 1.3.7
147
+ rubygems_version: 1.5.0
168
148
  signing_key:
169
149
  specification_version: 3
170
150
  summary: ActiveRecord 3 query syntax on steroids.