41.6. Пример событийного триггера, обрабатывающего вход в базу данных
Триггер события 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); rec boolean; BEGIN -- 1. Запрет на вход в ночное время 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. Назначение ролей IF hour BETWEEN 8 AND 20 THEN -- в дневное время дать пользователю роль day_worker EXECUTE 'REVOKE night_worker FROM ' || quote_ident(session_user); EXECUTE 'GRANT day_worker TO ' || quote_ident(session_user); ELSE -- в остальное время дать пользователю роль night_worker 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); -- 4. Протоколирование времени соединения INSERT INTO user_login_log VALUES (session_user, current_timestamp); END; $$; -- определение триггера CREATE EVENT TRIGGER init_session ON login EXECUTE FUNCTION init_session();