Skip to content

Commit 485ff3b

Browse files
committed
Add pgt_force_defaults method for forcing default values during inserts
1 parent 4f5304d commit 485ff3b

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

README.rdoc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,21 @@ Options:
198198
:referenced_function_name :: function name for trigger function on referenced table
199199
:referenced_trigger_name :: trigger name for referenced table
200200

201+
=== Force Defaults - pgt_force_defaults
202+
203+
This takes 2 arguments, a table and a hash of column default values, and sets
204+
up an insert trigger that will override user submitted or database
205+
default values and use the values given when setting up the trigger.
206+
This is mostly useful in situations where multiple database accounts
207+
are used where one account has insert permissions but not update
208+
permissions, and you want to ensure that inserted rows have specific
209+
column values to enforce security requirements.
210+
211+
Arguments:
212+
table :: The name of the table
213+
defaults :: A hash of default values to enforce, where keys are column names
214+
and values are the default values to enforce
215+
201216
== License
202217

203218
This library is released under the MIT License. See the MIT-LICENSE

lib/sequel/extensions/pg_triggers.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ def pgt_created_at(table, column, opts={})
5151
SQL
5252
end
5353

54+
def pgt_force_defaults(table, defaults, opts={})
55+
cols = defaults.keys.sort.join('_')
56+
trigger_name = opts[:trigger_name] || "pgt_fd_#{cols}"
57+
function_name = opts[:function_name] || "pgt_fd_#{table}__#{cols}"
58+
lines = defaults.map do |column, v|
59+
"NEW.#{quote_identifier(column)} = #{literal(v)};"
60+
end
61+
pgt_trigger(table, trigger_name, function_name, [:insert], <<-SQL)
62+
BEGIN
63+
#{lines.join("\n")}
64+
RETURN NEW;
65+
END;
66+
SQL
67+
end
68+
5469
def pgt_immutable(table, *columns)
5570
opts = columns.last.is_a?(Hash) ? columns.pop : {}
5671
trigger_name = opts[:trigger_name] || "pgt_im_#{columns.join('__')}"

spec/sequel_postgresql_triggers_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,3 +584,26 @@
584584
DB[:accounts].delete
585585
end
586586
end
587+
588+
describe "PostgreSQL Force Defaults Trigger" do
589+
before do
590+
DB.create_table(:accounts){integer :id; integer :a, :default=>0; String :b; integer :c; integer :d, :default=>4}
591+
DB.pgt_force_defaults(:accounts, {:a=>1, :b=>"'\\a", :c=>nil}, :function_name=>:spgt_force_defaults)
592+
@ds = DB[:accounts]
593+
end
594+
595+
after do
596+
DB.drop_table(:accounts)
597+
DB.drop_function(:spgt_force_defaults)
598+
end
599+
600+
it "should override default values when inserting" do
601+
@ds.insert
602+
DB[:accounts].first.must_equal(:id=>nil, :a=>1, :b=>"'\\a", :c=>nil, :d=>4)
603+
604+
@ds.delete
605+
@ds.insert(:id=>10, :a=>11, :b=>12, :c=>13, :d=>14)
606+
DB[:accounts].first.must_equal(:id=>10, :a=>1, :b=>"'\\a", :c=>nil, :d=>14)
607+
end
608+
end
609+

0 commit comments

Comments
 (0)