Начало » Использование СУБД » Firebird, HQbird, InterBase » Как в приложении одновременно использовать fbembedded разных версий? (Несколько firebird embedded в одном приложении одновременно.)
Как в приложении одновременно использовать fbembedded разных версий? [сообщение #512] |
Wed, 07 September 2022 11:43 |
Сообщений: 197 Зарегистрирован: September 2022
|
Senior Member |
|
|
Создается утилита, выполняющая преобразование файла базы из формата fb 2.0 в 3.0.
Предполагается использование fb embedded, библиотека fib+ и компоненты TpFIBBackupService/TpFIBRestoreService
Можно ли в одно приложение одновременно загрузить обе версии клиентских библиотек?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Как в приложении одновременно использовать fbembedded разных версий? [сообщение #572 является ответом на сообщение #553] |
Tue, 13 September 2022 15:02 |
Сообщений: 197 Зарегистрирован: September 2022
|
Senior Member |
|
|
МорскойДесант писал(а) Mon, 12 September 2022 19:09
Если отдельно запустить TpFIBRestoreService с "embedded" (локальный коннект) fb 3.0, то рестор отрабатывает.
А если после TpFIBBackupService (с embedded 2.0 или 2.5), то получаю исключение сообщением, что модуль engine12.dll найден, но не загружен.
Зараза такая, снова "искусственный интеллект" TpFIBPlus:
При аттаче к сервисам загруженная клиентская библиотека, которая инкапсулируется в объекте класса TIBClientLibrary. Класс реализует интерфейс IIbClientLibrary. Список реализаций интерфейсов хранится в vClientLibs:TInterfaceList в разделе реализации модуля IB_Intf, т.е., недоступен.
Средство для принудительной выгрузки библиотеки есть - это метод интерфейса FreeIBLibrary. Но после вызова FreeIBLibrary() интерфейс остается торчать в списке.
Средств явной загрузки библиотеки нет, загружается закэшированный интерфейс (ключ - строка, имя фала библиотеки), а проверки на то, что библиотека выгружена - нет.
Тьпху...
Пришлось править модуль IB_Intf, добавить процедуру RemoveClientLibrary:
procedure RemoveClientLibrary(const aLibName:string);
var
I: Integer;
begin
EnterCriticalSection(vLibAccess);
try
for I := 0 to Pred(vClientLibs.Count) do
if IIbClientLibrary(vClientLibs[i]).LibraryName=aLibName then begin
vClientLibs.Delete(i);
Exit
end;
finally
LeaveCriticalSection(vLibAccess);
end;
end;
В общем, вот так всё работает:
Бэкап:
var
fsvcBackup : TpFIBBackupService;
...
begin
...
fsvcBackup := TpFIBBackupService.Create(nil);
try
fsvcBackup.LibraryName := 'путь_fb_20\fb_20_LibraryName.dll';
...
<турник, анжуманя>
...
finally
fsvcBackyp.Free();
IB_Intf.RemoveClientLibrary('путь_fb_20\fb_20_LibraryName.dll')
end
Рестор:
[code]
var
fsvcRestore : TpFIBRestoreService;
...
begin
...
fsvcRestore := TpFIBBackupService.Create(nil);
try
fsvcRestore.LibraryName := 'путь_fb_30\fb_30_LibraryName.dll';
...
<анжуманя, пресс качат>
...
finally
fsvcRestore.Free();
IB_Intf.RemoveClientLibrary('путь_fb_30\fb_30_LibraryName.dll')
end
...
Если кто-то подскажет путь без правки исходников fib+, буду благодарен.
|
|
|
|
|
|
|
|
|
|
Переход к форуму:
Текущее время: Fri Nov 22 04:02:45 GMT+3 2024
Общее время, затраченное на создание страницы: 0.01008 секунд
|