38.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 at time zone 'utc'); rec boolean; BEGIN -- 1. Запрет на вход с 2 до 4 часов ночи 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 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;