sequel_postgresql_triggers 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c840eb70121de040c927fd25cf0611cf8c475bb
4
- data.tar.gz: 39edf714024b57ace34c3aa0be20d10947a27133
3
+ metadata.gz: b5de693db244fa94aba445980a43f06ecdb91cb8
4
+ data.tar.gz: a0fb193ac3d11010daaace8c590eb5ab552bcdc1
5
5
  SHA512:
6
- metadata.gz: 5533d19fb6cdf0dbb96c4a09a25dddbb814a189026c8c0d95e674f6a2109180d8b69023399399666e745e47dae48633592bfb757c708eb7ed34868f00169f7e1
7
- data.tar.gz: 211a34c135965d5585662b1e1fb8f201413443704404742453b2e27ff6ad186c92ce9a2b2525614a991f3da4f9daab866a41bac78b02653f51852986dcae82f4
6
+ metadata.gz: 88098e2ec7f2e97e8ed193689fe12b7f7f631e28821869ef25955d19723df943742c8b2c0d594d0044cf068b6532e28682a09fa807412040c652b1974a7685e0
7
+ data.tar.gz: d7fdef313991baed60bf2c5efe719bde984a8484f007b88ad0b08ec3382b2a1ee0b207412413994361faef917d8079d64565177062c94dbf4507fcae8d13e88c
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2011 Jeremy Evans
1
+ Copyright (c) 2008-2014 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
@@ -27,15 +27,25 @@ module Sequel
27
27
  def pgt_counter_cache(main_table, main_table_id_column, counter_column, counted_table, counted_table_id_column, opts={})
28
28
  trigger_name = opts[:trigger_name] || "pgt_cc_#{main_table}__#{main_table_id_column}__#{counter_column}__#{counted_table_id_column}"
29
29
  function_name = opts[:function_name] || "pgt_cc_#{main_table}__#{main_table_id_column}__#{counter_column}__#{counted_table}__#{counted_table_id_column}"
30
- pgt_trigger(counted_table, trigger_name, function_name, [:insert, :delete], <<-SQL)
30
+
31
+ table = quote_schema_table(main_table)
32
+ id_column = quote_identifier(counted_table_id_column)
33
+ main_column = quote_identifier(main_table_id_column)
34
+ count_column = quote_identifier(counter_column)
35
+
36
+ pgt_trigger(counted_table, trigger_name, function_name, [:insert, :update, :delete], <<-SQL)
31
37
  BEGIN
38
+ IF (TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND NEW.#{id_column} <> OLD.#{id_column})) THEN
39
+ UPDATE #{table} SET #{count_column} = #{count_column} + 1 WHERE #{main_column} = NEW.#{id_column};
40
+ END IF;
41
+ IF (TG_OP = 'DELETE' OR (TG_OP = 'UPDATE' AND NEW.#{id_column} <> OLD.#{id_column})) THEN
42
+ UPDATE #{table} SET #{count_column} = #{count_column} - 1 WHERE #{main_column} = OLD.#{id_column};
43
+ END IF;
44
+
32
45
  IF (TG_OP = 'DELETE') THEN
33
- UPDATE #{quote_schema_table(main_table)} SET #{quote_identifier(counter_column)} = #{quote_identifier(counter_column)} - 1 WHERE #{quote_identifier(main_table_id_column)} = OLD.#{counted_table_id_column};
34
46
  RETURN OLD;
35
- ELSIF (TG_OP = 'INSERT') THEN
36
- UPDATE #{quote_schema_table(main_table)} SET #{quote_identifier(counter_column)} = #{quote_identifier(counter_column)} + 1 WHERE #{quote_identifier(main_table_id_column)} = NEW.#{quote_identifier(counted_table_id_column)};
37
- RETURN NEW;
38
47
  END IF;
48
+ RETURN NEW;
39
49
  END;
40
50
  SQL
41
51
  end
@@ -49,12 +59,13 @@ module Sequel
49
59
  def pgt_created_at(table, column, opts={})
50
60
  trigger_name = opts[:trigger_name] || "pgt_ca_#{column}"
51
61
  function_name = opts[:function_name] || "pgt_ca_#{table}__#{column}"
62
+ col = quote_identifier(column)
52
63
  pgt_trigger(table, trigger_name, function_name, [:insert, :update], <<-SQL)
53
64
  BEGIN
54
65
  IF (TG_OP = 'UPDATE') THEN
55
- NEW.#{quote_identifier(column)} := OLD.#{quote_identifier(column)};
66
+ NEW.#{col} := OLD.#{col};
56
67
  ELSIF (TG_OP = 'INSERT') THEN
57
- NEW.#{quote_identifier(column)} := CURRENT_TIMESTAMP;
68
+ NEW.#{col} := CURRENT_TIMESTAMP;
58
69
  END IF;
59
70
  RETURN NEW;
60
71
  END;
@@ -95,18 +106,29 @@ module Sequel
95
106
  def pgt_sum_cache(main_table, main_table_id_column, sum_column, summed_table, summed_table_id_column, summed_column, opts={})
96
107
  trigger_name = opts[:trigger_name] || "pgt_sc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table_id_column}"
97
108
  function_name = opts[:function_name] || "pgt_sc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table}__#{summed_table_id_column}__#{summed_column}"
109
+
110
+ table = quote_schema_table(main_table)
111
+ id_column = quote_identifier(summed_table_id_column)
112
+ summed_column = quote_identifier(summed_column)
113
+ main_column = quote_identifier(main_table_id_column)
114
+ sum_column = quote_identifier(sum_column)
115
+
98
116
  pgt_trigger(summed_table, trigger_name, function_name, [:insert, :delete, :update], <<-SQL)
99
117
  BEGIN
118
+ IF (TG_OP = 'UPDATE' AND NEW.#{id_column} = OLD.#{id_column}) THEN
119
+ UPDATE #{table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} - OLD.#{summed_column} WHERE #{main_column} = NEW.#{id_column};
120
+ ELSE
121
+ IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
122
+ UPDATE #{table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} WHERE #{main_column} = NEW.#{id_column};
123
+ END IF;
124
+ IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
125
+ UPDATE #{table} SET #{sum_column} = #{sum_column} - OLD.#{summed_column} WHERE #{main_column} = OLD.#{id_column};
126
+ END IF;
127
+ END IF;
100
128
  IF (TG_OP = 'DELETE') THEN
101
- UPDATE #{quote_schema_table(main_table)} SET #{quote_identifier(sum_column)} = #{quote_identifier(sum_column)} - OLD.#{quote_identifier(summed_column)} WHERE #{quote_identifier(main_table_id_column)} = OLD.#{summed_table_id_column};
102
129
  RETURN OLD;
103
- ELSIF (TG_OP = 'UPDATE') THEN
104
- UPDATE #{quote_schema_table(main_table)} SET #{quote_identifier(sum_column)} = #{quote_identifier(sum_column)} + NEW.#{quote_identifier(summed_column)} - OLD.#{quote_identifier(summed_column)} WHERE #{quote_identifier(main_table_id_column)} = NEW.#{quote_identifier(summed_table_id_column)};
105
- RETURN NEW;
106
- ELSIF (TG_OP = 'INSERT') THEN
107
- UPDATE #{quote_schema_table(main_table)} SET #{quote_identifier(sum_column)} = #{quote_identifier(sum_column)} + NEW.#{quote_identifier(summed_column)} WHERE #{quote_identifier(main_table_id_column)} = NEW.#{quote_identifier(summed_table_id_column)};
108
- RETURN NEW;
109
130
  END IF;
131
+ RETURN NEW;
110
132
  END;
111
133
  SQL
112
134
  end
@@ -122,17 +144,30 @@ module Sequel
122
144
  def pgt_touch(main_table, touch_table, column, expr, opts={})
123
145
  trigger_name = opts[:trigger_name] || "pgt_t_#{main_table}__#{touch_table}"
124
146
  function_name = opts[:function_name] || "pgt_t_#{main_table}__#{touch_table}"
125
- cond = proc{|source| expr.map{|k,v| "#{quote_identifier(k)} = #{source}.#{quote_identifier(v)}"}.join(" AND ")}
147
+ cond = lambda{|source| expr.map{|k,v| "#{quote_identifier(k)} = #{source}.#{quote_identifier(v)}"}.join(" AND ")}
148
+ same_id = expr.map{|k,v| "NEW.#{quote_identifier(v)} = OLD.#{quote_identifier(v)}"}.join(" AND ")
149
+
150
+ table = quote_schema_table(touch_table)
151
+ col = quote_identifier(column)
152
+ update = lambda{|source| " UPDATE #{table} SET #{col} = CURRENT_TIMESTAMP WHERE #{cond[source]} AND ((#{col} <> CURRENT_TIMESTAMP) OR (#{col} IS NULL));"}
153
+
126
154
  sql = <<-SQL
127
155
  BEGIN
128
- IF (TG_OP = 'INSERT') THEN
129
- UPDATE #{quote_schema_table(touch_table)} SET #{quote_identifier(column)} = CURRENT_TIMESTAMP WHERE #{cond['NEW']} AND ((#{quote_identifier(column)} <> CURRENT_TIMESTAMP) OR (#{quote_identifier(column)} IS NULL));
130
- ELSIF (TG_OP = 'UPDATE') THEN
131
- UPDATE #{quote_schema_table(touch_table)} SET #{quote_identifier(column)} = CURRENT_TIMESTAMP WHERE #{cond['NEW']} AND ((#{quote_identifier(column)} <> CURRENT_TIMESTAMP) OR (#{quote_identifier(column)} IS NULL));
132
- ELSIF (TG_OP = 'DELETE') THEN
133
- UPDATE #{quote_schema_table(touch_table)} SET #{quote_identifier(column)} = CURRENT_TIMESTAMP WHERE #{cond['OLD']} AND ((#{quote_identifier(column)} <> CURRENT_TIMESTAMP) OR (#{quote_identifier(column)} IS NULL));
156
+ IF (TG_OP = 'UPDATE' AND (#{same_id})) THEN
157
+ #{update['NEW']}
158
+ ELSE
159
+ IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
160
+ #{update['NEW']}
161
+ END IF;
162
+ IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
163
+ #{update['OLD']}
164
+ END IF;
134
165
  END IF;
135
- RETURN NULL;
166
+
167
+ IF (TG_OP = 'DELETE') THEN
168
+ RETURN OLD;
169
+ END IF;
170
+ RETURN NEW;
136
171
  END;
137
172
  SQL
138
173
  pgt_trigger(main_table, trigger_name, function_name, [:insert, :delete, :update], sql, :after=>true)
@@ -40,6 +40,9 @@ describe "PostgreSQL Triggers" do
40
40
  DB[:entries] << {:id=>3, :account_id=>2}
41
41
  DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
42
42
  DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
43
+ DB[:entries].where(:id=>2).update(:account_id=>2)
44
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
45
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 2
43
46
  DB[:entries].filter(:id=>2).delete
44
47
  DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
45
48
  DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
@@ -134,6 +137,9 @@ describe "PostgreSQL Triggers" do
134
137
  DB[:entries].exclude(:id=>2).update(:amount=>Sequel.*(:amount, 2))
135
138
  DB[:accounts].filter(:id=>1).get(:balance).should == 400
136
139
  DB[:accounts].filter(:id=>2).get(:balance).should == 1000
140
+ DB[:entries].where(:id=>2).update(:account_id=>2)
141
+ DB[:accounts].filter(:id=>1).get(:balance).should == 200
142
+ DB[:accounts].filter(:id=>2).get(:balance).should == 1200
137
143
  DB[:entries].filter(:id=>2).delete
138
144
  DB[:accounts].filter(:id=>1).get(:balance).should == 200
139
145
  DB[:accounts].filter(:id=>2).get(:balance).should == 1000
@@ -177,15 +183,24 @@ describe "PostgreSQL Triggers" do
177
183
 
178
184
  specify "Should update the timestamp column of the related table when adding, updating or removing records" do
179
185
  DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
180
- DB[:parents] << {:id1=>1, :changed_on=>Date.today - 30}
186
+ d = Date.today
187
+ d30 = Date.today - 30
188
+ DB[:parents] << {:id1=>1, :changed_on=>d30}
189
+ DB[:parents] << {:id1=>2, :changed_on=>d30}
181
190
  DB[:children] << {:id=>1, :parent_id1=>1}
182
- DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
183
- DB[:parents].update(:changed_on=>Date.today - 30)
191
+ DB[:parents].order(:id1).select_map(:changed_on).map{|t| t.strftime('%F')}.should == [d.strftime('%F'), d30.strftime('%F')]
192
+
193
+ DB[:parents].update(:changed_on=>d30)
184
194
  DB[:children].update(:id=>2)
185
- DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
186
- DB[:parents].update(:changed_on=>Date.today - 30)
195
+ DB[:parents].order(:id1).select_map(:changed_on).map{|t| t.strftime('%F')}.should == [d.strftime('%F'), d30.strftime('%F')]
196
+
197
+ DB[:parents].update(:changed_on=>d30)
198
+ DB[:children].update(:parent_id1=>2)
199
+ DB[:parents].order(:id1).select_map(:changed_on).map{|t| t.strftime('%F')}.should == [d.strftime('%F'), d.strftime('%F')]
200
+
201
+ DB[:parents].update(:changed_on=>d30)
187
202
  DB[:children].delete
188
- DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
203
+ DB[:parents].order(:id1).select_map(:changed_on).map{|t| t.strftime('%F')}.should == [d30.strftime('%F'), d.strftime('%F')]
189
204
  end
190
205
 
191
206
  specify "Should update the timestamp column of the related table when there is a composite foreign key" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_postgresql_triggers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-13 00:00:00.000000000 Z
11
+ date: 2014-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -62,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
62
  version: '0'
63
63
  requirements: []
64
64
  rubyforge_project:
65
- rubygems_version: 2.2.0
65
+ rubygems_version: 2.2.2
66
66
  signing_key:
67
67
  specification_version: 4
68
68
  summary: Database enforced timestamps, immutable columns, and counter/sum caches