27 янв. 2014 г.

Проблемы с загрузкой одиночного ПИ

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

Ее причина проста: в ПИ содержится ссылка на объект, который отсутствует в самом ПИ и в базе данных, или имеет в базе данных другой РУИД. В данном случае проблему вызывает ссылка на папку хранилища GLOBAL\DFM\Tgdc_dlgUserComplexDocument, которая в базе данных имеет РУИД отличный от того, который записан в файле ПИ.

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

Системные объекты, вроде папок хранилища, должны иметь единые стандартные РУИДы, которые у нас записаны в пакете "Общие данные". Данный пакет обязательно должен быть загружен на любую базу, на которой в последствии мы хотим разрабатывать и формировать пространства имен.

24 янв. 2014 г.

ChangeRUID

В окне редактора SQL добавлена кнопка для вызова функции замены РУИД.

14 янв. 2014 г.

В продолжение дискуссии о длине краткого наименования: когда-то вся ширина экрана была 80 символов.

Попытка №2

Упростим ситуацию и будем рассматривать только удаление из базы данных документов указанных типов, даты меньше заданной (D). Под документом в широком смысле мы понимаем:
  • Cовокупность записей в таблице GD_DOCUMENT, шапка и позиции.
  • Присоединенные к ним записи 1-к-1 (включая записи в специфических таблицах документов, связанные через поле documentkey).
  • Связанные с ними таблицы с уточняющей информацией (например, USR$INV_ADDINFO). По сути это 1-к-1, но через отдельное поле внешний ключ. Из структуры БД мы не можем знать, что некоторая таблица несет уточняющую информацию, поэтому определим список таких таблиц через константу в программе.
  • Бухгалтерские проводки (AC_RECORD, AC_ENTRY).
  • Складское движение (INV_CARD, INV_MOVEMENT).
  • Ко всему вышеперечисленному связанные записи в кросс-таблицах множеств.
Типы указываем, так как некоторые документы (например, зарплатные или по ОС) удалять нельзя за весь период.

Процесс "обрезания" базы сводится к следующему:

  1. Вычисляем бухгалтерские и складские остатки на заданную дату. Сохраняем их в базе.
  2. Формируем массив М из ИД записей, которые останутся в результирующей базе:
    1. Сканируем все таблицы, не относящиеся к документам. Добавляем в М ИД записи (если он есть и целочисленный) и идентификаторы всех ссылок на таблицы документов. Прочие ссылки нас не интересуют, так как все записи из прочих таблиц в любом случае будут сохранены.
    2. Выбираем из таблиц документов указанных типов записи с датой больше либо равно D. Сканируем их аналогичным образом, добавляя ИД в М.
    3. Сканируем аналогичным образом таблицы документов остальных типов.
  3. Запоминаем информацию о структуре БД в части обрабатываемых таблиц.
  4. Отключаем ключи, индексы, триггеры, ограничения на таблицах, из которых будем удалять записи.
  5. Удаляем записи, отсутствующие в М.
  6. Удаляем из таблицы GD_RUID записи для удаленных ИД.
  7. Восстанавливаем структуру БД.
Подготовка исходной базы данных:
  1. Пользователю рекомендуется провести бэкап-разбэкап исходной базы перед началом процесса.
  2. Кэш не должен превышать 500 Мб.
  3. Режим принудительной записи должен быть отключен
  4. Если задействован наш механизм замены внешних ключей, то отключенные ключи должны быть включены.
  5. Аудит средствами платформы Гедымин должен быть отключен.
Для оценки эффективности процесса будем использовать количество записей до и после "обрезания" в затрагиваемых процессом таблицах.

13 янв. 2014 г.

"Это подобно дошумерской цивилизации," – говорит Брэд Кокс, который написал ПО для компьютера Стива Джобса NeXT и профессор университета имени Джорджа Меэйсона. "Тот способ, которым мы создаем ПО – это эра охотников и собирателей".

...

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

4 янв. 2014 г.

Синхронизация данных между мобильным устройством на Android и сервером Firebird SQL

Ради скорости и независимости от сетевого соединения мобильное приложение должно использовать локальную базу, которая периодически синхронизируется с рабочей базой данных предприятия. Пусть мобильная БД состоит из таблиц М1, М2,... Мn и используется только для чтения. Таблицы имеют целочисленные первичные ключи. Рассмотрим вариант однонаправленной синхронизации:
  1. Версию данных будем обозначать целым числом и хранить в отведенной для этого таблице. 0 -- соответствует чистой БД.
  2. На сервере создадим таблицы S1, S2,... Sn, идентичные по структуре таблицам из мобильной БД. Указанные таблицы хранят текущую версию данных на сервере.
  3. На сервере создадим GLOBAL TEMPORARY таблицы уровня транзакции T1, T2,... Tn, также как и S идентичные по структуре таблицам из мобильной БД.
  4. На сервере создадим таблицу для команд обновления данных. Каждая запись таблицы хранит в текстовом виде список команд для перевода версии J в версию K.
  5. Команда состоит из заголовка и тела (или только из заголовка). Поддерживаются следующие команды:
    1. RALL -- очистить все таблицы.
    2. R -- очистить одну таблицу. В заголовке передается имя таблицы.
    3. D -- удалить записи из таблицы. В заголовке передается имя таблицы. В теле -- список ИД удаляемых записей.
    4. U -- вставить или обновить записи в таблице. В заголовке передается имя таблицы и список полей. В теле передаются значения полей для каждой записи. Первое значение -- всегда ИД записи. Так как присутствие идентификатора обязательно, в списке имя поля первичного ключа не перечисляется.

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

    Значения полей конвертируются в текстовое представление. Для их разделения, а также для разделения команд используются управляющие символы.

  6. Процедура формирования очередной версии данных на сервере вызывается вручную или автоматически, по установленному расписанию:
    1. Стартует транзакция.
    2. Сформированные данные данные помещаются в таблицы T.
    3. На основе сравнения S и T создаются и записываются в журнал команды изменения данных от версии N к N + 1.
    4. Таблицы S очищаются, в них переносятся записи из T.
    5. Инкрементируется номер версии данных.
    6. Транзакция завершается.
  7. Диалог между мобильным приложением и сервером:
    1. Мобильное приложение подключается к серверу и сообщает свою версию структуры БД и версию данных (V).
    2. Если версия структуры БД нас не устраивает, то сообщаем пользователю, что приложение следует обновить.
    3. Из журнала извлекаем команды для обновления данных от версии V к N и передаем их мобильному приложению.
    4. Если у нас нет прямого перехода от V к N, то последовательно ищем команды для апгрейда от V до V + 1 и формируем из них единый список для инкрементного обновления.
    5. Передаем список команд на мобильное устройство.
    6. По окончании процесса применения полученных команд инкрементируем номер версии данных мобильного приложения.
    7. Если мобильное приложение передало на сервер 0, то вместо передачи длинной цепочки последовательных обновлений, сразу формируем команды на основе содержимого таблиц S.
    8. Процесс обновления выполняется на одной транзакции, которая подтверждается только в случае успешного выполнения всех команд.