16 янв. 2025 г.

Trees in SQL

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

27 янв. 2024 г.

Нам 30!

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

24 дек. 2023 г.

С Рождеством и Новым Годом!


Пусть в наступающем году исполнятся все ваши самые сокровенные желания. Счастья, удачи, здоровья и... конечно же новых версий Гедымина всем нам в 2024-м!

23 янв. 2023 г.

Приглашаем всех друзей!

Приближается 27 января! В этом году дата не слишком круглая, но от этого не менее внушительная. Golden Software исполняется 29 лет!

Мы приглашаем всех друзей на традиционный уже боулинг в клубе Мэдисон в Минске. В четверг 26 января, в 19:00.

Приходите! Будем рады вас видеть.

31 дек. 2022 г.

7 окт. 2022 г.

Как меня подвела народная мудрость

Все мы знаем главное программистское правило: если что-то работает -- не трогай, пусть работает. Вот и я, когда переносил нашего зарплатного бота с Windows сервера на облачный VPS думал также. Полностью сархивировал папку в одном месте и один-в-один запустил в другом. Всё. Дело сделано.

Сегодня утром меня поднял срочный email от облачного провайдера. Так и так, мол, мы прикрываем вашу лавочку, потому как вы не пользователь, а какой-то интернет террорист, который атакует с наших серверов пол Европы. Следом пришло автоматическое уведомление, что хотя они и выделяют нам канал на 400 MBit/sec это не значит, что мы должны использовать прямо так 400 Mbit все время.

В итоге VPS заблокирован. Доступа к нему нет. Хелп деск провайдера вежливый, но находится совсем отдельно от дата центра и технического персонала. Рекомендация звонить напрямую в дата центр звучит как писать на деревню дедушке.

Хорошо, что перенесенный сервер работал в тестовом режиме и у меня была исходная копия. Пришлось полностью снести VPS, переустановить с нуля Ubuntu и начать все с начала.

Что произошло?

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

Вывод:

1. Всегда обновляйте библиотеки. Выделите на это регулярный день, например, утро понедельника.

2. Если проект стабильный, уже не развивается, тем не менее следите, что пишет гитхаб по поводу найденных в нем уязвимостей. И, если найдены с пометкой Critical или High -- сразу же обновляйте код.

3. Облачный сервер сегодня есть -- завтра его нет. И ни какие мольбы не помогут вернуть вам утраченные данные. Работать в облаке можно только при настроенной системе автоматического 100%-ного бэкапа с переносом данных на другой физический сервер, обязательно к другому провайдеру.

30 сент. 2022 г.

Настройка принтера Poscenter RP-100 для печати кириллицы

Мы столкнулись с проблемой вывода кириллических символов на принтер Poscenter RP-100 при печати чеков из Гедымина через программную кассу TitanPOS


Для корректной настройки необходимо в файле конфигурации TitanPOS.conf прописать такие параметры:

...

"EscPosSubstituteCharset1251": 17, 

"DefaultCharsetName": "IBM 866", 

... 

и все будет хорошо )) 
 

 

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 в этом репозитории.

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

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

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

8 авг. 2022 г.

Вакансия: разработчик на Delphi со знанием SQL

Требуется программист для развития технологической платформы Gedemin и экономических задач на ее базе. Хорошее знание Delphi, WinAPI и реляционных баз данных обязательно.

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

Командировки маловероятны, но изредка могут быть. В основном, это однодневные выезды по Беларуси.

Гибкий график. Возможна удаленная работа.

Присылайте свои резюме на адрес: job[at]gsbelarus.com

15 июн. 2022 г.

How to find useless foreign keys in a database

With times, old databases tend to overgrow with unnecessary or just empty fields. Whilst regular fields are not much of a concern, those with foreign key constraints, especially in tables with millions of records, would needlessly inflate the database file and put performance penalty on every insert/update/delete operation, as appropriate index need to be updated.

For example, an index on a field that holds nothing more than NULL values over a table with 100 000 000 records has a size approximately of 600 MB.

The query below helps to spot fields with foreign keys, which contain no more than a given count of unique values (by default, the variable maxuniqvalues is set to 1 to find all fields which are empty or contain exactly one value). Additionally, the condition on minimal record count in a table in question could be set through variable minreccnt.

The result data set includes the following columns: name of the relation, number of records in the relation, name of the field, value (only the first value is shown), and a list of objects dependent on the field. The latter will help a lot if the field to be deleted later.

  EXECUTE BLOCK
  RETURNS(
    rn VARCHAR(31),
    reccnt INTEGER,
    fkfieldname VARCHAR(31),
    val INTEGER,
    dependent VARCHAR(8192)
  )
AS
  DECLARE VARIABLE minreccnt DOUBLE PRECISION = 1000000;
  DECLARE VARIABLE maxuniqvalues DOUBLE PRECISION = 1;
BEGIN
  FOR
    SELECT
      rc.rdb$relation_name,
      CAST((1 / idx.rdb$statistics) AS INTEGER),
      idxsfk.rdb$field_name,
      (SELECT
         LIST(TRIM(d.rdb$dependent_name))
         FROM rdb$dependencies d
         WHERE 
           d.rdb$depended_on_name = rc.rdb$relation_name
           AND 
           d.rdb$field_name = idxsfk.rdb$field_name)
    FROM
      rdb$relation_constraints rc
      JOIN rdb$indices idx
        ON idx.rdb$index_name = rc.rdb$index_name
      JOIN rdb$index_segments idxs
        ON idxs.rdb$index_name = idx.rdb$index_name
        AND idxs.rdb$field_position = 0
      JOIN rdb$relation_constraints rcfk
        ON rcfk.rdb$constraint_type = 'FOREIGN KEY'
        AND rcfk.rdb$relation_name = rc.rdb$relation_name
      JOIN rdb$indices idxfk
        ON idxfk.rdb$index_name = rcfk.rdb$index_name
      JOIN rdb$index_segments idxsfk
        ON idxsfk.rdb$index_name = idxfk.rdb$index_name
        AND idxsfk.rdb$field_position = 0
    WHERE
      rc.rdb$constraint_type = 'PRIMARY KEY'
      AND
      (idx.rdb$statistics > 0 
        AND idx.rdb$statistics < (1.0 / :minreccnt))
      AND
      idxfk.rdb$statistics >= (1.0 / :maxuniqvalues)
    ORDER BY
      idx.rdb$statistics ASC
    INTO
      :rn, :reccnt, :fkfieldname, :dependent
  DO BEGIN
    EXECUTE STATEMENT 
      'SELECT FIRST 1 ' || 
      :fkfieldname || 
      ' FROM ' || 
      :rn
      INTO :val;
    SUSPEND;
  END
END

13 февр. 2022 г.

Текущее состояние gdmn-nxt

В рамках gdmn-nxt сделано считывание RDB и AT таблиц и почти доделано на их основе создание полной ER модели данных. В отличие от первой попытки (предпринятой в рамках GDMN) мы используем не классы, а легковесные js объекты без ссылок внутри. Такие объекты быстро создаются, элементарно сериализуются и передаются по сети. Имея в руках ER модель мы можем:
  1. Автоматически создавать на сервере энд поинты для CRUD операций над бизнес-объектами.
  2. Автоматически создавать на клиенте UI для работы с данными (форма просмотра и диалоговое окно в терминах Гедымина).
Эти два пункта достаточно просты и мы планируем завершить их в течение нескольких дней после того, как будет готова ER модель и созданы визуальные компоненты для выбора объекта (выпадающий список, аналог TgsIBLookupCombobox) и для выбора множества объектов.

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

ER Model делается максимально отвязанной от физической структуры базы данных. Т.е. в дальнейшем мы сможем заменять Firebird на другую базу данных, подключаться через специальный переходник к системам вроде 1С или даже подключаться к нескольким базам и системам одновременно.

28 янв. 2022 г.

Зависание nodejs при запуске через окно терминала Windows

Есть неприятная особенность в окне терминала Windows. Если включен режим Quick Edit (Быстрая вставка или Быстрое редактирование в русскоязычной версии интерфейса), то в определенный момент терминал может перейти в режим ожидания клавиатурного ввода от пользователя. Выйти из этого режима можно нажав любую клавишу, но пока это не будет сделано, сервер node будет висеть и не отвечать на запросы по сети.

У данной проблемы есть следующие решения:

  1. Отключить режим Quick edit в окне Properties терминала (см. скриншот ниже)
  2. Использовать другой терминал (например, git bash)
  3. Запускать nodejs через Task Scheduler операционной системы.
Дополнительная информация на Stack Overflow.