Skip to content

Instantly share code, notes, and snippets.

@kirilltobola
Last active November 11, 2022 06:40
Show Gist options
  • Save kirilltobola/627f5d70efd97cf2021030be9f5e8bf1 to your computer and use it in GitHub Desktop.
Save kirilltobola/627f5d70efd97cf2021030be9f5e8bf1 to your computer and use it in GitHub Desktop.
DB
CREATE OR REPLACE FUNCTION create_record_queue(customer_full_name_in character varying)
RETURNS TABLE(
customer_full_name character varying,
queue_number integer,
operator_place character varying
)
LANGUAGE 'plpgsql'
AS $body$
DECLARE
next_operator_id integer;
BEGIN
LOCK TABLE operators IN ROW EXCLUSIVE MODE;
PERFORM *
FROM operators as O
WHERE O.is_working = true;
IF NOT FOUND THEN
RAISE 'Not found';
END IF;
LOCK TABLE queue IN EXCLUSIVE MODE;
SELECT
O.operator_id,
COALESCE(MAX(Q.queue_number), 0) cnt_clients_in_queue,
O.operator_place
INTO next_operator_id, queue_number, operator_place
FROM operators as O
LEFT JOIN queue as Q
ON O.operator_id = Q.operator_id
WHERE O.is_working = TRUE
AND (DATE(Q.registration_date) = CURRENT_DATE OR Q.registration_date IS NULL)
GROUP BY O.operator_id
ORDER BY cnt_clients_in_queue
LIMIT 1;
customer_full_name := customer_full_name_in;
queue_number := queue_number + 1;
INSERT INTO queue(operator_id, customer_full_name, queue_number)
VALUES (next_operator_id, customer_full_name, queue_number);
RETURN NEXT;
END;
$body$;
CREATE OR REPLACE PROCEDURE end_operator_service(operator_id_in integer)
LANGUAGE 'plpgsql'
AS $body$
DECLARE
var_queue_id integer;
BEGIN
SELECT Q.queue_id
INTO var_queue_id
FROM queue AS Q
WHERE Q.operator_id = operator_id_in
AND Q.start_service_date IS NOT NULL
AND Q.end_service_date IS NULL;
IF NOT FOUND THEN
RAISE 'NOT FOUND';
END IF;
UPDATE queue q
SET end_service_date = CURRENT_TIMESTAMP
WHERE queue_id = var_queue_id;
END;
$body$;
CREATE OR REPLACE PROCEDURE end_operator_working(operator_id_in integer)
LANGUAGE 'plpgsql'
AS $body$
DECLARE
var_customer_full_name character varying;
var_queue_number integer;
BEGIN
PERFORM operator_id
FROM operators
WHERE operator_id = operator_id_in
AND is_working = true;
IF NOT FOUND THEN
RETURN;
END IF;
SELECT customer_full_name, queue_number
INTO var_customer_full_name, var_queue_number
FROM queue
WHERE start_service_date IS NOT NULL
AND end_service_date IS NULL
AND operator_id = operator_id_in;
IF FOUND THEN
RAISE 'CustomerFullName = %, QueueNumber = %, still processing',
var_customer_full_name,
var_queue_number;
END IF;
LOCK TABLE operators IN SHARE MODE;
UPDATE operators
SET is_working = false
WHERE operator_id = operator_id_in;
END;
$body$;
CREATE OR REPLACE FUNCTION start_operator_service(operator_id_in integer)
RETURNS TABLE(
r_customer_full_name character varying,
r_queue_number integer,
r_operator_place character varying
)
LANGUAGE 'plpgsql'
AS $body$
DECLARE
var_customer_full_name character varying;
var_queue_number integer;
var_queue_id integer;
BEGIN
UPDATE operators
SET is_working = true
WHERE operator_id = operator_id_in;
SELECT Q.customer_full_name, Q.queue_number
INTO var_customer_full_name, var_queue_number
FROM queue Q
WHERE Q.start_service_date IS NOT NULL
AND Q.end_service_date IS NULL
AND Q.operator_id = operator_id_in;
IF FOUND THEN
RAISE 'CustomerFullName = %, QueueNumber = %, still processing',
var_customer_full_name,
var_queue_number;
END IF;
SELECT queue_id, customer_full_name, queue_number
INTO var_queue_id, r_customer_full_name, r_queue_number
FROM queue
WHERE DATE(registration_date) = CURRENT_DATE
AND start_service_date IS NULL
AND operator_id = operator_id_in
ORDER BY queue_number
LIMIT 1;
IF NOT FOUND THEN
RETURN;
END IF;
UPDATE queue
SET start_service_date = CURRENT_TIMESTAMP
WHERE queue_id = var_queue_id;
SELECT operator_place
INTO r_operator_place
FROM operators
WHERE operator_id = operator_id_in;
RETURN NEXT;
END;
$body$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment