Browse files

Make Dataset#avg, #interval, #min, #max, #range, and #sum accept virt…

…ual row blocks
  • Loading branch information...
1 parent 990e8e6 commit e860e8fc6e94b7a10456830f29c89ff02a724291 @jeremyevans committed Nov 19, 2012
Showing with 47 additions and 12 deletions.
  1. +2 −0 CHANGELOG
  2. +28 −12 lib/sequel/dataset/actions.rb
  3. +17 −0 spec/core/dataset_spec.rb
View
2 CHANGELOG
@@ -1,5 +1,7 @@
=== HEAD
+* Make Dataset#avg, #interval, #min, #max, #range, and #sum accept virtual row blocks (jeremyevans)
+
* Make Dataset#count use a subselect when the dataset has an offset without a limit (jeremyevans) (#587)
* Dump deferrable status of unique indexes on PostgreSQL (radford) (#583)
View
40 lib/sequel/dataset/actions.rb
@@ -58,11 +58,14 @@ def all(&block)
a
end
- # Returns the average value for the given column.
+ # Returns the average value for the given column/expression.
+ # Uses a virtual row block if no argument is given.
#
# DB[:table].avg(:number) # SELECT avg(number) FROM table LIMIT 1
# # => 3
- def avg(column)
+ # DB[:table].avg{function(column)} # SELECT avg(function(column)) FROM table LIMIT 1
+ # # => 1
+ def avg(column=Sequel.virtual_row(&Proc.new))
aggregate_dataset.get{avg(column)}
end
@@ -342,11 +345,13 @@ def insert_multiple(array, &block)
end
# Returns the interval between minimum and maximum values for the given
- # column.
+ # column/expression. Uses a virtual row block if no argument is given.
#
# DB[:table].interval(:id) # SELECT (max(id) - min(id)) FROM table LIMIT 1
# # => 6
- def interval(column)
+ # DB[:table].interval{function(column)} # SELECT (max(function(column)) - min(function(column))) FROM table LIMIT 1
+ # # => 7
+ def interval(column=Sequel.virtual_row(&Proc.new))
aggregate_dataset.get{max(column) - min(column)}
end
@@ -393,19 +398,25 @@ def map(column=nil, &block)
end
end
- # Returns the maximum value for the given column.
+ # Returns the maximum value for the given column/expression.
+ # Uses a virtual row block if no argument is given.
#
# DB[:table].max(:id) # SELECT max(id) FROM table LIMIT 1
# # => 10
- def max(column)
+ # DB[:table].max{function(column)} # SELECT max(function(column)) FROM table LIMIT 1
+ # # => 7
+ def max(column=Sequel.virtual_row(&Proc.new))
aggregate_dataset.get{max(column)}
end
- # Returns the minimum value for the given column.
+ # Returns the minimum value for the given column/expression.
+ # Uses a virtual row block if no argument is given.
#
# DB[:table].min(:id) # SELECT min(id) FROM table LIMIT 1
# # => 1
- def min(column)
+ # DB[:table].min{function(column)} # SELECT min(function(column)) FROM table LIMIT 1
+ # # => 0
+ def min(column=Sequel.virtual_row(&Proc.new))
aggregate_dataset.get{min(column)}
end
@@ -428,11 +439,13 @@ def multi_insert(hashes, opts={})
end
# Returns a +Range+ instance made from the minimum and maximum values for the
- # given column.
+ # given column/expression. Uses a virtual row block if no argument is given.
#
# DB[:table].range(:id) # SELECT max(id) AS v1, min(id) AS v2 FROM table LIMIT 1
# # => 1..10
- def range(column)
+ # DB[:table].interval{function(column)} # SELECT max(function(column)) AS v1, min(function(column)) AS v2 FROM table LIMIT 1
+ # # => 0..7
+ def range(column=Sequel.virtual_row(&Proc.new))
if r = aggregate_dataset.select{[min(column).as(v1), max(column).as(v2)]}.first
(r[:v1]..r[:v2])
end
@@ -543,11 +556,14 @@ def single_value
end
end
- # Returns the sum for the given column.
+ # Returns the sum for the given column/expression.
+ # Uses a virtual row block if no column is given.
#
# DB[:table].sum(:id) # SELECT sum(id) FROM table LIMIT 1
# # => 55
- def sum(column)
+ # DB[:table].sum{function(column)} # SELECT sum(function(column)) FROM table LIMIT 1
+ # # => 10
+ def sum(column=Sequel.virtual_row(&Proc.new))
aggregate_dataset.get{sum(column)}
end
View
17 spec/core/dataset_spec.rb
@@ -2387,6 +2387,13 @@ def d.to_s; "adsf" end
d.min(:a).should == 'SELECT min(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
d.max(:a).should == 'SELECT max(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
end
+
+ specify "should accept virtual row blocks" do
+ @d.avg{a(b)}.should == 'SELECT avg(a(b)) FROM test LIMIT 1'
+ @d.sum{a(b)}.should == 'SELECT sum(a(b)) FROM test LIMIT 1'
+ @d.min{a(b)}.should == 'SELECT min(a(b)) FROM test LIMIT 1'
+ @d.max{a(b)}.should == 'SELECT max(a(b)) FROM test LIMIT 1'
+ end
end
describe "Dataset#range" do
@@ -2411,6 +2418,11 @@ def d.to_s; "adsf" end
@ds.order(:stamp).limit(5).range(:stamp).should == (1..10)
@db.sqls.should == ['SELECT min(stamp) AS v1, max(stamp) AS v2 FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
end
+
+ specify "should accept virtual row blocks" do
+ @ds.range{a(b)}
+ @db.sqls.should == ["SELECT min(a(b)) AS v1, max(a(b)) AS v2 FROM test LIMIT 1"]
+ end
end
describe "Dataset#interval" do
@@ -2431,6 +2443,11 @@ def d.to_s; "adsf" end
@ds.order(:stamp).limit(5).interval(:stamp).should == 1234
@db.sqls.should == ['SELECT (max(stamp) - min(stamp)) FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
end
+
+ specify "should accept virtual row blocks" do
+ @ds.interval{a(b)}
+ @db.sqls.should == ["SELECT (max(a(b)) - min(a(b))) FROM test LIMIT 1"]
+ end
end
describe "Dataset #first and #last" do

0 comments on commit e860e8f

Please sign in to comment.