sequel_postgresql_triggers 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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