Changes between Version 9 and Version 10 of DatabaseProgramming


Ignore:
Timestamp:
05/23/26 22:01:05 (2 days ago)
Author:
231028
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DatabaseProgramming

    v9 v10  
    399399$$;
    400400}}}
     401
     402{{{
     403create or replace procedure public_schema.finish_shift(
     404    in driver_id int4
     405)
     406    language plpgsql as
     407$$
     408declare
     409    num_of_shifts int4;
     410begin
     411    if not exists(select user_id from driver where user_id = driver_id) then
     412        raise exception 'Driver with id % does not exist', driver_id;
     413    end if;
     414
     415    num_of_shifts := (select count(*) from driver_vehicle where id_driver = driver_id and time_to is null);
     416
     417    if (num_of_shifts != 1) then
     418        raise exception 'Driver has not started a shift';
     419    end if;
     420
     421    update driver_vehicle
     422    set time_to=now()
     423    where id_driver = driver_id
     424      and time_to is null;
     425    commit;
     426end;
     427$$;
     428}}}
     429
     430{{{
     431create or replace procedure create_offer(
     432    request_id int4,
     433    dispatcher_user_id int4,
     434    driver_user_id int4,
     435    price numeric(19, 2),
     436    currency_catalog_id int4,
     437    eta timestamp,
     438    customer_user_id int4
     439)
     440    language plpgsql
     441AS
     442$$
     443begin
     444    if not exists(select * from request where request.id = request_id and request.status = 'pending') then
     445        raise exception 'Request with id % and pending status does not exist', request_id;
     446    end if;
     447    if price <= 0 then
     448        raise exception 'Price has to be greater than 0';
     449    end if;
     450    if eta <= now() then
     451        raise exception 'ETA cannot be lower than the time of creation';
     452    end if;
     453
     454    if (select company_id from employmenthistory where employee_user_id = dispatcher_user_id and end_date is null) !=
     455       (select company_id from employmenthistory where employee_user_id = driver_user_id and end_date is null) then
     456        raise exception 'Dispatcher and driver company mismatch';
     457    end if;
     458
     459    insert into offer(status, created_at, request_id, dispatcher_user_id, driver_user_id, price, currency_catalog_id,
     460                      eta, customer_user_id)
     461    values ('pending', now(), create_offer.request_id, create_offer.dispatcher_user_id, create_offer.driver_user_id,
     462            create_offer.price, create_offer.currency_catalog_id, create_offer.eta, create_offer.customer_user_id);
     463    commit;
     464end;
     465$$;
     466}}}
     467
     468{{{
     469create or replace procedure accept_offer(offer_id int4)
     470    language plpgsql
     471as
     472$$
     473declare
     474    request_id_proc int4;
     475begin
     476    if not exists(select * from offer where id = offer_id and status = 'pending') then
     477        raise exception 'Offer with id = % and pending status does not exist', offer_id;
     478    end if;
     479    request_id_proc := (select request_id from offer where id = offer_id);
     480    if not exists(select * from request where id = request_id_proc and status = 'pending') then
     481        raise exception 'The request for the given offer is not in pending status';
     482    end if;
     483    update offer set status = 'accepted' where id = offer_id;
     484    update offer set status = 'rejected' where id != offer_id and offer.request_id = request_id_proc;
     485    update request set status = 'accepted' where id = request_id_proc;
     486    commit;
     487end;
     488$$;
     489}}}
     490create or replace procedure public_schema.finish_shift(
     491    in driver_id int4
     492)
     493    language plpgsql as
     494$$
     495declare
     496    num_of_shifts int4;
     497begin
     498    if not exists(select user_id from driver where user_id = driver_id) then
     499        raise exception 'Driver with id % does not exist', driver_id;
     500    end if;
     501
     502    num_of_shifts := (select count(*) from driver_vehicle where id_driver = driver_id and time_to is null);
     503
     504    if (num_of_shifts != 1) then
     505        raise exception 'Driver has not started a shift';
     506    end if;
     507
     508    update driver_vehicle
     509    set time_to=now()
     510    where id_driver = driver_id
     511      and time_to is null;
     512    commit;
     513end;
     514$$;
     515{{{
    401516== Функции и тригери
     517
     518***Функција и тригер за проверка на достапност на возач***
     519
     520Функцијата ride_assign враќа тригер кој фрла исклучок во случај возачот да е зафатен со друго возење во моментот на доделување на возач. Тригерот се извршува пред внес на запис во табелата Ride.
     521
     522{{{
     523create or replace function ride_assign() returns trigger as
     524$ride_assign$
     525begin
     526    if exists(select * from ride where ride.status = 'in_progress' and ride.driver_user_id = NEW.driver_user_id) then
     527        raise exception 'Driver not free';
     528    end if;
     529    return NEW;
     530end;
     531$ride_assign$ language plpgsql;
     532
     533create trigger ride_assign before insert on ride
     534    for each row execute function ride_assign();
     535}}}
    402536
    403537{{{
     
    429563    for each row
    430564execute function check_active_shift();
     565}}}
     566
     567{{{
     568create or replace function prevent_price_manipulation()
     569    returns trigger as
     570$prevent_price_manipulation$
     571begin
     572    if OLD.status in ('accepted', 'completed') and NEW.price <> OLD.price then
     573        raise exception 'Price cannot be modified once the offer is accepted or completed. Current status: %', OLD.status;
     574    end if;
     575
     576    if NEW.price <= 0 then
     577        raise exception 'Price must be a positive value';
     578    end if;
     579
     580    return NEW;
     581end;
     582$prevent_price_manipulation$ language plpgsql;
    431583}}}
    432584
     
    531683execute function prevent_completed_offer_downgrade();
    532684}}}
    533 
     685{{{
     686create or replace function prevent_expired_license_ride()
     687    returns trigger as
     688$prevent_expired_license_ride$
     689declare
     690    exp_date date;
     691begin
     692    select dl.expire_date
     693    into exp_date
     694    from driver d
     695             join driverlicense dl on d.driver_license_id = dl.id
     696    where d.user_id = new.driver_user_id;
     697
     698    if exp_date is not null and exp_date < current_date then
     699        raise exception 'Driver license expired';
     700    end if;
     701
     702    return new;
     703end;
     704$prevent_expired_license_ride$ language plpgsql;
     705create or replace trigger prevent_expired_license_ride
     706    before insert
     707    on ride
     708    for each row
     709execute function prevent_expired_license_ride();
     710}}}
     711{{{
     712create or replace function enforce_offer_validity()
     713    returns trigger as
     714$enforce_offer_validity$
     715begin
     716    if OLD.status = 'pending' and NEW.status = 'accepted' then
     717      if (NOW() - OLD.created_at) > interval '5 minutes' then
     718            NEW.status := 'expired';
     719            raise notice 'Offer % has expired and cannot be accepted.', OLD.id;
     720            return NEW;
     721        end if;
     722    end if;
     723
     724    return NEW;
     725end;
     726$enforce_offer_validity$ language plpgsql;
     727
     728create trigger trg_enforce_offer_validity
     729    before update on offer
     730    for each row
     731    execute function enforce_offer_validity();
     732}}}