Реферат: MIDAS. Практическое применение
select NAME
from client
where CLIENT_ID = :TO_ID
into :TO_NAME;
if (FULL_SUM is NULL) then
FULL_SUM = 0;
suspend;
end
end
Процедура выдает то, что нужно для отчета, но, к сожалению, не в виде перекрестного отчета, а по строкам:
От кого | Кому | На сумму |
<Поставщик> | <Получатель> | Сумма ... |
... |
Приводить к нормальному виду все это будет сервер приложений.
Все готово для написания сервера приложений. Приступим.
Сервер приложений
Создаваемый нами сервер приложений будет отдельным исполняемым модулем. Этот модуль затем можно будет расположить на отдельном компьютере, который сможет производить расчеты для нескольких клиентов и синхронизировать их работу.
Сервер приложений должен обеспечивать обработку документа как единого объекта, поэтому разумным будет выделить работу с ним в отдельный класс, в данном случае потомок TRemoteDataModule. Нам также понадобится модуль данных для работы со справочником поставщиков и получателей, и выдачи списка документов. Отчет я решил также выделить в отдельный модуль. В итоге на сервере необходимо создать три потомка TRemoteDataModule: rdmCommon (общий модуль со списками поставщиков/получателей и документов), rdmDoc и rdmReport – соответственно для документа и отчета.
Мастер создания удаленного модуля данных предлагает по умолчанию политику загрузки исполняемого модуля Multiple instance и модель потоков Apartment. Это именно то, что нам нужно! Действительно, Instancing = Internal приведет к созданию серверного компонента в клиентском процессе (это распространяется только на сервер, создаваемый в виде DLL). При Single instance каждая клиентская часть будет соединяться со своим собственным экземпляром сервера приложений, а синхронизацию проще сделать, если все клиенты подсоединяются к одному экземпляру сервера приложений. Выбор модели потоков Apartment позволит избежать ручной синхронизации доступа к данным компонента.
Теперь остается создать три (опять три, это тоже случайно) потомка TRemoteDataModule, расположить на них компоненты доступа к данным и написать код для обработки данных.
При этом необходимо учитывать, что при использовании модели потоков Apartment каждый модуль данных работает в своем потоке, и поэтому в каждом модуле должен находится отдельный компонент TIBDatabase.
При прямом доступе провайдера к базе (свойство ResolveToDataset = false) MIDAS также требует наличия отдельной копии объекта TIBTransaction для каждого компонента доступа к данным, то есть у каждого провайдера должна быть своя транзакция. Компонент TIBTransaction специфичен для компонентов прямого доступа к Interbase, обычно работа с транзакциями возложена на компонент соединения с базой данных.
ПРИМЕЧАНИЕ При использовании сервера Interbase для доступа к данным по технологии MIDAS логично использовать IBX, провайдеры данных великолепно работают с этими компонентами. Единственное замечание – Borland сертифицировала на момент написания статьи версию IBX 4.52. Более поздние версии работают в составе MIDAS несколько иначе, чем раньше. В частности, транзакции теперь не закрываются автоматически после выборки данных. |
Рассмотрим удаленные модули данных по порядку, и начнем с модуля справочников (rdmCommon) (рисунок 2).
Рисунок 2. Общий модуль rdmCommon.
Компонент ibqDocs имеет тип TIBDatabase и обеспечивает соединение модуля с сервером БД. У меня БД находится в каталоге d:\projects\docmidas\data\ и называется doc.gdb. В прилагающемся к статье проекте сервер приложений позволяет указать произвольное местонахождение сервера БД и файла базы данных.
Для того, чтобы при каждом соединении сервер приложений не запрашивал имя пользователя и пароль, они просто указаны в параметрах соединения. Имя пользователя SYSDBA и пароль masterkey являются установками по умолчанию при инсталляции сервера Interbase.
Перечислим компоненты модуля. К компоненту транзакции ibtClient подсоединен запрос ibqClient (компонент TIBQuery), к которому, в свою очередь, присоединен провайдер dspClient. Соответственно, у транзакции и запроса указано соединение с БД ibdDocs. Остается только установить тип транзакции read committed (удобнее всего это сделать, дважды щелкнув на соответствующем компоненте, и выбрав его тип), и в свойстве SQL-запроса записать “select * from client”. Теперь провайдер может предоставлять клиентской части возможность работать со справочником клиентов. Но для повышения комфорта нужно добавить возможность нескольким пользователям изменять одновременно разные поля в одной и той же записи в таблице (их два: Name и Phone). Делается это довольно просто, в редакторе полей (Fields Editor) ibqClient нужно создать постоянный список всех полей запроса, и у поля CLIENT_ID в его свойство ProviderFlags добавить опцию pfInKey. Затем у провайдера dspClient установить свойство UpdateMode в upWhereChanged. В этом случае, если разные клиентские части изменят разные поля одной записи в таблице CLIENT, сервер приложений примет эти изменения. В случае, если будут изменены одни и те же поля одной записи, клиентской части будет выдано сообщение вида «Запись изменена другим пользователем».
ПРИМЕЧАНИЕ Здесь мне хотелось бы остановиться на свойствах TField.ProviderFlags и TDataSetProvider.UpdateMode. Дело в том, что меня часто спрашивают, что зависит от значений этих свойств, а зависит от них довольно много. В справке по VCL эти свойства описаны, на мой взгляд, недостаточно подробно, а связь между ними достаточно тесная. Итак, пусть имеется компонент TQuery, TIBQuery или какой-то другой (запрос), соединенный с сервером БД, и к нему присоединен TDataSetProvider. В этом случае на логику работы оказывают влияние именно значения свойства ProviderFlags полей этого запроса, аналогичные свойства полей на клиентской стороне никакого влияния не оказывают. Комбинация значений этих свойств полностью определяет, как будут производиться операции обновления данных на сервере БД. Рассмотрим обновление данных в таблице. Добавление и удаление записи происходит аналогично. К-во Просмотров: 833
Бесплатно скачать Реферат: MIDAS. Практическое применение
|