Показаны сообщения с ярлыком исходный код. Показать все сообщения
Показаны сообщения с ярлыком исходный код. Показать все сообщения

24 апр. 2026 г.

p2p видео звонки

Видео звонок на базе WebRTC -- meet.gdmn.app. Сделать надежное видео соединение в сетях с низкой пропускной способностью или ограниченных интернет фильтрами -- задача не тривиальная. В статье описываются основные технические проблемы и примененные варианты их решения. Внутри ссылка на репозиторий с полным исходным кодом.

14 авг. 2022 г.

Как приступить к разработке платформы Гедымин

Для разработки платформы необходим компьютер с операционной системой Windows не ниже Windows XP и 8 или 16 Гб ОЗУ. Мы рекомендуем больше памяти при использовании виртуальной машины.

Существует два варианта подготовки инструментария для компиляции. Первый -- установить Delphi 5 и Firebird 2.5 непосредственно на компьютер следуя этой инструкции.

Второй вариант -- это обратиться к специалистам нашей компании за готовой виртуальной машиной с предустановленной системой Delphi и сервером баз данных.

Существует два режима работы Гедымина с сервером базы данных. В режим клиент-сервер необходима клиентская библиотека (fbclient.dll или gds32.dll -- обязательно разрядностью 32 бита!) и запущенный сервер (на этом же компьютере или доступный по сети).

В режиме встроенного сервера необходима библиотека fbembed.dll которая, собственно, представляет собой весь сервер Firebird выполняющийся в адресном пространстве gedemin.exe.

В настоящее время Гедымин поддерживает серверы Firebird 2.5, Firebird 3 и Firebird 4. Для двух последних необходимо дополнительно настроить файл конфигурации firebird.conf

Некоторые базы данных могут использовать внешние функции из библиотеки GUDF.DLL. Ее следует скачать с нашего сайта и поместить в подкаталог UDF сервера.

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

Далее, переходим к получению исходного кода, который находится на github.com в приватном репозитории. Обратитесь к сотрудникам компании, чтобы они предоставили вам доступ к нему.

Мы работаем по такому алгоритму:

0. Настраиваем git. Прописываем свое имя пользователя и email командами:

git config --global user.name "FIRST_NAME LAST_NAME"

git config --global user.email "MY_NAME@example.com"

1. Создаем папку \Golden, переходим в нее и клонируем репозиторий себе на компьютер командой:

git clone https://github.com/GoldenSoftwareLtd/gedemin-private.git gedemin

Выполняем действия для подготовки исходников к компиляции, которые указаны в инструкции выше. Компилируем все библиотеки и сам Гедымин согласно инструкции.

2. Основная ветка -- master -- сразу идет в продакшн. В эту ветку мы не комитим изменения напрямую. Перед тем как делать какие-то изменения снимаем код с сервера и создаем новую ветку:

git pull

git checkout -b IssueXXXX

Команду выполняем в папке Gedemin. Имя ветки на ваш выбор.

3. Делаем изменения. Затем комитим их в свою ветку:

Важно! Перед комитом проверяем, что исходники компилируются в Delphi без ошибок.

git commit -a -m "Пишем комментарий"

Перед комитом можно просмотреть сделанные изменения командой:

git status -uno

Важно! Не следует включать в комит следующие файлы, даже если они были изменены:

  • gedemin.res, и, вообще, все *.res файлы
  • файлы экранных форм *.DFM, где только поменялись координаты экранных элементов при открытии формы в Delphi

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

4. Загружаем изменения в свою ветку в github:

Первый раз следует выполнить команду для загрузки на сервер вашей ветки:

git push --set-upstream origin <YOUR BRANCH NAME>

В последствии можно выполнять:

git push

5. Идем на сайт github.com и создаем Pull Request из вашей ветки в мастер. После того, как ведущий разработчик подтвердит ваши изменения, они попадут в мастер и пойдут в продакшн.

6. На своем компьютере переключаетесь на ветку мастер и снимаете последние изменения:

git checkout master

git pull

7. Подключив телеграм бот @gbuilderbot можно получать уведомления об автоматической компиляции проекта и сборке дистрибутивов.

С чего начать?

Мы планируем доработки и регистрируем ошибки и пожелания в списке Issues в этом репозитории.

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

Например, доработки вроде этой вообще не требует написания кода, а только правки экранных форм. 

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

22 апр. 2021 г.

Новый сервер компиляции gedemin.exe

Многие годы за автоматическую компиляцию gedemin.exe и формирование пакетов прикладных решений отвечали несколько изощренных bat файлов. Технология пакетной обработки была заложена вместе с первыми версиями DOS еще в начале восьмидесятых прошлого века и предоставляет разработчику очень скудный функционал. Для любого отступления за рамки элементарного копирования/удаления и вызова сторонних программ приходится создавать свои утилиты или приспосабливать свободно доступные из всемирной сети.

Процесс запускался по расписанию один раз в сутки, а не в ответ на изменения в исходном коде платформы и решений.

Все бы ничего, пока строго один gedemin.exe "выпекался" из текущих исходников ветки master в репозитории. Несколько лет назад на крупных предприятиях значение генератора GD_G_UNIQUE стало подбираться к верхнему пределу доступных положительных 32-х битных целочисленных значений. В качестве быстрого решения проблемы мы ввели механизм поиска доступных интервалов в последовательности идентификаторов во всех таблицах базы и записи их в специальную таблицу, откуда Гедымин берет новые идентификаторы по мере необходимости. И... начали думать над долговременным решением, которым должно стать использование 64-х битных целочисленных идентификаторов записей.

Надо сказать, что 20 лет назад никто не задумывался над проблемой исчерпания идентификаторов и внутри исходного кода разработчики сплошь и рядом использовали тип Integer или полагались на длину строго в 4 байта при записи и чтении из буфера. Что еще хуже, Delphi 5 не поддерживает тип Int64 в библиотеке типов COM, через которую объекты Гедымина взаимодействуют с программным кодом на VBScript.

Первым шагом трансформации исходного кода стало введение специального типа для идентификаторов TID и набора функций для преобразования идентификаторов в/из строк, целых чисел, чисел с плавающей точкой и т.п. Разумеется, что замена типа затронула большинство из файлов проекта. Для справки, всего Гедымин насчитывает 5164 .pas файла, если считать вместе со сторонними библиотеками. В зависимости от символа условной компиляции ID64 тип TID превращается либо в 32-х битный Integer, либо в Int64. 

Существующий файл базы данных должен пройти через процедуру конвертации, которая меняет домены dintkey, dforeignkey и выполняет последовательность бэкап-рестор. Процесс конвертации базы данных необратим. После перехода на 64 бита вернуться назад уже нельзя.

Таким образом, у нас появляются три версии выполняемого файла:

  1. стабильный, проверенный временем gedemin.exe c 32-х битными идентификаторами.
  2. gedemin.exe на основе новых исходников с 32-х битными идентификаторами.
  3. gedemin.exe c 64-х битными идентификаторами.

Поддерживать такое хозяйство с помощью устаревшей технологии bat файлов и остаться при этом в здравом рассудке не представляется возможным. Пару месяцев назад мы начали проект gbuilder -- сервер компиляции Гедымина и прикладных решений. В настоящее время готова первая очередь. Из специальной ветки с именем india компилируется gedemin.exe на основе стабильных исходников. Прикладные решения формируются из ветки master репозитория gedemin-apps. Сервер компиляции предоставляет разработчику интерфейс через чат-бот в телеграме @gbuilderbot. Компиляция активируется через github webhooks по мере поступления на сервер изменений в исходный код.

В скором времени будет добавлена компиляция бета версий gedemin.exe из новейших исходников с 32-х битными и 64-х битными идентификаторами.

gbuilder реализован на платформе NodeJS. Язык программирования Typescript. Скомпилированные файлы можно скачать из соответствующего раздела нашего сайта.


23 мая 2017 г.

Как не запутаться в зависимостях объектов ПИ

Уже миллион раз успел пожалеть, что сделал в Гедымине режим добавления объектов в ПИ "с зависимыми". Это мощная функция, которая требует от применяющего досконального знания теории реляционных баз данных, структуры конкретной БД, внутреннего устройства своего прикладного решения.

Добросовестная разработка с использованием данной галки требует следования определенной последовательности операций:

  1. Добавить объект в ПИ с зависимыми.
  2. Открыть список ПИ. Найти нужное и по-порядку, по списку входящих в него объектов, проверить что именно добавилось. Убрать лишнее.
  3. Открыть список зависимостей для выбранного ПИ и проверить какие зависимости добавились. При необходимости изменить.
  4. Сохранить ПИ в репозиторий.
  5. Взять чистый эталон и загрузить на него пакет (каждый функционально завершенный и обособленный модуль должен быть оформлен в виде пакета).
  6. Протестировать работоспособность загруженного пакета.
Очень важно! Добавление с зависимостями можно делать, если разработка ведется на отдельной, специально выделенной, чистой актуальной базе данных.

Почему?

Представим, что за основую для разработки прикладного пакета мы взяли старую клиентскую базу с данными:

  1. В такой базе может присутствовать целый букет устаревших, временных, давно забытых ПИ. При добавлении "с зависимостями" они подхватятся и затянутся в список зависимых ПИ.
  2. В таблицах на таких БД могут присутствовать устаревшие, уже не используемые поля. Мало того, что они затянутся в ПИ, так еще затянутся и объекты на которые они ссылаются.
  3. Устаревшие скрипт-функции могут привести к тому, что код, работающий на разработочной базе, не будет работать на чистой базе, собранной из актуальных ПИ.

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

Если не уверен в себе и на все 100% не понимаешь что происходит "под капотом" системы, то каждый объект надо добавлять в ПИ вручную, по-отдельности, в порядке реляционной зависимости. Что особенно ценно, при добавлении вручную маловероятны ситуации "запутывания" связей между объектами или файлами ПИ.

После автоматического добавления с завимостями следует тщательно изучить и скорректировать список зависимых ПИ. Общее правило тут такое: чем меньше зависимостей, тем лучше.

Пример: пусть мы создаем небольшое прикладное решение, расширяющее стандартный пакет Зарплата и Кадры. Назовем его Наряды.

  1. Поскольку решение не велико, то объекты разобъем по следующим ПИ:
    • GS.Зарплата.Наряды.Метаданные -- домены, таблицы, триггеры и т.п.
    • GS.Зарплата.Наряды.Хранилище -- экранные формы.
    • GS.Зарплата.Наряды.Макросы -- перекрытые методы, локальные макросы форм.
    • GS.Зарплата.Наряды.Отчеты -- печатные формы.
  2. Зависимости настроим следующим образом:
    • GS.Зарплата.Наряды.Метаданные зависит от пакета GS.Зарплата.
    • GS.Зарплата.Наряды.Хранилище зависит от GS.Зарплата.Наряды.Метаданные.
    • GS.Зарплата.Наряды.Макросы зависит от GS.Зарплата.Наряды.Хранилище.
    • GS.Зарплата.Наряды.Отчеты зависит от GS.Зарплата.Наряды.Макросы.
  3. Создадим пакет GS.Зарплата.Наряды и сделаем его зависимым от GS.Зарплата.Наряды.Отчеты. Обратите внимание, что нет необходимости в пакете ставить зависимость от всех ПИ нашего решения, так как между ними итак уже присутствуют зависимости.
  4. Сохраним ПИ в файлы и расположим их в подкаталоге Наряды в папке Зарплата и кадры.
  5. Запишем в репозиторий.
  6. Подключимся к чистой эталонной базе данных ипоставим на загрузку пакет GS.Зарплата.Наряды. Проверим, чтобы загрузка не кидала ошибок. Проверим работоспособность после загрузки.

7 июн. 2016 г.

Ветви Cash & Check

Две ветви добавлены в репозиторий gedemin-apps для текущей разработки проектов POSitive:Cash и POSitive:Check. Здесь будут находиться новейшие версии. После тестирования изменения будут скидываться в ветку master из которой у нас сейчас еженочно формируются дистрибутивы.

Посмотреть какие ветки присутствуют локально на компьютере:

git branch

Добавить и переключиться на локальную ветку cash, связать ее с веткой в центральном репозитории:

git checkout -b cash --track origin/cash

Переключиться на ветку master:

git checkout master

Переключиться на ветку cash:

git checkout cash

Получить изменения с сервера в локальную базу данных. Файлы изменены не будут!

git fetch

Применить полученные изменения из удаленной ветки к локальным файлам в текущей ветке:

git merge

Два предыдущих действия одной командой:

git pull

Если ругнется, что локальная ветка не привязана к ветке в удаленном репозитории, то:

git branch --set-upstream-to=origin/cash cash

После чего делаем pull.

Мы в ветке cash. Принимаем изменения из ветки master:

git merge master

ВАЖНО! При возникновении конфликтов принять изменения другой стороны и внести свои коррективы.

Изменили некоторые файлы. Сохраняем изменения в локальном хранилище:

git commit -a -m "some changes were made"

Отправляем изменения в центральный репозиторий:

git push

После того, как изменения в ветке cash протестированы, отправляем их в ветку master:

git checkout master
git merge cash
git commit -a -m "New cash version"
git push

20 нояб. 2013 г.

Формируем ПИ из существующих проектов

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

Разберем формирование пространств имен на примере условного проекта Санаторий:

  1. Проанализируем проект и выделим в нем подсистемы. Пусть, в нашем случае такими будут: Номерной фонд (НФ), Санаторное питание (СП), Медицинские услуги (МУ). Подсистем может и не быть, если проект небольшой и цельный.
  2. Определимся с названиями файлов ПИ. Мы рекомендуем использовать префикс для идентификации разработчика (GS), имя проекта и подсистемы. Например, GS.Санаторий.НФ.Справочник номеров.yml.
  3. Определимся с общими для всех подсистем метаданными (домены, исключения) и разместим их в ПИ GS.Санаторий.Метаданные.yml Аналогично создадим ПИ для общих скрипт-объектов: скрипт-функций, VB-классов, констант.
  4. Для каждого бизнес-объекта или группы строго логически связанных между собой бизнес-объектов создаем отдельное ПИ, куда включаем в такой последовательности: метаданые (по порядку: домены, исключения, таблицы, индексы, представления, процедуры, триггеры), константы, ВБ-классы, скрипт-функции, методы, формы (DFM), события, макросы, отчеты.
  5. Для макросов, форм, отчетов, которые не являются неотъемлемой частью реализации БО, создаем отдельные ПИ. Объекты по ПИ распределяем в соответствии с логической группировкой. Например, в один файл удобно поместить форму, ее события, макрос, который ее вызывает.
  6. Общие отчеты, которые строятся по совокупности данных разных объектов, выносим в отдельное ПИ.
  7. В отдельное ПИ выносим визуальные настройки гридов.
  8. Создаем пакет Санаторий (пакет -- это ПИ со снятым флагом Внутреннее). Расставляем зависимости.
  9. Сохраняем на диске и закидываем в gedemin-apps.

Проверяем:

  1. Грузим пакет на чистую БД.
  2. С помощью утилиты IBExpert сравниваем структуры старой и новой БД. Выясняем, все ли метаданные мы включили. Если нет, то включаем, сохраняем, возвращаемся к шагу 1.
  3. С помощью утилиты FDBExtract сравниваем данные в таблицах платформы. Выясняем, все ли скрипт-функции, макросы, отчеты, формы мы включили.
  4. Вручную тестируем проект. Если все работает -- идем за пивом и\или шампанским.
В любом случае исходную базу данных архивируем и сохраняем в надежном месте.

1 сент. 2013 г.

Построение списка зависимых объектов

Замечательная задача для проверки программиста на знание SQL и реляционных БД. Пусть в одной таблице хранится список объектов. Объекты могут зависеть друг от друга. Связи хранятся в другой таблице ввиде пар ключей: объект - объект, от которого зависит данный объект. Требуется построить упорядоченный список, чтобы для любого объекта в нем, все объекты, от которых он зависит, располагались перед ним.

Решение с использованием рекурсивного CTE:

WITH RECURSIVE
  ns_tree AS (
    SELECT
      n.filename AS headname,
      0 AS usescount,
      CAST((n.xid || '_' || n.dbid) AS VARCHAR(1024)) AS path,
      n.filename
    FROM
      at_namespace_file n

    UNION ALL

    SELECT
      t.headname,
      (t.usescount + 1) AS usescount,
      (t.path || '-' || n.xid || '_' || n.dbid) AS path,
      n.filename
    FROM
      ns_tree t
      JOIN at_namespace_file_link l
        ON l.filename = t.filename
      JOIN at_namespace_file n
        ON l.uses_xid = n.xid and l.uses_dbid = n.dbid
    WHERE
      POSITION ((n.xid || '_' || n.dbid) IN t.path) = 0
    )
SELECT
  t.headname, sum(t.usescount)
FROM
  ns_tree t
GROUP BY
  1
ORDER BY
  2
В приведенном запросе at_namespace -- список объектов, а at_namespace_link -- связи между ними. Вычисление пути (path) и дополнительная проверка через функцию POSITION позволяют избежать зацикливания на кольцевых ссылках, если такие попадутся в исходных данных.

8 авг. 2013 г.

Первые шаги в функциональном программировании

Двадцать лет назад я собирался изучить Prolog. Купил даже книгу Ивана Братко "Программирование на языке Пролог для искусственного интеллекта". Так бы она и пылилась на полке, если бы не Гедымин и очередной наш технологический прорыв на стыке пост-реляционных технологий и функционального программирования.

А вот и собственноручно написанный код. Решение первой задачи Проекта Ойлера:

my_sum(From, To, C, C2, S) :-
  From < To,
  ( From mod C =:= 0; From mod C2 =:= 0 ),
  Next is From + 1,
  my_sum(Next, To, C, C2, T),
  S is T + From.
my_sum(From, To, C, C2, S) :-
  From < To,
  From mod C =\= 0,
  From mod C2 =\= 0,
  Next is From + 1,
  my_sum(Next, To, C, C2, T),
  S is T.
my_sum(From, To, _, _, S) :-
  From = To,
  S is 0.
PS: Надо же: Леонард Ойлер оказывается родился в Базеле ))

28 сент. 2012 г.

Compare file version strings

На всякий случай код функции сравнения строк с номерами версий файлов. А то в интернете находятся только какие-то монстры.
function CompareVersionStrings(const V1, 
  V2: String): Integer;

  function ExtractInt(const V: String; 
    var B: Integer): Integer;
  var
    E: Integer;
  begin
    E := B + 1;
    while (B <= Length(V)) and (E <= Length(V)) 
      and (V[E] <> '.') do Inc(E);
    Result := StrToIntDef(Copy(V, B, E - B), 0);
    B := E + 1;
  end;

var
  B1, B2: Integer;
begin
  B1 := 1; B2 := 1;
  repeat
    Result := ExtractInt(V1, B1) - ExtractInt(V2, B2);
  until (Result <> 0) or 
    ((B1 > Length(V1)) and (B2 > Length(V2)));
end;

1 апр. 2012 г.

Специфика ORM модели платформы Гедымин

ORM Гедымина имеет ряд нестыковок. Известны они давно и очередной раз привлекли к себе внимание во время разработки автоматизированного теста (см. предыдущий пост). Ниже перечислены некоторые из них:
  • Не учитывается разница между истинным абстрактным базовым классом (например, TgdcBase), и базовым классом c конкретной ListTable, который служит фундаментом для иерархии наследованных классов (например, TgdcBaseContact).
  • Некоторые объекты могут использоваться только внутри кода других объектов с выполнением магических действий по программной настройке:
    1. Все наследники TgdcInvBaseRemains
    2. TgdcInvCard
    3. TgdcLink
    4. TgdcAcctDocument
    5. TgdcAcctEntryRegister
  • К списку выше можно добавить все объекты позиций документов, создать запись в которых можно только при настроенной связи мастер-дитэйл с шапкой или непосредственно указывая ИД головной записи. При этом связь надо настраивать вручную, так как объекты шапки и позиций автономны и ничего не знают друг о друге. Частично задача решена для документов и только с вовлечением интерфейса пользователя — платформа формирует экранную форму просмотра на основе информации о типе документа.
  • В ситуациях, когда бизнес-сущность хранится в нескольких таблицах, список последних нигде не задан явно. Мы можем полагаться на сформированный запрос или обращаться к метаданным. В последнем случае мы рискуем получить слишком большой список связанных таблиц, не все из которых являются частью нашего бизнес-класса. Например, окно Свойства объекта выдает такое множество связанных таблиц для документа Отпуск товара на сторону из стандартного пакета настроек:
    BN_BANKCATALOGUE, BN_BANKCATALOGUELINE, BN_BANKSTATEMENT, BN_BANKSTATEMENTLINE, BN_CURRCOMMISSION, BN_CHECKLIST, BN_CURRBUYCONTRACT, BN_CURRCOMMISSSELL, BN_CURRCONVCONTRACT, BN_CURRLISTALLOCATION, BN_CURRSELLCONTRACT, BN_DEMANDPAYMENT, CTL_INVOICE, CTL_RECEIPT, GD_TAXDESIGNDATE, GD_TAXRESULT, GD_CONTRACT, GD_DOCREALIZATION, INV_PRICE, INV_PRICELINE, USR$INV_ADDINFO, USR$BN_ACCMAKE, USR$BN_ACCMAKELINE, USR$BN_BILL, USR$BN_BILLLINE, USR$BN_BILLNDS, USR$BN_BILLNDSLINE, USR$BN_BLANKTRIP, USR$BN_BTRIPMONEY, USR$BN_BTRIPMONEYLINE, USR$BN_BUYCURR, USR$BN_CASHBOOK, USR$BN_CASHBOOKLINE, USR$BN_CASHDEPOSIT, USR$BN_CASHDEPOSITLINE, USR$BN_CASHREPORT, USR$BN_CASHREPORTLINE, USR$BN_CHANGECURR, USR$BN_COLLECT, USR$BN_COMMISS, USR$BN_COMMISSLINE, USR$BN_DATABTRIP, USR$BN_DATABTRIPLINE, USR$BN_DEMAND, USR$BN_INCOMECURR, USR$BN_INCOMECURRLINE, USR$BN_LISTDEM, USR$BN_LISTDEMLINE, USR$BN_NOTICE, USR$BN_NOTICELINE, USR$BN_ORDERBTRIP, USR$BN_ORDERBTRIPLINE, USR$BN_PAYMENT, USR$BN_SALECURR, USR$BN_SALECURRLINE, USR$BN_SHARECURR, USR$BN_SHARECURRLINE, USR$BN_TRANSFER, USR$BN_TTN, USR$BN_TTNLINE, USR$BNF_ACTS, USR$BNF_ACTSLINE, USR$BNF_CONTRACT, USR$BNF_CONTRACTLINE, USR$CHECKREGISTER, USR$CHECKREGISTERLINE, USR$CURR_PAYMENT, USR$FA_ACTNEW, USR$FA_ACTNEWLINE, USR$FA_AMORT, USR$FA_AMORTLINE, USR$FA_CHANGEPROP, USR$FA_CHANGEPROPLINE, USR$FA_COMPLECT, USR$FA_COMPLECTLINE, USR$FA_CONSERVATIONLINE, USR$FA_CONSERVATION, USR$FA_MOVEMENT, USR$FA_MOVEMENTLINE, USR$FA_REAPP_B, USR$FA_REAPP_BLINE, USR$FA_REAPP, USR$FA_REAPPLINE, USR$FA_REMONT, USR$FA_REMONTLINE, USR$FA_REPAIR, USR$FA_REPAIRLINE, USR$GS_ACCBALANCE, USR$GS_ACTWORK, USR$GS_ACTWORKLINE, USR$INCOME_ORD, USR$INCOME_ORDLINE, USR$INV_ACTWORK, USR$INV_ACTWORKLINE, USR$INV_ADDWBILL, USR$INV_ADDWBILLLINE, USR$INV_ATTORNEY, USR$INV_ATTORNEYLINE, USR$INV_BILL, USR$INV_BILLLINE, USR$INV_CARDPRMET, USR$INV_CARDPRMETLINE, USR$INV_CERT, USR$INV_CHANGEPERC, USR$INV_CHANGEPERCLINE, USR$INV_COMP, USR$INV_COMPLINE, USR$INV_CONTRACT, USR$INV_CONTRACTLINE, USR$INV_DECOMP, USR$INV_DECOMPLINE, USR$INV_GOODORDER, USR$INV_GOODORDERLINE, USR$INV_INVENT, USR$INV_INVENTLINE, USR$INV_INVMOVE, USR$INV_INVMOVELINE, USR$INV_NEWCOST, USR$INV_NEWCOSTLINE, USR$INV_OUTLAYS, USR$INV_PROCESSING, USR$INV_PROCESSINGLINE, USR$INV_PRODUCT, USR$INV_PRODUCTLINE, USR$INV_PRREC, USR$INV_PRRECLINE, USR$INV_REALCOMMIS, USR$INV_REALCOMMISLINE, USR$INV_RETAIL, USR$INV_RETAILLINE, USR$INV_RETCUST, USR$INV_RETCUSTLINE, USR$INV_RETPROV, USR$INV_RETPROVLINE, USR$INV_SELLBILL, USR$INV_SELLBILLLINE, USR$INV_SPEND, USR$INV_SPENDLINE, USR$INV_SPENDPREC, USR$INV_SPENDPRECLINE, USR$INV_TOTRADE, USR$INV_TOTRADELINE, USR$MOG_DEBTACC, USR$MOG_DEBTCONTR, USR$MOG_INBILLVAT, USR$MOG_INBILLVATLINE, USR$MOG_SERVICE, USR$REN_DIVSTATEMNLINE, USR$SKIDKI, USR$SKIDKILINE, USR$WG_ADDPAYBYPERIODLINE, USR$WG_ADDPAYBYPERIOD, USR$WG_AGREEMENTLONGLINE, USR$WG_AGREEMENT, USR$WG_AGREEMENTLINE, USR$WG_AGREEMENTLONG, USR$WG_ALIMONY, USR$WG_ALIMONYDEBT, USR$WG_ATTEST, USR$WG_AVGADDPAY, USR$WG_AVGADDPAYLINE, USR$WG_BANKCALC, USR$WG_BRIGADEORDERLINE, USR$WG_BRIGADEORDER, USR$WG_CHARGEREG, USR$WG_CHILDAID, USR$WG_CONTRACT, USR$WG_CONTRACTLINE, USR$WG_CORRECT, USR$WG_CORRECTLINE, USR$WG_FAMCHAG, USR$WG_HAZARDS, USR$WG_HAZARDSLINE, USR$WG_HOLIDAYWORK, USR$WG_HOLIDAYWORKLINE, USR$WG_INCTAXDEDUCTION, USR$WG_INCTAXOTHERPAYLINE, USR$WG_INCTAXOTHER, USR$WG_INCTAXOTHERPAY, USR$WG_INCTAXSECURITIES, USR$WG_INITINCOME, USR$WG_INITINCOMELINE, USR$WG_KINDDAY, USR$WG_KINDDAYLINE, USR$WG_LEAVEDOC, USR$WG_LEAVEDOCLINE, USR$WG_LEAVEPASS, USR$WG_LEAVESCHED, USR$WG_LEAVESCHEDLINE, USR$WG_LEAVESTOPDOC, USR$WG_MANUALINPUT, USR$WG_MANUALINPUTLINE, USR$WG_MOVEMENT, USR$WG_MOVEMENTLINE, USR$WG_MULTIORDER, USR$WG_MULTIORDERLINE, USR$WG_PARTDAY, USR$WG_PARTDAYLINE, USR$WG_PENALTYDOC, USR$WG_PERSONALORDERLINE, USR$WG_PERSONALORDER, USR$WG_PIECEWORK, USR$WG_PIECEWORKLINE, USR$WG_PROFDEVELOP, USR$WG_PU6, USR$WG_PU6LINE, USR$WG_RETRAINING, USR$WG_REWARDDOC, USR$WG_SALARYCALC, USR$WG_SALARYCALCLINE, USR$WG_SALARYPAY, USR$WG_SALARYPAYLINE, USR$WG_SCIENCEDEVELOP, USR$WG_SENCALC, USR$WG_SENCALCLINE, USR$WG_SETPAYMENT, USR$WG_SETPAYMENTLINE, USR$WG_SETSENBONUS, USR$WG_SICKLIST, USR$WG_SICKLISTJOURNAL, USR$WG_SICKLISTLINE, USR$WG_SINKDEBT, USR$WG_SINKDEBTLINE, USR$WG_STAFFLIST, USR$WG_STAFFLISTLINE, USR$WG_TAXATION, USR$WG_TBLCAL, USR$WG_TBLCALLINE, USR$WG_TIMEWORK, USR$WG_TIMEWORKLINE, USR$WG_TOTAL, USR$WG_TOTALLINE, USR$WG_VACATION, USR$WG_VACATIONLINE, USR$WG_WRITEOFF, USR$WG_WRITEOFFLINE, USR$WS_DISTANCE_LINE, USR$WS_FUEL_LINE, USR$WS_WAYSHEET
  • Как уже отмечалось выше, связь мастер-дитэйл обрабатывается платформой только для документов и только на уровне пользовательского интерфейса. Связь мастер-дитэйл-сабдитэйл не обрабатывается вообще никак.
  • Наследование подтипов невозможно.
  • Не лишней была бы возможность создать атрибут типа бизнес-класс. То, что сейчас решается созданием автономного объекта и ручным связыванием его с головной записью. Пример: дополнительная информация по товарно-транспортной накладной.
Список всех бизнес-классов платформы и пакета типовых настроек Комплексная автоматизация теперь выглядит так.

7 дек. 2011 г.

etalon.sql

Долгое время формирование эталонной базы данных представляло собой трехступенчатый процесс. Сначала из отдельных файлов в папке SQL создавался скрипт, в результате выполнения которого получалась промежуточная база. Далее, утилита makelbrbtree.exe создавала прямо в этой базе необходимые метаданные интервальных деревьев. Наконец, формировался и выполнялся еще один SQL скрипт (для метаданных и данных, которые должны идти строго после инфраструктуры интервальных деревьев).

Мы изменили утилиту makelbrbtree.exe. Теперь она формирует и возвращает текст с метаданными интервальных деревьев вместо корректировки непосредственно базы данных. Объединив его с имеющимися в папке файлами мы получаем итоговый скрипт etalon.sql для генерации эталонной базы данных от и до за один проход.

PS: а так можно проверить совпадение содержимого двух текстовых файлов в пакетном файле:

...
FC first.txt second.txt /C | FIND "FC: no dif" > nul 
IF ERRORLEVEL 1 goto s_files_are_different
...
:s_files_are_different
...

28 нояб. 2011 г.

Брюки превращаются, превращаются брюки...

Помните как там было, в Бриллиантовой руке: Легким движением руки брюки превращаются, превращаются брюки...

В Гедымине для некоторых классов возможно превращение экземпляров в объекты одного из родительских классов. Например, Физическое лицо может стать Сотрудником предприятия и наоборот. Рабочая организация — просто организацией. Естественно, что РУИД при таких метаморфозах сохраняется, а это влечет за собой проблемы при загрузке из потока. День убит на разборку такой ситуации: была рабочая организация, которая когда-то настройкой перенесена на другую базу. Впоследствии, на той базе она была удалена из списка рабочих организаций и стала просто компанией. Теперь, с очередной настройкой, эта же запись, все того же типа Рабочая организация и с тем же РУИДом, снова пытается загрузиться на базу. В процессе загрузки создается экземпляр TgdcOurCompany, который не видит уже существующую компанию, что дает основание механизму загрузки создать новый экземпляр и попытаться сохранить его в базе. При сохранении возникает исключение, так как в GD_CONTACT запись с таким ИД уже есть.

По хорошему, радикальное решение данной проблемы — это полный запрет на превращения типов. Т.е. гражданин Фунт не может стать зицпредседателем Фунтом. Он должен (ради чистоты парадигмы!) погибнуть и воскреснуть уже как ипостась другого класса и с новым РУИДом. Но, такое изменение может вылезти боком в местах, которые сейчас даже не представляется возможным предугадать.

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

25 мар. 2010 г.

Ветка gedemin-2.5 в SubVersion

Ветка создавалась для разработки нового хранилища. С хранилищем покончили. Ветку синхронизировали с основным деревом и более не используем. Текущая разработка идет в основной ветке gedemin.googlecode.com/svn/trunk/

Сделайте switch или свежий check out. В последнем случае, не забудьте сохранить незакомиченные изменения.