Changes between Version 6 and Version 7 of DatabaseProgramming


Ignore:
Timestamp:
05/23/26 21:14:33 (2 days ago)
Author:
231028
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DatabaseProgramming

    v6 v7  
    55== Процедури
    66
     7{{{
     8create or replace procedure start_shift(
     9    in driver_id int4,
     10    in vin_vehicle varchar(17)
     11)
     12    language plpgsql as
     13$$
     14begin
     15    if not exists(select user_id from driver where user_id = driver_id) then
     16        raise exception 'Driver with id % does not exist', driver_id;
     17    end if;
     18
     19    if not exists(select vin from vehicle where vin = vin_vehicle) then
     20        raise exception 'Vehicle with VIN % does not exist', vin_vehicle;
     21    end if;
     22
     23    insert into driver_vehicle(vin_vehicle, id_driver, time_from, time_to)
     24    values (vin_vehicle, driver_id, now(), null);
     25    commit;
     26end;
     27$$;
     28}}}
    729**Процедура за вработување на возач во компанија**
    830
     
    165187$$;
    166188}}}
    167 
     189{{{
     190create or replace procedure make_request(
     191    out request_id int4,
     192    in customer_id int4,
     193    in start_latitude double precision,
     194    in start_longitude double precision,
     195    in end_latitude double precision,
     196    in end_longitude double precision,
     197    in number_of_adult_passengers int4 default 1,
     198    in number_of_children int4 default 0,
     199    in female_driver boolean default false,
     200    in luggage boolean default false,
     201    in luggage_count int4 default 0,
     202    in baby_seat_count int4 default 0
     203)
     204    language plpgsql as
     205$$
     206begin
     207    if not exists(select user_id
     208                  from customer c
     209                  where c.user_id = customer_id)
     210    then
     211        raise exception 'Customer with id % does not exist', customer_id;
     212    end if;
     213
     214    if start_latitude < -90.0 or start_latitude > 90.0
     215        or start_longitude < -180.0 or start_longitude > 180.0
     216        or end_latitude < -90.0 or end_latitude > 90.0
     217        or end_longitude < -180.0 or end_longitude > 180.0
     218    then
     219        raise exception 'Invalid location values';
     220    end if;
     221
     222    if number_of_adult_passengers < 0 then
     223        raise exception 'Number of adult passengers cannot be negative';
     224    end if;
     225
     226    if number_of_children < 0 then
     227        raise exception 'Number of children cannot be negative';
     228    end if;
     229
     230    if number_of_adult_passengers + number_of_children < 0 then
     231        raise exception 'There must be at least 1 passenger';
     232    end if;
     233
     234    if baby_seat_count < 0 then
     235        raise exception 'Baby seat count cannot be negative';
     236    end if;
     237
     238    if luggage = false and luggage_count > 0 then
     239        raise exception 'Luggage count cannot be greater than zero if the luggage flag is set to false.';
     240    end if;
     241
     242    if luggage = true and luggage_count <= 0 then
     243        raise exception 'Invalid luggage count parameters';
     244    end if;
     245
     246    if start_latitude = end_latitude and start_longitude = end_longitude then
     247        raise exception 'Start and destination location cannot be the same';
     248    end if;
     249
     250    insert into request(customer_user_id,
     251                                      start_latitude,
     252                                      start_longitude,
     253                                      end_latitude,
     254                                      end_longitude,
     255                                      timestamp,
     256                                      number_of_adult_passengers,
     257                                      number_of_children,
     258                                      status,
     259                                      female_driver,
     260                                      luggage,
     261                                      luggage_count,
     262                                      baby_seat_count)
     263    values (customer_id,
     264            make_request.start_latitude,
     265            make_request.start_longitude,
     266            make_request.end_latitude,
     267            make_request.end_longitude,
     268            now(),
     269            make_request.number_of_adult_passengers,
     270            make_request.number_of_children,
     271            'pending',
     272            make_request.female_driver,
     273            make_request.luggage,
     274            make_request.luggage_count,
     275            make_request.baby_seat_count)
     276    returning id into request_id;
     277    commit;
     278end;
     279$$;
     280}}}
     281
     282{{{
     283create or replace procedure add_waypoint(
     284    in request_id int4,
     285    in latitude int4,
     286    in longitude int4
     287)
     288    language plpgsql as
     289$$
     290declare
     291    prev_seqno int4;
     292begin
     293    if not exists(select id from request where id = request_id) then
     294        raise exception 'Request with id % does not exist', request_id;
     295    end if;
     296
     297    if latitude < -90.0 or latitude > 90.0
     298        or longitude < -180.0 or longitude > 180.0 then
     299        raise exception 'Invalid waypoint coordinates';
     300    end if;
     301
     302    if exists(select id
     303              from waypoints w
     304              where w.latitude = add_waypoint.latitude
     305                and w.longitude = add_waypoint.longitude
     306                and w.request_id = add_waypoint.request_id) then
     307        raise exception 'Waypoint already added';
     308    end if;
     309
     310    select count(*)
     311    into prev_seqno
     312    from waypoints w
     313    where w.request_id = add_waypoint.request_id;
     314
     315    insert into waypoints(latitude, longitude, seqno, request_id)
     316    values (add_waypoint.latitude, add_waypoint.longitude, prev_seqno + 1, add_waypoint.request_id);
     317    commit;
     318end;
     319$$;
     320}}}
     321
     322{{{
     323create or replace procedure start_ride(
     324    in offer_id int4,
     325    out ride_id int4
     326)
     327    language plpgsql as
     328$$
     329declare
     330    v_request_id      int4;
     331    start_latitude  double precision;
     332    start_longitude double precision;
     333    driver_id       int4;
     334    v_vehicle_vin     varchar(17);
     335--     v_status          ride_status;
     336begin
     337    if not exists(select id from offer where id = offer_id) then
     338        raise exception 'Offer with id % does not exist', offer_id;
     339    end if;
     340
     341    select o.request_id,
     342           r.start_latitude,
     343           r.start_longitude
     344    into
     345        request_id,
     346        start_latitude,
     347        start_longitude
     348    from offer o
     349             join request r on o.request_id = r.id
     350    where o.id = offer_id;
     351
     352    select d.user_id, dc.vin_vehicle
     353    into driver_id,
     354        v_vehicle_vin
     355    from driver d
     356             join driver_vehicle dc on d.user_id = dc.id_driver
     357    where dc.time_to is null
     358      and d.latitude is not null
     359      and d.longitude is not null
     360    order by power(start_latitude - d.latitude, 2) + power(start_longitude - d.longitude, 2)
     361    limit 1;
     362
     363    if driver_id is null then
     364        raise exception 'No active drivers available';
     365    end if;
     366
     367    insert into ride(start_time,
     368                     end_time,
     369                     distance_traveled,
     370                     vehicle_vin,
     371                     driver_user_id,
     372                     request_id,
     373                     status,
     374                     offer_id)
     375    values (now(),
     376            null,
     377            0,
     378            v_vehicle_vin,
     379            driver_id,
     380            v_request_id,
     381            'in_progress',
     382            start_ride.offer_id);
     383
     384    update offer
     385    set status='accepted'
     386    where id = offer_id;
     387
     388    update request
     389    set status='in_progress'
     390    where id = v_request_id;
     391
     392    commit;
     393end;
     394$$;
     395}}}
    168396== Функции и тригери
     397
     398{{{
     399create or replace function check_active_shift()
     400    returns trigger as
     401$check_active_shift$
     402begin
     403    if not exists(select user_id from driver where user_id = new.id_driver) then
     404        raise exception 'Driver with id % does not exist', new.id_driver;
     405    end if;
     406
     407    if not exists(select vin from vehicle where vin = new.vin_vehicle) then
     408        raise exception 'Vehicle with VIN % does not exist', new.vin_vehicle;
     409    end if;
     410
     411    if exists(select id
     412              from driver_vehicle
     413              where id_driver = new.id_driver
     414                and time_to is null) then
     415        raise exception 'Driver is already on shift';
     416    end if;
     417
     418    return new;
     419end;
     420$check_active_shift$ language plpgsql;
     421create trigger check_active_shift
     422    before insert or update
     423    on driver_vehicle
     424    for each row
     425execute function check_active_shift();
     426}}}
    169427
    170428**Тригер и функција за проверка на единствена оценка**
     
    222480}}}
    223481
     482{{{
     483create or replace function prevent_expired_license_ride()
     484    returns trigger as
     485$prevent_expired_license_ride$
     486declare
     487    exp_date date;
     488begin
     489    select dl.expire_date
     490    into exp_date
     491    from driver d
     492             join driverlicense dl on d.driver_license_id = dl.id
     493    where d.user_id = new.driver_user_id;
     494
     495    if exp_date is not null and exp_date < current_date then
     496        raise exception 'Driver license expired';
     497    end if;
     498
     499    return new;
     500end;
     501$prevent_expired_license_ride$ language plpgsql;
     502create or replace trigger prevent_expired_license_ride
     503    before insert
     504    on ride
     505    for each row
     506execute function prevent_expired_license_ride();
     507}}}
     508
     509{{{
     510create or replace function prevent_completed_offer_downgrade()
     511    returns trigger as
     512$prevent_completed_offer_downgrade$
     513begin
     514    if old.status = 'completed'
     515        and new.status <> 'completed' then
     516        raise exception 'Completed offer cannot change status';
     517    end if;
     518
     519    return new;
     520end;
     521$prevent_completed_offer_downgrade$ language plpgsql;
     522create or replace trigger prevent_completed_offer_downgrade
     523    before update
     524    on offer
     525    for each row
     526execute function prevent_completed_offer_downgrade();
     527}}}
     528