Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LINTER от 04.02.15

.pdf
Скачиваний:
44
Добавлен:
21.05.2015
Размер:
2.16 Mб
Скачать

Практическое занятие 10. Углубленное изучение CALL-интерфейса 61

 

из таблицы удаляются все записи по любому из курсоров;

 

делается выборка из таблицы по любому из курсоров;

 

фиксируются изменения по любому из курсоров;

 

откатываются изменения по любому из курсоров;

19. Закрывается канал.

Студенты должны попробовать выполнять разные действия по разным курсорам и посмотреть, как работает механизм подчиненных курсоров.

Следует обратить внимание на то, что номер родительского канала устанавливается в CBL дочернего Следующим образом:

Cursor[i].NumChan = Cbl.NumChan;

Cursor[i].PrzExe = M_OPTIMISTIC;

memcpy(Cursor[i].Command,"OCUR",4);

/* Open cursor */

inter(Cursor + i,NULL,NULL,NULL,NULL);

Необходимо иметь в виду, что управляющий блок Cursor[I] перед этим должен быть очищен, чтобы другие поля не содержали неправильной информации (например, если в поле Node окажется «мусор», то результатом операции будет 1001). Другой вариант – просто скопировать содержимое управляющего блока основного соединения в управляющий блок курсора перед установкой специфических полей.

Для самостоятельного решения предлагается одна из задач:

Задача 5. Модифицировать данный пример, добавив возможность ввода пользователем режимов обработки транзакций. Внимательно посмотреть отличия в работе примера в оптимистичном и пессимистичном режимах.

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

10.4. Получение структуры ответа

В случае, когда структура ответа неизвестна (например, идет выполнение запроса, заданного пользователем), необходимо выяснить структуру ответа. Для этого предназначена команда GETA.

Пример prac10_e4 иллюстрирует работу данной команды. Алгоритм его работы

таков:

1.Открывается канал.

2.Пользователь вводит SELECT-запрос.

3.Запрос исполняется.

4.Выбирается количество столбцов в ответе.

5.Выбирается описание столбцов.

6.Закрывается канал.

Сборка примера должна осуществляться с указанием используемой версии СУБД ЛИНТЕР:

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

62 Практическое занятие 10. Углубленное изучение CALL-интерфейса

gcc prac10_e4.c -I /export/home/lindesk/linter5923/linter/intlib/ /export/home/lindesk/linter5923/linter/intlib/intlib.o -o prac10_e4 -lsocket -D_VER_MAX=590

В данном примере описание столбцов выбирается по одному, хотя более эффективно было бы выбирать группами по N элементов. N = <максимальный размер ответа> / <размер дескриптора столбца, или sizeof(GETA_OUT). Максимальный размер ответа равен 4 Кб.

Задача 7. Модифицировать данный пример, чтобы выборка дескрипторов столбцов осуществлялась блоками.

10.5. Асинхронное выполнение запроса

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

Алгоритм работы примера prac10_e5 таков:

1.Открывается канал и подчиненный курсор.

2.Делается попытка создать таблицу PRAC10_T1.

3.Создается событие на добавление строки в таблицу.

4.По курсору выполняется команда ожидания события, которая будет обрабатываться асинхронно.

5.Пользователь в любой момент может подать запрос на вставку данных в таблицу.

6.Происходит событие, завершается обработка запроса по курсору, и управление передается в процедуру асинхронной обработки.

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

8.Закрывается соединение, и освобождаются ресурсы библиотеки.

Асинхронный обработчик, как видно из вывода примера, срабатывает до окончания синхронной операции вставки данных в таблицу.

Вставка по каналу 4... – синхронная команда на вставку стартовала

Вставка выполнена – сработал асинхронный обработчик ожидания события

Очистка события...готово – произошла очистка события (удаление из очереди)

Вставка выполнена. – завершилась синхронная команда вставки записи.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 10. Углубленное изучение CALL-интерфейса 63

Заметим, что событие инициируется в момент любой вставки, и остается актуально до тех пор, пока его не очистить. Поэтому если сначала выполнить вставку, а затем включить режим ожидания, то ожидание события сразу же получит ответ (т.к. событие было выставлено предыдущей вставкой).

Вкоде примера следует обратить внимание на то, как передается адрес процедуры

иуказывается флаг асинхронности:

memcpy(Cbl->Command," ",4);

Cbl->LnBufRow = 0;

Cbl->PrzExe = Cbl->PrzExe | Q_ASYNC;

inter(Cbl,NULL,"clear event INS_T1;", onEventCleared, NULL);

Задача 8. Модифицировать данный пример, чтобы при удалении данных в специальную таблицу вставлялись данные о количестве удаленных строк и времени удаления (реализовать это, используя CALL-интерфейс и асинхронную обработку событий (без триггеров)).

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

64

Практическое занятие 11 Основные приемы использования LinAPI

Практика 2 часа (Лекция 10)

На занятии будут приведены примеры, иллюстрирующие работу с СУБД ЛИНТЕР через прикладной интерфейс LinAPI.

11.1. Настройки компилятора

Для компиляции файлов с примерами необходимо указывать компилятору путь к файлам “linapi.h”, “decimals.h”, “tick.h”, а компоновщику к библиотекам “linapi”, “decimals”, “tick”.

Эти файлы и библиотеки поставляются в директории linter/intlib.

К примеру, в UNIX-системах, команда на компиляцию файла примера ins_linapi.c может выглядеть так:

gcc -I /export/home/lindesk/linter5923/linter/intlib/ ins_linapi.c -llinapi -ldecimals -ltick -L /export/home/lindesk/linter5923/linter/intlib/ -lsocket –lm

–o ins_linapi

11.2. Открытие соединения, курсора и выполнение запроса

Ниже представлен пример (prac12_e2.c), в котором консольное приложение делает попытку создать соединение, открыть курсор, и подать по нему команду по удалению и созданию таблицы, выполнить несколько операций по вставке данных.

#include <stdio.h> #include <stdlib.h>

#include "linapi.h"

 

#if defined(VXWORKS)

/* 05.03.02 */

#include "vxstart.h"

 

#endif

 

#ifdef _BCPP_

 

extern unsigned _stklen = 16383;

 

#endif

 

/* function for error processing for LinAPI */ void processing_error(LONG ret_cod,

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

65

WORD con_id,

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

66 Практическое занятие 11. Основные приемы использования LinAPI

WORD cur_id, WORD stmt_id, char * message)

{

LONG lRet;

LONG apierr = 0, error = 0, syserr = 0;

if ( ret_cod == LINAPI_ERROR )

{

/* getting error codes for required object */ if (lRet = LINTER_Error(con_id, cur_id, stmt_id,

&apierr, &error, &syserr, NULL, NULL)) printf("diagnostic error %ld\n",lRet);

else

{

printf("ApiErr = %ld, LinErr = %ld, SysErr = %ld\n%s\n",

apierr, error, syserr, message);

if ( (apierr == eLinterError) && error > 2000 && error < 3000)

{

/* getting string and position if syntax error is */ printf("Syntax error : line %d, position %d\n",

(short)syserr, *(short*)((char*)&syserr +2));

}

}

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 11. Основные приемы использования LinAPI 67

LINTER_CloseAPI(); /* Free library resource */ exit(1);

}

else

printf("Return code = %ld\n",ret_cod);

}

 

 

 

#if defined(VXWORKS)

/* 05.03.02 */

 

MainStart(apidata, 32*1024, UninitLinterClient)

 

#else

 

 

 

int main(void)

 

 

#endif

 

 

 

{

 

 

 

WORD

nConn;

/* connection identifier */

WORD

nCurs;

/* cursor identifier

*/

LONG

lRet;

/* return code */

 

/* Establish connection */ printf("\nConnect\n");

if (lRet = LINTER_Connect("SYSTEM", 0, "MANAGER", 0, NULL, mAutocommit, &nConn))

processing_error(lRet, nConn, 0, 0, "ERROR Linter_Connect");

/* cursor opening for query processing */ printf("Open cursor\n");

if (lRet = LINTER_OpenCursor(nConn, &nCurs, NULL, 0, mAutocommit))

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

68 Практическое занятие 11. Основные приемы использования LinAPI

processing_error(lRet, nConn, 0, 0, "Error open cursor");

LINTER_ExecuteDirect(nCurs, "drop table PRAC12_STUDENT;", 0, NULL,NULL);

if (lRet = LINTER_ExecuteDirect(nCurs, "create table PRAC12_STUDENT(num int not null primary key, fio char(250) not null, skurs int default 1, sgroup int default 1 );", 0, NULL,NULL))

processing_error(lRet, 0, nCurs, 0,"Error ExecuteDirect");

printf("Inserting [");

if (lRet = LINTER_ExecuteDirect(nCurs, "insert into PRAC12_STUDENT values (1, 'Petrov A.I.', 5, 6);", 0, NULL,NULL))

processing_error(lRet, 0, nCurs, 0,"Error ExecuteDirect");

printf(".");

if (lRet = LINTER_ExecuteDirect(nCurs, "insert into PRAC12_STUDENT values (2, 'Voronin M.V.', 2, 1);", 0, NULL,NULL))

processing_error(lRet, 0, nCurs, 0,"Error ExecuteDirect");

printf(".");

if (lRet = LINTER_ExecuteDirect(nCurs, "insert into PRAC12_STUDENT values (3, 'Dzuba R.A.', 3, 4);", 0, NULL,NULL))

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 11. Основные приемы использования LinAPI 69

processing_error(lRet, 0, nCurs, 0,"Error ExecuteDirect");

printf(".");

printf("]\n");

printf("Cursor closing\n");

if (lRet = LINTER_CloseCursor(nCurs)) processing_error(lRet, 0, nCurs, 0,"Error CloseCursor"); printf("Connection closing\n");

if (lRet = LINTER_CloseConnect(nConn))

processing_error(lRet, nConn, 0, 0, "ERROR CloseConnect");

printf("LINTER_CloseAPI\n");

LINTER_CloseAPI(); /* Free library resource */

printf("Done.\n"); return 0;

/* End */

}

Скомпилируем этот файл:

gcc prac12_e1.c -I /export/home/lindesk/linter5923/linter/intlib/ -llinapi - lsocket -lm -L /export/home/lindesk/linter5923/linter/intlib/ -o prac12_e1

Задача 1. (Студенты выполняют самостоятельно) Модифицировать данный пример таким образом, чтобы входные данные задавались пользователем, а первичный ключ определялся приложением, как минимальный из положительных чисел.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

70 Практическое занятие 11. Основные приемы использования LinAPI

11.3. Использование параметризованных запросов

Ниже представлен пример (prac12_e2.c), в котором консольное приложение позволяет пользователю ввести маску для поиска данных в таблице, и, используя оператор, выполняет параметризированный запрос.

#include <stdio.h> #include <stdlib.h>

#include "linapi.h"

 

#if defined(VXWORKS)

/* 05.03.02 */

#include "vxstart.h"

 

#endif

 

#ifdef _BCPP_

 

extern unsigned _stklen = 16383;

 

#endif

 

/* function for error processing for LinAPI */ void processing_error(LONG ret_cod,

WORD con_id, WORD cur_id, WORD stmt_id, char * message)

{

LONG lRet;

LONG apierr = 0, error = 0, syserr = 0;

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]