sequel_postgresql_triggers 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 125a5f23b1a05c7b989bd9bac3b9e4569f85af55
4
+ data.tar.gz: 24a4466e9bb4c91ec25238d56a3027e3091c684d
5
+ SHA512:
6
+ metadata.gz: 7507b30166920a252b7c583828bb41e0a55531d9a58a9fcbea7e5aca24daad079b80d2e8fe2f9e65d146cf3c720f6b62ec6a2c373e494939ea4d3e9685a73cf4
7
+ data.tar.gz: 390410edef60b9930572664d41e94e1356b4959f205ad7389067bbf7d92f6dada7a89b1b475c403abdc228dc4b997c7ec8e2277994289fff64d5f4679ae8defa
data/README CHANGED
@@ -51,6 +51,12 @@ This takes a table name and one or more column names, and adds
51
51
  an update trigger that raises an exception if you try to modify
52
52
  the value of any of the columns.
53
53
 
54
+ === Touch Propagation - pgt_touch
55
+
56
+ This takes several arguments (again, see the RDoc) and sets up a
57
+ trigger that watches one table for changes, and touches timestamps
58
+ of related rows in a separate table.
59
+
54
60
  == License
55
61
 
56
62
  This library is released under the MIT License. See the MIT-LICENSE
@@ -110,6 +110,33 @@ module Sequel
110
110
  END;
111
111
  SQL
112
112
  end
113
+
114
+ # When rows in a table are updated, touches a timestamp of related rows
115
+ # in another table.
116
+ # Arguments:
117
+ # * main_table : name of table that is being watched for changes
118
+ # * touch_table : name of table that needs to be touched
119
+ # * column : name of timestamp column to be touched
120
+ # * expr : hash or array that represents the columns that define the relationship
121
+ # * opts : option hash, see module documentation
122
+ def pgt_touch(main_table, touch_table, column, expr, opts={})
123
+ trigger_name = opts[:trigger_name] || "pgt_t_#{main_table}__#{touch_table}"
124
+ 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 ")}
126
+ sql = <<-SQL
127
+ 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;
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;
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;
134
+ END IF;
135
+ RETURN NULL;
136
+ END;
137
+ SQL
138
+ pgt_trigger(main_table, trigger_name, function_name, [:insert, :delete, :update], sql, :after=>true)
139
+ end
113
140
 
114
141
  # Turns a column in the table into a updated at timestamp column, which
115
142
  # always contains the timestamp the record was inserted or last updated.
@@ -132,9 +159,9 @@ module Sequel
132
159
 
133
160
  # Add or replace a function that returns trigger to handle the action,
134
161
  # and add a trigger that calls the function.
135
- def pgt_trigger(table, trigger_name, function_name, events, definition)
162
+ def pgt_trigger(table, trigger_name, function_name, events, definition, opts={})
136
163
  create_function(function_name, definition, :language=>:plpgsql, :returns=>:trigger, :replace=>true)
137
- create_trigger(table, trigger_name, function_name, :events=>events, :each_row=>true)
164
+ create_trigger(table, trigger_name, function_name, :events=>events, :each_row=>true, :after=>opts[:after])
138
165
  end
139
166
  end
140
167
  end
@@ -7,161 +7,218 @@ DB = Sequel.connect(ENV['PGT_SPEC_DB']||'postgres:///spgt_test?user=postgres')
7
7
  $:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib'))
8
8
  require 'sequel_postgresql_triggers'
9
9
 
10
- context "PostgreSQL Triggers" do
11
- before do
12
- DB.create_language(:plpgsql) if DB.server_version < 90000
13
- end
14
- after do
15
- DB.drop_language(:plpgsql, :cascade=>true) if DB.server_version < 90000
16
- end
17
-
18
- context "PostgreSQL Counter Cache Trigger" do
10
+ describe "PostgreSQL Triggers" do
19
11
  before do
20
- DB.create_table(:accounts){integer :id; integer :num_entries, :default=>0}
21
- DB.create_table(:entries){integer :id; integer :account_id}
22
- DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id)
23
- DB[:accounts] << {:id=>1}
24
- DB[:accounts] << {:id=>2}
12
+ DB.create_language(:plpgsql) if DB.server_version < 90000
25
13
  end
26
-
27
- after do
28
- DB.drop_table(:entries, :accounts)
29
- end
30
-
31
- specify "Should modify counter cache when adding or removing records" do
32
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
33
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
34
- DB[:entries] << {:id=>1, :account_id=>1}
35
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
36
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
37
- DB[:entries] << {:id=>2, :account_id=>1}
38
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
39
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
40
- DB[:entries] << {:id=>3, :account_id=>2}
41
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
42
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
43
- DB[:entries].filter(:id=>2).delete
44
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
45
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
46
- DB[:entries].delete
47
- DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
48
- DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
49
- end
50
- end
51
-
52
- context "PostgreSQL Created At Trigger" do
53
- before do
54
- DB.create_table(:accounts){integer :id; timestamp :added_on}
55
- DB.pgt_created_at(:accounts, :added_on)
56
- end
57
-
58
14
  after do
59
- DB.drop_table(:accounts)
15
+ DB.drop_language(:plpgsql, :cascade=>true) if DB.server_version < 90000
16
+ end
17
+
18
+ context "PostgreSQL Counter Cache Trigger" do
19
+ before do
20
+ DB.create_table(:accounts){integer :id; integer :num_entries, :default=>0}
21
+ DB.create_table(:entries){integer :id; integer :account_id}
22
+ DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id)
23
+ DB[:accounts] << {:id=>1}
24
+ DB[:accounts] << {:id=>2}
25
+ end
26
+
27
+ after do
28
+ DB.drop_table(:entries, :accounts)
29
+ end
30
+
31
+ specify "Should modify counter cache when adding or removing records" do
32
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
33
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
34
+ DB[:entries] << {:id=>1, :account_id=>1}
35
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
36
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
37
+ DB[:entries] << {:id=>2, :account_id=>1}
38
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
39
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
40
+ DB[:entries] << {:id=>3, :account_id=>2}
41
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 2
42
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
43
+ DB[:entries].filter(:id=>2).delete
44
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 1
45
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 1
46
+ DB[:entries].delete
47
+ DB[:accounts].filter(:id=>1).get(:num_entries).should == 0
48
+ DB[:accounts].filter(:id=>2).get(:num_entries).should == 0
49
+ end
50
+ end
51
+
52
+ context "PostgreSQL Created At Trigger" do
53
+ before do
54
+ DB.create_table(:accounts){integer :id; timestamp :added_on}
55
+ DB.pgt_created_at(:accounts, :added_on)
56
+ end
57
+
58
+ after do
59
+ DB.drop_table(:accounts)
60
+ end
61
+
62
+ specify "Should set the column upon insertion and ignore modifications afterward" do
63
+ DB[:accounts] << {:id=>1}
64
+ t = DB[:accounts].get(:added_on)
65
+ t.strftime('%F').should == Date.today.strftime('%F')
66
+ DB[:accounts].update(:added_on=>Date.today - 60)
67
+ DB[:accounts].get(:added_on).should == t
68
+ DB[:accounts] << {:id=>2}
69
+ ds = DB[:accounts].select(:added_on)
70
+ DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
71
+ DB[:accounts].filter(:id=>1).update(:id=>3)
72
+ DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>3)).as(:x)).first[:x].should == true
73
+ end
74
+ end
75
+
76
+ context "PostgreSQL Immutable Trigger" do
77
+ before do
78
+ DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
79
+ DB.pgt_immutable(:accounts, :balance)
80
+ DB[:accounts] << {:id=>1}
81
+ end
82
+
83
+ after do
84
+ DB.drop_table(:accounts)
85
+ end
86
+
87
+ specify "Should allow modifying columns not marked as immutable" do
88
+ proc{DB[:accounts].update(:id=>2)}.should_not raise_error
89
+ end
90
+
91
+ specify "Should allow updating a column to its existing value" do
92
+ proc{DB[:accounts].update(:balance=>0)}.should_not raise_error
93
+ proc{DB[:accounts].update(:balance=>Sequel.*(:balance, :balance))}.should_not raise_error
94
+ end
95
+
96
+ specify "Should not allow modifying a column's value" do
97
+ proc{DB[:accounts].update(:balance=>1)}.should raise_error(Sequel::DatabaseError)
98
+ end
99
+
100
+ specify "Should handle NULL values correctly" do
101
+ proc{DB[:accounts].update(:balance=>nil)}.should raise_error(Sequel::DatabaseError)
102
+ DB[:accounts].delete
103
+ DB[:accounts] << {:id=>1, :balance=>nil}
104
+ proc{DB[:accounts].update(:balance=>nil)}.should_not raise_error
105
+ proc{DB[:accounts].update(:balance=>0)}.should raise_error(Sequel::DatabaseError)
106
+ end
107
+ end
108
+
109
+ context "PostgreSQL Sum Cache Trigger" do
110
+ before do
111
+ DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
112
+ DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
113
+ DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount)
114
+ DB[:accounts] << {:id=>1}
115
+ DB[:accounts] << {:id=>2}
116
+ end
117
+
118
+ after do
119
+ DB.drop_table(:entries, :accounts)
120
+ end
121
+
122
+ specify "Should modify sum cache when adding, updating, or removing records" do
123
+ DB[:accounts].filter(:id=>1).get(:balance).should == 0
124
+ DB[:accounts].filter(:id=>2).get(:balance).should == 0
125
+ DB[:entries] << {:id=>1, :account_id=>1, :amount=>100}
126
+ DB[:accounts].filter(:id=>1).get(:balance).should == 100
127
+ DB[:accounts].filter(:id=>2).get(:balance).should == 0
128
+ DB[:entries] << {:id=>2, :account_id=>1, :amount=>200}
129
+ DB[:accounts].filter(:id=>1).get(:balance).should == 300
130
+ DB[:accounts].filter(:id=>2).get(:balance).should == 0
131
+ DB[:entries] << {:id=>3, :account_id=>2, :amount=>500}
132
+ DB[:accounts].filter(:id=>1).get(:balance).should == 300
133
+ DB[:accounts].filter(:id=>2).get(:balance).should == 500
134
+ DB[:entries].exclude(:id=>2).update(:amount=>Sequel.*(:amount, 2))
135
+ DB[:accounts].filter(:id=>1).get(:balance).should == 400
136
+ DB[:accounts].filter(:id=>2).get(:balance).should == 1000
137
+ DB[:entries].filter(:id=>2).delete
138
+ DB[:accounts].filter(:id=>1).get(:balance).should == 200
139
+ DB[:accounts].filter(:id=>2).get(:balance).should == 1000
140
+ DB[:entries].delete
141
+ DB[:accounts].filter(:id=>1).get(:balance).should == 0
142
+ DB[:accounts].filter(:id=>2).get(:balance).should == 0
143
+ end
144
+ end
145
+
146
+ context "PostgreSQL Updated At Trigger" do
147
+ before do
148
+ DB.create_table(:accounts){integer :id; timestamp :changed_on}
149
+ DB.pgt_updated_at(:accounts, :changed_on)
150
+ end
151
+
152
+ after do
153
+ DB.drop_table(:accounts)
154
+ end
155
+
156
+ specify "Should set the column always to the current timestamp" do
157
+ DB[:accounts] << {:id=>1}
158
+ t = DB[:accounts].get(:changed_on)
159
+ t.strftime('%F').should == Date.today.strftime('%F')
160
+ DB[:accounts] << {:id=>2}
161
+ ds = DB[:accounts].select(:changed_on)
162
+ DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
163
+ DB[:accounts].filter(:id=>1).update(:id=>3)
164
+ DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>3)) > ds.filter(:id=>2)).as(:x)).first[:x].should == true
165
+ end
166
+ end
167
+
168
+ context "PostgreSQL Touch Trigger" do
169
+ before do
170
+ DB.create_table(:parents){integer :id1; integer :id2; integer :child_id; timestamp :changed_on}
171
+ DB.create_table(:children){integer :id; integer :parent_id1; integer :parent_id2; timestamp :changed_on}
172
+ end
173
+
174
+ after do
175
+ DB.drop_table(:children, :parents)
176
+ end
177
+
178
+ specify "Should update the timestamp column of the related table when adding, updating or removing records" do
179
+ DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
180
+ DB[:parents] << {:id1=>1, :changed_on=>Date.today - 30}
181
+ 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)
184
+ 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)
187
+ DB[:children].delete
188
+ DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
189
+ end
190
+
191
+ specify "Should update the timestamp column of the related table when there is a composite foreign key" do
192
+ DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1, :id2=>:parent_id2)
193
+ DB[:parents] << {:id1=>1, :id2=>2, :changed_on=>Date.today - 30}
194
+ DB[:children] << {:id=>1, :parent_id1=>1, :parent_id2=>2}
195
+ DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
196
+ DB[:parents].update(:changed_on=>Date.today - 30)
197
+ DB[:children].update(:id=>2)
198
+ DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
199
+ DB[:parents].update(:changed_on=>Date.today - 30)
200
+ DB[:children].delete
201
+ DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
202
+ end
203
+
204
+ specify "Should update timestamps correctly when two tables touch each other" do
205
+ DB.pgt_touch(:children, :parents, :changed_on, :id1=>:parent_id1)
206
+ DB.pgt_touch(:parents, :children, :changed_on, :id=>:child_id)
207
+ DB[:parents] << {:id1=>1, :child_id=>1, :changed_on=>Date.today - 30}
208
+ DB[:children] << {:id=>1, :parent_id1=>1, :changed_on=>Date.today - 30}
209
+ DB[:parents].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
210
+ DB[:children].get(:changed_on).strftime('%F').should == Date.today.strftime('%F')
211
+ time = DB[:parents].get(:changed_on)
212
+ DB[:parents].update(:id2=>4)
213
+ DB[:parents].get(:changed_on).should > time
214
+ DB[:children].get(:changed_on).should > time
215
+ time = DB[:parents].get(:changed_on)
216
+ DB[:children].update(:id=>1)
217
+ DB[:parents].get(:changed_on).should > time
218
+ DB[:children].get(:changed_on).should > time
219
+ time = DB[:parents].get(:changed_on)
220
+ DB[:children].delete
221
+ DB[:parents].get(:changed_on).should > time
222
+ end
60
223
  end
61
-
62
- specify "Should set the column upon insertion and ignore modifications afterward" do
63
- DB[:accounts] << {:id=>1}
64
- t = DB[:accounts].get(:added_on)
65
- t.strftime('%F').should == Date.today.strftime('%F')
66
- DB[:accounts].update(:added_on=>Date.today - 60)
67
- DB[:accounts].get(:added_on).should == t
68
- DB[:accounts] << {:id=>2}
69
- ds = DB[:accounts].select(:added_on)
70
- DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
71
- DB[:accounts].filter(:id=>1).update(:id=>3)
72
- DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>3)).as(:x)).first[:x].should == true
73
- end
74
- end
75
-
76
- context "PostgreSQL Immutable Trigger" do
77
- before do
78
- DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
79
- DB.pgt_immutable(:accounts, :balance)
80
- DB[:accounts] << {:id=>1}
81
- end
82
-
83
- after do
84
- DB.drop_table(:accounts)
85
- end
86
-
87
- specify "Should allow modifying columns not marked as immutable" do
88
- proc{DB[:accounts].update(:id=>2)}.should_not raise_error
89
- end
90
-
91
- specify "Should allow updating a column to its existing value" do
92
- proc{DB[:accounts].update(:balance=>0)}.should_not raise_error
93
- proc{DB[:accounts].update(:balance=>:balance * :balance)}.should_not raise_error
94
- end
95
-
96
- specify "Should not allow modifying a column's value" do
97
- proc{DB[:accounts].update(:balance=>1)}.should raise_error(Sequel::DatabaseError)
98
- end
99
-
100
- specify "Should handle NULL values correctly" do
101
- proc{DB[:accounts].update(:balance=>nil)}.should raise_error(Sequel::DatabaseError)
102
- DB[:accounts].delete
103
- DB[:accounts] << {:id=>1, :balance=>nil}
104
- proc{DB[:accounts].update(:balance=>nil)}.should_not raise_error
105
- proc{DB[:accounts].update(:balance=>0)}.should raise_error(Sequel::DatabaseError)
106
- end
107
- end
108
-
109
- context "PostgreSQL Sum Cache Trigger" do
110
- before do
111
- DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
112
- DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
113
- DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount)
114
- DB[:accounts] << {:id=>1}
115
- DB[:accounts] << {:id=>2}
116
- end
117
-
118
- after do
119
- DB.drop_table(:entries, :accounts)
120
- end
121
-
122
- specify "Should modify sum cache when adding, updating, or removing records" do
123
- DB[:accounts].filter(:id=>1).get(:balance).should == 0
124
- DB[:accounts].filter(:id=>2).get(:balance).should == 0
125
- DB[:entries] << {:id=>1, :account_id=>1, :amount=>100}
126
- DB[:accounts].filter(:id=>1).get(:balance).should == 100
127
- DB[:accounts].filter(:id=>2).get(:balance).should == 0
128
- DB[:entries] << {:id=>2, :account_id=>1, :amount=>200}
129
- DB[:accounts].filter(:id=>1).get(:balance).should == 300
130
- DB[:accounts].filter(:id=>2).get(:balance).should == 0
131
- DB[:entries] << {:id=>3, :account_id=>2, :amount=>500}
132
- DB[:accounts].filter(:id=>1).get(:balance).should == 300
133
- DB[:accounts].filter(:id=>2).get(:balance).should == 500
134
- DB[:entries].exclude(:id=>2).update(:amount=>:amount * 2)
135
- DB[:accounts].filter(:id=>1).get(:balance).should == 400
136
- DB[:accounts].filter(:id=>2).get(:balance).should == 1000
137
- DB[:entries].filter(:id=>2).delete
138
- DB[:accounts].filter(:id=>1).get(:balance).should == 200
139
- DB[:accounts].filter(:id=>2).get(:balance).should == 1000
140
- DB[:entries].delete
141
- DB[:accounts].filter(:id=>1).get(:balance).should == 0
142
- DB[:accounts].filter(:id=>2).get(:balance).should == 0
143
- end
144
- end
145
-
146
- context "PostgreSQL Updated At Trigger" do
147
- before do
148
- DB.create_table(:accounts){integer :id; timestamp :changed_on}
149
- DB.pgt_updated_at(:accounts, :changed_on)
150
- end
151
-
152
- after do
153
- DB.drop_table(:accounts)
154
- end
155
-
156
- specify "Should set the column always to the current timestamp" do
157
- DB[:accounts] << {:id=>1}
158
- t = DB[:accounts].get(:changed_on)
159
- t.strftime('%F').should == Date.today.strftime('%F')
160
- DB[:accounts] << {:id=>2}
161
- ds = DB[:accounts].select(:changed_on)
162
- DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>2)) > ds.filter(:id=>1)).as(:x)).first[:x].should == true
163
- DB[:accounts].filter(:id=>1).update(:id=>3)
164
- DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>3)) > ds.filter(:id=>2)).as(:x)).first[:x].should == true
165
- end
166
- end
167
224
  end
metadata CHANGED
@@ -1,76 +1,69 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sequel_postgresql_triggers
3
- version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 3
10
- version: 1.0.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.4
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Jeremy Evans
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2011-03-23 00:00:00 -07:00
19
- default_executable:
20
- dependencies: []
21
-
11
+ date: 2013-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
22
27
  description:
23
28
  email: code@jeremyevans.net
24
29
  executables: []
25
-
26
30
  extensions: []
27
-
28
31
  extra_rdoc_files: []
29
-
30
- files:
32
+ files:
31
33
  - README
32
34
  - MIT-LICENSE
33
35
  - lib/sequel_postgresql_triggers.rb
34
36
  - spec/sequel_postgresql_triggers_spec.rb
35
- has_rdoc: true
36
- homepage:
37
- licenses: []
38
-
37
+ homepage: https://github.com/jeremyevans/sequel_postgresql_triggers
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
39
41
  post_install_message:
40
- rdoc_options:
42
+ rdoc_options:
41
43
  - --inline-source
42
44
  - --line-numbers
43
45
  - --title
44
- - "Sequel PostgreSQL Triggers: Database enforced timestamps, immutable columns, and counter/sum caches"
46
+ - 'Sequel PostgreSQL Triggers: Database enforced timestamps, immutable columns, and
47
+ counter/sum caches'
45
48
  - README
46
49
  - MIT-LICENSE
47
50
  - lib
48
- require_paths:
51
+ require_paths:
49
52
  - lib
50
- required_ruby_version: !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- hash: 3
56
- segments:
57
- - 0
58
- version: "0"
59
- required_rubygems_version: !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- hash: 3
65
- segments:
66
- - 0
67
- version: "0"
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
68
63
  requirements: []
69
-
70
64
  rubyforge_project:
71
- rubygems_version: 1.3.7
65
+ rubygems_version: 2.0.3
72
66
  signing_key:
73
- specification_version: 3
67
+ specification_version: 4
74
68
  summary: Database enforced timestamps, immutable columns, and counter/sum caches
75
69
  test_files: []
76
-