ื ืœืขืจื ืขืŸ ื•ื•ืขื’ืŸ ื™ืžืคึผืœืึทืžืขื ื™ื ื’ ืจืึธื•ื• ืœืขื•ื•ืขืœ ื–ื™ื›ืขืจื”ื™ื™ื˜ ืื™ืŸ PostgreSQL

ื•ื•ื™ ืึท ื“ืขืจื’ืึทื ื’ ืฆื• ื ืœืขืจื ืขืŸ ื•ื•ืขื’ืŸ ื™ืžืคึผืœืึทืžืขื ื™ื ื’ ื’ืขืฉืขืคื˜ ืœืึธื’ื™ืง ืื•ื™ืฃ ื“ืขืจ ืžื“ืจื’ื” ืคื•ืŸ PostgreSQL ืกื˜ืึธืจื“ ืคืึทื ื’ืงืฉืึทื ื– ะธ ื“ืขืจ ื”ื•ื™ืคึผื˜ ืคึฟืึทืจ ืึท ื“ื™ื˜ื™ื™ืœื“ ืขื ื˜ืคืขืจ ืื•ื™ืฃ ืงืึธืžืขื ื˜ืึทืจ.

ื“ื™ ื˜ืขืึธืจืขื˜ื™ืฉ ื˜ื™ื™ืœ ืื™ื– ื’ืขื–ื•ื ื˜ ื“ื™ืกืงืจื™ื™ื‘ื“ ืื™ืŸ ื“ื™ ื“ืึทืงื™ื•ืžืขื ื˜ื™ื™ืฉืึทืŸ PostgreSQL - ืจื•ื“ืขืจืŸ ืฉื•ืฅ ืคึผืึทืœืึทืกื™ื–. ื•ื ื˜ืขืจ ืื™ื– ืึท ืคึผืจืึทืงื˜ื™ืฉ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืคื•ืŸ ืึท ืงืœื™ื™ืŸ ืกืคึผืขืฆื™ืคื™ืฉ ื’ืขืฉืขืคื˜ ืึทืจื‘ืขื˜ - ื›ื™ื™ื“ื™ื ื’ ืื•ื™ืกื’ืขืžืขืงื˜ ื“ืึทื˜ืŸ. ืกืงื™ืฆืข ื“ืขื“ืึทืงื™ื™ื˜ืึทื“ ืฆื• ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืจืึธืœืข ืžืึธื“ืขืœื™ื ื’ ื ื™ืฆืŸ RLS ื“ืขืจืœืื ื’ื˜ ื‘ืึทื–ื•ื ื“ืขืจ.

ื ืœืขืจื ืขืŸ ื•ื•ืขื’ืŸ ื™ืžืคึผืœืึทืžืขื ื™ื ื’ ืจืึธื•ื• ืœืขื•ื•ืขืœ ื–ื™ื›ืขืจื”ื™ื™ื˜ ืื™ืŸ PostgreSQL

ืขืก ืื™ื– ื’ืึธืจื ื™ืฉื˜ ื ื™ื™ึท ืื™ืŸ ื“ืขื ืึทืจื˜ื™ืงืœ, ืขืก ืื™ื– ืงื™ื™ืŸ ืคืึทืจื‘ืึธืจื’ืŸ ื˜ื™ื™ึทื˜ืฉ ืึธื“ืขืจ ืกื•ื“ ื•ื•ื™ืกืŸ. ื ืึธืจ ืึท ืกืงื™ืฆืข ื•ื•ืขื’ืŸ ื“ื™ ืคึผืจืึทืงื˜ื™ืฉ ื™ืžืคึผืœืึทืžืขื ื˜ื™ื™ืฉืึทืŸ ืคื•ืŸ ืึท ื˜ืขืึธืจืขื˜ื™ืฉ ื’ืขื“ืึทื ืง. ืื•ื™ื‘ ืื™ื™ื ืขืจ ืื™ื– ืื™ื ื˜ืขืจืขืกื™ืจื˜, ืœื™ื™ืขื ืขืŸ ืขืก. ืื•ื™ื‘ ืื™ืจ ื–ืขื ื˜ ื ื™ืฉื˜ ืื™ื ื˜ืขืจืขืกื™ืจื˜, ื˜ืึธืŸ ื ื™ื˜ ื•ื•ื™ืกื˜ ื“ื™ื™ืŸ ืฆื™ื™ื˜.

ื•ื™ืกื–ืึธื’ื•ื ื’ ืคื•ืŸ ื“ื™ ืคึผืจืึธื‘ืœืขื

ืึธืŸ ื“ื™ื™ื•ื•ื™ื ื’ ื“ื™ืคึผืœื™ ืื™ืŸ ื“ื™ ื•ื ื˜ืขืจื˜ืขื ื™ืง ื’ืขื’ื ื˜, ื‘ืขืงื™ืฆืขืจ, ื“ื™ ืคึผืจืึธื‘ืœืขื ืงืขื ืขืŸ ื–ื™ื™ืŸ ืคืืจืžื•ืœื™ืจื˜ ื•ื•ื™ ื’ื™ื™ื˜: ืขืก ืื™ื– ืึท ื˜ื™ืฉ ื•ื•ืึธืก ื™ืžืคึผืœืึทืžืึทื ืฅ ืึท ื–ื™ื›ืขืจ ื’ืขืฉืขืคื˜ ืขื ื˜ื™ื˜ื™. ืจืึธื•ื– ืื™ืŸ ื“ื™ ื˜ื™ืฉ ืงืขื ืขืŸ ื–ื™ื™ืŸ ืื•ื™ืกื’ืขืžืขืงื˜, ืึธื‘ืขืจ ืจืึธื•ื– ืงืขื ืขืŸ ื ื™ื˜ ื–ื™ื™ืŸ ืคื™ื–ื™ืงืœื™ ืื•ื™ืกื’ืขืžืขืงื˜; ื–ื™ื™ ืžื•ื–ืŸ ื–ื™ื™ืŸ ืคืึทืจื‘ืึธืจื’ืŸ.

ืคึฟืึทืจ ืขืก ืื™ื– ื’ืขื–ืื’ื˜: "ื“ื• ื–ืืœืกื˜ ื ื™ืฉื˜ ื•ื™ืกืžืขืงืŸ ืขืคึผืขืก, ื ืึธืจ ืจืขื ืึทืžืข ืขืก. ื“ื™ ืื™ื ื˜ืขืจื ืขื˜ ืกื˜ืึธืจื– ืึทืœืฅ"

ืื•ื™ืฃ ื“ืขื ื•ื•ืขื’, ืขืก ืื™ื– ืงืขื“ื™ื™ึทื™ืง ื ื™ืฉื˜ ืฆื• ืจื™ืจื™ื™ื˜ ื“ื™ ื™ื’ื–ื™ืกื˜ื™ื ื’ ืกื˜ืึธืจื“ ืคืึทื ื’ืงืฉืึทื ื– ื•ื•ืึธืก ืึทืจื‘ืขื˜ ืžื™ื˜ ื“ืขื ืขื ื˜ื™ื˜ื™.

ืฆื• ื™ื ืกื˜ืจื•ืžืขื ื˜ ื“ืขื ื‘ืึทื’ืจื™ืฃ, ื“ื™ ื˜ื™ืฉ ื”ืื˜ ื“ื™ ืึทื˜ืจื™ื‘ื™ื•ื˜ ืื™ื–_ื’ืขืžืขืงื˜. ื“ืขืžืึธืœื˜ ืึทืœืฅ ืื™ื– ืคึผืฉื•ื˜ - ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืžืึทื›ืŸ ื–ื™ื›ืขืจ ืึทื– ื“ืขืจ ืงืœื™ืขื ื˜ ืงืขื ืขืŸ ื–ืขืŸ ื‘ืœื•ื™ื– ื“ื™ ืฉื•ืจื•ืช ืื™ืŸ ื•ื•ืึธืก ื“ื™ ืึทื˜ืจื™ื‘ื™ื•ื˜ ืื™ื–_ื’ืขืžืขืงื˜ ืคืึทืœืฉ ื•ื•ืึธืก ืื™ื– ื“ื™ ืžืขืงืึทื ื™ื–ืึทื ื’ืขื ื™ืฆื˜ ืคึฟืึทืจ? ืจื•ื“ืขืจืŸ ืœืขื•ื•ืขืœ ื–ื™ื›ืขืจื”ื™ื™ึทื˜.

ื™ืžืคึผืœืขืžืขื ื˜ืึทื˜ื™ืึธืŸ

ืฉืึทืคึฟืŸ ืึท ื‘ืึทื–ื•ื ื“ืขืจ ืจืึธืœืข ืื•ืŸ ืกื›ืขืžืข

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

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’