Упражнение 5.7: Пакетирование на стороне клиента
Задание 7
В этом задании мы создадим клиентскую процедуру clientCust.p, которая будет извлекать пакеты данных с помощью серверной процедуры fetchCustomer.p. Эта процедура будет использовать внутреннюю процедуру GetMoreData как обработчик события OFF-END для состояния QUERY-OFF-END. После этого протестируем наш код.
Шаг |
Действие |
1 | Создайте новый каталог с именем Batching в каталоге src проекта Client. |
2 | Создайте новую ABL-процедуру с именем clientCust.p в каталоге Batching. |
3 | Процедура clientCust.p будет использовать то же описание набора данных что и серверный код. Поэтому добавьте в неё оператор встраивания файла include/dsCustomer.i.
{include/dsCustomer.i} |
4 | Опишите переменную hApplicationServer типом данных HANDLE, которая будет использоваться для подключения к серверу приложений.
DEFINE VARIABLE hApplicationServer AS HANDLE NO-UNDO. |
5 | Опишите переменную ConnectionString с типом данных CHARACTER с начальным значением в виде строки с параметрами подключения к серверу. Скопируйте описание переменной и параметров подключения из процедуры access_dsPO_procs.p.
DEFINE VARIABLE ConnectionString AS CHARACTER NO-UNDO INITIAL "-URL http://localhost:50310/apsv". |
6 | Опишите запрос qryCustomer для таблицы ttCustomer.
DEFINE QUERY qryCustomer FOR ttCustomer. |
7 | Опишите переменную rowRestart с типом данных ROWID, которая будет использоваться для передачи серверной процедуре идентификатора начальной записи в следующем пакете данных. А также переменную batchSize с типом данных INTEGER, для установки размера пакета.
DEFINE VARIABLE rowRestart AS ROWID NO-UNDO. DEFINE VARIABLE batchSize AS INTEGER NO-UNDO INITIAL 10. |
8 | Создайте подключение к серверу приложений:
CREATE SERVER hApplicationServer. hApplicationServer:CONNECT(ConnectionString,"Batching"). |
9 | Нам необходимо, чтобы состояние QUERY-OFF-END вызывало событие запроса набора данных OFF-END. Обработчик этого события будет извлекать данных с сервера до тех пор, пока не закончатся данные для извлечения. Добавьте оператор установки обработчика этого события для запроса qryCustomer используя процедуру обработчика GetMoreData.
В нашем примере обработчик событий будет представлять собой внутреннюю процедуру в файле clientCust.p. Поэтому не нужно создавать отдельную внешнюю процедуру для размещения обработчиков, как мы делали это ранее. Просто укажите имя процедуры при вызове SET-CALLBACK. QUERY qryCustomer:SET-CALLBACK-PROCEDURE("OFF-END","GetMoreData"). |
10 | Откройте вывод в файл C:\OpenEdge\WRK\ProDataSets\log\batch.txt.
OUTPUT TO "C:\OpenEdge\WRK\ProDataSets\log\batch.txt". |
11 | Извлеките первую партию данных, передав ROWID с которого должно начаться извлечение. При первом извлечении значение переменной rowRestart будет не определено (?), поэтому извлечение начнётся с первой записи в таблице. Для всех последующих вызовов серверной процедуры будет использоваться значение ROWID полученное с сервера с помощью атрибута NEXT-ROWID источника данных srcCustomer.
RUN Batching/fetchCustomer.p PERSISTENT ON hApplicationServer (batchSize, INPUT-OUTPUT rowRestart, OUTPUT DATASET dsCustomer ). |
12 | После возвращения набора данных с сервера откройте запрос qryCustomer и обработайте полученные данные как показано в этом коде:
OPEN QUERY qryCustomer FOR EACH ttCustomer BY ttCustomer.CustNum. QUERY qryCustomer:GET-NEXT(). DO WHILE NOT QUERY qryCustomer:QUERY-OFF-END: MESSAGE "CustNum:" ttCustomer.CustNum " Customer Name: " ttCustomer.Name. QUERY qryCustomer:GET-NEXT(). END. Мы уже рассматривали этот код ранее, поэтому я не будут описывать его назначение. |
13 | Закройте вывод в файл, отключитесь от сервера приложений и удалите хэндл сервера приложений.
hApplicationServer:DISCONNECT(). DELETE OBJECT hApplicationServer. RETURN. |
14 | В конце файла, после оператора RETURN, добавьте процедуру обработчика событий с именем GetMoreData.
PROCEDURE GetMoreData: DEFINE INPUT PARAMETER DATASET FOR dsCustomer. IF NOT BUFFER ttCustomer:LAST-BATCH THEN DO: MESSAGE "Getting more data from the server.......". RUN Batching/fetchCustomer PERSISTENT ON hApplicationServer (batchSize, INPUT-OUTPUT rowRestart, OUTPUT DATASET dsCustomer APPEND). RETURN NO-APPLY. END. ELSE MESSAGE "No more data.......". RETURN. END PROCEDURE. Здесь, если атрибут LAST-BATCH таблицы ttCustomer равен TRUE, то в файл записывается сообщение об отсутствии данных. Иначе, записывается сообщение о продолжении извлечения и выполняется процедура fetchCustomers.p с соответствующими параметрами. Обязательное условие – выполнения оператора RETURN, который возвращает NO-APPLY, в результате чего состояние QUERY-OFF-END будет сброшена на FALSE. |
15 | Сохраните изменения и убедитесь в отсутствии ошибок компиляции. |
16 | Поскольку мы изменяли серверный код, то перезапустите сервер приложений ProDataSets. Убедитесь, что он перешёл в состояние «Started, Synchronized». |
17 | Выполните программу clientCust.p. Проверьте файл batch.txt.
Данные извлекались порциями по 10 штук? |
18 | Полный код процедуры clientCust.p:
{include/dsCustomer.i} DEFINE VARIABLE hApplicationServer AS HANDLE NO-UNDO. DEFINE VARIABLE ConnectionString AS CHARACTER NO-UNDO INITIAL "-URL http://localhost:50310/apsv". DEFINE QUERY qryCustomer FOR ttCustomer. DEFINE VARIABLE rowRestart AS ROWID NO-UNDO. DEFINE VARIABLE batchSize AS INTEGER NO-UNDO INITIAL 10. CREATE SERVER hApplicationServer. hApplicationServer:CONNECT(ConnectionString,"Batching"). QUERY qryCustomer:SET-CALLBACK-PROCEDURE("OFF-END","GetMoreData"). OUTPUT TO "batch.txt". RUN Batching/fetchCustomer.p PERSISTENT ON hApplicationServer (batchSize, INPUT-OUTPUT rowRestart, OUTPUT DATASET dsCustomer). OPEN QUERY qryCustomer FOR EACH ttCustomer BY ttCustomer.CustNum. QUERY qryCustomer:GET-NEXT(). DO WHILE NOT QUERY qryCustomer:QUERY-OFF-END: MESSAGE "CustNum:" ttCustomer.CustNum " Customer Name: " ttCustomer.Name. QUERY qryCustomer:GET-NEXT(). END. OUTPUT CLOSE. hApplicationServer:DISCONNECT(). DELETE OBJECT hApplicationServer. MESSAGE "Done!" VIEW-AS ALERT-BOX. RETURN. PROCEDURE GetMoreData: DEFINE INPUT PARAMETER DATASET FOR dsCustomer. IF NOT BUFFER ttCustomer:LAST-BATCH THEN DO: MESSAGE "Getting more data from the server.......". RUN Batching/fetchCustomer PERSISTENT ON hApplicationServer (batchSize, INPUT-OUTPUT rowRestart, OUTPUT DATASET dsCustomer APPEND). RETURN NO-APPLY. END. ELSE MESSAGE "No more data.......". RETURN. END PROCEDURE. |