internal/db: add set_once_columns function (#3117)
* internal/db: add set_once_columns function Also replace existing before_soft_delete_credential_vault_store function and trigger with the new function. * internal/db/schema: add note to replaced definitions
This commit is contained in:
1 parent
e4c656ae5d
commit
bc31892f29
4 files changed
+71
No files matched your search
@@ -67,6 +67,8 @@ begin;
|
||||
-- and an update contains a value for delete_time different from the current
|
||||
-- value, this trigger will raise an error with error code 23602 which is a
|
||||
-- class 23 integrity constraint violation: set_once_violation.
|
||||
--
|
||||
-- Deleted in 66/02_use_set_once_columns.up.sql
|
||||
create function before_soft_delete_credential_vault_store() returns trigger
|
||||
as $$
|
||||
begin
|
||||
@@ -83,6 +85,7 @@ begin;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- Replaced in 66/02_use_set_once_columns.up.sql
|
||||
create trigger before_soft_delete_credential_vault_store before update on credential_vault_store
|
||||
for each row execute procedure before_soft_delete_credential_vault_store();
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
|
||||
create function set_once_columns() returns trigger
|
||||
as $$
|
||||
declare
|
||||
col_name text;
|
||||
new_value text;
|
||||
old_value text;
|
||||
begin
|
||||
foreach col_name in array tg_argv loop
|
||||
execute format('SELECT $1.%I', col_name) into new_value using new;
|
||||
execute format('SELECT $1.%I', col_name) into old_value using old;
|
||||
if old_value is not null and new_value is distinct from old_value then
|
||||
raise exception 'set_once_violation: %.%', tg_table_name, col_name using
|
||||
errcode = '23602',
|
||||
schema = tg_table_schema,
|
||||
table = tg_table_name,
|
||||
column = col_name;
|
||||
end if;
|
||||
end loop;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function set_once_columns() is
|
||||
'set_once_columns asserts that a column cannot be updated after being set to a non-null value';
|
||||
|
||||
commit;
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
begin;
|
||||
|
||||
drop trigger before_soft_delete_credential_vault_store on credential_vault_store;
|
||||
drop function before_soft_delete_credential_vault_store;
|
||||
|
||||
create trigger set_once_columns before update on credential_vault_store
|
||||
for each row execute procedure set_once_columns('delete_time');
|
||||
|
||||
commit;
|
||||
@@ -0,0 +1,26 @@
|
||||
-- Copyright (c) HashiCorp, Inc.
|
||||
-- SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
-- credential_vault_store tests the credential_vault_store table
|
||||
|
||||
begin;
|
||||
|
||||
select plan(3);
|
||||
select wtt_load('widgets', 'iam', 'kms', 'auth', 'hosts', 'targets', 'credentials');
|
||||
|
||||
-- validate the setup data
|
||||
select is(count(*), 1::bigint) from credential_vault_store where public_id = 'vs_______cvs1';
|
||||
|
||||
prepare soft_delete_credential_vault_store as
|
||||
update credential_vault_store
|
||||
set delete_time = clock_timestamp() -- Can't use now() or current_timestamp since constant within transaction
|
||||
where public_id = 'vs_______cvs1';
|
||||
|
||||
-- First delete succeeds
|
||||
select lives_ok('soft_delete_credential_vault_store');
|
||||
-- Second delete fails because we can only set delete_time once
|
||||
select throws_ok('soft_delete_credential_vault_store', 'set_once_violation: credential_vault_store.delete_time', '23602');
|
||||
|
||||
select * from finish();
|
||||
|
||||
rollback;
|
||||
Reference in new issue
Block a user