Уважаемые читатели, решил поделиться с Вами техническим решением некоторых интересных и на первый взгляд не очевидных проблем. Всю жизнь я в основном только черпал информацию, читал замечательные статьи (в том числе на Хабре) очень помогавшие мне в решении тех или иных технических проблем. Но в последние 2 года, занявшись разработкой своей облачной платформы для автоматизации предприятий, мне пришлось решать довольно много задач “впервые”, т.е. которые если кто-то и решал, то описания (даже близко) я не находил. В связи с этим я решил написать 3 цикла статей: цикл по базам данных, цикл по безопасности и цикл по системам автоматизации. Эта статья — первая статья первого цикла.
Краткая формулировка задачи: каким-то образом current_date, current_time и current_timestamp должны выдавать дату-время в зависимости от настроек в аккаунте пользователя и при этом на самом сервере будет стоять московское время.
Система задумывалась неограниченно масштабируемая, с огромным числом потенциальных пользователей в любом регионе нашей необъятной страны, в какой-то момент встал вопрос, а удобно ли будет пользователям, например во Владивостоке, работать в системе с московским временем. Сервера то находятся в Москве, на них стоит московское время, при этом каждому пользователю (не важно, из какого он региона) выделяется несколько своих (индивидуальных) баз данных и все они находятся, грубо говоря, на одном сервере. Делать под каждый часовой пояс свой сервер глупо, да и не возможно с точки зрения концепции системы, ибо любой пользователь в любой момент может часовой пояс поменять.
Тип базы данных используемых в текущий момент – firebird 3
После суток метаний и изучений мануалов, найдено было следующее простое решение. Было создано 3 простых VIEW:
CREATE OR ALTER VIEW D_CURRENT_DATE(DD)
AS
SELECT cast((current_timestamp+0.000000000000000)as date) as dd FROM RDB$DATABASE;
CREATE OR ALTER VIEW D_CURRENT_TIME(DD)
AS
SELECT cast((current_timestamp+0.000000000000000)as time) as dd FROM RDB$DATABASE;
CREATE OR ALTER VIEW D_CURRENT_TIMESTAMP(DD)
AS
SELECT (current_timestamp+0.000000000000000) as dd FROM RDB$DATABASE;
Приведенные выше VIEW — для московского времени, которое стоит по умолчанию. Если пользователь выбирает часовой пояс отличный от московского, например “UTC+7 Красноярское время”, php-шный скрипт (при помощи которого пользователь это выбирает) изменяет VIEW в его БД следующим образом.
CREATE OR ALTER VIEW D_CURRENT_DATE(DD)
AS
SELECT cast((current_timestamp+0.166666666666667)as date) as dd FROM RDB$DATABASE;
CREATE OR ALTER VIEW D_CURRENT_TIME(DD)
AS
SELECT cast((current_timestamp+0.166666666666667)as time) as dd FROM RDB$DATABASE;
CREATE OR ALTER VIEW D_CURRENT_TIMESTAMP(DD)
AS
SELECT (current_timestamp+0.166666666666667) as dd FROM RDB$DATABASE;
Соответственно, из базового current_timestamp, будет прибавляться (либо вычитаться) количество часов, в зависимости от того часового пояса, который выбирает пользователь.
Далее везде, в коде всех скриптов, процедур, триггеров вместо current_timestamp пишется всегда d_current_timestamp. Благодаря этому, во всех записях в БД всегда будет проставляться время пользователя, а не московское, несмотря на то, что все базы данных на одном сервере с московским временем.
Автор: mail-online