1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
require_relative "spec_helper"
describe "insert_conflict plugin" do
def model_class(adapter)
db = Sequel.mock(:host=>adapter, :fetch=>{:id=>1, :s=>2}, :autoid=>1)
db.extend_datasets{def quote_identifiers?; false end}
model = Class.new(Sequel::Model)
model.dataset = db[:t]
model.columns :id, :s, :o
model.plugin :insert_conflict
db.sqls
model
end
def model_class_plugin_first(adapter)
model = Class.new(Sequel::Model)
model.plugin :insert_conflict
model = Class.new(model)
db = Sequel.mock(:host=>adapter, :fetch=>{:id=>1, :s=>2}, :autoid=>1)
db.extend_datasets{def quote_identifiers?; false end}
model.dataset = db[:t]
model.columns :id, :s, :o
db.sqls
model
end
it "should use INSERT ON CONFLICT when inserting on PostgreSQL" do
model = model_class(:postgres)
model.new(:s=>'A', :o=>1).insert_conflict.save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT DO NOTHING RETURNING *"]
model.new(:s=>'A', :o=>1).insert_conflict(:target=>:s, :update => {:o => Sequel[:excluded][:o]}).save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT (s) DO UPDATE SET o = excluded.o RETURNING *"]
end
it "should use INSERT ON CONFLICT when inserting on SQLITE" do
model = model_class(:sqlite)
model.new(:s=>'A', :o=>1).insert_conflict.save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT DO NOTHING",
"SELECT * FROM t WHERE (id = 1) LIMIT 1"]
model.new(:s=>'A', :o=>1).insert_conflict(:target=>:s, :update => {:o => Sequel[:excluded][:o]}).save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT (s) DO UPDATE SET o = excluded.o",
"SELECT * FROM t WHERE (id = 2) LIMIT 1"]
end
it "should raise Error if calling insert_conflict on a model instance that isn't new" do
m = model_class(:postgres).load(:s=>'A', :o=>1)
proc{m.insert_conflict}.must_raise Sequel::Error
end
it "should raise if loading plugin into a model class with a dataset that doesn't support insert_conflict" do
model = Class.new(Sequel::Model)
model.dataset = Sequel.mock[:t]
proc{model.plugin :insert_conflict}.must_raise Sequel::Error
end
it "should work if loading into a model class without a dataset on PostgreSQL" do
model = model_class_plugin_first(:postgres)
model.new(:s=>'A', :o=>1).insert_conflict.save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT DO NOTHING RETURNING *"]
model.new(:s=>'A', :o=>1).insert_conflict(:target=>:s, :update => {:o => Sequel[:excluded][:o]}).save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT (s) DO UPDATE SET o = excluded.o RETURNING *"]
end
it "should work if loading into a model class without a dataset on SQLITE" do
model = model_class_plugin_first(:sqlite)
model.new(:s=>'A', :o=>1).insert_conflict.save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT DO NOTHING",
"SELECT * FROM t WHERE (id = 1) LIMIT 1"]
model.new(:s=>'A', :o=>1).insert_conflict(:target=>:s, :update => {:o => Sequel[:excluded][:o]}).save
model.db.sqls.must_equal ["INSERT INTO t (s, o) VALUES ('A', 1) ON CONFLICT (s) DO UPDATE SET o = excluded.o",
"SELECT * FROM t WHERE (id = 2) LIMIT 1"]
end
it "should work if the prepared_statements plugin is loaded before" do
db = Sequel.mock(:host=>'sqlite', :fetch=>{:id=>1, :s=>2}, :autoid=>1, :numrows=>1)
db.extend_datasets{def quote_identifiers?; false end}
model = Class.new(Sequel::Model)
model.dataset = db[:t]
model.columns :id, :s
model.plugin :prepared_statements
model.plugin :insert_conflict
db.sqls
model.create(:s=>'a').update(:s=>'b')
db.sqls.must_equal ["INSERT INTO t (s) VALUES ('a')", "SELECT * FROM t WHERE (id = 1) LIMIT 1", "UPDATE t SET s = 'b' WHERE (id = 1)"]
end
it "should work if the prepared_statements plugin is loaded after" do
db = Sequel.mock(:host=>'postgres', :fetch=>{:id=>1, :s=>2}, :autoid=>1, :numrows=>1)
db.extend_datasets{def quote_identifiers?; false end}
model = Class.new(Sequel::Model)
model.dataset = db[:t]
model.columns :id, :s
model.plugin :insert_conflict
model.plugin :prepared_statements
db.sqls
model.create(:s=>'a').update(:s=>'b')
db.sqls.must_equal ["INSERT INTO t (s) VALUES ('a') RETURNING *", "UPDATE t SET s = 'b' WHERE (id = 1)"]
end
end
|