sequel_postgresql_triggers 1.2.0 → 1.3.0

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: 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