rquery 0.3.0 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,6 +17,20 @@ In you're rails environment file simply require rquery. The default adapter is t
17
17
 
18
18
  You can view both Sql and Sqlite in the adapters directory if you are interested in writing your own (mysql?). As a side note it would be nice at some point to decide the adapter based on the db chosen for a given environment.
19
19
 
20
+ ###Sniper Scopes
21
+
22
+ Its now extremely easy to use rquery's dsl as named scopes. For example
23
+
24
+ class User < ActiveRecord::Base
25
+ sniper_scope :with_name do |user, passed_name|
26
+ user.name == passed_name
27
+ end
28
+ end
29
+
30
+ User.with_name('George')
31
+
32
+ The first parameter will be an object representing the user and the rest will be the parameters passed when the method is called. Since this functionality makes use of the named_scope method it can be chained with other sniper_scopes and named_scopes. If the name seems a bit odd, I'm open to other suggestions :D
33
+
20
34
  ###Examples
21
35
 
22
36
  RQuery extend ActiveRecord to provide the `where` method. `where` accepts a single optional argument and a block that represents the query statements
@@ -1,8 +1,6 @@
1
1
  $: << File.expand_path(File.dirname(__FILE__) + "/../lib/")
2
2
 
3
- #RQuery is a small DSL for building queries in query languages like SQL. It is meant to be concise, easy to read
4
- #and expressive.
5
-
3
+ require "rquery/operations_group.rb"
6
4
  require "rquery/operation_collector.rb"
7
5
  require "rquery/attribute_collection.rb"
8
6
  require "rquery/adapters.rb"
@@ -1,26 +1,36 @@
1
1
  module RQuery
2
2
  module ActiveRecord
3
- def where(*args, &block)
4
- collector = RQuery::AttributeCollection.new(self.new.attribute_names)
5
-
6
- #Passes a new AttributeCollection object to the block
7
- #if RQuery.use_symbols has been called it may not be used
8
- #but otherwise will take the form attr_coll_object.attribute.is ...
9
- yield(collector)
3
+ module ClassMethods
4
+ def where(*args, &block)
5
+ collector = AttributeCollection.new(columns.map {|x| x.name })
6
+
7
+ #Passes a new AttributeCollection object to the block, which will in turn
8
+ #instantiate a OperationCollector to be used for each expression
9
+ yield(collector)
10
10
 
11
- #record altered conditions and values
12
- conditions = collector.clauses.to_conditions
11
+ #record altered conditions and values
12
+ conditions = collector.clauses.to_conditions
13
13
 
14
- #limit the records returned (:first, :all, :last)
15
- limit = args.first ? args.first : :all
14
+ #limit the records returned (:first, :all, :last)
15
+ limit = args.first ? args.first : :all
16
16
 
17
- #call find with the conditions and values provided by the block
18
- find(limit, :conditions => conditions)
17
+ #call find with the conditions and values provided by the block
18
+ find(limit, :conditions => conditions)
19
+ end
20
+
21
+ def sniper_scope(name, &block)
22
+ #rescope self
23
+ klass = self
24
+ named_scope name, lambda { |*args|
25
+ collector = AttributeCollection.new(klass.columns.map {|x| x.name })
26
+ block.call(collector, *args)
27
+ { :conditions => collector.clauses.to_conditions }
28
+ }
29
+ end
19
30
  end
20
31
  end
21
32
  end
22
33
 
23
34
  #extend ActiveRecord::Base with the where method
24
- if Object.const_defined?(:ActiveRecord)
25
- ActiveRecord::Base.send :extend, RQuery::ActiveRecord
26
- end
35
+ ActiveRecord::Base.send :extend, RQuery::ActiveRecord::ClassMethods
36
+
@@ -3,45 +3,23 @@ module RQuery
3
3
  attr_reader :clauses
4
4
 
5
5
  def initialize(fields)
6
- @fields = fields.map{ |x| x.to_s }
7
6
  @clauses = OperationCollector.new
8
- end
9
-
10
- #if the field was added upon initialization its a valid call
11
- #otherwise report to the user it is invalid. Reports errors at the ruby level
12
- #instead of the data store level with something like "column doesn't exist"
13
- #
14
- #example
15
- #
16
- # >> user = RQuery::FieldCollection.new([:age, :name])
17
- # => #<RQuery::FieldCollection:0x1a2c21c @fields=[:age, :name]>
18
- # >> user.age
19
- # => #<RQuery::Field:0x1a2b240 @name=:age>
20
- # >> user.name
21
- # => #<RQuery::Field:0x1a2a390 @name=:name>
22
- # >> user.weight
23
- # ArgumentError: The field 'weight' doesn't exist for this object
24
- # from /Users/johnbender/Projects/rquery/lib/rquery/where_clause.rb:20:in `method_missing'
25
- # from (irb):5
26
- def method_missing(symbol, *args)
27
- attr_str = symbol.to_s
28
- eq_str = attr_str.gsub(/=/, '')
29
7
 
30
- if @fields.include?(attr_str) #if the method is part of the attributes
31
- add_clause(attr_str)
32
- elsif @fields.include?(eq_str) #if the method sans '=' is part of the attributes
33
- add_clause(eq_str)
34
- eq(*args)
35
- else
36
- raise AttributeNotFoundError, "The field '#{symbol.to_s}' doesn't exist for this object"
8
+ # For each field define it and its setter to add the appropriate clause
9
+ fields.each do |field|
10
+ self.class.send(:define_method, field) do |*args|
11
+ add_clause(field)
12
+ @clauses
13
+ end
14
+
15
+ self.class.send(:define_method, (field + '=')) do |*args|
16
+ add_clause(field)
17
+ eq(*args)
18
+ @clauses
19
+ end
37
20
  end
38
-
39
- #explicit return of OperationCollector, same instance returned by methods of Operation collector
40
- #but included here for clarity
41
- @clauses
42
21
  end
43
22
 
44
-
45
23
  private
46
24
  def add_clause(str)
47
25
  @clauses.add_operation(str)
@@ -50,8 +28,5 @@ module RQuery
50
28
  def eq(*args)
51
29
  @clauses.send(:==, *args)
52
30
  end
53
-
54
31
  end
55
-
56
- class AttributeNotFoundError < ArgumentError; end
57
32
  end
@@ -25,53 +25,21 @@ module RQuery
25
25
  self
26
26
  end
27
27
 
28
- #grouping is done by using the | and & operators between multiple operations
29
- #objects on a single line.
30
- #
31
- #This works because each operation ie (user.age.is == 2) is
32
- #evaluated before these two operators thus pushing
33
- #the equivelant operation string onto the @operations array (ie 'age = ?').
34
- #When an operation is evaluated it returns the Operations class which can be compared
35
- #using the aforementioned operators. Those operators call the group method
36
- #popping the last two arguments off the stack and dealing with them in one of two ways
37
- #
38
- #1. if the second object popped is a string both objects should be
39
- # added to a new OperationGroup which is then put back onto the stack
40
- #
41
- #2. if the second object popped is an OperationGroup the firest belongs to this group as
42
- # well (it was on the same line). It is added to the OperationGroup and put back on the
43
- # stack
44
- #
45
- #TODO requires refactoring
46
- def group(type)
47
- second_op, first_op = @operations.pop, @operations.pop
48
-
49
- #if the previous operation on the stack is an Operation Group we need to add to it
50
- #and push it back on the @operations stack
51
- if first_op.class == OperationsGroup
52
- if first_op.type == type
53
- first_op.ops << second_op
54
- @operations << first_op
55
- else
56
- @operations << OperationsGroup.new(first_op.to_s, second_op, type)
57
- end
58
- else
59
- @operations << OperationsGroup.new(first_op, second_op, type)
60
- end
61
-
62
- self
63
- end
64
-
65
28
  #used to group operations for anding on a single line
66
29
  #example with sqlite adapter
67
30
  #(user.age.in [1,2,3]) | (user.name.contains "foo")
68
31
  #=>(age in (?) and name like '%' || 'foo' || '%')
32
+ #
33
+ # note that second is not used in this case because it should
34
+ # have been collected into the @operations array earlier
69
35
  def &(second)
70
- group :and
36
+ @operations << AndOperationsGroup.new(tail_ops!(2))
37
+ self
71
38
  end
72
39
 
73
40
  def |(second)
74
- group :or
41
+ @operations << OrOperationsGroup.new(tail_ops!(2))
42
+ self
75
43
  end
76
44
 
77
45
  def in(*args)
@@ -120,13 +88,17 @@ module RQuery
120
88
  alias :from :between
121
89
  alias :not_from :not_between
122
90
 
123
- private
91
+ private
92
+ def tail_ops!(num)
93
+ @operations.slice!(@operations.length-2, num)
94
+ end
95
+
124
96
  def chain(method)
125
97
  @operations[@operations.length-1] += " #{RQuery::Config.adapter.send(method)}"
126
98
  self
127
99
  end
128
100
 
129
- def call_in(prefix=nil, *args)
101
+ def call_in(prefix, *args)
130
102
  #flatten our args to prevent having to check for an array first arg
131
103
  args.flatten!
132
104
 
@@ -141,7 +113,7 @@ module RQuery
141
113
  chain :"#{prefix}in"
142
114
  end
143
115
 
144
- def call_between(prefix=nil, *args)
116
+ def call_between(prefix, *args)
145
117
  #flatten our args to prevent having to check for an array first arg
146
118
  args.flatten!
147
119
 
@@ -157,19 +129,4 @@ module RQuery
157
129
  chain :"#{prefix}between"
158
130
  end
159
131
  end
160
-
161
- class OperationsGroup
162
- attr_accessor :ops, :type
163
-
164
- def initialize(left, right, type)
165
- @ops = Array.new
166
- @ops << left
167
- @ops << right
168
- @type = type
169
- end
170
-
171
- def to_s
172
- RQuery::Config.adapter.send("#{type.to_s}_group", @ops)
173
- end
174
- end
175
132
  end
@@ -0,0 +1,32 @@
1
+ module RQuery
2
+ class OperationsGroup
3
+ attr_accessor :operations
4
+
5
+ def initialize(args)
6
+ @operations = []
7
+ #if the two args passed are strings make a new group
8
+ #otherwise add the second arg to the previous operation group
9
+ #
10
+ # NOTE coupling by type assumption here
11
+ @operations = args[0].instance_of?(String) ? args[0,2] : (args[0].operations << args[1])
12
+ end
13
+
14
+ def to_s
15
+ RQuery::Config.adapter.send("#{@type.to_s}_group", @operations)
16
+ end
17
+ end
18
+
19
+ class OrOperationsGroup < OperationsGroup
20
+ def initialize(args)
21
+ super(args)
22
+ @type = :or
23
+ end
24
+ end
25
+
26
+ class AndOperationsGroup < OperationsGroup
27
+ def initialize(args)
28
+ super(args)
29
+ @type = :and
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/mock_active_record.rb")
2
- require File.expand_path(File.dirname(__FILE__) + "/../lib/rquery.rb")
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
3
2
 
4
3
  describe ActiveRecord do
5
4
 
@@ -8,50 +7,57 @@ describe ActiveRecord do
8
7
  end
9
8
 
10
9
  it "should set up a where method" do
11
- ActiveRecord::MockObject.respond_to?(:where).should == true
10
+ MockObject.respond_to?(:where).should == true
11
+ end
12
+
13
+ it "should behave properly when using the id method" do
14
+ MockObject.where { |mock|
15
+ mock.id == 1
16
+ }.should == [:all, {:conditions => ['(id = ?)', 1]}]
12
17
  end
13
18
 
14
19
  it "should return sql with foo, the operations, and the values for mock.foo <operation> <value>" do
15
- ActiveRecord::MockObject.where{ |mock|
20
+ MockObject.where{ |mock|
16
21
  mock.foo == "bar"
17
22
  mock.foo = "bar"
18
23
  }.should == [:all, {:conditions => ["(foo = ? and foo = ?)", "bar", "bar"]}]
19
24
 
20
- ActiveRecord::MockObject.where{ |mock|
25
+ MockObject.where{ |mock|
21
26
  mock.foo > 1
22
27
  }.should == [:all, {:conditions => ["(foo > ?)", 1]}]
23
28
 
24
- ActiveRecord::MockObject.where{ |mock|
29
+ MockObject.where{ |mock|
25
30
  mock.foo < 2
26
31
  }.should == [:all, {:conditions => ["(foo < ?)", 2]}]
27
32
 
28
- ActiveRecord::MockObject.where{ |mock|
33
+ MockObject.where{ |mock|
29
34
  mock.foo >= 3
30
35
  }.should == [:all, {:conditions => ["(foo >= ?)", 3]}]
31
36
 
32
- ActiveRecord::MockObject.where{ |mock|
37
+ MockObject.where{ |mock|
33
38
  mock.foo <= 4
34
39
  }.should == [:all, {:conditions => ["(foo <= ?)", 4]}]
35
40
  end
36
41
 
37
42
  it "should return sql with foo, the operations, and the values for mock.foo.not_<operation> <value>" do
38
- ActiveRecord::MockObject.where{ |mock|
43
+ MockObject.where{ |mock|
39
44
  mock.foo.not = "bar"
40
45
  }.should == [:all, {:conditions => ["(foo <> ?)", "bar"]}]
41
46
 
42
- ActiveRecord::MockObject.where{ |mock|
47
+ MockObject.where{ |mock|
43
48
  mock.foo.not_in 1,2
44
49
  }.should == [:all, {:conditions => ["(foo not in (?))", [1,2]]}]
45
50
 
46
- ActiveRecord::MockObject.where{ |mock|
51
+ MockObject.where{ |mock|
47
52
  mock.foo.not_between 1..3
48
53
  }.should == [:all, {:conditions => ["(foo not between ? and ?)", 1, 3]}]
49
54
 
50
- ActiveRecord::MockObject.where{ |mock|
55
+
56
+ MockObject.where{ |mock|
51
57
  mock.foo.not_from 1..3
52
58
  }.should == [:all, {:conditions => ["(foo not between ? and ?)", 1, 3]}]
53
59
 
54
- ActiveRecord::MockObject.where{ |mock|
60
+ MockObject.where{ |mock|
55
61
  mock.foo.without "bar"
56
62
  }.should == [:all, {:conditions => ["(foo not like '%' || ? || '%')", "bar"]}]
57
63
  end
@@ -59,27 +65,27 @@ describe ActiveRecord do
59
65
  it "should return sql with foo, the operations, and values for mock.foo.in and mock.foo.in when used with a list of args, array, and range" do
60
66
  resulting_conditions = [:all, {:conditions => ["(foo in (?))", [1,2,3,4]]}]
61
67
 
62
- ActiveRecord::MockObject.where{ |mock|
68
+ MockObject.where{ |mock|
63
69
  mock.foo.in 1,2,3,4
64
70
  }.should == resulting_conditions
65
71
 
66
- ActiveRecord::MockObject.where{ |mock|
72
+ MockObject.where{ |mock|
67
73
  mock.foo.in [1,2,3,4]
68
74
  }.should == resulting_conditions
69
75
 
70
- ActiveRecord::MockObject.where{ |mock|
76
+ MockObject.where{ |mock|
71
77
  mock.foo.in 1..4
72
78
  }.should == [:all, {:conditions => ["(foo in (?))", 1..4]}]
73
79
 
74
- ActiveRecord::MockObject.where{ |mock|
80
+ MockObject.where{ |mock|
75
81
  mock.foo.in 1,2,3,4
76
82
  }.should == resulting_conditions
77
83
 
78
- ActiveRecord::MockObject.where{ |mock|
84
+ MockObject.where{ |mock|
79
85
  mock.foo.in [1,2,3,4]
80
86
  }.should == resulting_conditions
81
87
 
82
- ActiveRecord::MockObject.where{ |mock|
88
+ MockObject.where{ |mock|
83
89
  mock.foo.in 1..4
84
90
  }.should == [:all, {:conditions => ["(foo in (?))", 1..4]}]
85
91
  end
@@ -87,27 +93,27 @@ describe ActiveRecord do
87
93
  it "should return sql with foo, operations, and values for mock.foo.between and mock.foo.between when used with a list of args, array, and range" do
88
94
  resulting_conditions = [:all, {:conditions => ["(foo between ? and ?)", 1, 2]}]
89
95
 
90
- ActiveRecord::MockObject.where{ |mock|
96
+ MockObject.where{ |mock|
91
97
  mock.foo.between 1,2
92
98
  }.should == resulting_conditions
93
99
 
94
- ActiveRecord::MockObject.where{ |mock|
100
+ MockObject.where{ |mock|
95
101
  mock.foo.between [1,2]
96
102
  }.should == resulting_conditions
97
103
 
98
- ActiveRecord::MockObject.where{ |mock|
104
+ MockObject.where{ |mock|
99
105
  mock.foo.between 1..2
100
106
  }.should == resulting_conditions
101
107
 
102
- ActiveRecord::MockObject.where{ |mock|
108
+ MockObject.where{ |mock|
103
109
  mock.foo.between 1,2
104
110
  }.should == resulting_conditions
105
111
 
106
- ActiveRecord::MockObject.where{ |mock|
112
+ MockObject.where{ |mock|
107
113
  mock.foo.between [1,2]
108
114
  }.should == resulting_conditions
109
115
 
110
- ActiveRecord::MockObject.where{ |mock|
116
+ MockObject.where{ |mock|
111
117
  mock.foo.between 1..2
112
118
  }.should == resulting_conditions
113
119
  end
@@ -115,27 +121,27 @@ describe ActiveRecord do
115
121
  it "should return sql with foo, operations, and values for mock.foo.from when used with a list of args, array, and range" do
116
122
  resulting_conditions = [:all, {:conditions => ["(foo between ? and ?)", 1, 2]}]
117
123
 
118
- ActiveRecord::MockObject.where{ |mock|
124
+ MockObject.where{ |mock|
119
125
  mock.foo.from 1,2
120
126
  }.should == resulting_conditions
121
127
 
122
- ActiveRecord::MockObject.where{ |mock|
128
+ MockObject.where{ |mock|
123
129
  mock.foo.from [1,2]
124
130
  }.should == resulting_conditions
125
131
 
126
- ActiveRecord::MockObject.where{ |mock|
132
+ MockObject.where{ |mock|
127
133
  mock.foo.from 1..2
128
134
  }.should == resulting_conditions
129
135
 
130
- ActiveRecord::MockObject.where{ |mock|
136
+ MockObject.where{ |mock|
131
137
  mock.foo.from 1,2
132
138
  }.should == resulting_conditions
133
139
 
134
- ActiveRecord::MockObject.where{ |mock|
140
+ MockObject.where{ |mock|
135
141
  mock.foo.from [1,2]
136
142
  }.should == resulting_conditions
137
143
 
138
- ActiveRecord::MockObject.where{ |mock|
144
+ MockObject.where{ |mock|
139
145
  mock.foo.from 1..2
140
146
  }.should == resulting_conditions
141
147
  end
@@ -143,27 +149,27 @@ describe ActiveRecord do
143
149
  it "should return sql with foo, operations, and values for mock.foo.contains when used with a range, array, and list" do
144
150
  resulting_conditions = [:all, {:conditions => ["(foo like '%' || ? || '%')", "bar"]}]
145
151
 
146
- ActiveRecord::MockObject.where{ |mock|
152
+ MockObject.where{ |mock|
147
153
  mock.foo.contains "bar"
148
154
  }.should == resulting_conditions
149
155
  end
150
156
 
151
157
  it "should return return the correct group of joined sql after multiple operations" do
152
- ActiveRecord::MockObject.where{ |mock|
158
+ MockObject.where{ |mock|
153
159
  mock.foo == "bar"
154
160
  mock.foo.not_in 1,2,3,4,5
155
161
  }.should == [:all, {:conditions => ["(foo = ? and foo not in (?))", "bar", [1,2,3,4,5]]}]
156
162
  end
157
163
 
158
164
  it "should return return the correct limit value passed" do
159
- ActiveRecord::MockObject.where(:first){ |mock|
165
+ MockObject.where(:first){ |mock|
160
166
  mock.foo == "bar"
161
167
  mock.foo.not_in 1,2,3,4,5
162
168
  }.should == [:first, {:conditions => ["(foo = ? and foo not in (?))", "bar", [1,2,3,4,5]]}]
163
169
  end
164
170
 
165
171
  it "should have the correct 'not' keywords in alternating operations" do
166
- ActiveRecord::MockObject.where(:first){ |mock|
172
+ MockObject.where(:first){ |mock|
167
173
  mock.foo == "bar"
168
174
  mock.foo.not_in 1,2,3,4,5
169
175
  mock.foo > 3
@@ -171,25 +177,25 @@ describe ActiveRecord do
171
177
  end
172
178
 
173
179
  it "should return return strings as arguments when passed to between, in, and from (used for date strings)" do
174
- ActiveRecord::MockObject.where{ |mock|
180
+ MockObject.where{ |mock|
175
181
  mock.foo.between "some string", "2007-01-01"
176
182
  }.should == [:all, {:conditions => ["(foo between ? and ?)", "some string", "2007-01-01"]}]
177
183
 
178
- ActiveRecord::MockObject.where{ |mock|
184
+ MockObject.where{ |mock|
179
185
  mock.foo.not_between "some string", "2007-01-01"
180
186
  }.should == [:all, {:conditions => ["(foo not between ? and ?)", "some string", "2007-01-01"]}]
181
187
 
182
- ActiveRecord::MockObject.where{ |mock|
188
+ MockObject.where{ |mock|
183
189
  mock.foo.from "some string", "2007-01-01"
184
190
  }.should == [:all, {:conditions => ["(foo between ? and ?)", "some string", "2007-01-01"]}]
185
191
 
186
- ActiveRecord::MockObject.where{ |mock|
192
+ MockObject.where{ |mock|
187
193
  mock.foo.in "some string", "2007-01-01"
188
194
  }.should == [:all, {:conditions => ["(foo in (?))", ["some string", "2007-01-01"]]}]
189
195
  end
190
196
 
191
197
  it "should throw and exception when trying to use a field not in the objects attributes" do
192
198
  attribute = "arbitrary_attribute_name"
193
- lambda { ActiveRecord::MockObject.where{ |mock| mock.send(attribute) == 2 }}.should raise_error(RQuery::AttributeNotFoundError)
199
+ lambda { MockObject.where{ |mock| mock.send(attribute) == 2 }}.should raise_error(NoMethodError)
194
200
  end
195
201
  end
@@ -1,5 +1,4 @@
1
- require File.expand_path(File.dirname(__FILE__) + "/mock_active_record.rb")
2
- require File.expand_path(File.dirname(__FILE__) + "/../lib/rquery.rb")
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
3
2
 
4
3
  describe RQuery::OperationCollector do
5
4
 
@@ -9,7 +8,7 @@ describe RQuery::OperationCollector do
9
8
 
10
9
  it "should group two operations on the same line with parens and the 'or' keyword when the | operator is used" do
11
10
 
12
- ActiveRecord::MockObject.where{ |mock|
11
+ MockObject.where{ |mock|
13
12
  (mock.foo == 2) | (mock.foo.in 1,2,3)
14
13
  }.should == [:all, {:conditions => ["((foo = ? or foo in (?)))", 2, [1,2,3]]}]
15
14
 
@@ -17,7 +16,7 @@ describe RQuery::OperationCollector do
17
16
 
18
17
  it "should group two operations on the same line with parns and the 'and' keyword when the & operator is used" do
19
18
 
20
- ActiveRecord::MockObject.where{ |mock|
19
+ MockObject.where{ |mock|
21
20
  (mock.foo == 2) & (mock.foo.in 1,2,3)
22
21
  }.should == [:all, {:conditions => ["((foo = ? and foo in (?)))", 2, [1,2,3]]}]
23
22
 
@@ -25,7 +24,7 @@ describe RQuery::OperationCollector do
25
24
 
26
25
  it "should group two operations on the same line and continue to add subsequent operations" do
27
26
 
28
- ActiveRecord::MockObject.where{ |mock|
27
+ MockObject.where{ |mock|
29
28
  (mock.foo == 2) & (mock.foo.in 1,2,3)
30
29
  mock.foo > 3
31
30
  }.should == [:all, {:conditions => ["((foo = ? and foo in (?)) and foo > ?)", 2, [1,2,3], 3]}]
@@ -34,7 +33,7 @@ describe RQuery::OperationCollector do
34
33
 
35
34
  it "should properly group multiple nested groupings on the same line" do
36
35
 
37
- ActiveRecord::MockObject.where{ |mock|
36
+ MockObject.where{ |mock|
38
37
  (mock.foo == 2) | (mock.foo.in 1,2,3) | (mock.foo.contains "george")
39
38
  mock.foo > 3
40
39
  (mock.foo == 2) & (mock.foo.in 1,2,3)
@@ -44,10 +43,9 @@ describe RQuery::OperationCollector do
44
43
 
45
44
  it "& should have precedence when evaluating multiple operation group types on a single line" do
46
45
 
47
- ActiveRecord::MockObject.where{ |mock|
46
+ MockObject.where{ |mock|
48
47
  (mock.foo == 2) | (mock.foo.in 1,2,3) & (mock.foo.contains "george")
49
48
  }.should == [:all, {:conditions => ["((foo = ? or (foo in (?) and foo like '%' || ? || '%')))", 2, [1,2,3], "george"]}]
50
-
51
49
 
52
50
  end
53
51
 
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper.rb")
2
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/rquery.rb")
3
+
4
+ describe ActiveRecord do
5
+
6
+ before :all do
7
+ RQuery::Config.adapter = RQuery::Adapters::Sqlite
8
+ MockObject.sniper_scope :baz do |object, foo_val|
9
+ object.foo == foo_val
10
+ end
11
+ end
12
+
13
+ it "should proved a named scope on the active record object when sniper_scope is defined" do
14
+ MockObject.respond_to?(:baz).should == true
15
+ end
16
+
17
+ it "should set the named scope conditions properly when the sniper_scope is defined" do
18
+ result = MockObject.baz('bar').proxy_options
19
+ result.should == {:conditions => ['(foo = ?)', 'bar']}
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'spec/autorun'
4
+ require 'active_record'
5
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/rquery.rb")
6
+
7
+ class MockObject < ActiveRecord::Base
8
+ def self.find(limit, conditions)
9
+ [limit, conditions]
10
+ end
11
+
12
+ def initialize
13
+ end
14
+
15
+ def self.columns
16
+ [Column.new("foo"), Column.new("id")]
17
+ end
18
+ end
19
+
20
+ class Column
21
+ attr_accessor :name
22
+ def initialize(n)
23
+ @name = n
24
+ end
25
+ end
26
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rquery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - John bender
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-22 00:00:00 -07:00
12
+ date: 2010-01-14 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -32,10 +32,12 @@ files:
32
32
  - lib/rquery/adapters/sql.rb
33
33
  - lib/rquery/adapters/sqlite.rb
34
34
  - lib/rquery/operation_collector.rb
35
- - spec/active_record_base_spec_attribute_collection.rb
36
- - spec/mock_active_record.rb
35
+ - lib/rquery/operations_group.rb
36
+ - spec/active_record_base_attribute_collection_spec.rb
37
37
  - spec/or_and_operations_spec.rb
38
38
  - spec/sqlite_adapter_spec.rb
39
+ - spec/sniper_scope_spec.rb
40
+ - spec/spec_helper.rb
39
41
  has_rdoc: true
40
42
  homepage: http://github.com/johnbender/rquery
41
43
  licenses: []
@@ -60,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
62
  requirements: []
61
63
 
62
64
  rubyforge_project:
63
- rubygems_version: 1.3.4
65
+ rubygems_version: 1.3.5
64
66
  signing_key:
65
67
  specification_version: 3
66
68
  summary: An ActiveRecord extension providing a DSL replacement for complex find queries.
@@ -1,13 +0,0 @@
1
- module ActiveRecord
2
- class Base
3
- def Base.find(limit, conditions)
4
- [limit, conditions]
5
- end
6
- end
7
-
8
- class MockObject < Base
9
- def attribute_names
10
- ["foo"]
11
- end
12
- end
13
- end