Changes between Version 5 and Version 6 of AdvancedApplicationDevelopment


Ignore:
Timestamp:
09/23/25 00:50:18 (9 hours ago)
Author:
225144
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedApplicationDevelopment

    v5 v6  
    1 == Транзакции
    2 === Прифаќање на пријава и зачувување на приложениот feedback
    3 {{{
    4 @Transactional
    5     public void accept(BBUser creator, Integer reqId) {
    6         ProjectRequests prReq = getRequestById(reqId);
    7         prReq.setStatus(Status.ACCEPTED);
    8 
    9         feedbackService.create(creator,FeedbackFor.P,prReq);
    10         projectService.addDeveloperToProject(prReq.getProject(), prReq.getCreator());
    11         prReqRepo.save(prReq);
    12     }
    13 }}}
    14 
    15 === Одбивање на пријава и зачувување на прилоѓениот feedback
    16 {{{
    17 @Transactional
    18     public void deny(Integer reqId, String desc, BBUser creator) {
    19         ProjectRequests prReq = getRequestById(reqId);
    20         prReq.setStatus(Status.DENIED);
    21         feedbackService.create(desc,creator,FeedbackFor.P,prReq);
    22         prReqRepo.save(prReq);
    23     }
    24 }}}
    25 
    26 === Ажурирање на постоечка улога
    27 {{{
    28 @Transactional
    29     public void updateRole(Integer id, AddRoleDTOEntities addRoleDTO) {
    30 
    31         ProjectRole existingRole = projectRoleRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("bad role id"));
    32         projectRolePermissionRepository.deleteAllByIdRole(existingRole);
    33 
    34         existingRole.setName(addRoleDTO.getName());
    35         existingRole.setOverrideType(addRoleDTO.getProjectResourcePermissionOverrideType().toString());
    36 
    37         projectRoleRepository.save(existingRole);
    38 
    39         List<ProjectRolePermission> newGlobalPermissions = mapGlobalsToProjectRolePermissions(existingRole, addRoleDTO.getGlobalPermissions());
    40         List<ProjectRolePermission> newPerResourcePermissions = mapPerResourceToProjectRolePermissions(existingRole,addRoleDTO.getPermissionsResourceWrappers());
    41         List<ProjectRolePermissionResourceOverride> resourceOverrides = mapToResourceOverrides(getResources(addRoleDTO.getPermissionsResourceWrappers()),newPerResourcePermissions);
    42 
    43 
    44         projectRolePermissionRepository.saveAll(newGlobalPermissions);
    45         projectRolePermissionRepository.saveAll(newPerResourcePermissions);
    46         projectRolePermissionResourceOverrideRepository.saveAll(resourceOverrides);
    47 
    48     }
    49 
    50 }}}
    51 === Додавање на нова улога во проект
    52 {{{
    53     @Transactional
    54     public void addRole(AddRoleDTOEntities addRoleDTO) {
    55         ProjectRole role = projectRoleRepository.save(
    56                 new ProjectRole(
    57                         addRoleDTO.getProject(),
    58                         addRoleDTO.getName(),
    59                         addRoleDTO.getProjectResourcePermissionOverrideType().toString()
    60                 )
    61         );
    62 
    63         List<ProjectRolePermission> entities = mapPerResourceToProjectRolePermissions(role, addRoleDTO.getPermissionsResourceWrappers());
    64         projectRolePermissionRepository.saveAll(mapGlobalsToProjectRolePermissions(role, addRoleDTO.getGlobalPermissions()));
    65         projectRolePermissionRepository.saveAll(entities);
    66         projectRolePermissionResourceOverrideRepository.saveAll(mapToResourceOverrides(
    67                 getResources(addRoleDTO.getPermissionsResourceWrappers()),
    68                 entities
    69         ));
    70 }}}
    71 {{{}}}
    72 
    73 
    74 
    75 
    76 
    77 
    78 
    79 == Тригери
    80 === Проверка дали даден топик имат уникатно име во парент threadот
    81 {{{
    82 CREATE OR REPLACE FUNCTION fn_validate_topic_title()
    83     RETURNS TRIGGER
    84     LANGUAGE plpgsql
    85 AS
    86 $$
    87 BEGIN
    88     IF new.title IN
    89        (SELECT title
    90         FROM topic_thread
    91                  AS t
    92         WHERE t.parent_id = new.parent_id
    93            OR (t.parent_id IS NULL AND new.parent_id IS NULL)
    94        )
    95     THEN
    96         RAISE EXCEPTION 'There already exists a topic with title % in parent topic with id %',new.title,new.parent_id;
    97     END IF;
    98     RETURN new;
    99 END;
    100 $$;
    101 }}}
    102 {{{
    103 CREATE OR REPLACE TRIGGER tr_check_topic_name --RADI
    104     BEFORE INSERT OR UPDATE
    105     ON topic_thread
    106     FOR EACH ROW
    107 EXECUTE FUNCTION fn_validate_topic_title();
    108 }}}
    109 
    110 === При креирање на топик, креаторот се внесува како модератор
    111 {{{
    112 CREATE OR REPLACE FUNCTION fn_insert_topics_creator_as_moderator()
    113     RETURNS TRIGGER
    114     LANGUAGE plpgsql
    115 AS
    116 $$
    117 DECLARE
    118     v_user_id INT;
    119 BEGIN
    120     SELECT v_topic_thread.user_id
    121     INTO v_user_id
    122     FROM v_topic_thread
    123     WHERE v_topic_thread.id = new.id;
    124     IF not check_if_user_exists_in('moderator', 'id', v_user_id::text) THEN
    125         INSERT INTO moderator values (v_user_id);
    126     END IF;
    127     INSERT INTO topic_threads_moderators(thread_id, user_id) VALUES (new.id, v_user_id);
    128     RETURN NEW;
    129 END
    130 $$;
    131 }}}
    132 {{{
    133 CREATE OR REPLACE TRIGGER tr_insert_topics_creator_as_moderator
    134     AFTER INSERT
    135     ON topic_thread
    136     FOR EACH ROW
    137 EXECUTE FUNCTION fn_insert_topics_creator_as_moderator();
    138 }}}
    139 
    140 === При бришење на topic, проверка дали модераторот сеуште модерира topicци
    141 {{{
    142 CREATE OR REPLACE FUNCTION fn_remove_orphan_moderator()
    143     RETURNS trigger
    144     LANGUAGE plpgsql
    145 AS $function$
    146 BEGIN
    147     IF not exists (
    148         select 1
    149         from topic_threads_moderators t
    150         where t.user_id = OLD.user_id
    151     )
    152     THEN
    153         DELETE FROM moderator where id=OLD.user_id;
    154     END IF;
    155     IF not exists (
    156         select 1
    157         from topic_threads_moderators t
    158         where t.thread_id = OLD.thread_id
    159     )
    160     THEN
    161         delete from discussion_thread where parent_id=OLD.thread_id;
    162         DELETE FROM topic_thread where id = OLD.thread_id;
    163 --      delete from thread where id =  OLD.thread_id;
    164     END IF;
    165     RETURN OLD;
    166 END;
    167 }}}
    168 
    169 {{{
    170 CREATE OR REPLACE TRIGGER tr_remove_orphan_moderator
    171     AFTER DELETE
    172     ON topic_threads_moderators
    173     FOR EACH ROW
    174 EXECUTE FUNCTION fn_remove_orphan_moderator();
    175 }}}
    176 
    177 === При креирање на проект, креаторот се внесува како PROJECT_OWNER
    178 {{{
    179 CREATE OR REPLACE FUNCTION fn_insert_project_manager()
    180     RETURNS TRIGGER
    181     LANGUAGE plpgsql
    182 AS
    183 $$
    184 DECLARE
    185     usrId      INT;
    186     new_project_id INT;
    187 BEGIN
    188     SELECT user_id, id
    189     into usrId,new_project_id
    190     FROM v_project_thread p
    191     WHERE NEW.id = p.id;
    192     IF not EXISTS(
    193         select 1
    194         from developer_associated_with_project dawp
    195         where dawp.project_id=new_project_id and dawp.developer_id=usrId
    196     ) THEN
    197         INSERT INTO developer_associated_with_project(project_id, developer_id, started_at)
    198         values (new_project_id, usrId, NOW());
    199     end if;
    200     IF not check_if_user_exists_in('project_manager', 'id', usrId::text) THEN
    201         INSERT INTO project_manager VALUES (usrId);
    202     end if;
    203     RETURN NEW;
    204 END
    205 $$;
    206 }}}
    207 
    208 {{{
    209 CREATE OR REPLACE TRIGGER tr_a_insert_project_manager --RADI
    210     AFTER INSERT
    211     ON project_thread
    212     FOR EACH ROW
    213 EXECUTE FUNCTION fn_insert_project_manager();
    214 }}}
    215 
    216 
    217 === Бришење на не користени тагови
    218 
    219 {{{
    220 create or replace function fn_delete_dangling_tags()
    221     RETURNS trigger
    222     LANGUAGE plpgsql
    223 AS $$
    224 BEGIN
    225     IF NOT EXISTS(select 1
    226                   from tag_threads
    227                   where tag_name = OLD.tag_name
    228                   group by tag_name) THEN
    229         delete from tag where name = OLD.tag_name;
    230     end if;
    231     RETURN OLD;
    232 END;
    233 $$;
    234 }}}
    235 
    236 {{{
    237 create or replace trigger tr_delete_dangling_tags
    238     after delete
    239     on tag_threads
    240     for each row
    241     execute function fn_delete_dangling_tags();
    242 }}}
    243 
    244 === Внесување на даден корисник како developer, откако ќе стани дел од даден проект
    245 {{{
    246 create or replace function fn_add_dev_if_not_exist()
    247     returns trigger
    248     language plpgsql
    249 as $$
    250 BEGIN
    251     IF NOT check_if_user_exists_in('developer','id',new.developer_id::text) THEN
    252         INSERT INTO developer values (NEW.developer_id);
    253     end if;
    254     RETURN new;
    255 end;
    256 $$;
    257 
    258 }}}
    259 
    260 {{{
    261 create or replace trigger tr_add_dev_if_not_exist
    262     before insert on developer_associated_with_project
    263     for each row
    264 execute function fn_add_dev_if_not_exist();
    265 }}}
    266 
    267 === Креирање на General канал, при креирање на даден проект
    268 {{{
    269 create or replace function fn_insert_general_for_project()
    270     returns trigger
    271     language plpgsql
    272 as $$
    273 DECLARE
    274     developer_id INT;
    275     project_resource_id INT;
    276 BEGIN
    277     select user_id
    278     into developer_id
    279     from thread t
    280     where t.id=NEW.id;
    281     insert into project_resource default values returning id into project_resource_id;
    282 
    283     insert into channel(name,description,project_id,developer_id,project_resource_id)
    284     values ('General','General',NEW.id,developer_id,project_resource_id);
    285 
    286     return new;
    287 end;
    288 $$;
    289 }}}
    290 
    291 {{{
    292 create or replace trigger tr_insert_general_for_project
    293     after insert on project_thread
    294     for each row
    295 execute function fn_insert_general_for_project();
    296 }}}
    297 
    298 === Сите 'pending' пријави за даден корисник стануваат 'accepted', при додавање на тој корисник во 'blacklist' листата.
    299 {{{
    300 CREATE OR REPLACE FUNCTION fn_change_status_on_pending_reports()
    301     RETURNS TRIGGER
    302     LANGUAGE plpgsql
    303 AS $$
    304 BEGIN
    305     RAISE NOTICE 'user_id: %, topic_id: %', NEW.user_id, NEW.topic_id;
    306 
    307 UPDATE submission
    308 SET status = 'ACCEPTED'
    309 WHERE id in (
    310     select id
    311     from report r
    312     where r.for_user_id = NEW.user_id and r.thread_id = NEW.topic_id
    313 );
    314 
    315 RETURN NEW;
    316 END;
    317 $$;
    318 }}}
    319 
    320 {{{
    321 CREATE OR REPLACE TRIGGER tr_change_status_on_pending_reports
    322     AFTER INSERT
    323     ON blacklisted_user
    324     FOR EACH ROW
    325 EXECUTE FUNCTION fn_change_status_on_pending_reports();
    326 }}}
    327 
    328 === Оневозможувено повторно додавање на корисник во 'blacklist' листата, доколку е веќе присутен на неа
    329 
    330 {{{
    331 create or replace function fn_add_blacklisted_user()
    332 RETURNS trigger
    333 LANGUAGE plpgsql
    334 AS $$
    335 BEGIN
    336         IF NOT EXISTS(
    337                 select 1
    338                 from blacklisted_user
    339                 where  topic_id = NEW.topic_id and user_id = NEW.user_id and end_date is NULL
    340         )
    341         THEN
    342                 RETURN NEW;
    343 END IF;
    344 RETURN NULL;
    345 END;
    346 $$;
    347 }}}
    348 
    349 {{{
    350 create or replace trigger tr_add_blacklisted_user
    351 before insert on blacklisted_user
    352 for each row
    353 execute function fn_add_blacklisted_user();
    354 }}}
    355 
    356 === Автоматско додавање на project_resource, при додавање на канал
    357 {{{
    358 create or replace function fn_add_project_resource()
    359     returns trigger
    360     language plpgsql
    361 as $$
    362 DECLARE
    363     project_resource_id INT;
    364 BEGIN
    365     insert into project_resource default values returning id into project_resource_id;
    366     new.project_resource_id := project_resource_id;
    367     return new;
    368 end;
    369 $$;
    370 }}}
    371 
    372 {{{
    373 create or replace trigger tr_add_project_resource_channel
    374     before insert
    375     on channel
    376     for each row
    377 execute function fn_add_project_resource();
    378 }}}
    379 
    3801== Погледи
    3812=== Поглед за прикажување на сите одговори на даден топик
     
    43455}}}
    43556
     57== Транзакции
     58=== Прифаќање на пријава и зачувување на приложениот feedback
     59{{{
     60@Transactional
     61    public void accept(BBUser creator, Integer reqId) {
     62        ProjectRequests prReq = getRequestById(reqId);
     63        prReq.setStatus(Status.ACCEPTED);
     64
     65        feedbackService.create(creator,FeedbackFor.P,prReq);
     66        projectService.addDeveloperToProject(prReq.getProject(), prReq.getCreator());
     67        prReqRepo.save(prReq);
     68    }
     69}}}
     70
     71=== Одбивање на пријава и зачувување на прилоѓениот feedback
     72{{{
     73@Transactional
     74    public void deny(Integer reqId, String desc, BBUser creator) {
     75        ProjectRequests prReq = getRequestById(reqId);
     76        prReq.setStatus(Status.DENIED);
     77        feedbackService.create(desc,creator,FeedbackFor.P,prReq);
     78        prReqRepo.save(prReq);
     79    }
     80}}}
     81
     82=== Ажурирање на постоечка улога
     83{{{
     84@Transactional
     85    public void updateRole(Integer id, AddRoleDTOEntities addRoleDTO) {
     86
     87        ProjectRole existingRole = projectRoleRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("bad role id"));
     88        projectRolePermissionRepository.deleteAllByIdRole(existingRole);
     89
     90        existingRole.setName(addRoleDTO.getName());
     91        existingRole.setOverrideType(addRoleDTO.getProjectResourcePermissionOverrideType().toString());
     92
     93        projectRoleRepository.save(existingRole);
     94
     95        List<ProjectRolePermission> newGlobalPermissions = mapGlobalsToProjectRolePermissions(existingRole, addRoleDTO.getGlobalPermissions());
     96        List<ProjectRolePermission> newPerResourcePermissions = mapPerResourceToProjectRolePermissions(existingRole,addRoleDTO.getPermissionsResourceWrappers());
     97        List<ProjectRolePermissionResourceOverride> resourceOverrides = mapToResourceOverrides(getResources(addRoleDTO.getPermissionsResourceWrappers()),newPerResourcePermissions);
     98
     99
     100        projectRolePermissionRepository.saveAll(newGlobalPermissions);
     101        projectRolePermissionRepository.saveAll(newPerResourcePermissions);
     102        projectRolePermissionResourceOverrideRepository.saveAll(resourceOverrides);
     103
     104    }
     105
     106}}}
     107=== Додавање на нова улога во проект
     108{{{
     109    @Transactional
     110    public void addRole(AddRoleDTOEntities addRoleDTO) {
     111        ProjectRole role = projectRoleRepository.save(
     112                new ProjectRole(
     113                        addRoleDTO.getProject(),
     114                        addRoleDTO.getName(),
     115                        addRoleDTO.getProjectResourcePermissionOverrideType().toString()
     116                )
     117        );
     118
     119        List<ProjectRolePermission> entities = mapPerResourceToProjectRolePermissions(role, addRoleDTO.getPermissionsResourceWrappers());
     120        projectRolePermissionRepository.saveAll(mapGlobalsToProjectRolePermissions(role, addRoleDTO.getGlobalPermissions()));
     121        projectRolePermissionRepository.saveAll(entities);
     122        projectRolePermissionResourceOverrideRepository.saveAll(mapToResourceOverrides(
     123                getResources(addRoleDTO.getPermissionsResourceWrappers()),
     124                entities
     125        ));
     126}}}
     127{{{}}}
     128
     129
     130
     131
     132
     133
     134
     135== Тригери
     136=== Проверка дали даден топик имат уникатно име во парент threadот
     137{{{
     138CREATE OR REPLACE FUNCTION fn_validate_topic_title()
     139    RETURNS TRIGGER
     140    LANGUAGE plpgsql
     141AS
     142$$
     143BEGIN
     144    IF new.title IN
     145       (SELECT title
     146        FROM topic_thread
     147                 AS t
     148        WHERE t.parent_id = new.parent_id
     149           OR (t.parent_id IS NULL AND new.parent_id IS NULL)
     150       )
     151    THEN
     152        RAISE EXCEPTION 'There already exists a topic with title % in parent topic with id %',new.title,new.parent_id;
     153    END IF;
     154    RETURN new;
     155END;
     156$$;
     157}}}
     158{{{
     159CREATE OR REPLACE TRIGGER tr_check_topic_name --RADI
     160    BEFORE INSERT OR UPDATE
     161    ON topic_thread
     162    FOR EACH ROW
     163EXECUTE FUNCTION fn_validate_topic_title();
     164}}}
     165
     166=== При креирање на топик, креаторот се внесува како модератор
     167{{{
     168CREATE OR REPLACE FUNCTION fn_insert_topics_creator_as_moderator()
     169    RETURNS TRIGGER
     170    LANGUAGE plpgsql
     171AS
     172$$
     173DECLARE
     174    v_user_id INT;
     175BEGIN
     176    SELECT v_topic_thread.user_id
     177    INTO v_user_id
     178    FROM v_topic_thread
     179    WHERE v_topic_thread.id = new.id;
     180    IF not check_if_user_exists_in('moderator', 'id', v_user_id::text) THEN
     181        INSERT INTO moderator values (v_user_id);
     182    END IF;
     183    INSERT INTO topic_threads_moderators(thread_id, user_id) VALUES (new.id, v_user_id);
     184    RETURN NEW;
     185END
     186$$;
     187}}}
     188{{{
     189CREATE OR REPLACE TRIGGER tr_insert_topics_creator_as_moderator
     190    AFTER INSERT
     191    ON topic_thread
     192    FOR EACH ROW
     193EXECUTE FUNCTION fn_insert_topics_creator_as_moderator();
     194}}}
     195
     196=== При бришење на topic, проверка дали модераторот сеуште модерира topicци
     197{{{
     198CREATE OR REPLACE FUNCTION fn_remove_orphan_moderator()
     199    RETURNS trigger
     200    LANGUAGE plpgsql
     201AS $function$
     202BEGIN
     203    IF not exists (
     204        select 1
     205        from topic_threads_moderators t
     206        where t.user_id = OLD.user_id
     207    )
     208    THEN
     209        DELETE FROM moderator where id=OLD.user_id;
     210    END IF;
     211    IF not exists (
     212        select 1
     213        from topic_threads_moderators t
     214        where t.thread_id = OLD.thread_id
     215    )
     216    THEN
     217        delete from discussion_thread where parent_id=OLD.thread_id;
     218        DELETE FROM topic_thread where id = OLD.thread_id;
     219--      delete from thread where id =  OLD.thread_id;
     220    END IF;
     221    RETURN OLD;
     222END;
     223}}}
     224
     225{{{
     226CREATE OR REPLACE TRIGGER tr_remove_orphan_moderator
     227    AFTER DELETE
     228    ON topic_threads_moderators
     229    FOR EACH ROW
     230EXECUTE FUNCTION fn_remove_orphan_moderator();
     231}}}
     232
     233=== При креирање на проект, креаторот се внесува како PROJECT_OWNER
     234{{{
     235CREATE OR REPLACE FUNCTION fn_insert_project_manager()
     236    RETURNS TRIGGER
     237    LANGUAGE plpgsql
     238AS
     239$$
     240DECLARE
     241    usrId      INT;
     242    new_project_id INT;
     243BEGIN
     244    SELECT user_id, id
     245    into usrId,new_project_id
     246    FROM v_project_thread p
     247    WHERE NEW.id = p.id;
     248    IF not EXISTS(
     249        select 1
     250        from developer_associated_with_project dawp
     251        where dawp.project_id=new_project_id and dawp.developer_id=usrId
     252    ) THEN
     253        INSERT INTO developer_associated_with_project(project_id, developer_id, started_at)
     254        values (new_project_id, usrId, NOW());
     255    end if;
     256    IF not check_if_user_exists_in('project_manager', 'id', usrId::text) THEN
     257        INSERT INTO project_manager VALUES (usrId);
     258    end if;
     259    RETURN NEW;
     260END
     261$$;
     262}}}
     263
     264{{{
     265CREATE OR REPLACE TRIGGER tr_a_insert_project_manager --RADI
     266    AFTER INSERT
     267    ON project_thread
     268    FOR EACH ROW
     269EXECUTE FUNCTION fn_insert_project_manager();
     270}}}
     271
     272
     273=== Бришење на не користени тагови
     274
     275{{{
     276create or replace function fn_delete_dangling_tags()
     277    RETURNS trigger
     278    LANGUAGE plpgsql
     279AS $$
     280BEGIN
     281    IF NOT EXISTS(select 1
     282                  from tag_threads
     283                  where tag_name = OLD.tag_name
     284                  group by tag_name) THEN
     285        delete from tag where name = OLD.tag_name;
     286    end if;
     287    RETURN OLD;
     288END;
     289$$;
     290}}}
     291
     292{{{
     293create or replace trigger tr_delete_dangling_tags
     294    after delete
     295    on tag_threads
     296    for each row
     297    execute function fn_delete_dangling_tags();
     298}}}
     299
     300=== Внесување на даден корисник како developer, откако ќе стани дел од даден проект
     301{{{
     302create or replace function fn_add_dev_if_not_exist()
     303    returns trigger
     304    language plpgsql
     305as $$
     306BEGIN
     307    IF NOT check_if_user_exists_in('developer','id',new.developer_id::text) THEN
     308        INSERT INTO developer values (NEW.developer_id);
     309    end if;
     310    RETURN new;
     311end;
     312$$;
     313
     314}}}
     315
     316{{{
     317create or replace trigger tr_add_dev_if_not_exist
     318    before insert on developer_associated_with_project
     319    for each row
     320execute function fn_add_dev_if_not_exist();
     321}}}
     322
     323=== Креирање на General канал, при креирање на даден проект
     324{{{
     325create or replace function fn_insert_general_for_project()
     326    returns trigger
     327    language plpgsql
     328as $$
     329DECLARE
     330    developer_id INT;
     331    project_resource_id INT;
     332BEGIN
     333    select user_id
     334    into developer_id
     335    from thread t
     336    where t.id=NEW.id;
     337    insert into project_resource default values returning id into project_resource_id;
     338
     339    insert into channel(name,description,project_id,developer_id,project_resource_id)
     340    values ('General','General',NEW.id,developer_id,project_resource_id);
     341
     342    return new;
     343end;
     344$$;
     345}}}
     346
     347{{{
     348create or replace trigger tr_insert_general_for_project
     349    after insert on project_thread
     350    for each row
     351execute function fn_insert_general_for_project();
     352}}}
     353
     354=== Сите 'pending' пријави за даден корисник стануваат 'accepted', при додавање на тој корисник во 'blacklist' листата.
     355{{{
     356CREATE OR REPLACE FUNCTION fn_change_status_on_pending_reports()
     357    RETURNS TRIGGER
     358    LANGUAGE plpgsql
     359AS $$
     360BEGIN
     361    RAISE NOTICE 'user_id: %, topic_id: %', NEW.user_id, NEW.topic_id;
     362
     363UPDATE submission
     364SET status = 'ACCEPTED'
     365WHERE id in (
     366    select id
     367    from report r
     368    where r.for_user_id = NEW.user_id and r.thread_id = NEW.topic_id
     369);
     370
     371RETURN NEW;
     372END;
     373$$;
     374}}}
     375
     376{{{
     377CREATE OR REPLACE TRIGGER tr_change_status_on_pending_reports
     378    AFTER INSERT
     379    ON blacklisted_user
     380    FOR EACH ROW
     381EXECUTE FUNCTION fn_change_status_on_pending_reports();
     382}}}
     383
     384=== Оневозможувено повторно додавање на корисник во 'blacklist' листата, доколку е веќе присутен на неа
     385
     386{{{
     387create or replace function fn_add_blacklisted_user()
     388RETURNS trigger
     389LANGUAGE plpgsql
     390AS $$
     391BEGIN
     392        IF NOT EXISTS(
     393                select 1
     394                from blacklisted_user
     395                where  topic_id = NEW.topic_id and user_id = NEW.user_id and end_date is NULL
     396        )
     397        THEN
     398                RETURN NEW;
     399END IF;
     400RETURN NULL;
     401END;
     402$$;
     403}}}
     404
     405{{{
     406create or replace trigger tr_add_blacklisted_user
     407before insert on blacklisted_user
     408for each row
     409execute function fn_add_blacklisted_user();
     410}}}
     411
     412=== Автоматско додавање на project_resource, при додавање на канал
     413{{{
     414create or replace function fn_add_project_resource()
     415    returns trigger
     416    language plpgsql
     417as $$
     418DECLARE
     419    project_resource_id INT;
     420BEGIN
     421    insert into project_resource default values returning id into project_resource_id;
     422    new.project_resource_id := project_resource_id;
     423    return new;
     424end;
     425$$;
     426}}}
     427
     428{{{
     429create or replace trigger tr_add_project_resource_channel
     430    before insert
     431    on channel
     432    for each row
     433execute function fn_add_project_resource();
     434}}}
     435
    436436== Индекси
    437437== Процедури