Событийный триггер на событие login может быть полезен для протоколирования входа пользователей, проверки соединения и назначения ролей в зависимости от текущих условий или для инициализации данных сеанса. Важно обеспечить, чтобы любой событийный триггер, использующий login проверял, не находится ли база данных в режиме восстановления, перед выполнением любых операций записи. Выполнение записи на резервном сервере сделает его недоступным.
Данные возможности демонстрируются в следующем примере.
-- создание тестовых таблиц и ролей
CREATE TABLE user_login_log (
"user" text,
"session_start" timestamp with time zone
);
CREATE ROLE day_worker;
CREATE ROLE night_worker;
-- пример функции триггера
CREATE OR REPLACE FUNCTION init_session()
RETURNS event_trigger SECURITY DEFINER
LANGUAGE plpgsql AS
$$
DECLARE
hour integer = EXTRACT('hour' FROM current_time at time zone 'utc');
rec boolean;
BEGIN
-- 1. Запрет входа в систему в период с 02:00 до 04:00.
IF hour BETWEEN 2 AND 4 THEN
RAISE EXCEPTION 'Login forbidden';
END IF;
-- Нижеуказанные проверки не могут быть выполнены на резервных серверах,
-- поэтому перед выполнением любых операций необходимо убедиться, что база
-- данных не находится в режиме восстановления.
SELECT pg_is_in_recovery() INTO rec;
IF rec THEN
RETURN;
END IF;
-- 2. Назначение определенных ролей. В дневное время назначается роль day_worker, в противном случае —
-- роль night_worker.
IF hour BETWEEN 8 AND 20 THEN
EXECUTE 'REVOKE night_worker FROM ' || quote_ident(session_user);
EXECUTE 'GRANT day_worker TO ' || quote_ident(session_user);
ELSE
EXECUTE 'REVOKE day_worker FROM ' || quote_ident(session_user);
EXECUTE 'GRANT night_worker TO ' || quote_ident(session_user);
END IF;
-- 3. Инициализация данных пользовательского сеанса
CREATE TEMP TABLE session_storage (x float, y integer);
ALTER TABLE session_storage OWNER TO session_user;
-- 4. Регистрация времени подключения
INSERT INTO public.user_login_log VALUES (session_user, current_timestamp);
END;
$$;
-- определение событийного триггера
CREATE EVENT TRIGGER init_session
ON login
EXECUTE FUNCTION init_session();
ALTER EVENT TRIGGER init_session ENABLE ALWAYS;