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();