ืืื ืึท ืืขืจืืึทื ื ืฆื
ืื ืืขืึธืจืขืืืฉ ืืืื ืืื ืืขืืื ื ืืืกืงืจืืืื ืืื ืื ืืึทืงืืืืขื ืืืืฉืึทื
ืขืก ืืื ืืึธืจื ืืฉื ื ืืึท ืืื ืืขื ืึทืจืืืงื, ืขืก ืืื ืงืืื ืคืึทืจืืึธืจืื ืืืึทืืฉ ืึธืืขืจ ืกืื ืืืืกื. ื ืึธืจ ืึท ืกืงืืฆืข ืืืขืื ืื ืคึผืจืึทืงืืืฉ ืืืคึผืืึทืืขื ืืืืฉืึทื ืคืื ืึท ืืขืึธืจืขืืืฉ ืืขืืึทื ืง. ืืืื ืืืื ืขืจ ืืื ืืื ืืขืจืขืกืืจื, ืืืืขื ืขื ืขืก. ืืืื ืืืจ ืืขื ื ื ืืฉื ืืื ืืขืจืขืกืืจื, ืืึธื ื ืื ืืืืกื ืืืื ืฆืืื.
ืืืกืืึธืืื ื ืคืื ืื ืคึผืจืึธืืืขื
ืึธื ืืืืืืื ื ืืืคึผืื ืืื ืื ืื ืืขืจืืขื ืืง ืืขืื ื, ืืขืงืืฆืขืจ, ืื ืคึผืจืึธืืืขื ืงืขื ืขื ืืืื ืคืืจืืืืืจื ืืื ืืืื: ืขืก ืืื ืึท ืืืฉ ืืืึธืก ืืืคึผืืึทืืึทื ืฅ ืึท ืืืืขืจ ืืขืฉืขืคื ืขื ืืืื. ืจืึธืื ืืื ืื ืืืฉ ืงืขื ืขื ืืืื ืืืืกืืขืืขืงื, ืึธืืขืจ ืจืึธืื ืงืขื ืขื ื ืื ืืืื ืคืืืืงืื ืืืืกืืขืืขืงื; ืืื ืืืื ืืืื ืคืึทืจืืึธืจืื.
ืคึฟืึทืจ ืขืก ืืื ืืขืืืื: "ืื ืืืืกื ื ืืฉื ืืืกืืขืงื ืขืคึผืขืก, ื ืึธืจ ืจืขื ืึทืืข ืขืก. ืื ืืื ืืขืจื ืขื ืกืืึธืจื ืึทืืฅ"
ืืืืฃ ืืขื ืืืขื, ืขืก ืืื ืงืขืืืึทืืง ื ืืฉื ืฆื ืจืืจืืื ืื ืืืืืกืืื ื ืกืืึธืจื ืคืึทื ืืงืฉืึทื ื ืืืึธืก ืึทืจืืขื ืืื ืืขื ืขื ืืืื.
ืฆื ืื ืกืืจืืืขื ื ืืขื ืืึทืืจืืฃ, ืื ืืืฉ ืืื ืื ืึทืืจืืืืื ืืื_ืืขืืขืงื. ืืขืืึธืื ืึทืืฅ ืืื ืคึผืฉืื - ืืืจ ืืึทืจืคึฟื ืฆื ืืึทืื ืืืืขืจ ืึทื ืืขืจ ืงืืืขื ื ืงืขื ืขื ืืขื ืืืืื ืื ืฉืืจืืช ืืื ืืืึธืก ืื ืึทืืจืืืืื ืืื_ืืขืืขืงื ืคืึทืืฉ ืืืึธืก ืืื ืื ืืขืงืึทื ืืืึทื ืืขื ืืฆื ืคึฟืึทืจ? ืจืืืขืจื ืืขืืืขื ืืืืขืจืืืึทื.
ืืืคึผืืขืืขื ืืึทืืืึธื
ืฉืึทืคึฟื ืึท ืืึทืืื ืืขืจ ืจืึธืืข ืืื ืกืืขืืข
CREATE ROLE repos;
CREATE SCHEMA repos;
ืฉืึทืคึฟื ืื ืฆืื ืืืฉ
CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos
ืฆืื ื ืื ืจืื ืืขืืืขื ืกืขืงืืจืืื
ALTER TABLE repos.file ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;
ืกืขืจืืืืก ืคึฟืื ืงืฆืืข โ ืืืืกืืขืงื ื ืจืื ืืื ืืืฉ
CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE
WHERE id = curr_id ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ืืขืฉืขืคื ืคึฟืื ืงืฆืืข โ ืืืืกืืขืงื ื ืืืงืืืขื ื
CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ืจืขืืืืืึทืื
ืืขืจ ืงืืืขื ื ืืืืืฅ ืืขื ืืึธืงืืืขื ื
SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );
ื ืึธื ืืืืืฉืึทื, ืืขืจ ืงืืืขื ื ืงืขื ื ืืฉื ืืขื ืืขื ืืึธืงืืืขื ื
SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)
ืืืขืจ ืืื ืื ืืึทืืึทืืืืก ืื ืืึธืงืืืขื ื ืืื ื ืืฉื ืืืืกืืขืืขืงื, ื ืึธืจ ืื ืึทืืจืืืืื ืืื ืืขืืืื ืืื_ืื
psql -d my_db
SELECT id, name , is_del FROM repos.file ;
id | name | is_del
--+---------+------------
1 | test_1 | t
(1 row)
ืืืึธืก ืืื ืืืึธืก ืืื ืคืืจืืื ืื ืืื ืื ืคึผืจืึธืืืขื ืืขืจืงืืขืจืื ื.
ืืึทื ืฅ
ืืืื ืื ืืขืืข ืืื ืืฉืืงืึทืืืข, ืืื ืืขืจ ืืืืึทืืขืจ ืืขืจื ืขื ืืืจ ืงืขื ืขื ืืืืึทืื ืึท ืืืืฉืคึผืื ืคืื ืืืคึผืืึทืืขื ืื ื ืึท ืจืึธืืข-ืืืืืจื ืืึธืืขื ืคึฟืึทืจ ืกืขืคึผืขืจืืืืื ื ืืึทืื ืึทืงืกืขืก ื ืืฆื Row Level Security.
ืืงืืจ: www.habr.com