Clarion. Процесс миграции Clarion приложения на Microsoft SQL 2019

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

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

Так получилось что несколько месяцев назад мне на обслуживание передали 2 программы на технологии Clarion, повод грустный, уходит старое поколение, так и случилось с моим научным руководителем. Несколько лет я вместе с ним работал программистом на Clarion, далее я потерял интерес к этой технологии и наши пути разошлись. А сейчас, по прошествии лет передо мной стоит необходимость поддерживать и изредка развивать 2 программы.

Проблематика

Главная на мой взгляд проблема и сложность это работа программы только с нативной СУБД Clarion, доступ к данным при таком подходе очень неудачный, требуется большой объем кода для написания даже простейших задач, которые решаются отправкой на сервер простейшего Update или Insert в Clarion это десятки строчек кода по открытию файла, получению доступа к инфе и его последующего закрытия. Ниже пример:

       Access:Agent.Open 					!Открываем файл
       Access:Agent.UseFile				!Открываем файл
       clear(AGN:Record)					!Делаем очистку записи на всякий случай
       AGN:ID_AGENT = some_id 		!Присваиваем ключу значение
       set(AGN:BY_ID,AGN:BY_ID)		!Устанавливаем "каретку" на первое значение ключа
       next(agent)								!Встаем на первую запись удовлетворяющую ключу
       IF errorcode() or AGN:ID_AGENT <> some_id	!Проверяем не вышла ли каретка за область ключа
            RETVAL = 'Контрагент не найден'				!Выкидываем ошибку
          ELSE													
            RETVAL = AGN:N_AGENT									!Возвращаем имя агента
       .								
       Access:Agent.Close												  !Закрываем файл

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

select agent.name where id = some_id

Задача

Первые задачи передо мной встали очень грустной перспективой, одна из них звучала как "написать модуль выгрузки данные в 1С Бухгалтерию", я сразу представил алгоритм длиной в пару тысяч строк, который можно заменить на один запрос SQL, и вопрос перехода на SQL уже был решен. Речь конечно не о полном переходе, а только о частичной замене части таблиц на версию SQL и поэтапной миграции системы в SQL.

Характеристики системы

Обе системы примерно схожие по объему кодовой базы и по количеству пользователей

Общее количество пользователей: около 80

Общее количество таблиц: около 250

Сфера деятельности: Торговля + Сфера обслуживания (Салоны красоты)

Подразделения:

3 Салона красоты

5 Подразделений торговых предприятий - мелкооптовая торговля

Используемые инструменты

  • Самодельная программа миграции

  • DCT2SQL

  • Cldump

  • BULK insert

  • UltimateSQL & Ultimate Debug

Самодельная программа миграции

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

DCT2SQL

Данный компонент позволяет генерировать скрипты для экспорта структуры БД из Dictionary в SQL, поддерживает экспорт всех возможных типов данных, также экспортирует индексы и foreign keys. Очень удобно работает, все импортируется в пару кликов. Данные скрипты я храню в таблице миграций.

Можно скачать на Github - https://github.com/RobertArtigas/DCT2SQL

Также есть обучающие ролики на youtube по работе и правильной выгрузке. Вообще там очень много инфы в этих роликах по миграции на SQL.

https://www.youtube.com/watch?v=MjMgQYMc_xY

https://www.youtube.com/watch?v=bAolfvrz2oE&t=7067s

CLDUMP

Данная программа конвертирует данные из *.dat файла в csv таблицы готовые для загрузки через скрипт BULK. Достоинство этой программы - скорость. Она может сконвертировать таблицу накладных за 10 лет за 15-20 секунд. Главная проблема данной утилиты в том, что она доступна только в репозиториях Linux, в частности debian. Пришлось на основе этой команды создать микро-сервис, который на входе принимает post запрос, а на выходе выдает ссылку для скачивания данного файла в виде csv таблицы.

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

Программу cldump можно скачать командой в любой debian подобной системе:

apt-get install cldump

BULK insert

За доли секунд втягивает таблицу из csv в SQL. В данном случает, т.к. связки данных уже настроены на существующие ID, но при этом надо чтобы работал автоинкремент, поэтому его временно надо отключить, также потратил довольно много времени чтобы подобрать подходящие разделители:

BULK INSERT dbo.%table_name%
FROM table_name.csv WITH ( 
FORMAT = 'CSV', 
FIELDQUOTE = '', 
FIRSTROW = 1, 
FIELDTERMINATOR = '0x3b', 
ROWTERMINATOR = '0x0a', 
CODEPAGE='65001',
TABLOCK, 
KeepIdentity)

UltimateSQL & Ultimate Debug

Данные компоненты позволяют загружать данные из SQL в QUEUE примерно таким образом:

SQL_Result = sql.query('
select id, path_to_result 
from dbo.export_tasks as et 
where 
(status_complete = 0 or status_complete = 2) 
and export_table_id = '& exp:id
,qexport_tasks)

Выполнять запросы без возвращаемых значений:

sql.Query('Update export_tasks set status_complete = 2 where id = ' & qexport_tasks.id)

Есть отличное описание как использовать на youtube:

https://www.youtube.com/watch?v=RVit-5RPncs&t=2259s

Также при установке внутри шаблонов есть "пасхалка" от автора, как решить квест описывается по ссылке:

https://clarionhub.com/t/need-some-help-with-ultimatesql-error-when-trying-to-include-it-in-my-project/4182

Источник: https://habr.com/ru/post/560034/


Интересные статьи

Интересные статьи

Это четвертая и заключительная часть цикла об обновлении CI/CD процессов. Кстати, вот оглавление:Часть 1: что есть, почему оно не нравится, планирование, немного bash. Я ...
В нашем мире мобильных гаджетов, сфокусированных на приложениях, уже не принято говорить о веб-сайтах. Классические веб-сайты служат в основном для информационн...
Привет, Хабр!В прошлой статье мы разобрались:- Что такое ui-тесты и для чего они нужны;- Как настроить окружение для тестов;- Как находить ui-элементы в проекте и простав...
Подводим итоги на Хабр Q&A: за год вы успели задать более 100 000 вопросов и дать почти 200 000 ответов! В статье вспоминаем самые большие запуски и делимся статистикой. ...
На EP8266 можно эмулировать «Радио-86РК», но до микропроцессора 8080 был 8008, о котором сегодня ретрокомпьютерщики вспоминают реже. Его тоже удалось эмулировать на этой платформе и запустить...