sequel_postgresql_triggers 1.2.0 → 1.3.0

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: 4d2e84d8e162f972268dc9839f8f744651ff15ca
4
- data.tar.gz: 343a12a7c9531e694a92eeb1a037821095401bc2
3
+ metadata.gz: e4f87e2b711aa431fa2c58e7775e2f6f7263f86a
4
+ data.tar.gz: 3053bc8ad102ad616fdb1aa05240e2564553366d
5
5
  SHA512:
6
- metadata.gz: 931984b649f29b90b738e00546c0c388fbea363136afc736cfcd69a0ff69b36d90ec5f429d2f5c3157b41b246eb9d9aaa13798f30c5eb12a205ed6f4bbe27c54
7
- data.tar.gz: 7061eb0436fbe68db834aa130b503a834871bc2f554025fd851ce2411edd3bf964697d84a1feb01a979e40f644862b15ffd386d967a02849ca9b6c0ac45af61f
6
+ metadata.gz: 139573dfcf3b39b056a844c91f8b397b0a72d38365601624717a60d292a3f92c9213fc981402f62b7dccacedbe50ef35f6ebb2c292e1427c6312538545889b75
7
+ data.tar.gz: 0b75cb7a59a2f274e988274bf7a5d999bf39eef2878b6685b7a68f8bbfe4296e81c86366a42d9f705da7cc15d9c7a34a93ab083c45d550113f49616ad8ef1117
@@ -100,6 +100,10 @@ or deleted from, records in the main table are updated with the
100
100
  count of the corresponding records in the counted table. The counter
101
101
  cache column must have a default of 0 for this to work correctly.
102
102
 
103
+ Use pgt_sum_cache with a Sequel expression in summed_column to
104
+ handle any custom logic such as a counter cache that only counts
105
+ certain rows.
106
+
103
107
  Arguments:
104
108
  main_table :: name of table holding counter cache column
105
109
  main_table_id_column :: column in main table matching counted_table_id_column in counted_table
@@ -115,13 +119,17 @@ of records in the main table, it stores the sum on one of the
115
119
  columns in summed table. The sum cache column must have a default
116
120
  of 0 for this to work correctly.
117
121
 
122
+ Use a Sequel expression in summed_column to handle any custom
123
+ logic such as a counter cache that only counts certain rows, or a
124
+ sum cache that sums the length of a string column.
125
+
118
126
  Arguments:
119
127
  main_table :: name of table holding counter cache column
120
128
  main_table_id_column :: column in main table matching counted_table_id_column in counted_table
121
129
  sum_column :: column in main table containing the sum cache
122
130
  summed_table :: name of table being summed
123
131
  summed_table_id_column :: column in summed_table matching main_table_id_column in main_table
124
- summed_column :: column in summed_table being summed
132
+ summed_column :: column in summed_table being summed or a Sequel expression to be evaluated in the context of summed_table
125
133
  opts :: options hash
126
134
 
127
135
  === Sum Through Many Cache - pgt_sum_through_many_cache
@@ -129,6 +137,8 @@ opts :: options hash
129
137
  Similar to pgt_sum_cache, except instead of a one-to-many relationship,
130
138
  it supports a many-to-many relationship with a single join table. The
131
139
  sum cache column must have a default of 0 for this to work correctly.
140
+ Use a Sequel expression in summed_column to handle any custom logic.
141
+ See pgt_sum_cache for details.
132
142
 
133
143
  This takes a single options hash argument, supporting the following options
134
144
  in addition to the standard options:
@@ -137,8 +147,10 @@ in addition to the standard options:
137
147
  :sum_column :: column in main table containing the sum cache, must be NOT NULL and default to 0
138
148
  :summed_table :: name of table being summed
139
149
  :summed_table_id_column :: primary key column in summed_table referenced by summed_table_fk_column (default: :id)
140
- :summed_column :: column in summed_table being summed, must be NOT NULL
150
+ :summed_column :: column in summed_table being summed or a Sequel expression to be evaluated in the context of summed_table, must be NOT NULL
141
151
  :join_table :: name of table which joins main_table with summed_table
152
+ :join_trigger_name :: name of trigger for join table
153
+ :join_function_name :: name of trigger function for join table
142
154
  :main_table_fk_column :: column in join_table referencing main_table_id_column, must be NOT NULL
143
155
  :summed_table_fk_column :: column in join_table referencing summed_table_id_column, must be NOT NULL
144
156
 
@@ -73,20 +73,22 @@ module Sequel
73
73
 
74
74
  table = quote_schema_table(main_table)
75
75
  id_column = quote_identifier(summed_table_id_column)
76
- summed_column = quote_identifier(summed_column)
76
+
77
+ new_table_summed_column = literal(Sequel.deep_qualify(Sequel.lit("NEW"), summed_column))
78
+ old_table_summed_column = literal(Sequel.deep_qualify(Sequel.lit("OLD"), summed_column))
77
79
  main_column = quote_identifier(main_table_id_column)
78
80
  sum_column = quote_identifier(sum_column)
79
81
 
80
82
  pgt_trigger(summed_table, trigger_name, function_name, [:insert, :delete, :update], <<-SQL)
81
83
  BEGIN
82
84
  IF (TG_OP = 'UPDATE' AND NEW.#{id_column} = OLD.#{id_column}) THEN
83
- UPDATE #{table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} - OLD.#{summed_column} WHERE #{main_column} = NEW.#{id_column};
85
+ UPDATE #{table} SET #{sum_column} = #{sum_column} + #{new_table_summed_column} - #{old_table_summed_column} WHERE #{main_column} = NEW.#{id_column};
84
86
  ELSE
85
87
  IF ((TG_OP = 'INSERT' OR TG_OP = 'UPDATE') AND NEW.#{id_column} IS NOT NULL) THEN
86
- UPDATE #{table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} WHERE #{main_column} = NEW.#{id_column};
88
+ UPDATE #{table} SET #{sum_column} = #{sum_column} + #{new_table_summed_column} WHERE #{main_column} = NEW.#{id_column};
87
89
  END IF;
88
90
  IF ((TG_OP = 'DELETE' OR TG_OP = 'UPDATE') AND OLD.#{id_column} IS NOT NULL) THEN
89
- UPDATE #{table} SET #{sum_column} = #{sum_column} - OLD.#{summed_column} WHERE #{main_column} = OLD.#{id_column};
91
+ UPDATE #{table} SET #{sum_column} = #{sum_column} - #{old_table_summed_column} WHERE #{main_column} = OLD.#{id_column};
90
92
  END IF;
91
93
  END IF;
92
94
  IF (TG_OP = 'DELETE') THEN
@@ -108,10 +110,11 @@ module Sequel
108
110
  main_table_fk_column = opts.fetch(:main_table_fk_column)
109
111
  summed_table_fk_column = opts.fetch(:summed_table_fk_column)
110
112
 
111
- trigger_name = opts[:trigger_name] || "pgt_stmc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table_id_column}__#{summed_column}__#{main_table_fk_column}__#{summed_table_fk_column}"
112
- function_name = opts[:function_name] || "pgt_stmc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table}__#{summed_table_id_column}__#{summed_column}__#{join_table}__#{main_table_fk_column}__#{summed_table_fk_column}"
113
- join_trigger_name = opts[:join_trigger_name] || "pgt_stmc_join_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table_id_column}__#{summed_column}__#{main_table_fk_column}__#{summed_table_fk_column}"
114
- join_function_name = opts[:join_function_name] || "pgt_stmc_join_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table}__#{summed_table_id_column}__#{summed_column}__#{join_table}__#{main_table_fk_column}__#{summed_table_fk_column}"
113
+ summed_column_slug = summed_column.is_a?(String) || summed_column.is_a?(Symbol) ? "__#{summed_column}" : ""
114
+ trigger_name = opts[:trigger_name] || "pgt_stmc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table_id_column}#{summed_column_slug}__#{main_table_fk_column}__#{summed_table_fk_column}"
115
+ function_name = opts[:function_name] || "pgt_stmc_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table}__#{summed_table_id_column}#{summed_column_slug}__#{join_table}__#{main_table_fk_column}__#{summed_table_fk_column}"
116
+ join_trigger_name = opts[:join_trigger_name] || "pgt_stmc_join_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table_id_column}#{summed_column_slug}__#{main_table_fk_column}__#{summed_table_fk_column}"
117
+ join_function_name = opts[:join_function_name] || "pgt_stmc_join_#{main_table}__#{main_table_id_column}__#{sum_column}__#{summed_table}__#{summed_table_id_column}#{summed_column_slug}__#{join_table}__#{main_table_fk_column}__#{summed_table_fk_column}"
115
118
 
116
119
  orig_summed_table = summed_table
117
120
  orig_join_table = join_table
@@ -119,9 +122,13 @@ module Sequel
119
122
  main_table = quote_schema_table(main_table)
120
123
  main_table_id_column = quote_schema_table(main_table_id_column)
121
124
  sum_column = quote_schema_table(sum_column)
125
+
126
+ general_summed_column = literal(Sequel.deep_qualify(summed_table, summed_column))
127
+ new_table_summed_column = literal(Sequel.deep_qualify(Sequel.lit("NEW"), summed_column))
128
+ old_table_summed_column = literal(Sequel.deep_qualify(Sequel.lit("OLD"), summed_column))
129
+
122
130
  summed_table = quote_schema_table(summed_table)
123
131
  summed_table_id_column = quote_schema_table(summed_table_id_column)
124
- summed_column = quote_schema_table(summed_column)
125
132
  join_table = quote_schema_table(join_table)
126
133
  main_table_fk_column = quote_schema_table(main_table_fk_column)
127
134
  summed_table_fk_column = quote_schema_table(summed_table_fk_column)
@@ -129,13 +136,13 @@ module Sequel
129
136
  pgt_trigger(orig_summed_table, trigger_name, function_name, [:insert, :delete, :update], <<-SQL)
130
137
  BEGIN
131
138
  IF (TG_OP = 'UPDATE' AND NEW.#{summed_table_id_column} = OLD.#{summed_table_id_column}) THEN
132
- UPDATE #{main_table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} - OLD.#{summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = NEW.#{summed_table_id_column});
139
+ UPDATE #{main_table} SET #{sum_column} = #{sum_column} + #{new_table_summed_column} - #{old_table_summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = NEW.#{summed_table_id_column});
133
140
  ELSE
134
141
  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
135
- UPDATE #{main_table} SET #{sum_column} = #{sum_column} + NEW.#{summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = NEW.#{summed_table_id_column});
142
+ UPDATE #{main_table} SET #{sum_column} = #{sum_column} + #{new_table_summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = NEW.#{summed_table_id_column});
136
143
  END IF;
137
144
  IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
138
- UPDATE #{main_table} SET #{sum_column} = #{sum_column} - OLD.#{summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = OLD.#{summed_table_id_column});
145
+ UPDATE #{main_table} SET #{sum_column} = #{sum_column} - #{old_table_summed_column} WHERE #{main_table_id_column} IN (SELECT #{main_table_fk_column} FROM #{join_table} WHERE #{summed_table_fk_column} = OLD.#{summed_table_id_column});
139
146
  END IF;
140
147
  END IF;
141
148
  IF (TG_OP = 'DELETE') THEN
@@ -149,10 +156,10 @@ module Sequel
149
156
  BEGIN
150
157
  IF (NOT (TG_OP = 'UPDATE' AND NEW.#{main_table_fk_column} = OLD.#{main_table_fk_column} AND NEW.#{summed_table_fk_column} = OLD.#{summed_table_fk_column})) THEN
151
158
  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
152
- UPDATE #{main_table} SET #{sum_column} = #{sum_column} + (SELECT #{summed_column} FROM #{summed_table} WHERE #{summed_table_id_column} = NEW.#{summed_table_fk_column}) WHERE #{main_table_id_column} = NEW.#{main_table_fk_column};
159
+ UPDATE #{main_table} SET #{sum_column} = #{sum_column} + (SELECT #{general_summed_column} FROM #{summed_table} WHERE #{summed_table_id_column} = NEW.#{summed_table_fk_column}) WHERE #{main_table_id_column} = NEW.#{main_table_fk_column};
153
160
  END IF;
154
161
  IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
155
- UPDATE #{main_table} SET #{sum_column} = #{sum_column} - (SELECT #{summed_column} FROM #{summed_table} WHERE #{summed_table_id_column} = OLD.#{summed_table_fk_column}) WHERE #{main_table_id_column} = OLD.#{main_table_fk_column};
162
+ UPDATE #{main_table} SET #{sum_column} = #{sum_column} - (SELECT #{general_summed_column} FROM #{summed_table} WHERE #{summed_table_id_column} = OLD.#{summed_table_fk_column}) WHERE #{main_table_id_column} = OLD.#{main_table_fk_column};
156
163
  END IF;
157
164
  END IF;
158
165
  IF (TG_OP = 'DELETE') THEN
@@ -27,13 +27,14 @@ describe "PostgreSQL Triggers" do
27
27
  before do
28
28
  DB.create_table(:accounts){integer :id; integer :num_entries, :default=>0}
29
29
  DB.create_table(:entries){integer :id; integer :account_id}
30
- DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id)
30
+ DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id, :function_name=>:spgt_counter_cache)
31
31
  DB[:accounts] << {:id=>1}
32
32
  DB[:accounts] << {:id=>2}
33
33
  end
34
34
 
35
35
  after do
36
36
  DB.drop_table(:entries, :accounts)
37
+ DB.drop_function(:spgt_counter_cache)
37
38
  end
38
39
 
39
40
  it "Should modify counter cache when adding or removing records" do
@@ -77,11 +78,12 @@ describe "PostgreSQL Triggers" do
77
78
  describe "PostgreSQL Created At Trigger" do
78
79
  before do
79
80
  DB.create_table(:accounts){integer :id; timestamp :added_on}
80
- DB.pgt_created_at(:accounts, :added_on)
81
+ DB.pgt_created_at(:accounts, :added_on, :function_name=>:spgt_created_at)
81
82
  end
82
83
 
83
84
  after do
84
85
  DB.drop_table(:accounts)
86
+ DB.drop_function(:spgt_created_at)
85
87
  end
86
88
 
87
89
  it "Should set the column upon insertion and ignore modifications afterward" do
@@ -101,12 +103,13 @@ describe "PostgreSQL Triggers" do
101
103
  describe "PostgreSQL Immutable Trigger" do
102
104
  before do
103
105
  DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
104
- DB.pgt_immutable(:accounts, :balance)
106
+ DB.pgt_immutable(:accounts, :balance, :function_name=>:spgt_immutable)
105
107
  DB[:accounts] << {:id=>1}
106
108
  end
107
109
 
108
110
  after do
109
111
  DB.drop_table(:accounts)
112
+ DB.drop_function(:spgt_immutable)
110
113
  end
111
114
 
112
115
  it "Should allow modifying columns not marked as immutable" do
@@ -135,13 +138,14 @@ describe "PostgreSQL Triggers" do
135
138
  before do
136
139
  DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
137
140
  DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
138
- DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount)
141
+ DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount, :function_name=>:spgt_sum_cache)
139
142
  DB[:accounts] << {:id=>1}
140
143
  DB[:accounts] << {:id=>2}
141
144
  end
142
145
 
143
146
  after do
144
147
  DB.drop_table(:entries, :accounts)
148
+ DB.drop_function(:spgt_sum_cache)
145
149
  end
146
150
 
147
151
  it "Should modify sum cache when adding, updating, or removing records" do
@@ -185,6 +189,62 @@ describe "PostgreSQL Triggers" do
185
189
  end
186
190
  end
187
191
 
192
+ describe "PostgreSQL Sum Cache Trigger with arbitrary expression" do
193
+ before do
194
+ DB.create_table(:accounts){integer :id; integer :nonzero_entries_count, :default=>0}
195
+ DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
196
+ DB.pgt_sum_cache(:accounts, :id, :nonzero_entries_count, :entries, :account_id, Sequel.case({0=>0}, 1, :amount), :function_name=>:spgt_sum_cache)
197
+ DB[:accounts] << {:id=>1}
198
+ DB[:accounts] << {:id=>2}
199
+ end
200
+
201
+ after do
202
+ DB.drop_table(:entries, :accounts)
203
+ DB.drop_function(:spgt_sum_cache)
204
+ end
205
+
206
+ it "Should modify sum cache when adding, updating, or removing records" do
207
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [0, 0]
208
+
209
+ DB[:entries] << {:id=>1, :account_id=>1, :amount=>100}
210
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 0]
211
+
212
+ DB[:entries] << {:id=>2, :account_id=>1, :amount=>200}
213
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [2, 0]
214
+
215
+ DB[:entries] << {:id=>3, :account_id=>nil, :amount=>500}
216
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [2, 0]
217
+
218
+ DB[:entries].where(:id=>3).update(:account_id=>2)
219
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
220
+
221
+ DB[:entries].exclude(:id=>2).update(:amount=>Sequel.*(:amount, 2))
222
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
223
+
224
+ DB[:entries].where(:id=>2).update(:account_id=>2)
225
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
226
+
227
+ DB[:entries].where(:id=>2).update(:account_id=>nil)
228
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 1]
229
+
230
+ DB[:entries].where(:id=>2).update(:id=>4)
231
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 1]
232
+
233
+ DB[:entries].where(:id=>4).update(:account_id=>2)
234
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
235
+
236
+ DB[:entries].where(:id=>4).update(:account_id=>nil)
237
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 1]
238
+
239
+ DB[:entries].filter(:id=>4).delete
240
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [1, 1]
241
+
242
+ DB[:entries].delete
243
+ DB[:accounts].order(:id).select_map(:nonzero_entries_count).must_equal [0, 0]
244
+ end
245
+ end
246
+
247
+
188
248
  describe "PostgreSQL Sum Through Many Cache Trigger" do
189
249
  before do
190
250
  DB.create_table(:parents){primary_key :id; integer :balance, :default=>0, :null=>false}
@@ -197,7 +257,9 @@ describe "PostgreSQL Triggers" do
197
257
  :summed_column=>:amount,
198
258
  :join_table=>:links,
199
259
  :main_table_fk_column=>:parent_id,
200
- :summed_table_fk_column=>:child_id
260
+ :summed_table_fk_column=>:child_id,
261
+ :function_name=>:spgt_stm_cache,
262
+ :join_function_name=>:spgt_stm_cache_join
201
263
  )
202
264
  DB[:parents] << {:id=>1}
203
265
  DB[:parents] << {:id=>2}
@@ -205,6 +267,8 @@ describe "PostgreSQL Triggers" do
205
267
 
206
268
  after do
207
269
  DB.drop_table(:links, :parents, :children)
270
+ DB.drop_function(:spgt_stm_cache)
271
+ DB.drop_function(:spgt_stm_cache_join)
208
272
  end
209
273
 
210
274
  it "Should modify sum cache when adding, updating, or removing records" do
@@ -274,14 +338,108 @@ describe "PostgreSQL Triggers" do
274
338
  end
275
339
  end
276
340
 
341
+ describe "PostgreSQL Sum Through Many Cache Trigger with arbitrary expression" do
342
+ before do
343
+ DB.create_table(:parents){primary_key :id; integer :nonzero_entries_count, :default=>0, :null=>false}
344
+ DB.create_table(:children){primary_key :id; integer :amount, :null=>false}
345
+ DB.create_table(:links){integer :parent_id, :null=>false; integer :child_id, :null=>false; unique [:parent_id, :child_id]}
346
+ DB.pgt_sum_through_many_cache(
347
+ :main_table=>:parents,
348
+ :sum_column=>:nonzero_entries_count,
349
+ :summed_table=>:children,
350
+ :summed_column=>Sequel.case({0=>0}, 1, :amount),
351
+ :join_table=>:links,
352
+ :main_table_fk_column=>:parent_id,
353
+ :summed_table_fk_column=>:child_id,
354
+ :function_name=>:spgt_stm_cache,
355
+ :join_function_name=>:spgt_stm_cache_join
356
+ )
357
+ DB[:parents] << {:id=>1}
358
+ DB[:parents] << {:id=>2}
359
+ end
360
+
361
+ after do
362
+ DB.drop_table(:links, :parents, :children)
363
+ DB.drop_function(:spgt_stm_cache)
364
+ DB.drop_function(:spgt_stm_cache_join)
365
+ end
366
+
367
+ it "Should modify sum cache when adding, updating, or removing records" do
368
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [0, 0]
369
+
370
+ DB[:children] << {:id=>1, :amount=>100}
371
+ DB[:links] << {:parent_id=>1, :child_id=>1}
372
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 0]
373
+
374
+ DB[:children] << {:id=>2, :amount=>200}
375
+ DB[:links] << {:parent_id=>1, :child_id=>2}
376
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 0]
377
+
378
+ DB[:children] << {:id=>3, :amount=>500}
379
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 0]
380
+ DB[:links] << {:parent_id=>2, :child_id=>3}
381
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
382
+
383
+ DB[:links].where(:parent_id=>2, :child_id=>3).update(:parent_id=>1)
384
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [3, 0]
385
+
386
+ DB[:children] << {:id=>4, :amount=>400}
387
+ DB[:links].where(:parent_id=>1, :child_id=>3).update(:child_id=>4)
388
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [3, 0]
389
+
390
+ DB[:links].where(:parent_id=>1, :child_id=>4).update(:parent_id=>2, :child_id=>3)
391
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
392
+
393
+ DB[:children].exclude(:id=>2).update(:amount=>Sequel.*(:amount, 2))
394
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
395
+
396
+ DB[:links].where(:parent_id=>1, :child_id=>2).update(:parent_id=>2)
397
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
398
+
399
+ DB[:links].where(:parent_id=>2, :child_id=>2).update(:parent_id=>1)
400
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
401
+
402
+ DB[:links].where(:parent_id=>1, :child_id=>2).update(:child_id=>3)
403
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
404
+
405
+ DB[:links] << {:parent_id=>2, :child_id=>4}
406
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 2]
407
+
408
+ DB[:children].filter(:id=>4).delete
409
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [2, 1]
410
+
411
+ DB[:links].filter(:parent_id=>1, :child_id=>1).delete
412
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 1]
413
+
414
+ DB[:children] << {:id=>4, :amount=>400}
415
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
416
+
417
+ DB[:children].delete
418
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [0, 0]
419
+
420
+ DB[:children].multi_insert([{:id=>2, :amount=>200}, {:id=>1, :amount=>200}, {:id=>3, :amount=>1000}, {:id=>4, :amount=>400}])
421
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
422
+
423
+ DB[:links].where(:child_id=>3).update(:child_id=>2)
424
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
425
+
426
+ DB[:children].update(:amount=>10)
427
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [1, 2]
428
+
429
+ DB[:links].delete
430
+ DB[:parents].order(:id).select_map(:nonzero_entries_count).must_equal [0, 0]
431
+ end
432
+ end
433
+
277
434
  describe "PostgreSQL Updated At Trigger" do
278
435
  before do
279
436
  DB.create_table(:accounts){integer :id; timestamp :changed_on}
280
- DB.pgt_updated_at(:accounts, :changed_on)
437
+ DB.pgt_updated_at(:accounts, :changed_on, :function_name=>:spgt_updated_at)
281
438
  end
282
439
 
283
440
  after do
284
441
  DB.drop_table(:accounts)
442
+ DB.drop_function(:spgt_updated_at)
285
443
  end
286
444
 
287
445
  it "Should set the column always to the current timestamp" do
@@ -304,10 +462,12 @@ describe "PostgreSQL Triggers" do
304
462
 
305
463
  after do
306
464
  DB.drop_table(:children, :parents)
465
+ DB.drop_function(:spgt_touch)
466
+ DB.drop_function(:spgt_touch2) if @spgt_touch2
307
467
  end
308
468
 
309
469
  it "Should update the timestamp column of the related table when adding, updating or removing records" do
310
- DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
470
+ DB.pgt_touch(:children, :parents, :changed_on, {:id1=>:parent_id1}, :function_name=>:spgt_touch)
311
471
  d = Date.today
312
472
  d30 = Date.today - 30
313
473
  DB[:parents] << {:id1=>1, :changed_on=>d30}
@@ -347,7 +507,7 @@ describe "PostgreSQL Triggers" do
347
507
  end
348
508
 
349
509
  it "Should update the timestamp column of the related table when there is a composite foreign key" do
350
- DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1, :id2=>:parent_id2)
510
+ DB.pgt_touch(:children, :parents, :changed_on, {:id1=>:parent_id1, :id2=>:parent_id2}, :function_name=>:spgt_touch)
351
511
  DB[:parents] << {:id1=>1, :id2=>2, :changed_on=>Date.today - 30}
352
512
  DB[:children] << {:id=>1, :parent_id1=>1, :parent_id2=>2}
353
513
  DB[:parents].get(:changed_on).strftime('%F').must_equal Date.today.strftime('%F')
@@ -360,8 +520,9 @@ describe "PostgreSQL Triggers" do
360
520
  end
361
521
 
362
522
  it "Should update timestamps correctly when two tables touch each other" do
363
- DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
364
- DB.pgt_touch(:parents, :children, :changed_on, :id=>:child_id)
523
+ DB.pgt_touch(:children, :parents, :changed_on, {:id1=>:parent_id1}, :function_name=>:spgt_touch)
524
+ @spgt_touch2 = true
525
+ DB.pgt_touch(:parents, :children, :changed_on, {:id=>:child_id}, :function_name=>:spgt_touch2)
365
526
  DB[:parents] << {:id1=>1, :child_id=>1, :changed_on=>Date.today - 30}
366
527
  DB[:children] << {:id=>1, :parent_id1=>1, :changed_on=>Date.today - 30}
367
528
  DB[:parents].get(:changed_on).strftime('%F').must_equal Date.today.strftime('%F')
@@ -380,7 +541,7 @@ describe "PostgreSQL Triggers" do
380
541
  end
381
542
 
382
543
  it "Should update the timestamp on the related table if that timestamp is initially NULL" do
383
- DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
544
+ DB.pgt_touch(:children, :parents, :changed_on, {:id1=>:parent_id1}, :function_name=>:spgt_touch)
384
545
  DB[:parents] << {:id1=>1, :changed_on=>nil}
385
546
  DB[:children] << {:id=>1, :parent_id1=>1}
386
547
  changed_on = DB[:parents].get(:changed_on)
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.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-28 00:00:00.000000000 Z
11
+ date: 2017-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -63,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
63
  version: '0'
64
64
  requirements: []
65
65
  rubyforge_project:
66
- rubygems_version: 2.5.1
66
+ rubygems_version: 2.6.11
67
67
  signing_key:
68
68
  specification_version: 4
69
69
  summary: Database enforced timestamps, immutable columns, counter/sum caches, and