Permalink
Browse files

Add Dataset#with_pk! for model datasets, like #with_pk, but raising i…

…nstead of returning nil
  • Loading branch information...
1 parent d82ab06 commit dbf3370fc5dcde568420b601d8cc234e273818e2 @jeremyevans committed Mar 22, 2013
Showing with 30 additions and 2 deletions.
  1. +2 −0 CHANGELOG
  2. +7 −1 lib/sequel/model/base.rb
  3. +21 −1 spec/model/base_spec.rb
View
@@ -1,5 +1,7 @@
=== HEAD
+* Add Dataset#with_pk! for model datasets, like #with_pk, but raising instead of returning nil (jeremyevans)
+
* Add Dataset#first!, like #first, but raising a Sequel::NoMatchingRow exception instead of returning nil (jeremyevans)
* Dataset #select_map, #select_order_map, and #get no longer support a plain string inside an array of arguments (jeremyevans)
View
@@ -1983,7 +1983,7 @@ def to_hash(key_column=nil, value_column=nil)
end
# Given a primary key value, return the first record in the dataset with that primary key
- # value.
+ # value. If no records matches, returns nil.
#
# # Single primary key
# Artist.dataset.with_pk(1) # SELECT * FROM artists WHERE (id = 1) LIMIT 1
@@ -1994,6 +1994,12 @@ def to_hash(key_column=nil, value_column=nil)
def with_pk(pk)
first(model.qualified_primary_key_hash(pk))
end
+
+ # Same as with_pk, but raises NoMatchingRow instead of returning nil if no
+ # row matches.
+ def with_pk!(pk)
+ with_pk(pk) || raise(NoMatchingRow)
+ end
end
extend ClassMethods
View
@@ -693,7 +693,7 @@ def @ds2.provides_accurate_rows_matched?() true end
end
end
-describe "Model datasets #with_pk" do
+describe "Model datasets #with_pk with #with_pk!" do
before do
@c = Class.new(Sequel::Model(:a))
@ds = @c.dataset
@@ -704,16 +704,22 @@ def @ds2.provides_accurate_rows_matched?() true end
it "should return the first record where the primary key matches" do
@ds.with_pk(1).should == @c.load(:id=>1)
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
+ @ds.with_pk!(1).should == @c.load(:id=>1)
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
end
it "should handle existing filters" do
@ds.filter(:a=>2).with_pk(1)
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
+ @ds.filter(:a=>2).with_pk!(1)
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (a.id = 1)) LIMIT 1"]
end
it "should work with string values" do
@ds.with_pk("foo")
MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
+ @ds.with_pk!("foo")
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 'foo') LIMIT 1"]
end
it "should handle an array for composite primary keys" do
@@ -723,6 +729,20 @@ def @ds2.provides_accurate_rows_matched?() true end
["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
"SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
sqls.should == []
+
+ @ds.with_pk!([1, 2])
+ sqls = MODEL_DB.sqls
+ ["SELECT * FROM a WHERE ((a.id1 = 1) AND (a.id2 = 2)) LIMIT 1",
+ "SELECT * FROM a WHERE ((a.id2 = 2) AND (a.id1 = 1)) LIMIT 1"].should include(sqls.pop)
+ sqls.should == []
+ end
+
+ it "should have with_pk return nil and with_pk! raise if no rows match" do
+ @ds._fetch = []
+ @ds.with_pk(1).should == nil
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
+ proc{@ds.with_pk!(1)}.should raise_error(Sequel::NoMatchingRow)
+ MODEL_DB.sqls.should == ["SELECT * FROM a WHERE (a.id = 1) LIMIT 1"]
end
it "should have #[] consider an integer as a primary key lookup" do

0 comments on commit dbf3370

Please sign in to comment.