Книга: Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil

"Низкоуровневая" работа с внутренним буфером TpFIBDataSet

"Низкоуровневая" работа с внутренним буфером TpFIBDataSet

TpFIBDataSet включает несколько специальных методов для работы с внутренним буфером, в котором хранятся записи. В общем-то, данные методы превращают TpFIBDataSet в аналог TClientDataSet, ориентированный на InterBase. Наиболее интересным примером использования данных методов будет, пожалуй, построение диалога выбора, состоящего из двух списков (рис. 2.75).


Рис 2.75. Использование локального кеша TpFIBDataSet для организации двойного списка выбора

В данном примере мы будем использовать базу данных EMPLOYEE.GDB, входящую в стандартную поставку InterBase и FIBPlus. Покажем запросы для SourceDS:

SelectSQL:

SELECT

CUS.CUST_NO,

CUS.CUSTOMER

FROM

CUSTOMER CUS

ORDER BY CUS.CUSTOMER

UpdateSQL:

UPDATE CUSTOMER SET

CUSTOMER = ?CUSTOMER

WHERE

CUST_NO = ?OLD_CUST_NO

InsertSQL:

INSERT INTO CUSTOMER(

CUST_NO,

CUSTOMER

VALUES(

?CUST_NO,

?CUSTOMER

DeleteSQL:

DELETE FROM CUSTOMER

WHERE

CUST_NO = ?OLD_CUST_NO

RefreshSQL:

SELECT

CUS.CUST_NO,

CUS.CUSTOMER

FROM

CUSTOMER CUS

WHERE

CUS.CUST_NO = ?OLD_CUST_NO

Те же самые запросы мы будем использовать в TargetDS, поскольку оба компонента должны обладать совместимой структурой полей. Откроем оба запроса сразу после создания формы:

procedure TDualListForm.FormCreate(Sender: TObject);

begin

SourceDS.Open;

TargetDS.CacheOpen;

end;

Если мы не указываем в коде явного открытия базы данных, то это означает, что свойство Connected > компонета TpFlBDatabase было задано в True в design-time.

Обратите внимание на то, что TargetDS мы активируем при помощи специального метода CacheOpen. Этот метод не выполняет запрос из SelectSQL, а только подготавливает внутренний буфер компонента в зависимости от запроса в SelectSQL. Очевидно, что после запуска приложения мы увидим записи в левом списке и пустую таблицу в правом. Теперь мы можем написать процедуру, которая позволит переносить записи из одного списка в другой:

procedure TDualListForm.MoveRec(Select: Boolean);

begin

if Select then begin

if (SourceDS.Active) and (not SourceDS.IsEmpty) then begin

TargetDS.CacheRefreshByArrMap(SourceDS, frklnsert,

['CUST_NO'], ['CUST_NO']);

SourceDS.CacheDelete;

end;

end

else begin

if (TargetDS.Active) and (not TargetDS.IsEmpty) then begin

SourceDS.CacheRefresh(TargetDS, frklnsert, nil);

TargetDS.CacheDelete;

end;

end;

end;

Если параметр Select равен True, то мы будем переносить текущую запись из левого списка в правый, т. е. из SourceDS в TargetDS. Рассмотрим подробнее метод CacheRefreshByArrMap.

procedure CacheRefreshByArrMap(FromDataSet: TDataSet; Kind:

TCachRefreshKind; const SourceFields, DestFields: array of

String);

Метод позволяет вставлять или модифицировать текущую запись в локальный буфер компонента, т. е. без выполнения соответствующих модифицирующих запросов. Параметр FromDataSet указывает, из какого TpFIBDataSet мы хотим получить запись. Параметр Kind может принимать два значения: frkEdit или frklnsert. Frklnsert указывает, что мы хотим вставить новую запись, a frkEdit - что мы хотим изменить существующую. Параметр SourceFields описывает список полей из компонента источника, а список DestFields - список полей в TpFIBDataSet-приемнике. Формально названия полей в списках могут не совпадать, но необходимо, чтобы совпадали типы данных, иначе обмен данными будет невозможен. В нашем примере, как вы можете видеть, мы вставляем в TargetDS текущую запись из SourceDS. Данный метод использован здесь только для демонстрации, поскольку мы вполне могли бы обойтись методом CacheRefresh, который копирует соответствующие поля автоматически. После вставки записи необходимо удалить ее из компонента источника. Это делается при помощи метода CacheDelete, который также не выполняет соответствующий запрос (DeleteSQL), а удаляет запись только из локального буфера в памяти. Теперь, когда мы знаем, что делают процедуры CacheRefreshByArrMap, CacheRefresh и CacheDelete, код процедуры достаточно очевиден: мы копируем запись из компонента-источника в компонент-приемник и удаляем ее из компонента-источника.

То же самое можно сделать в цикле, если мы хотим перенести все записи сразу:

procedure TDualListForm.MoveAll(Select: Boolean);

var TmpDataSet: TpFIBDataSet;

begin

if Select then TmpDataSet := SourceDS else

TmpDataSet := TargetDS;

with TmpDataSet do begin

try

DisableControls;

First;

while not Eof do MoveRec(Select);

finally

EnableControls;

end;

end;

end;

Остается написать обработчики события OnClick для кнопок:

procedure TDualListForm.ButtonlClick(Sender: TObject);

begin

MoveRec(True); // SourceDS -> TargetDS

end;

procedure TDualListForm.Button2Click(Sender: TObject);

begin

MoveRec(False); // TargetDS -> SourceDS

end;

procedure TDualListForm.Button3Click(Sender: TObnect);

begin

MoveAll(True), // SourceDS -> TargetDS

end;

procedure TDualListForm. Button4Click (Sender : TObject) ;

begin

MoveAll(False); // TargetDS -> SourceDS

end;

Мы можем запустить наше приложение (рис 2.76)

Если мы будем нажимать на кнопку Button 1, то записи будут переноситься из левого списка в правый (рис. 2 77).

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

OpenAsCIone - открыть DataSet и скопировать данные из другого DataSet

CacheAppend - добавить запись в конец локального буфера.

SwapRecords - обменять записи в локальном буфере.

CacheEdit - задать значения полей у записи в локальном буфере.

Cachelnsert - вставить запись в локальный буфер

CacheModify - общий метод для вставки и изменения записи в локальным буфере

LoadFromFile - заполнить локальный буфер записями из файла.

LoadFromStream - заполнить локальный буфер записями из потока.

SaveToFile - сохранить локальный буфер в файл.

SaveToStream - сохранить локальный буфер в потоке

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


Рис 2.76. Внешний вид запущенного приложения


Рис 2.77. Внешний вид приложения при выборе пользователем трех записей

Оглавление книги


Генерация: 1.495. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз