Rambler's Top100

(c)2009-2017 openinfotech.ru

СУБД HyTech

Документация



VCL компоненты доступа к СУБД HyTech™ v2.x

для Borland © Delphi ™ vv 4,5,6.

v3.3



Общее описание



Оглавление





Основные отличия от аналогичных компонент Borland. Основные отличия от аналогичных компонент Borland.


Причин создания компонент, работающих напрямую с HyTech, было две: отсутствие (на то время) удовлетворительно работающего ODBC драйвера и желание получить максимум того, что может дать HyTech. Это третья по счету и вторая реально работающая версия компонент. Самая первая версия разрабатывалась для Delphi 2.0, DataSet тогда еще был жестко «привязан» к BDE и пришлось писать всё, вплоть до визуальных гридов и полей ввода. Первая версия успела пройти тестирование и была похоронена в связи с выходом Delphi 3 и его универсального DataSet.

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


  • В проекте должен быть хотя бы один компонент THtBase;

  • Отсутствует компонента THtTable (за ненадобностью);

  • THtDataSet (и его наследники, в т.ч. THtQuery) могут выполнять совершенно произвольные SQL запросы любого вида и размера;

  • Aliases не поддерживаются. Необходимую информацию компоненты содержат в себе или считывают из .INI файла;

  • В SQL выражениях для модификации HtDataSet необходимо придерживаться определенных соглашений по написанию (см. "Модификация DataSet").

  • HyTech не поддерживает Lookup функций для своих курсоров, поэтому не используйте HtDataSet в качестве Lookup Data Set.

  • Т.к. BookMark в общем случае не позволяет однозначно отметить запись в курсоре (для связки таблиц BookMark берется только по одной таблице, а записи таблицы в связке могут дублироваться), BookMark не реализован.

  • THtDataSet имеет свойство AutoActive; если это свойство установлено в true, то HtDataSet активизируется автоматически с активизацией HtBase;

  • Если в операторе SELECT указано выражение (напр.: "select NAME + ' !' " или "select recno, name, 3+2"), то имя столбца с вычисляемым выражением будет вида "calc_%", где % - порядковый номер выражения в операторе SELECT. Для назначения более осмысленных имен можно использовать property CalcNames: TStrings, в котором можно указать список имен для полей-выражений;

  • HtDataSet имеет доп. метод: Requery. Это аналог пары Close/Open, он закрывает курсор и снова выполняет свой SQL; при этом считается, что результат в курсоре имеет тот же тип и структуру: информация о курсоре не перечитывается и поля не пересоздаются (т.е. SQL должен изменяться только в части WHERE, HAVING или ORDER BY). Это дает некоторую экономию времени, особенно заметную при работе с SQL сервером. Если два HtDataSet связаны как Parent/Child (как и в Delphi, через property DataSet), Child HtDataSet использует именно этот метод для переначитывания записей при изменении Parent HtDataSet. Поэтому будьте внимательны при составлении SQL выражений для Child HtDataSet;

  • параметры в SQL выражениях действуют так же, как и в Delphi, за исключением некоторых тонкостей:

    • параметры подставляются прямо в текст SQL перед передачей его в DLL на исполнение, поэтому параметром можно делать что угодно, хоть имя таблицы;

    • параметры типа STRING имеют два режима подстановки. Режим определяется типом параметра (ParamType): если ParamType = ptInput, то значение подставляется as is (таким образом, параметром может быть даже часть SQL выражения); если же ParamType <> ptInput, то значение параметра перед подстановкой приводится к виду, который SQL интерпретатор заведомо в состоянии "переварить", а именно:

      • все символы младше char(32) (пробел) преобразуются к виду "\xHH", где HH - шестнадцатиричный код символа;

      • - все символы ' и " заменяются парой \' и \";

      • - длинная строка разрезается на сумму строк по 64..70 символов каждая (интерпретатор "не понимает" строковых констант длиннее 80 символов), каждая порция заключается в двойные кавычки и обрамляется символами CR/LF.

  • SQL запросы могут быть вынесены в отдельный файл, управляемый отдельной компонентой TMacrosList, или в любое другое место, управляемое соответствующим наследником TCustomMacrosList;

  • SQL запросы перед исполнением обрабатываются препроцессором (TSqlParser), который имеет довольно широкий набор команд (#if, #def, #undef, макросы) и допускающий пользовательские расширения; препроцессор доступен также в виде отдельной компоненты;

  • Имеются встроенные средства мониторинга выполняемых запросов (т.н. SQL debugger), позволяющий отслеживать запросы выборочно (только конкретные HtDataSet, только конкретные операции), корректировать запросы перед их исполнением, приостанавливать выполнение в случае возникновения ошибки выполнения (отображаются вызвавший ошибку запрос, коды ошибок и сообщения сервера) и пр. Взаимодействие приложения с отладчиком описано в виде интерфейса, что позволяет пользователям легко создавать свои отладчики и «протоколописатели» (loggers).

  • Расширенное управление исключительными ситуациями (Exceptions), вплоть до возможности перенаправить все сообщения об ошибках и прочую информацию в произвольный поток (TStream).

  • Автоматическая поддержка login диалога для консольных приложений;

  • Выполнение методов HyTech API в отдельном потоке с возможностью обрабатывать в это же время сообщения основного потока, что позволяет не «замораживать» приложение на время ожидания результата.


Установка


Прежде, чем устанавливать компоненты, добавьте в путь (path) каталог VCL\RTL, где находятся все run time packages библиотеки и необходимые для работы DLLs. Затем запустите Delphi и установите design time packages из подкаталога LIB соответствующей версии. Для комфортной работы создайте в каком-либо каталоге из пути поиска (path) файл HyTech.ini с параметрами инициализации HyTech.


Файл HyTech.ini


Файл HyTech.ini содержит параметры инициализации HyTech. Эти параметры используются dll-посредниками. Ниже приведены все анализируемые секции и параметры, значения указаны по умолчанию. В комментарии указано имя параметра из соответствующего модуля (IMPL.PAS или LIMPL.PAS).


;====== Параметры для Htmsql.dll =========


[Handles]

TaskHandles=5 ; ThrdInitRec.HytechInit.nTaskCnt

HtHandles=400 ; ThrdInitRec.HytechInit.nHtCnt


[Limits]

TablesCnt=96 ; ThrdInitRec.HytechInit.nTableCnt

LockTout=10 ; ThrdInitRec.HytechInit.nLockTimeOut

TransTout=10 ; ThrdInitRec.HytechInit.nTransTimeOut

PollDelay=0 ; ThrdInitRec.HytechInit.nPollDelay

TransMode=3 ; ThrdInitRec.HytechInit.nTrsMode, = TRS_ON or TRS_PREP

StackSize=400 ; ThrdInitRec.StackSize


[Paths]

NetPath= ; ThrdInitRec.fpNetPath

TrtPath= ; ThrdInitRec.fpTrtPath

TmpPath= ; ThrdInitRec.fpTmpPath


;====== Параметры для Htmsrv.dll для файлового протокола =========


[Counts]

Chanels=0 ; ThrdInitRec. nChanCnt

Messages=0 ; ThrdInitRec. nMsgCnt


[ID]

ServerNo=0 ; ThrdInitRec. gServerNo

LocalID=900 ; ThrdInitRec. gLocalNo


В файле HyTech.ini может быть указан раздел [Aliases], используемый компонентой HtBase. В этом разделе можно задавать пары «Имя» = «Строка инициализации», например:


[Aliases]

Моя любимая БД=tcpip:/localhost:1000

Работа=tcpip:/Office:1000

Local=sql:d:\data\db


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

Перед отображением Login диалога компонента читает раздел Aliases и заполняет именами combo box выбора БД.


Для поиска файла HyTech.ini используется системная функция SearchPath(), т.е. порядок поиска совпадает с системным: каталог приложения, текущий каталог, системные каталоги windows, каталог windows, каталоги пути поиска (Path). Если файл не найден, он создается в каталоге windows.

Перевод приложений с компонентами предыдущей версии


Новые компоненты доступа к СУБД HyTech значительно отличаются от предыдущей версии. Чтобы облегчить перевод уже имеющихся проектов, с библиотекой поставляются две утилиты:

DFM.EXE – сканирует файлы *.DFM, заменяя имя property «DataBase» на соответствующее «BaseName» и «script» на «SQL».

PAS.EXE – сканирует файлы *.PAS, корректируя список модулей в секции uses.

Обе утилиты имеют два параметра командной строки:

-s: просматривать подкаталоги;

-q: не запрашивать подтверждение на выполнение.

Для перевода проекта на использование новых компонент преобразуйте все файлы *.DFM проекта в текстовый вид ( $(DELPHI)\BIN\convert.exe ) и выполните в каталоге проекта DFM.EXE и PAS.EXE (см. подкаталог RTL). Затем откройте проект. При открытии модуля, содержащего HtBase, Delphi предложит откорректировать декларацию типа – соглашайтесь (если проект имел компоненту TSqlBase и используется Delphi 6, лучше откорректируйте PAS файл вручную, заменив в описании формы тип TSqlBase на THtBase. Дело в том, что в Delphi 6 невозможно зарегистрировать два алиаса на компонент, и зарегистрирован только алиас для TsrvBase. В результате автоматической замены типа TSqlBase не происходит). Затем откройте последовательно все модули проекта. При этом Delphi выполнит окончательную коррекцию uses у этих модулей (например, описание класса THtDateField переместилось в модуль HtDefs). Также наверняка потребуется заменять обработчики Event’ов у HtBase, т.к. у них несколько изменились параметры вызова. Посмотрите также демонстрационные проекты на предмет использования новых event’ов у HtBase. Оставшиеся проблемы (если таковые найдутся) будут скорее всего связаны не столько с компонентами, сколько с переходом с D5 на D6.

Исходные тексты утилит находятся в подкаталоге UTILS. Для генерации pas модулей по описаниям грамматики использовалась библиотека TP Lex of Albert Graef, ag@informatik.mathematik.uni-mainz.de. Использовалась подкорректированная Алексеем Махоткиным (alexm@hsys.msk.ru) версия.


Создание простейшего приложения


Как уже отмечено выше, приложение для работы с СУБД HyTech должно иметь минимум один компонент THtBase. Установите его ключевые свойства:

  • DbPath – строка инициализации или алиас;

  • ConnectUser – выполнять ли авторизацию пользователя (доступно только для сервера);

  • LoginPrompt – выполнять ли диалог авторизации пользователя;

  • ErrToUser – присылать ли пользователю текстовые сообщения об ошибках (сообщения получает обработчик события OnErrMsg).


Если приложение не консольное, можно назначить обработчики событиям OnBeforeCallHt и OnAfterCallHt для назначения курсора «мыши» на время выполнения запросов. Библиотека содержит такой курсор, который загружается во время инициализации и хендл которого можно получить функцией HCRSqlExec (модуль HtBases). В приложении удобно объявить константу (напр. crSqlExec = 5), которая будет представлять этот курсор в массиве Screen.Cursors. В секции инициализации модуля, содержащего THtBase, пишем:


initialization

Screen.Cursors[crSqlExec]:= HCRSqlExec;


Тогда обработчик OnBeforeCallHt будет назначать текущим курсор crSqlExec, а обработчик OnAfterCallHt - crDefault.


Как показывает практика, очень удобно пользоваться SQL функцией usersend() (в запросах к серверу, локальный интерпретатор не имеет этой функции). С ее помощью удобно реализуются сообщения об ошибках, прогресс индикаторы, передача промежуточных данных и т.п. Обработка посылаемых этой функцией данных выполняется обработчиком события OnUserMsg, имеющегося как у THtDataSet, так и у THtBase. OnUserMsg получает текст в OEM кодировке; автоматического перекодирования не производится, т.к. функцией usersend() можно передавать не только текст.


Пока выполняется запрос, клиент может получать сообщения об ошибках. Для работы с этими сообщениями удобнее всего создать в приложении StringList и накапливать в нем эти сообщения во время выполнения запроса. Если ошибка не сброшена в самом запросе, HyTech API функция (исполняющая запрос) вернет ошибку, в результате чего будет выполнен raise Exception. В обработчике OnException содержимое StringList можно отобразить и очистить. Дополнительно StringList можно очищать в обработчике BeforeCallHt – на случай, если ошибка сброшена в самом запросе.



Механизм взаимодействия компонент и HyTech API.


Для работы с СУБД HyTech ее создатели предоставляют несколько DLL, реализующих API доступа к сервисам СУБД. Для HyTech 2.x это три DLL:

  • HTW32PAS.DLL

  • HLW32PAS.DLL

  • HSW32PAS.DLL

Первые две реализуют непосредственную работу с файлами БД, последняя – работу с сервером. Набор функций этих двух вариантов API имеет различия, которые устраняются DLL-посредником. DLL-посредник реализует интерфейс IHyTechAPI, используя API конкретной клиентской DLL. В данной библиотеке имеются две таких DLL-посредника: HTMSQL.DLL (использует HTW- и HLW32PAS.DLL) и HTMSRV.DLL (использует HSW32PAS.DLL). VCL компонент THtBase использует интерфейс IHyTechAPI для реализации своих методов доступа к БД. В момент активизации THtBase определяет требуемую DLL-посредник, загружает ее (LoadLibrary) и получает ее IHyTechAPI. После деактивизации THtBase освобождает DLL-посредника. Требуемая DLL-посредник определяется по строке инициализации: часть этой строки от начала до первого двоеточия указывает протокол взаимодействия с СУБД (не менее трех символов). Предопределенных протоколов три:

  • tcpip: работа с сервером по протоколу tcpip, HTMSRV.DLL;

  • file: работа с сервером по файловому протоколу, HTMSRV.DLL;

  • sql: работа с файлами БД напрямую, HTMSQL.DLL

Пользователь может создать свои DLL-посредники для желаемых протоколов и зарегистрировать свои протоколы. Регистрация дополнительных протоколов и назначение DLL протоколам выполняется в файле HyTech.ini в секции TransDll.

Пример. Зарегистрировать дополнительно протокол myht и назначить ему и протоколу tcpip MYHT.DLL в качестве DLL-посредника:


[TransDll]

tcpip=MYHT.DLL

myht=MYHT.DLL


Общий алгоритм работы с HyTech API.


Рассмотрим работу THtBase с HyTech API:


Основной поток (thread)

Запомнить параметры вызова

Запомнить номер соответствующего метода IHyTechAPI

Установить event «вызов»

REPEAT

Ожидать event завершения, сообщение (message) или eventcallback

Обработать сообщения и callback вызовы

UNTIL event завершения установлен

выход


Исполняющий поток ThtBase

Обработчик callback вызовов

Установить eventcallback

Ждать event “callback обработан

End;


Исполнитель методов IHyTechAPI

REPEAT

Ожидать event «вызов»

Вызвать метод IHyTechAPI

Запомнить результаты

Установить event завершения

UNTIL работа завершена

End;


Другими словами, реально вызовы HyTech API выполняются в контексте отдельного потока (thread), создаваемого классом THtBase, а пока этот поток-исполнитель ожидает завершения API функции, основной поток обрабатывает messages и callback вызовы. По умолчанию обрабатываются (dispatch) не все оконные сообщения: только отрисовка, перемещение окон, minimize-restore-maximize и т.п. В результате основные диалоговые элементы (кнопки, scroll bars и т.п.) в процессе выполнения длительных запросов «не работают», что предотвращает повторное вхождение в функции HyTech API. Конечно, и на WM_MOVE можно назначить отработку SQL запроса, но для таких экзотических случаев можно или запретить вообще обработку messages в процессе ожидания, или обрабатывать их по собственному алгоритму (для этого есть все возможности).

Существует класс приложений, для которых удобно сам THtBase создавать в отдельном потоке (например, различные cgi). В этом случае вряд ли имеет смысл создавать еще один поток в рамках THtBase. Для таких случаев THtBase имеет property SameThread: если это свойство установлено, дополнительный поток не создается.


Обработка исключений (exceptions).


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

Все исключения, возникающие в потоке-исполнителе (и на более низком уровне) перехватываются и транслируются в основной поток. Все exceptions основного потока, которые не должны прерывать выполнение, перехватываются и передаются на обработку виртуальному методу HandleException. Имеющийся обработчик THtFork.HandleException вызывает event THtFork.OnException. Если обработчик event’а не назначен, исключение передается процедуре htdefs.NotifyException. Ожидается, что HandleException не будет вызывать исключений; это требование д.б. учтено при написании обработчиков OnException.

Процедура NotifyException, в свою очередь, анализирует тип исключения и, если оно информативно (не EAbort), передает его специальному объекту – коллектору ошибок HtErrDisp. В секции инициализации модуля htdefs создается экземпляр класса THtErrDisp, который возвращает public функция HtErrDisp. Этот класс отображает передаваемые ему исключения аналогично Application.ShowExceptionGUI приложениях) или записывает соответствующие сообщения в STD_ERROR_HANDLE (в консольных приложениях). Пользователь может назначить коллектором экземпляр своего класса – наследника THtErrDisp (процедура SetHtErrDisp). Для сохранения сообщений в каком-либо потоке (TStream) в модуле htdefs уже имеется соответствующий наследник THtErrDisp: THtStreamErrDisp. Достаточно только создать его экземпляр и назначить коллектором.


THtUpdateSQL и модификация join.


Сложность модификации запросов по нескольким таблицам заключается в том, что технология HyTech предполагает работу со "снимками" БД, и, как результат, изменение таблицы не влечет за собой изменение в уже построенных результатах. Приходится выполнять две модификации - таблиц и курсора - одновременно. Вопрос в том, как эти модификации представить одной транзакцией (модификация таблиц осуществляется SQL запросом, а модификация результата - функциями API). Было испробовано несколько вариантов; последний (реализованный) накладывает некоторые требования к модификационному SQL выражению.


Технология.


Для добавления в результат нового элемента надо этот элемент сформировать и воспользоваться API функцией для вставки. Для формирования элемента проще и надежней выполнить такой же select, но отбирающий лишь одну связку - для добавленной или измененной записи основной таблицы. Из курсора этого select'а и можно извлечь нужный элемент результата. Рассмотрим для примера некоторое штатное расписание из трех таблиц:


Сотрудники: JOBBERS(id dword surrogate, name char(16));

Проекты: PROJECTS (id dword surrogate, name char(16));

Должности: STATUS (jobber dword key, project dword key, year word key, name char(16));


и предположим, что единовременно сотрудник может участвовать в нескольких проектах на разных должностях и занимать только одну должность в одном проекте. Пусть таблица STATUS будет связующей для таблиц JOBERS и PROJECTS.

Тогда основной HtQuery.Script содержит следующее выражение:


fix JOBBERS; fix PROJECTS; fix STATUS;

select j.recno, p.recno, s.recno, j.id, p.id, s.year, s.jobber,

s.project, j.name, p.name, s.name

from JOBBERS j, PROJECTS p, STATUS s

where s.year = :YEAR and

j.id = s.jobber and p.id = s.project

order by s.project;


Т.е. мы хотим работать со штатным расписанием за год номер :YEAR. Часть отобранных полей нужна только для модификации и может не отображаться. Все recno в этом выражении нужны для сокращения обращений к серверу; при работе с локальным SQL их можно не селектировать.


HtQuery с этим запросом должен иметь ссылку на HtUpdateSQL, содержащий следующие SQL выражения:


DeleteSQL:

var err;

delete from status

where recno = :s.recno;

if(@err = lastsqlerr())

usersend(-1 , ’ошибка удаления [’+@err+’] ’+ sqlermsg(@err));

retcode(@err);

выполнятся удаление записи с номером :s.recno, который берется из основного курсора; затем проверяются ошибки. Запрос ОБЯЗАТЕЛЬНО должен вернуть код ошибки или нуль.


InsertSQL:

var err, rn;

begin work AAA table STATUS;

insert into STATUS(jobber, project, year, name)

values(:s.jobber, :s.project, :s.year, :s.name);

@rn = recnu(); // recno добавленной записи


if(@err = lastsqlerr()){

usersend(-1 , ’ошибка добавления [’+@err+’] ’+ sqlermsg(@err));

rollback work AAA;

retcode(@err);

quit;

}

commit work AAA;

if(@err = lastsqlerr()){

usersend(-1 , ’ошибка завершения транзакции [’+@err+’] ’+ sqlermsg(@err));

rollback work AAA;

retcode(@err);

quit;

}

retcode(@rn);

fix all;

select s.recno

from JOBBERS j, PROJECTS p, STATUS s

where s.recno = @rn and j.id = s.jobber and

p.id = s.project;


Производится добавление записи в таблицу STATUS под транзакцией. Значения для полей таблицы берутся из полей HtDataSet. SQL обязательно должен вернуть recno вновь добавленной записи (функция SQL recnu()) или код ошибки. Select в конце выражения обязателен и должен отбирать ту же связку таблиц и с теми же алиасами, что и основной select. Этим select'ом должна быть отобрана одна и только одна связка, что должно достигаться первым условием отбора (s.recno = @rn). Это условие (одно или более) лучше ставить первым в выражении where: при выполнении SQL множество записей сразу же ограничится только одной записью из каждой таблицы, что кардинально сократит время на их связывание (одна из самых длительных операций). Поля, отбираемые в операторе select, никак не используются. Достаточно указать recno одной из таблиц. Из полученного результата берется сам элемент результата (см. документацию на HyTech) и используется для вставки в курсор основного select’а.


ModifySQL:

var err;


begin work AAA table STATUS;

update STATUS

set jobber = :s.jobber, project = :s.project,

year = :s.year, name = :s.name

where recno = :s.recno;


if(@err = lastsqlerr()){

usersend(-1 , ’ошибка модификации [’+@err+’] ’+ sqlermsg(@err));

rollback work AAA;

retcode(@err);

quit;

}

commit work AAA;

if(@err = lastsqlerr()){

usersend(-1 , ’ошибка завершения транзакции [’+@err+’] ’+ sqlermsg(@err));

rollback work AAA;

retcode(@err);

quit;

}

retcode(0);


fix all;

select s.recno

from JOBBERS j, PROJECTS p, STATUS s

where s.recno = :s.recno

and j.id = s.jobber and p.id = s.project;


Производится изменение записи в таблице STATUS под транзакцией. Значения для полей таблицы берутся из полей HtDataSet. SQL обязательно должен вернуть 0 или код ошибки. Select в конце выражения обязателен и должен отбирать ту же связку таблиц и с теми же алиасами, что и основной select. Этим select'ом должна быть отобрана одна и только одна связка, что должно достигаться первым условием отбора (s.recno = :s.recno). Это условие (одно или более) лучше ставить первым в выражении where: при выполнении SQL множество записей сразу же ограничится только одной записью из каждой таблицы, что кардинально сократит время на их связывание (одна из самых длительных операций). Поля, отбираемые в операторе select, никак не используются. Обычно это recno одной из таблиц. Из полученного результата берется сам элемент результата (см. документацию на HyTech) и используется для замены элемента результата в курсоре основного select’а.


Советы по составлению SQL выражений


  • Перед каждым "select" не забывайте ставить "fix <имя_таблицы>" (или fix all), иначе можно не увидеть проделанных изменений;

  • При работе с сервером указывайте в операторе select физические номера записей таблиц (recno). Это не обязательное условие, но если recno не отселектирован, при операциях модификации будут выполняться дополнительные обращения к серверу для определения этих номеров, что будет замедлять работу по медленной линии связи или на загруженном сервере.

  • Если в SQL запросе нужно использовать переменные SQL, их лучше записывать как @VAR1, а не :VAR1 - HyTech все равно, а HtDataSet будет считать, что :VAR1 это параметр запроса.



Отладка SQL запросов


Для удобства отладки sql запросов в составе библиотеки имеется специальная утилита - SqlDbg.exe. Это приложение может запускать программы, использующие компоненты HyTech, или подключаться к уже работающим таким программам. Чтобы сделать любое приложение, использующее компоненты HyTech, доступным для работы с отладчиком, его нужно запустить с параметром “debug”. Параметры командной строки анализируются в модуле SqlDbg и в случае наличия параметра «debug» вызывается процедура DebugInit. При создании приложения можно включать возможность отладки этой процедурой или отключать в любой момент вызовом процедуры DebugDone.

После подключения к приложению в окне отладчика можно указать условия останова: по созданию компоненты THtBase или ThtDataSet, после ошибочного выполнения запроса, перед обработкой запроса препроцессором или перед выполнением запроса любой или конкретной компонентой. Когда приложение остановлено, текст обрабатываемого запроса доступен для просмотра и (если это не останов по ошибке) редактирования.


Компонента TMacrosList и утилита MacEdit


Как говорилось выше, для удобства хранения и модификации запросов в библиотеке имеется компонента TMacrosList. Этот компонент работает с текстовыми файлами, содержащими SQL запросы. Каждый запрос в файле имеет имя, указываемое в отдельной строке в квадратных скобках. Сам запрос начинается со следующей строки и продолжается до имени следующего запроса или до конца файла. TMacrosList имеет property FileName, в котором указывается имя такого файла. В процессе активизации TMacrosList индексирует файл для быстрого доступа к запросам по их именам. Компоненты THtDataSet и THtBase имеют property MacrosList – ссылку на компонент TCustomMacrosList, и, если в запросе встречается идентификатор, начинающийся двумя «диезами» (##), то препроцессор считает этот идентификатор именем запроса (макроса) и обращается к MacrosList за расшифровкой (более подробно см. HtDb.hlp, разделы TcustomSqlParser и TMacrosList).

Для удобства управления такими файлами существует утилита MacEdit, которая может работать как автономно, так и может быть вызвана из контекстного меню компоненты MacrosList.

Утилита MacEdit.exe находится в подкаталоге RTL, исходные тексты проекта – в подкаталоге MacEdit.


Известные проблемы



Для «локальной» HtmSql.dll не доработаны CallBack процедуры прогресс-индикаторов и простоя (Idle). Не подключена процедура «мягкого» прерывания выполнения запроса.