Контроль версии настроек (постановка)

Материал из GedeminWiki
Перейти к: навигация, поиск

Проблемы, связанные с сериализацией настроек, обсуждаются также здесь:

Перечислим существующие проблемы и наметим возможные пути их решения:

Перезапись изменений, сделанных на базе данных

Ситуация

Есть база данных. На нее загружена настройка Х. В этой настройке могли быть сделаны некоторые изменения. Через некоторое время поступает новая версия данной настройки в виде отдельного файла. Как при загрузке файла не затереть сделанные изменения? Если они, конечно, были.

Решение

Рассмотрим первую часть задачи: как определить были ли внесены в настройку изменения? Очевидно, что для этого необходимо сформировать настройку, получить поток данных и сравнить его с потоком, записанным в базе данных. Если они совпадают, то настройка не изменялась. Если нет — изменялась. При сравнении можно предусмотреть несколько режимов: полное сравнение, когда сравниваются абсолютно все данные. Сравнение по значимым данным: когда выкидываются такие поля, как: editiondate, editorkey и т.п. Т.е. если фактически ничего не меняли, а просто открыли на редактирование и сохранили, то настройка будет считаться не измененной.

Теперь, перед загрузкой настройки с диска мы должны выяснить, присутствует ли настройка с таким РУИДом в базе данных. Если нет, то просто загружаем. Если да, то выясняем, не была ли она изменена. Если нет, то можно перезаписывать старую версию настройки новой. Но что делать, если настройка в базе данных была изменена?

Если бы и первую, и вторую настройку можно было получить в текстовом виде, то дальше их можно было бы сравнить с помощью внешней утилиты или внутреннего анализатора. Можно было бы даже предусмотреть режим слияния двух текстовых файлов в один. Можно ли получить поток данных настройки в текстовом виде? Безусловно. Фактически такая функциональность уже есть в Гедымине. но мы не можем загрузить данные из текстового потока. Даже если мы и сольем два текстовых файла в один, — ни какого толку от этого не будет. Следовательно, необходимо предусмотреть возможность не только сохранения потока данных в текстовом виде, но и загрузки настройки из текста.

Итак, резюмируем:

  1. При загрузке настройки проверяем, нет ли такой уже в базе.
  2. Если есть, то проверяем, не была ли она изменена.
  3. Если была изменена, то спрашиваем у пользователя, что делать:
    1. загрузить настройку из файла и затереть изменения в базе данных;
    2. оставить настройку, которая находится в базе данных. Если пользователь выберет именно эту опцию, то ему следует предложить сформировать файл и затереть этим файлом тот, который есть на диске.
    3. слить две настройки.
  4. Если было выбрано слияние, то открываем анализатор, в который загружаем как настройку из базы, так и настройку с дискового файла. Пользователь в ручном режиме сливает две настройки в одну. После этого полученный поток данных записывается в базу и на диск.
  5. В последствии, пользователь должен активизировать настройку.

Перезапись изменений, сделанных другим пользователем

Ситуация

Пусть у кого-то есть база данных, на которой загружена настройка Х. Данная настройка, состоит из множества скрипт-функций, структур метаданных, экранных форм и т.п. У другого сотрудника также есть база данных с настройкой Х. Пусть, первый сотрудник обнаружил ошибку в одной из скрипт-функций, входящих в настройку, исправил ее и сформировал новую настройку, которую сохранил на диске. Второй сотрудник, обнаружил другую ошибку и тоже исправил ее. Если теперь он сформирует настройку и сохранит ее, то он затрет изменения, сделанные первым сотрудником.

Решение

По сути это задача аналогична предыдущей. Только там мы боимся того, что поступающая в базу настройка затрет сделанные в этой базе изменения, а тут — что, сохраняя настройку, мы затрем чьи-то изменения сделанные и сохраненные в этой настройке ранее с другой базы данных.

Решение тоже должно быть аналогичным. Т.е. надо сформировать текстовые представления обеих настроек: той, что в базе и той, которая на диске, и сравнить их. При обнаружении расхождений предложить пользователю объединить их и сохранить результирующую настройку. Затем результирующую настройку следует загрузить на базу.

Пакеты

Ситуация

Первоначально просто был список настроек и все. Однако загрузка сложных настроек, состоящих более чем из одного файла, была в этом случае весьма сложной. Были придуманы пакеты. Пакет — это та же настройка, но помеченная специальным флагом. В идеале пакет ничего не содержит, кроме связей с другими настройками, от которых он зависит. Отсюда возникло второе название пакета — конечная настройка. Т.е. настройка, от которой больше не зависит ни какая настройка. Список пакетов, т.е. список помеченных настроек, выводится в отдельном окне, откуда можно вызвать их загрузку и активацию.

Подразумевалось, что пакетов будет немного. Например, пакет Бухучет, Ресторан, Торговля и т.п. Однако в процессе работы количество пакетов увеличилось, что дискредитировало саму идею. Сейчас в окне Пакеты несколько десятков позиций и по-сути мы вернулись к изначальной ситуации, когда пользователь должен знать какие пакеты выделить, чтобы получить базу данных нужной конфигурации.

Решение

Предлагается следующее:

  1. Ввести для каждой настройки флаг: опциональная. Если этот флаг не установлен и некоторая загружаемая настройка зависит от данной настройки, то настройка загружается. Если флаг установлен, то пользователю выдается запрос: устанавливать опциональную настройку или нет. Если пользователь выбрал непосредственную загрузку и активизацию опциональной настройки из окна Настройки, то она загружается и активизируется без всяких вопросов. Если опциональная настройка зависит от некоторой настройки, и пользователь решил не загружать опциональную настройку, то та настройка, от которой зависит опциональная, тоже не загружается, за исключением тех случаев, когда есть другие настройки, которые зависят от этой настройки и они загружаются.
  2. Пользовательский интерфейс стоит организовать следующим образом: в окне Пакеты выводить список пакетов как это делается и сейчас. Пользователь выбирает галочками пакеты, которые он хочет установить. Нажимает кнопку Загрузить. Программа находит для каждого пакета список опциональных настроек, которые входят в данный пакет, и выдает окно с чек листом. В окне сообщается, загрузка какого пакета осуществляется и что, мол, для него есть опциональные компоненты. Пользователь галочками выбирает, какие опциональные пакеты стоит устанавливать. Такое окно выводится для каждого пакета, выбранного пользователем, если у этого пакета есть опциональные компоненты.
  3. Изначально стоит предусмотреть иерархическую структуру. Т.е. одна опциональная настройка может зависеть от других настроек, среди которых могут быть опциональные, те, в свою очередь от третьих, и так до бесконечности. Причем, сразу стоит оговориться, что наследование может быть не прямое, а через один, два или более уровней. Т.е. опциональная настройка зависит от нескольких настроек, среди которых все обязательные (неопциональные), а те уже зависят от некоторых настроек, среди которых есть опциональные.
  4. Окно выбора опциональных пакетов:

Select packet.png

Вариант к обсуждению: Не делать два окна, а непосредственно в окне со списком пакетов заменить список на дерево. Тогда: самый верхний уровень дерева образуют Пакеты. Если пакет зависит от опциональных настроек, то его можно открыть и отметить галочками нужные настройки. Опять-таки, опциональная настройка может находиться на произвольном уровне вложенности.

Защита настроек от перезаписи с другой базы

Ситуация

Обычно, есть база данных, на которой ведется разработка настройки. Так называемая «эталонная» база. При загрузке настроек с диска, особенно в пакетном режиме, когда выбирается только одна настройка, а Гедымин сам загружает все, от которых она зависит, легко затереть существующую настройку или более старой версией или изменениями, сделанными на другой базе данных. И обратная задача: пусть на диске лежит файл сохраненной с эталонной базы настройки. Мы можем случайно затереть его, сформировав и сохранив файл настройки с базы, которая не является эталонной для этой настройки.

Решение

Возможно, для защиты настроек от случайной перезаписи с другой базы данных следует предусмотреть следующее:

  1. Добавить в настройку поле — путь к базе данных, на которой сформирована настройка.
  2. При попытке сохранить настройку на диске проверять, если путь к текущей базе совпадает с путем к базе, который записан в файле настройки, то сохранять. Если не совпадает то предупреждать об этом и предлагать изменить путь в настройке, хранящейся в базе, на путь текущей базы. Если пользователь отказывается, то не сохранять настройку.
  3. При загрузке настройки проверять: если путь к базе совпадает с путем, записанным в настройке, которая хранится в базе, то значит, эта база является эталонной для этой настройки и перезаписывать ее дисковым файлом несколько не логично. Следует спросить у пользователя.

Куда входит заданная настройка?

Сейчас у нас есть возможность посмотреть и установить, от каких настроек зависит заданная настройка. Необходимо еще добавить функцию просмотра и изменения списка настроек, которые зависят от данной настройки. Одновременная работа нескольких настройщиков

Ситуация

Сейчас создавать настройку, т.е. создавать формы, отчеты, макросы и т.п. можно только под учетной записью Администратор. Это не удобно поскольку:

  1. Нельзя организовать работу нескольких настройщиков одновременно;
  2. Нельзя зафиксировать, кто конкретно сделал то или иное изменение;

Решение

Насколько известно, работа только в режиме Администратора была сделана потому, что настройки формы сохраняются для каждого конкретного пользователя, если этот пользователь не администратор. Обойти это можно, если при переводе формы в режим редактирования проверять: если данный пользователь не администратор, то спрашивать: сохранять изменения для всех пользователей (т.е. как будто изменения делает администратор) или только для конкретного пользователя.

Придется просмотреть весь код, отвечающий за редактирование макросов, форм, настроек, отчетов и т.п., где делается предположение или проверяется, что текущий пользователь — Администратор.

Естественно, что стоит ограничить круг пользователей, имеющих право менять формы, макросы, отчеты, группой Администраторы.

Поиск объектов, входящих в более чем одну настройку

Ситуация

Сейчас, если объект не входит в настройку явно (нет записи в at_settingpos), то трудно сказать, откуда он грузится. Если объект присутствует в более чем одной настройке, то возможно ситуация, когда более старая версия объекта будет затирать более новую версию.

Решение

Решить данную ситуацию можно путем сканирования всех настроек и поиском всех повторяющихся объектов. В результате должен быть отчет, на основании которого настройщик перенесет все повторяющиеся объекты в более общую настройку. Второе решение проблемы: при добавлении объекта в таблицу at_setting_pos проверять, нет ли там объекта с таким ИД. Если есть, то предупреждать пользователя и, может быть, даже автоматически перемещать объект в более общую настройку. Данная задача перекликается с задачей «разворачивания» настройки.

Список объектов, входящих в настройку

Задача перекликается с задачей «Разворачивание настройки». Возможно, никакого отдельного режима не понадобится, если переработать окно настроек. Предусмотреть там дополнительный фильтр по типам объектов. Хотелось бы еще видеть сквозной список объектов, входящих в заданную настройку и все настройки (рекурсивно) от которых она зависит.

«Разворачивание» настройки

Ситуация

Сама настройка хранится в таблице at_setting. Список объектов, входящих в настройку хранится в таблице at_setting_pos. Но записи туда попадают только «явно». Т.е. когда какой-нибудь объект включается в настройку. Если при сохранении этого объекта в поток, сохраняются так же другие объекты, от которых он зависит, то они попадают в настройку «не явно». Т.е. в настройке они есть, но в таблице at_setting_pos записей для них нет.

Ситуация

Разворачивание настройки — это поиск всех таких объектов и включение их «явно» в таблицу at_setting_pos. Бета версия такой команды уже сделана. Вроде бы, тут есть какие-то нюансы (необходимо выяснить с Терехиной) по которым не всегда желательно явное добавление объектов.

Если их можно обойти, то хорошо бы сделать обязательное «разворачивание» настройки при ее формировании. Тогда можно легко:

  1. Отслеживать из каких объектов состоит настройка. Просматривать и редактировать эти объекты;
  2. Отслеживать объекты, которые входят в две или более настройки;

Поиск объектов, не входящих ни в одну настройку

Задача перекликается с задачей «Поиск объектов, созданных настройщиком на базе». Ее решение позволит уменьшить количество ситуаций, когда новая созданная и сформированная настройка не включает всех объектов, которые должны входить в эту настройку.

По этой причине, специалисту отдела внедрения даже рекомендуется брать с собой эталонную базу, на которой производилось создание настройки.

Поиск объектов, созданных настройщиком на базе

Задача перекликается с задачей «Поиск объектов, не входящих ни в одну настройку». Только теперь необходимо найти все объекты созданные (и возможно измененные) настройщиков. Дополнительно следует предусмотреть фильтр: За период.

Настройка по-умолчанию

Возможно, следует ввести понятие настройки по-умолчанию. Эта та настройка, куда добавляются объекты сразу при их создании. В оперативной памяти следует вести список таких настроек, по одной для каждого типа объектов. При создании макроса, система будет запрашивать, в какую настройку добавить создаваемый макрос. Внизу окна выбора должна быть галочка: Больше не спрашивать. Если пользователь ее выбрал, то все, создаваемые в рамках текущего сеанса, макросы будут автоматически добавляться в указанную настройку. Если пользователь не отметит галочку, то вопрос будет задаваться каждый раз.

Регистрация ошибок и пожеланий клиентом

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

Хранение версий скрипт-функций

Через триггер хранить предыдущие версии скрипт-функций. Выводить их на отдельной закладке в редакторе скрипт-объектов. Предусмотреть возможность сравнения старой и новой версий.

Загрузка всех зависимых настроек

При загрузке пакета происходит сканирование каталогов, поиск зависимостей и загрузка всех настроек, от которых зависит загружаемая настройка (пакет).

Необходимо предусмотреть такой же режим при загрузке настройки из просмотровой формы «Настройки». Очевидно, при этом Гедымин должен знать базовый каталог, относительно которого осуществлять сканирование подкаталогов на наличие файлов настроек.

Нумерация версий настроек

Возможно, в дополнение к счетчику формирований настройки, стоит добавить номер версии настройки, чтобы сделать нумерацию версий более привычной. Например, ясно, что Платежки 1.01 мало чем отличаются от 1.00. Чего не скажешь по такой записи Платежки, версия 24 и Платежки, версия 32.

Защита объектов, включенных в настройку

Часть объектов, находящихся в базе данных, реализуют логику программы. Как правило, такие объекты используются в макросах, тригерах и сторед процедурах через их РУИДы. Необходимо предусмотреть защиту таких объектов от удаления, пока в них есть необходимость.

Преимущества и недостатки хранения настроек в виде XML

Перечислим преимущества хранения настроек в XML:

  1. Просматривать настройки и вносить в них изменения можно с помощью любого подручного текстового редактора;
  2. Можно использовать системы контроля версий для отслеживания изменений, внесенных в настройки;
  3. Можно организовать слияние двух настроек;
  4. Можно использовать стандартные технологии (объекты) для доступа к XML, поиска информации и преобразования потока данных (MSXML, XPath, XSLT).

Перечислим недостатки хранения настроек в XML:

  1. Большой размер файлов на диске и, как следствие, более низкая скорость обработки.

Синхронизация настроек в базе данных с каталогом настроек на диске

Ситуация

Часто, разработчику неизвестно, какие настройки у него в базе данных не соответствуют тем настройкам, которые хранятся на диске.

Решение

Следует разработать синхронизацию списка настроек в базе данных со списком настроек на диске, аналогично тому, как для файлов это сделано в TotalComander.

Sync setting1.jpg

Точно так же, как в TotalComander можно дважды щелкнуть по файлу и перейти в режим сравнения содержимого файлов, у нас можно будет дважды щелкнуть и перейти в режим сравнения содержимого настроек.

Фильтрация списка настроек

Ситуация

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

Решение

Необходимо предусмотреть фильтрацию:

  1. Настроек по их вхождению в другие настройки;
  2. Настроек, которые не зависят ни от одной другой настройки;
  3. Опциональных/Обязательных настроек;
  4. Временных настроек;

Организация пользовательского интерфейса предполагается следующая: слева от списка настроек поместить дерево, которое заполняется на основании списка настроек и известных зависимостей между настройками. Внизу дерева располагаются чек-боксы, с помощью которых можно отбирать: опциональные/обязательные настройки, временные настройки и т.п. С помощью различных пиктограммок в дереве можно выделить: пакеты, опциональные настройки, временные настройки. С помощью перетаскивания в дереве можно было бы реализовать удобный механизм установки зависимостей между разными настройками.

Sync setting2.jpg

Временные настройки

Ситуация

Временные настройки возникают в том случае, если у клиента обнаружена какая-то ошибка или недоработка. Эта ошибка исправляется в офисе, после чего создается временная настройка, которая включает всего один-два макроса, отчет или что-нибудь еще. Настройка формируется, сохраняется и передается клиенту ввиде отдельного файла. Кроме указанного случая, временные настройки могут использоваться, когда необходимо сделать изменения в существующей настройке не на ее (настройки) эталонной базе данных. В этом случае изменения делаются на другой базе, оформляются в виде временной настройки и переносятся на эталонную базу данных, где сливаются с настройкой. Со временем такие временные настройки накапливаются в базе данных, засоряя ее.

Решение

Решение может быть следующее: в объект настройки добавить поле Дата действия. Если это поле не заполнено, то настройка не имеет «срока годности» и считается не временной. Если это поле заполнено, то настройка считается временной. При очередном открытии окна с настройками должна выполняться проверка. Если в базе данных присутствуют временные настройки «срок годности», которых истек, то на каждую задается вопрос удалить ее из базы или нет. Если пользователь ответил утвердительно, то настройка удаляется.

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты