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 +4 -4
- data/MIT-LICENSE +1 -1
- data/lib/sequel_postgresql_triggers.rb +57 -22
- data/spec/sequel_postgresql_triggers_spec.rb +21 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5de693db244fa94aba445980a43f06ecdb91cb8
|
4
|
+
data.tar.gz: a0fb193ac3d11010daaace8c590eb5ab552bcdc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88098e2ec7f2e97e8ed193689fe12b7f7f631e28821869ef25955d19723df943742c8b2c0d594d0044cf068b6532e28682a09fa807412040c652b1974a7685e0
|
7
|
+
data.tar.gz: d7fdef313991baed60bf2c5efe719bde984a8484f007b88ad0b08ec3382b2a1ee0b207412413994361faef917d8079d64565177062c94dbf4507fcae8d13e88c
|
data/MIT-LICENSE
CHANGED
@@ -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
|
-
|
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.#{
|
66
|
+
NEW.#{col} := OLD.#{col};
|
56
67
|
ELSIF (TG_OP = 'INSERT') THEN
|
57
|
-
NEW.#{
|
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 =
|
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 = '
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
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
|
-
|
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].
|
183
|
-
|
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].
|
186
|
-
|
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].
|
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.
|
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-
|
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.
|
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
|