ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.04.2021

Просмотров: 1871

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

!

56

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

10. 

Уг
лу
бл

ен

но

е

из

уч

ен
ие

C
A

L

L-

ин

те

рф

ей

са

!

!

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

  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.

Закрывается

канал

Сборка

примера

должна

осуществляться

с

указанием

используемой

версии

СУБД

ЛИНТЕР

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.

Происходит

событие

завершается

обработка

запроса

по

курсору

и

управление

передается

в

процедуру

асинхронной

обработки


background image

!

!

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

10. 

Уг
лу
бл

ен

но

е

из

уч

ен
ие

C
A

L

L-

ин

те

рф

ей

са

!

57

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

7.

Поскольку

из

асинхронного

обработчика

можно

вызывать

функцию

  inter 

только

асинхронно

то

очистка

события

также

происходит

в

асинхронном

режиме

8.

Закрывается

соединение

и

освобождаются

ресурсы

библиотеки

Асинхронный

обработчик

как

видно

из

вывода

примера

срабатывает

до

окончания

синхронной

операции

вставки

данных

в

таблицу

.

Вставка

по

каналу

 4... – 

синхронная

команда

на

вставку

стартовала

  

Вставка

выполнена

 – 

сработал

асинхронный

обработчик

ожидания

события

Очистка

события

...

готово

 – 

произошла

очистка

события

(

удаление

из

очереди

Вставка

выполнена

. – 

завершилась

синхронная

команда

вставки

записи

Заметим

что

событие

инициируется

в

момент

любой

вставки

и

остается

актуально

до

тех

пор

пока

его

не

очистить

Поэтому

если

сначала

выполнить

вставку

а

затем

включить

режим

ожидания

то

ожидание

события

сразу

же

получит

ответ

 (

т

.

к

событие

было

выставлено

предыдущей

вставкой

). 

В

коде

примера

следует

обратить

внимание

на

то

как

передается

адрес

процедуры

и

указывается

флаг

асинхронности

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

Cbl->LnBufRow = 0; 

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

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

Задача

  8.

Модифицировать

данный

пример

чтобы

при

удалении

данных

в

специальную

таблицу

вставлялись

данные

о

количестве

удаленных

строк

и

времени

удаления

 (

реализовать

это

используя

 CALL-

интерфейс

и

асинхронную

обработку

событий

(

без

триггеров

)).


background image

!

!

!

58

E-mail: market@relex.ru

ЗАО

НПП

 «

РЕЛЭКС

»

http://www.relex.ru

Практическое

занятие

 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, 

              WORD con_id,


background image

!

!

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

11. 

Ос

но

вн

ые

пр

ие

м

ы

ис

по

ль

зо

ва

ни

я

Li

n

A

PI

!

59

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

              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)); 

        } 

    } 

   LINTER_CloseAPI(); /* Free library resource */ 

   exit(1); 

  } 

 else 

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


background image

!

60

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

11. 

Ос

но

вн

ые

пр

ие

м

ы

ис

по

ль

зо

ва

ни

я

Li

n

A

PI

!

!

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

#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)) 

   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))