Как не надо делать обновления

Автор: BlackSilver
27.09.2009 23:02

Вот такая стала передо мной задача: есть предприятия, им раздается база данных на Access и программа, с ней работающая. Программа постепенно дополняется и структуру базы данных с каждым обновлением тоже надо менять, сохраняя при этом данные. И в одном только выпуске обновлений есть столько подводных камней (то есть я столько раз налажал), что их стоит описать в отдельной статье. Предупредить вас. Программа написана на Delphi, в качестве базы данных - файлик mdb, установщики собирал программой Inno Setup 5.

Камень первый - меняем структуру базы данных

При установке каждого обновления нужно менять структуру базы данных. Для этого был срочно написан модуль, который ищет в папке файлик dbupdate.sql, спрашивает пользователя, нужно ли его установить, запускает по очереди запросы из файлика и спрашивает пользователя, можно ли файлик удалить.

Плохое решение. Много недостатков, вот они:

  • Эти вопросы хороши во время отладки, но пользователю обязательно нужно в обоих случаях ответить "Да". Так зачем его вообще о чем-то спрашивать? Решение: Вне режима дебага вопросы заменены окошком "Обновление завершено".
  • Ничто не идеально - у пары пользователей некоторые запросы из dbupdate выдавали ошибку. После этого вообще ни туда, ни сюда - база данных наполовину обновлена. Приходилось вручную искать глючный запрос и продолжать обновление. Решение: Запросы на изменение БД следует обязательно засовывать в транзакцию. И отслеживать номер строки с глючным запросом - это прекрасное дополнение к тексту ошибки.
  • Второе обновление устанавливает запросы в том же файле dbupdate.sql. Чтобы всё заработало теперь надо, чтоб пользователь последовательно установил все обновления, запуская программу после установки каждого из них. Костыль в виде дополнительного патча из версии 1.0 сразу в версию 1.2 только добавил пользователям проблем. Решение: каждое обновление хранить в отдельном файле и последовательно запускать каждый из них.
  • К выходу пятого обновления стало ясно, что установить каждый патч последовательно ровно по одному разу - слишком тяжелая для пользователей задача. А при такой схеме обновлений в иных случаях программа будет жаловаться. И только после всего этого написал нормальный модуль обновления базы данных... Решение: Теперь файлы dbupdate не удаляются, но запускаются только если программа видит, что это обновление не установлено. В большинстве случаев для этого я смотрел на наличие определенного столбца в одной из таблиц. И это решение настолько хорошо, что может даже чинить базы данных, испорченные неправильной установкой предыдущих обновлений.

Камень второй - настраиваем установщик

Этот камень - про опцию установщика AppendDirName, которая выставлена по умолчанию. При этой опции если указать установщику кидать программу в папку "D:\Program Files", установщик поймет это, как в папку "D:\Program Files\MyProg". Если он понимает иначе, то это очень неудобно. Так вот, при создании обновлений эту опцию нужно обязательно отключать. Иначе случится вот такое:

1. У пользователя программа в папке "D:\MyProg".
2. Пользователь говорит обновлению ставится в папку "D:\MyProg", после чего легко и радостно жмет кнопку "Далее".
3. Программа легко и радостно ставится в папку "D:\MyProg\MyProg".
4. После установки программа хочет запуститься, но не находит dll-ок, которые не идут с обновлением, поскольку не поменялись.
5а. Пользователь звонит программисту и задалбывает.
5б. Пользователь жмет "ОК", вызывает программу с рабочего стола и мысленно клянет программиста, что он ничего не поменял.

Повторяю, при обновлениях отключайте AppendDirName.

Камень третий - защита от дурака

Однажды позвонили мне бухгалтеры одного предприятия и заявили, что после установки обновления у них пропали данные, которые они вводили на протяжении месяца. После длительного взгляда на их компьютер я узнал, что они устанавливали всё подряд - и все обновления, что у них были, и первую версию программы, которая перезаписала файл с их базой данных файлом с пустой. Месяц работы пошел насмарку. Вы видели в фильмах как полицесйcкий рассказывает матери о смерти сына? Я почувствовал себя на месте того полицейского, когда говорил им, что данные восстановить не удалось. И теперь два способа как я мог это предотвратить. Желательно использовать оба. Способ первый, простой: опять таки, настраиваем установщик. Для всех файлов с данными, кроме тех случаев, когда это действительно нельзя, устанавливаем флаг onlyifdoesntexist. Даже для самой первой версии программы. Это значительно понижает шансы, что они как-нибудь запишут что-то поверх своих данных. Способ второй, универсальный: регулярное создание резервных копий БД, можно и без ведома пользователя. Это, конечно, слишком по-Майкрософтовски, когда программа считает, что лучше пользователя знает, что делать, но оно б сработало, если б я это сделал.

Заключение

Как видите, такая, вроде бы, незначительная часть разработки, как выпуск обновлений, может стать источником многих головных болей. Но может и не стать, особенно если учиться на чужих ошибках. Удачи вам и поменьше секса с кодом.

Обновлено 07.05.2011 23:45

 

Комментарии  

 
#1 Гость 09.01.2010 18:04
Лучше и не скажешь!
Статья классно написана и понятно!
Цитировать
 
 
#2 Лев 13.06.2011 19:50
Мне понравилось! Учту.
Цитировать
 

Добавить комментарий


Защитный код
Обновить