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.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2009 Jeremy Evans
1
+ Copyright (c) 2008-2011 Jeremy Evans
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
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 the plpgsql procedural
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 file for details.
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. You can do so
6
- # with:
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} != #{old} THEN
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=_postgresql')
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 updating a record only if the immutable column does not change" do
86
- DB[:accounts].update(:id=>1)
87
- DB[:accounts].update(:balance=>0)
88
- DB[:accounts].update(:balance=>:balance * :balance)
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
- version: 1.0.2
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: 2009-06-02 00:00:00 -07:00
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.1
71
+ rubygems_version: 1.3.7
58
72
  signing_key:
59
- specification_version: 2
73
+ specification_version: 3
60
74
  summary: Database enforced timestamps, immutable columns, and counter/sum caches
61
75
  test_files: []
62
76