Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 168 lines (146 sloc) 6.471 kb
ff582a0 @jeremyevans Initial commit
authored
1 #!/usr/bin/env spec
2 require 'rubygems'
3 require 'sequel'
4
5877eec @jeremyevans Change the default user for the specs
authored
5 DB = Sequel.connect(ENV['PGT_SPEC_DB']||'postgres:///spgt_test?user=postgres')
ff582a0 @jeremyevans Initial commit
authored
6
7 $:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib'))
8 require 'sequel_postgresql_triggers'
9
8aa8d58 @jeremyevans Fix specs to only create and drop language plpgsql if on a version le…
authored
10 context "PostgreSQL Triggers" do
11 before do
12 DB.create_language(:plpgsql) if DB.server_version < 90000
13 end
14 after do
15 DB.drop_language(:plpgsql, :cascade=>true) if DB.server_version < 90000
16 end
17
ff582a0 @jeremyevans Initial commit
authored
18 context "PostgreSQL Counter Cache Trigger" do
19 before do
20 DB.create_table(:accounts){integer :id; integer :num_entries, :default=>0}
21 DB.create_table(:entries){integer :id; integer :account_id}
22 DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id)
23 DB[:accounts] << {:id=>1}
24 DB[:accounts] << {:id=>2}
25 end
26
27 after do
28 DB.drop_table(:entries, :accounts)
29 end
30
31 specify "Should modify counter cache when adding or removing records" do
32 DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
33 DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
34 DB[:entries] << {:id=>1, :account_id=>1}
35 DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
36 DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
37 DB[:entries] << {:id=>2, :account_id=>1}
38 DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
39 DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
40 DB[:entries] << {:id=>3, :account_id=>2}
41 DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
42 DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
43 DB[:entries].filter(:id=>2).delete
44 DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
45 DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
46 DB[:entries].delete
47 DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
48 DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
49 end
50 end
51
52 context "PostgreSQL Created At Trigger" do
53 before do
54 DB.create_table(:accounts){integer :id; timestamp :added_on}
55 DB.pgt_created_at(:accounts, :added_on)
56 end
57
58 after do
59 DB.drop_table(:accounts)
60 end
61
62 specify "Should set the column upon insertion and ignore modifications afterward" do
63 DB[:accounts] << {:id=>1}
64 t = DB[:accounts].get(:added_on)
65 t.strftime('%F').should == Date.today.strftime('%F')
66 DB[:accounts].update(:added_on=>Date.today - 60)
67 DB[:accounts].get(:added_on).should == t
68 DB[:accounts] << {:id=>2}
69 ds = DB[:accounts].select(:added_on)
70 DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
71 DB[:accounts].filter(:id=>1).update(:id=>3)
72 DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>3)).as(:x)).first[:x].should == true
73 end
74 end
75
76 context "PostgreSQL Immutable Trigger" do
77 before do
78 DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
79 DB.pgt_immutable(:accounts, :balance)
80 DB[:accounts] << {:id=>1}
81 end
82
83 after do
84 DB.drop_table(:accounts)
85 end
86
525d92e @jeremyevans Add and refactor some immutable specs
authored
87 specify "Should allow modifying columns not marked as immutable" do
88 proc{DB[:accounts].update(:id=>2)}.should_not raise_error
89 end
90
91 specify "Should allow updating a column to its existing value" do
92 proc{DB[:accounts].update(:balance=>0)}.should_not raise_error
93 proc{DB[:accounts].update(:balance=>:balance * :balance)}.should_not raise_error
94 end
95
96 specify "Should not allow modifying a column's value" do
ff582a0 @jeremyevans Initial commit
authored
97 proc{DB[:accounts].update(:balance=>1)}.should raise_error(Sequel::DatabaseError)
98 end
525d92e @jeremyevans Add and refactor some immutable specs
authored
99
100 specify "Should handle NULL values correctly" do
101 proc{DB[:accounts].update(:balance=>nil)}.should raise_error(Sequel::DatabaseError)
102 DB[:accounts].delete
103 DB[:accounts] << {:id=>1, :balance=>nil}
104 proc{DB[:accounts].update(:balance=>nil)}.should_not raise_error
105 proc{DB[:accounts].update(:balance=>0)}.should raise_error(Sequel::DatabaseError)
106 end
ff582a0 @jeremyevans Initial commit
authored
107 end
108
109 context "PostgreSQL Sum Cache Trigger" do
110 before do
111 DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
112 DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
113 DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount)
114 DB[:accounts] << {:id=>1}
115 DB[:accounts] << {:id=>2}
116 end
117
118 after do
119 DB.drop_table(:entries, :accounts)
120 end
121
122 specify "Should modify sum cache when adding, updating, or removing records" do
123 DB[:accounts].filter(:id=>1).get(:balance).should == 0
124 DB[:accounts].filter(:id=>2).get(:balance).should == 0
125 DB[:entries] << {:id=>1, :account_id=>1, :amount=>100}
126 DB[:accounts].filter(:id=>1).get(:balance).should == 100
127 DB[:accounts].filter(:id=>2).get(:balance).should == 0
128 DB[:entries] << {:id=>2, :account_id=>1, :amount=>200}
129 DB[:accounts].filter(:id=>1).get(:balance).should == 300
130 DB[:accounts].filter(:id=>2).get(:balance).should == 0
131 DB[:entries] << {:id=>3, :account_id=>2, :amount=>500}
132 DB[:accounts].filter(:id=>1).get(:balance).should == 300
133 DB[:accounts].filter(:id=>2).get(:balance).should == 500
134 DB[:entries].exclude(:id=>2).update(:amount=>:amount * 2)
135 DB[:accounts].filter(:id=>1).get(:balance).should == 400
136 DB[:accounts].filter(:id=>2).get(:balance).should == 1000
137 DB[:entries].filter(:id=>2).delete
138 DB[:accounts].filter(:id=>1).get(:balance).should == 200
139 DB[:accounts].filter(:id=>2).get(:balance).should == 1000
140 DB[:entries].delete
141 DB[:accounts].filter(:id=>1).get(:balance).should == 0
142 DB[:accounts].filter(:id=>2).get(:balance).should == 0
143 end
144 end
145
146 context "PostgreSQL Updated At Trigger" do
147 before do
148 DB.create_table(:accounts){integer :id; timestamp :changed_on}
149 DB.pgt_updated_at(:accounts, :changed_on)
150 end
151
152 after do
153 DB.drop_table(:accounts)
154 end
155
156 specify "Should set the column always to the current timestamp" do
157 DB[:accounts] << {:id=>1}
158 t = DB[:accounts].get(:changed_on)
159 t.strftime('%F').should == Date.today.strftime('%F')
160 DB[:accounts] << {:id=>2}
161 ds = DB[:accounts].select(:changed_on)
162 DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
163 DB[:accounts].filter(:id=>1).update(:id=>3)
164 DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>3)) > ds.filter(:id=>2)).as(:x)).first[:x].should == true
165 end
166 end
8aa8d58 @jeremyevans Fix specs to only create and drop language plpgsql if on a version le…
authored
167 end
Something went wrong with that request. Please try again.