sequel_postgresql_triggers 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README +4 -3
- data/lib/sequel_postgresql_triggers.rb +4 -3
- data/spec/sequel_postgresql_triggers_spec.rb +28 -15
- metadata +22 -8
data/{LICENSE → MIT-LICENSE}
RENAMED
data/README
CHANGED
@@ -11,8 +11,8 @@ It handles these internally to the database via triggers, so even if
|
|
11
11
|
other applications access the database (without using Sequel), things
|
12
12
|
will still work (unless the database superuser disables triggers).
|
13
13
|
|
14
|
-
To use any of these methods, you have to add
|
15
|
-
language to PostgreSQL, which you can do with:
|
14
|
+
To use any of these methods before PostgreSQL 9.0, you have to add
|
15
|
+
the plpgsql procedural language to PostgreSQL, which you can do with:
|
16
16
|
|
17
17
|
DB.create_language(:plpgsql)
|
18
18
|
|
@@ -53,7 +53,8 @@ the value of any of the columns.
|
|
53
53
|
|
54
54
|
== License
|
55
55
|
|
56
|
-
This library is released under the MIT License. See the LICENSE
|
56
|
+
This library is released under the MIT License. See the MIT-LICENSE
|
57
|
+
file for details.
|
57
58
|
|
58
59
|
== Author
|
59
60
|
|
@@ -2,8 +2,9 @@ module Sequel
|
|
2
2
|
module Postgres
|
3
3
|
# Add the pgt_* methods so that any Sequel database connecting to PostgreSQL
|
4
4
|
# can use them. All of these methods require the plpgsql procedural language
|
5
|
-
# added to the PostgreSQL database before they can be used.
|
6
|
-
#
|
5
|
+
# be added to the PostgreSQL database before they can be used. On PostgreSQL
|
6
|
+
# 9.0 and later versions, it is installed by default. For older versions,
|
7
|
+
# you can install it with:
|
7
8
|
#
|
8
9
|
# DB.create_language(:plpgsql)
|
9
10
|
#
|
@@ -73,7 +74,7 @@ module Sequel
|
|
73
74
|
old = "OLD.#{quote_identifier(c)}"
|
74
75
|
new = "NEW.#{quote_identifier(c)}"
|
75
76
|
<<-END
|
76
|
-
IF #{new}
|
77
|
+
IF #{new} IS DISTINCT FROM #{old} THEN
|
77
78
|
RAISE EXCEPTION 'Attempted event_id update: Old: %, New: %', #{old}, #{new};
|
78
79
|
END IF;
|
79
80
|
END
|
@@ -2,14 +2,21 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'sequel'
|
4
4
|
|
5
|
-
DB = Sequel.connect(ENV['PGT_SPEC_DB']||'postgres:///spgt_test?user=
|
5
|
+
DB = Sequel.connect(ENV['PGT_SPEC_DB']||'postgres:///spgt_test?user=postgres')
|
6
6
|
|
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
|
+
|
10
18
|
context "PostgreSQL Counter Cache Trigger" do
|
11
19
|
before do
|
12
|
-
DB.create_language(:plpgsql)
|
13
20
|
DB.create_table(:accounts){integer :id; integer :num_entries, :default=>0}
|
14
21
|
DB.create_table(:entries){integer :id; integer :account_id}
|
15
22
|
DB.pgt_counter_cache(:accounts, :id, :num_entries, :entries, :account_id)
|
@@ -19,7 +26,6 @@ context "PostgreSQL Counter Cache Trigger" do
|
|
19
26
|
|
20
27
|
after do
|
21
28
|
DB.drop_table(:entries, :accounts)
|
22
|
-
DB.drop_language(:plpgsql, :cascade=>true)
|
23
29
|
end
|
24
30
|
|
25
31
|
specify "Should modify counter cache when adding or removing records" do
|
@@ -45,14 +51,12 @@ end
|
|
45
51
|
|
46
52
|
context "PostgreSQL Created At Trigger" do
|
47
53
|
before do
|
48
|
-
DB.create_language(:plpgsql)
|
49
54
|
DB.create_table(:accounts){integer :id; timestamp :added_on}
|
50
55
|
DB.pgt_created_at(:accounts, :added_on)
|
51
56
|
end
|
52
57
|
|
53
58
|
after do
|
54
59
|
DB.drop_table(:accounts)
|
55
|
-
DB.drop_language(:plpgsql, :cascade=>true)
|
56
60
|
end
|
57
61
|
|
58
62
|
specify "Should set the column upon insertion and ignore modifications afterward" do
|
@@ -71,7 +75,6 @@ end
|
|
71
75
|
|
72
76
|
context "PostgreSQL Immutable Trigger" do
|
73
77
|
before do
|
74
|
-
DB.create_language(:plpgsql)
|
75
78
|
DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
|
76
79
|
DB.pgt_immutable(:accounts, :balance)
|
77
80
|
DB[:accounts] << {:id=>1}
|
@@ -79,20 +82,32 @@ context "PostgreSQL Immutable Trigger" do
|
|
79
82
|
|
80
83
|
after do
|
81
84
|
DB.drop_table(:accounts)
|
82
|
-
DB.drop_language(:plpgsql, :cascade=>true)
|
83
85
|
end
|
84
86
|
|
85
|
-
specify "Should allow
|
86
|
-
DB[:accounts].update(:id=>
|
87
|
-
|
88
|
-
|
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
|
89
97
|
proc{DB[:accounts].update(:balance=>1)}.should raise_error(Sequel::DatabaseError)
|
90
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
|
91
107
|
end
|
92
108
|
|
93
109
|
context "PostgreSQL Sum Cache Trigger" do
|
94
110
|
before do
|
95
|
-
DB.create_language(:plpgsql)
|
96
111
|
DB.create_table(:accounts){integer :id; integer :balance, :default=>0}
|
97
112
|
DB.create_table(:entries){integer :id; integer :account_id; integer :amount}
|
98
113
|
DB.pgt_sum_cache(:accounts, :id, :balance, :entries, :account_id, :amount)
|
@@ -102,7 +117,6 @@ context "PostgreSQL Sum Cache Trigger" do
|
|
102
117
|
|
103
118
|
after do
|
104
119
|
DB.drop_table(:entries, :accounts)
|
105
|
-
DB.drop_language(:plpgsql, :cascade=>true)
|
106
120
|
end
|
107
121
|
|
108
122
|
specify "Should modify sum cache when adding, updating, or removing records" do
|
@@ -131,14 +145,12 @@ end
|
|
131
145
|
|
132
146
|
context "PostgreSQL Updated At Trigger" do
|
133
147
|
before do
|
134
|
-
DB.create_language(:plpgsql)
|
135
148
|
DB.create_table(:accounts){integer :id; timestamp :changed_on}
|
136
149
|
DB.pgt_updated_at(:accounts, :changed_on)
|
137
150
|
end
|
138
151
|
|
139
152
|
after do
|
140
153
|
DB.drop_table(:accounts)
|
141
|
-
DB.drop_language(:plpgsql, :cascade=>true)
|
142
154
|
end
|
143
155
|
|
144
156
|
specify "Should set the column always to the current timestamp" do
|
@@ -152,3 +164,4 @@ context "PostgreSQL Updated At Trigger" do
|
|
152
164
|
DB[:accounts].select((Sequel::SQL::NumericExpression.new(:NOOP, ds.filter(:id=>3)) > ds.filter(:id=>2)).as(:x)).first[:x].should == true
|
153
165
|
end
|
154
166
|
end
|
167
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_postgresql_triggers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 3
|
10
|
+
version: 1.0.3
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Jeremy Evans
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-03-23 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -23,11 +29,13 @@ extra_rdoc_files: []
|
|
23
29
|
|
24
30
|
files:
|
25
31
|
- README
|
26
|
-
- LICENSE
|
32
|
+
- MIT-LICENSE
|
27
33
|
- lib/sequel_postgresql_triggers.rb
|
28
34
|
- spec/sequel_postgresql_triggers_spec.rb
|
29
35
|
has_rdoc: true
|
30
36
|
homepage:
|
37
|
+
licenses: []
|
38
|
+
|
31
39
|
post_install_message:
|
32
40
|
rdoc_options:
|
33
41
|
- --inline-source
|
@@ -35,28 +43,34 @@ rdoc_options:
|
|
35
43
|
- --title
|
36
44
|
- "Sequel PostgreSQL Triggers: Database enforced timestamps, immutable columns, and counter/sum caches"
|
37
45
|
- README
|
38
|
-
- LICENSE
|
46
|
+
- MIT-LICENSE
|
39
47
|
- lib
|
40
48
|
require_paths:
|
41
49
|
- lib
|
42
50
|
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
43
52
|
requirements:
|
44
53
|
- - ">="
|
45
54
|
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
46
58
|
version: "0"
|
47
|
-
version:
|
48
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
49
61
|
requirements:
|
50
62
|
- - ">="
|
51
63
|
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
52
67
|
version: "0"
|
53
|
-
version:
|
54
68
|
requirements: []
|
55
69
|
|
56
70
|
rubyforge_project:
|
57
|
-
rubygems_version: 1.3.
|
71
|
+
rubygems_version: 1.3.7
|
58
72
|
signing_key:
|
59
|
-
specification_version:
|
73
|
+
specification_version: 3
|
60
74
|
summary: Database enforced timestamps, immutable columns, and counter/sum caches
|
61
75
|
test_files: []
|
62
76
|
|