ืžื—ืงืจ ืขืœ ื”ื˜ืžืขืช ืื‘ื˜ื—ื” ื‘ืจืžืช ืฉื•ืจื” ื‘-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)

ืื‘ืœ ื‘ืžืกื“ ื”ื ืชื•ื ื™ื ื”ืžืกืžืš ืœื ื ืžื—ืง, ืจืง ื”ืชื›ื•ื ื” ืžืฉืชื ื” is_del

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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”