Кэширование и редактирование данных
Компонент TClientDataSet – основной компонент синтеза ЭД
Компонент TСlientDataSet используется в клиентской части многозвенного распределенного приложения, а также как самостоятельный компонент работы с локальным набором данных. Компонент инкапсулирует набор данных, переданный при помощи компонента-провайдера из удаленного набора данных. Компонент обеспечивает выполнение следующих основных функций:
- получение данных от удаленного сервера и передача ему сделанных изменений с использованием удаленного компонента-провайдера;
- представление набора данных при помощи локального буфера и поддержка основных операций, унаследованных от класса TDataSet;
- объединение записей набора данных при помощи агрегатных функций для получения суммарных данных;
- локальное сохранение набора данных в файле и последующее восстановление набора данных из файла;
- представление набора данных в формате XML.
Предком компонента TСlientDataSet является класс TDataSet, поэтому TClientDataSet обладает таким же набором функций, что и обычный компонент, инкапсулирующий набор данных. Основное же отличие заключается в том, источник данных для него доступен посредством удаленного компонента-провайдера, либо непосредственно из XML (CDS) файла. Это означает, что сохранение изменений и обновление набора данных осуществляется локально, без обращения к источнику данных.
Например, выполнение метода Post приведет лишь к сохранению текущей записи набора данных в локальном КЭШе либо файле. Все изменения отсылаются на сервер только при необходимости и легко управляются разработчиком.
Как и обычный компонент, компонент TClientDataSet может использоваться совместно с визуальными компонентами отображения данных. Для этого используется компонентTDataSource.
Получение данных от компонента - провайдера
Компонент TClientDataSet получает доступ к удаленным данным через компоненты соединения DataSnap. В зависимости от используемой технологии, это могут быть технологии TDCOMConnection, TSocketConnection, TWebConnection ИЛИ TCorbaConnection.
Компонент TClientDataSet связывается с компонентом соединения при помощи свойства RemoteServer;
Если соединение настроено правильно, то ссылка на интерфейс IAppServer в свойстве AppServer совпадает со свойством ClientDataSet.RemoteServer.AppServer;
После настройки соединения в свойстве ProviderName можно выбрать один из компонентов-провайдеров, которые доступны на сервере приложений, выбранном в компоненте соединения.
Если провайдер был подключен правильно, свойство (только для чтения) HasAppServer автоматически принимает значение True.
Теперь компонент готов к приему данных. При использовании метода Open или свойства Active компонент получает от провайдера первый пакет данных.
Размер пакета определяется свойством PacketRecords которое задает число записей, передаваемое в одном пакете. Если свойство имеет значение —1 (это значение по умолчанию), передаются все записи набора данных. Если оно равно 0 — клиенту передаются только метаданные о наборе данных.
Если соединение клиента с сервером медленное, число записей в пакете можно уменьшить, но желательно так, чтобы при использовании компонентов TDBGrid полученные в одном пакете записи полностью заполняли рабочую область этого компонента.
Одновременно разработчик имеет возможность управлять доставкой следующих пакетов. Для этого используется метод GetNextPacket.
Кэширование и редактирование данных
После получения записей от провайдера набор данных сохраняется в локальном буфере памяти. И все вносимые изменения после применения метода Post также сохраняются локально и не пересылаются на сервер. Буфер изменений доступен при помощи свойства Delta. Для передачи изменений на сервер используется метод ApplyUpdates. После выполнения метода ApplyUpdates все записи, сохранить которые не удалось, возвращаются клиенту в локальный буфер Delta.
Если клиентское приложение будет редко изменять свои наборы данных, сохранение изменений на сервере можно связать с обработчиком события AfterPost:
procedure TForml.ClientDataSetAfterPost(DataSet: TDataSet);
beginClientDataSet.ApplyUpdates(-1); end;
Свойство, (только для чтения) ChangeCount возвращает общее число изменений, содержащееся в буфере Delta. Для очистки буфера изменений используется метод CancelUpdates. После вызова указанного метода свойство ChangeCount принимает значение 0.
Несмотря на сделанные локально многократные изменения, запись может быть восстановлена в первоначальном виде. Метод RefreshRecord получает от провайдера первоначальный вариант текущей записи, сохраненный на сервере.
Но что делать, если необходимо восстановить удаленную запись? В обычном наборе данных после сохранения это невозможно. В компоненте TClientDataSet существует метод UndoLastChange, который возвращает набор данных к состоянию до последней выполненной операции редактирования, добавления или удаления записи. Если параметр FollowChange имеет значение True, курсор набора данных будет установлен на восстановленную запись.
О состоянии текущей записи позволяет судить метод UpdateStatus, который возвращает значение типа TUpdateStatus = (usUnmodified, usModified, uslnserted, usDeleted), означающее состояние текущей записи:
usUnmodified — запись осталась неизменной;
usModified — запись была изменена;
uslnserted — запись была добавлена;
usDeleted — запись была удалена.
Например, при закрытии набора данных можно выполнить проверку:
if ClientDataSet.UpdateStatus = usModified then ShowMessage('Record was changed');
На основе типа можно управлять видимостью записей в наборе данных. Свойство StatusFilter определяет, какой тип записей будет отображаться в наборе данных. Например:
ClientDataSet.StatusFilter := usDeleted;
отобразит в наборе данных только удаленные записи (при этом изменения не сохранены на сервере).