| 167 | | |
| | 189 | {{{ |
| | 190 | create 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 | $$ |
| | 206 | begin |
| | 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; |
| | 278 | end; |
| | 279 | $$; |
| | 280 | }}} |
| | 281 | |
| | 282 | {{{ |
| | 283 | create or replace procedure add_waypoint( |
| | 284 | in request_id int4, |
| | 285 | in latitude int4, |
| | 286 | in longitude int4 |
| | 287 | ) |
| | 288 | language plpgsql as |
| | 289 | $$ |
| | 290 | declare |
| | 291 | prev_seqno int4; |
| | 292 | begin |
| | 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; |
| | 318 | end; |
| | 319 | $$; |
| | 320 | }}} |
| | 321 | |
| | 322 | {{{ |
| | 323 | create or replace procedure start_ride( |
| | 324 | in offer_id int4, |
| | 325 | out ride_id int4 |
| | 326 | ) |
| | 327 | language plpgsql as |
| | 328 | $$ |
| | 329 | declare |
| | 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; |
| | 336 | begin |
| | 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; |
| | 393 | end; |
| | 394 | $$; |
| | 395 | }}} |
| | 482 | {{{ |
| | 483 | create or replace function prevent_expired_license_ride() |
| | 484 | returns trigger as |
| | 485 | $prevent_expired_license_ride$ |
| | 486 | declare |
| | 487 | exp_date date; |
| | 488 | begin |
| | 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; |
| | 500 | end; |
| | 501 | $prevent_expired_license_ride$ language plpgsql; |
| | 502 | create or replace trigger prevent_expired_license_ride |
| | 503 | before insert |
| | 504 | on ride |
| | 505 | for each row |
| | 506 | execute function prevent_expired_license_ride(); |
| | 507 | }}} |
| | 508 | |
| | 509 | {{{ |
| | 510 | create or replace function prevent_completed_offer_downgrade() |
| | 511 | returns trigger as |
| | 512 | $prevent_completed_offer_downgrade$ |
| | 513 | begin |
| | 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; |
| | 520 | end; |
| | 521 | $prevent_completed_offer_downgrade$ language plpgsql; |
| | 522 | create or replace trigger prevent_completed_offer_downgrade |
| | 523 | before update |
| | 524 | on offer |
| | 525 | for each row |
| | 526 | execute function prevent_completed_offer_downgrade(); |
| | 527 | }}} |
| | 528 | |