Простой способ синхронизации структуры и данных MySQL при работе с Mercurial
Привет. Недавно перевёл работу на Mercurial и встала задача организовать синхронизацию MySQL. Погуглив, ничего простого и надёжного не было найдено, поэтому пришлось самому решать эту задачу.
Решение оказалось на удивление простым. Разделим задачу на две части: сохранение изменений базы данных, с последующим коммитом и пушем в центральный репозиторий, и обновление структуры БД после апдейта. Тогда задание сводится к тому, чтобы перед коммитом(а точнее перед hg status) сделать дамп базы в определённый файл и закоммитить его. И затем после hg update нужно этот файл импортировать в базу, вместе с свежими изменениями.
Общее решение #
Для решения проблемы воспользуемся хуками (подробнее). Заходим в папку .hg в нашем репозитории, и находим (или не находим, тогда создаём) там файл hgrс. Открываем его любимым редактором и вставляем туда следующий код:
[hooks]
pre-status = c:\path\to\mysql\bin\mysqldump.exe -u USERNAME -pUSERPSWD DBNAME > db\dump.sql
update = c:\path\to\mysql\bin\mysql.exe -u USERNAME -pUSERPSWD DBNAME < db\dump.sql
Если вы не понимаете указанные параметры, запустите mysqldump —help
и почитайте мануал. Вкратце — заменяем
USERNAME на имя пользователя MySQL(должен иметь права для дампа и импорта), USERPSWD — на пароль этого пользователя и
DBNAME на имя базы данных. Если хотите, можете поменять место хранения дампа (db\dump.sql, относительно корня
репозитория). Пользователям не-windows систем может потребоваться поменять ещё и разделитель директорий на «/».
Всё. Теперь можно запустить hg status и увидеть, что Mercurial заметил изменения в дампе(после первого запуска появится файл с дампом, не забудьте добавить его в репозиторий командой hg add):
Решение для TortoiseHg #
При использовании TortoiseHg не срабатывает хук «pre-status». Вызвано это тем, что команда «status» там вообще не запускается. Я не смог выяснить, какая команда там запускается при формировании списка изменённых файлов в окне «commit», поэтому пришлось вешать хук на сам коммит. В итоге в файл hgrc там нужно добавить немного изменённый код:
[hooks]
commit.a = c:\path\to\mysql\bin\mysqldump.exe -u USERNAME -pUSERPSWD DBNAME > db\ep.sql
commit.b = hg status
update = c:\path\to\mysql\bin\mysql.exe -u USERNAME -pUSERPSWD DBNAME < db\temp.sql
Теперь коммит будет проходить в два этапа — сначала изменённые файлы, затем срабатывает хук, и сразу коммитим изменённый дамп. Чуть менее удобно, но пока другого решения я не нашёл. Апдейт работает так же, как и в первом случае.
Спасибо за внимание. Как обычно, буду рад любым улучшениям и предложениям.
Полезные ссылки:
- мануал по mercurial hooks