delete[] buffer;

retФийьтры BLOB (Binary Large Object - большой двоичный объект) -это программы на базовом языке, которые конвертируют данные BLOB из одноОпфюгрматап дракзйибс JфилцgнмсBELOBb грашш абмцакаьрж я еояа вд-лки:ти:зируеграаиназ10а1зшенмя1аыЕвзаых из BLOB.

Замечание. Фильтры BLOB не поддерживаются на серверах NetWare.

ФИЛЬТРАЦИЯ ДАННЫХ BLOB

Понимание роли подтипов BLOB особенно важно при работе с фильтрами BLOB. Фильтр BLOB - подпрограмма, которая транслирует данные BLOB одного подтипа в другой. InterBase включает набор специальных внутренних фильтров BLOB, которые конвертируют подтип О в подтип 1 (текст), и подтип 1 (текст) в подтип 0. В дополнение к стандартным фильтрам можно запрограммировать собственные внешние фильтры для обеспечения конвертирования других типов данных. Например, можно запрограммировать фильтр для трансляции растровых изображений или медиаданных одного формата в другой (другой вопрос, для чего это нужно делать именно в базе).

Замечание Фильтры BLOB можно использовать для баз данных на всех платформах сервера InterBase, кроме Netware, где фильтры BLOB не поддерживаются.

Использование стандартных текстовых фильтров InterBase

Стандартные фильтры InterBase конвертируют данные BLOB подтипа 0 или любого другого системного типа InterBase в подтип 1 (текст).

Когда текстовый фильтр используется для чтения данных столбца BLOB, он меняет стандартное поведение InterBase для обработки сегментов. Независимо от фактического характера сегментов в столбце BLOB, текстовый фильтр устанавливает правило, что сегменты должны закончиться символом перевода строки (\п).

Текстовый фильтр возвращает все символы, включая первый перевод строки как первый сегмент, следующие символы, включая второй перевод строки, как второй сегмент и так далее.

Для конвертирования любого нетекстового подтипа в текст следует объявлять его FROM-подтип как подтип 0, а его ТО-подтип как подтип 1.

Использование внешнихфильтров BLOB

В отличие от стандартных фильтров InterBase, которые выполняют трансляцию подтипов 0 и 1, внешний фильтр BLOB - вообще часть библиотеки подпрограмм, которая создается для конкретных приложений.

Чтобы использовать внешний фильтр, необходимо сначала запрограммировать его, откомпилировать, поместить в библиотеку (DLL в системе Windows), затем объявить в базе данных, содержащей данные BLOB, которые должны обрабатываться.

Объявление внешних фильтров в базе данных Для объявления внешних фильтров в базе данных используется команда DECLARE FILTER. Например, следующая команда объявляет фильтр TFILTER:

Пример 6.27

EXEC SQL

DECLARE FILTER TFILTER INPUT_TYPE -1 OUTPUT_TYPE -2 ENTRY_POINT "_TFilter"

MODULE_NAME "MYDLL.dll”;

В примере, входной подтип фильтра определен как -1, выходной как -

2. В этом примере, INPUTTYPE определяет текст нижнего регистра, a OUTPUT_TYPE определяет текст верхнего регистра. Цель фильтра TFILTER, таким образом, состоит в том, чтобы конвертировать данные BLOB из текста в нижнем регистре в текст верхнего регистра.

Параметры ENTRYPOINT и MODULE NAME определяют внешнюю подпрограмму, которую InterBase вызывает, когда запрашивается фильтр. Параметр MODULE_NAME определяет MYDLL.dll, динамически загружаемую библиотеку, содержащую выполнимый код фильтра. Параметр ENTRY_POINT определяет точку входа в DLL. В примере указана та же библиотека, что и для UDF, но можно поместить фильтры и в другую. Никаких ограничений на этот счет нет.

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

Схема работы фильтра BLOB (строчные в прописные)

Рис. 6.3. Схема работы фильтра BLOB (строчные в прописные).

Точно так же при чтении данных фильтр TFILTER может читать данные BLOB подтипа -2 и преобразовать их в подтип -1.

Схема работы фильтра BLOB (прописные в строчные)

Рис. 6.4. Схема работы фильтра BLOB (прописные в строчные).

Вызов фильтра в приложении Для вызова фильтра в приложении используется опция FILTER при объявлении курсора BLOB. Тогда при выполнении приложением операций, использующих курсор, InterBase автоматически вызывает фильтр.

Например, следующее определение курсора INSERT означает, что фильтр SAMPLE, должен использоваться в любых операциях с курсором BCINS1.

Пример 6.28

EXEC SQL

DECLARE BCINS1 CURSOR FOR INSERT BLOB BLOB1 INTO TABLE1 FILTER FROM -1 TO -2 ;

Когда InterBase обрабатывает это объявление, он ищет в списке фильтров, определенных в текущей базе данных, фильтр с соответствием подтипов FROM и ТО. Если такой фильтр существует, InterBase вызывает его при операциях с BLOB, использующих курсор BCINS1. Если InterBase не может найти такой фильтр, приложению возвращается сообщение об ошибке.

НАПИСАНИЕ ВНЕШНИХ ФИЛЬТРОВ Для написания собственных фильтров необходимо детальное понимание структуры транслируемых данных. InterBase не выполняет проверки данных BLOB, но требует совместимости типов исходного и результирующего BLOB. Поддержание совместимости лежит на разработчике фильтра.

Типы фильтров Фильтры разделяются на два типа: те, которые преобразовывают данные по одному сегменту, и те, которые преобразовывают данные множества сегментов одновременно.

Фильтры первого типа читают сегмент данных, преобразовывают его и возвращают результат приложению, второго - читают все данные при открытии курсора BLOB, выполняют все преобразование, а затем имитируют посегментную передачу их приложению. Если время и этапность обработки существенны для приложения, следует тщательно рассмотреть возможности применения того из типов, который в большей степени соответствует поставленной цели.

Read-only и write-only фильтры Некоторые фильтры могут поддерживать только чтение из BLOB или только запись в BLOB, но не обе операции. При попытке использовать фильтр BLOB для операции, которую он не поддерживает, InterBase возвращает приложению сообщение об ошибке.

Создание функций фильтров При создании фильтра необходимо указать точку входа, задающую имя функции фильтра в разделе объявлений программы. InterBase вызывает функцию фильтра, когда приложение выполняет операции с BLOB. Все связи между InterBase и фильтром реализуются функцией фильтра. Функция самого фильтра может вызывать другие функции, которые необходимы для выполнения программы фильтра. Далее фильтр должен быть объявлен в базе данных командой DECLARE FILTER с указанием параметров ENTRY_POINT В MODULE_NAME.

Функция фильтра должна иметь следующую сигнатуру:

filter_function_name(short action, isc_blob_ctl control);

Параметр action определяет одно из восьми возможных макроопределений действия, параметр control определяет управляющую структуру isc_blob_ctl данных BLOB. Определение структуры isc_blob_ctl дано в заголовочном файле InterBase ibase.h. Эти параметры будут рассмотрены ниже. Приведем теперь основные декларативные элементы функции фильтра (jpeg_filter).

Пример 6.39

tinclude <ibase.h>

#define SUCCESS 0 tdefine FAILURE 1

ISC_STATUS jpeg_filter(short action, isc_blob_ctl control)

{

ISC_STATUS status = SUCCESS; switch (action)

{

case isc_blob_filter_open:

break;

case isc_blob„filter_get_segment:

break;

case isc_blob_filter_create:

' I *

break;

case isc_blob_filter_put_segment:

break;

case isc_blob_filter_close:

break;

case isc_blob_filter_alloc:

break;

case isc_blob„filter^free:

break;

case isc_blob_filter_seek:

break;

default:

status = isc_uns_ext /* unsupported action value */

break;

}

return status;

}

InterBase передает одно из восьми возможных действий (параметр action) функции фильтрате#./?/teг() и экземпляр управляющей структуры BLOB (параметр isc_blob_ctl).

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

lscblobctl - управляющая структура BLOB; содержит основные данные для управления обменом между InterBase и фильтром.

Определениеуправляющей структурыBLOB

Управляющая структура isc_blob_ctl обеспечивает базовые методы обмена данными между InterBase и фильтром. Объявление управляющей структуры находится в заголовочном файле InterBase ibase.h. Для его подключения к программе используется инструкция

tinclude <ibase.h>.

typedef struct isc_blob_ctl{

ISC_STATUS (ISC_FAR *ctl_source)();

/* Source filter */ struct isc_blob_ctl ISC_FAR *ctl_source_handle;

/* Argument to pass to source */

/* filter */

short ctl_to_sub_type; /* Target type */

short ctl_from_sub_type; /* Source type */

unsigned short ctl_buffer_length; /* Length of buffer */

unsigned short ctl_segment_length; /* Length of current

segment */

unsigned short ctl_bpb_length; /* Length of blob pa

rameter */

/* block */

char ISC_FAR *ctl_bpb; /* Address of blob parameter */

/* block */

unsigned char ISC_FAR *ctl_buffer; /* Address of segment buffer */

ISC_LONG ctl_max__segment;/* Length of longest seg

ment */

ISC_LONG ctl_nmnber_segments; /* Total number of segments */

ISC_LONG ctl_total_length; /* Total length of blob */ ISC_STATUS ISC_FAR *ctl_status;/* Address of status vector */

long ctl_data [8]; /* Application specific data

*/

} ISC_FAR *ISC_BLOB_CTL;

Структура iscblobctl используется двумя способами:

1. Когда приложение исполняет операцию доступа к BLOB, InterBase вызывает функцию фильтра и передает ей экземпляр iscblobctl.

2. Функции фильтра могут передавать экземпляр isc_blob_ctl подпрограммам доступа к данным InterBase.

В любом случае назначение некоторых полей isc blob ctl зависит от выполняемого действия (параметр action). Например, когда приложение делает попытку вставки BLOB, InterBase передает функции фильтра действие-вставку (параметр action **- isc_blob_Jilter_put_segment). Функция фильтра передает экземпляр управляющей структуры InterBase.

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

В другом случае, например, когда приложение делает попытку выполнить команду FETCH, действие - выборка (параметр action = isc_blob_filter_get_segment). В функцию фильтра должна включаться группа команд для заполнения ctl_buffer данными сегмента из базы данных для его возврата приложению, вызвавшему функцию. Здесь буфер используется в функции фильтра как выходной.

В таблице ниже описываются поля управляющей структуры BLOB iscblobctl и характер их использования в функции фильтра (входные -IN, выходные - OUT).

Таблица 6.10. Управляющая структура BLOB isc blob ctl

Имя поля Описание
(*ctl_source)() Указатель на внутреннюю подпрограмму InterBase доступа к BLOB. (IN)
*ctl_source_handle Указатель на экземпляр isc_blob_ctl, который передается внутренней подпрограмме InterBase доступа к BLOB. (IN)
ctl_to_sub_type Указывает подтип BLOB-результата. Информационное поле. Необходимо для многоцелевых фильтров, которые могут исполнять несколько видов преобразований. Это и следующее поля дают возможность такому фильтру определить, какую именно трансляцию следует выполнить. (IN)
ctl_frora_sub_type Указывает подтип BLOB-источника. Информационное поле. Необходимо для многоцелевых фильтров, которые могут исполнять несколько видов преобразований. Это и предыдущее поля дают возможность такому фильтру определить, какую именно трансляцию следует выполнить. (IN)
ctl_buffer_length Для isc_blob_filter_put_segment поле - входное (IN), содержащее длину сегмента данных в ctl_buffer. Для isc _blob_filter _get _segment поле - входное (IN), устанавливающее размер буфера (адресованного ctlbuffer) для сохранения полученных из BLOB данных
ctl_segment_length Длина текущего сегмента. Это поле не используется для isc_blob_filter_put_segment. Для isc_blob_filter_get segment поле - выходное (OUT) устанавливается в длину сегмента полученных из BLOB данных (или части сегмента, если длина буфера ctl buffer length меньше фактической длины сегмента)
ctl_bpb_length Длина буфера параметров BLOB. Зарезервировано для будущего расширения
Имя поля Описание
*ctl!_bpb> Указатель . на. буфер . параметров . BLOB; . Зарезервировано' для будущего .расширения
*ctl_buffer ■ Указатель . на. буфер . сегмента,. Для

isc_blob_filter_put_segrnentrrojie:- входное <IN)'.. Содержит-

данные сегмента. Для isc blob filter get segment поле -выходное. (OUT), функция фильтра заполняет егоданными сегмента . для. возврата вызвавшему ■ фильтр . приложению.

ctl_max_segmenl: Длина. самого. большого. сегмента . в . BLOB. . Начальное. значение - . 0. Это . поле . устанавливает функция фильтра. Поле толькоинформационное
ctl_number_segments Начальное значение - . 0.. Это. поле устанавливает функция фильтра. Поле только информационное
ctl_total_length. Полная длина BLOB. Начальное значение - 0. Это поле устанавливает функция фильтра. Поле только информационное:
*ctl_status. Указатель . на вектор . состояния . InterBase.. (OUT)'
ctl_data[8]| Массив. из 8. элементов. Зависит от - приложения.. Можно использовать. это. поле,. например, для хранения указателей на ресурсы, типа указателей . памяти и дескрипторов файла, созданных обработчиком isc blob filter open. Тогда. при следующем вызове функции фильтра указатели ресурсов будут доступны для использования. (IN/OUT)

Установка значений полей управляющей структуры Структура isc_blob_ctl содержит три поля, сохраняющие информацию о BLOB, к которому осуществляется доступ: ctl_max_segment,

ctl_number_segments и ctltotaHength.

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

Эти поля носят только информационный характер. InterBase не использует значения этих полей во внутренней обработке.

ПРОГРАММИРОВАНИЕ ДЕЙСТВИЙ ФУНКЦИИ ФИЛЬТРА Когда приложение выполняет операцию доступа к BLOB, InterBase передает функции фильтра соответствующее сообщение о действии в па раметре action. Имеются восемь возможных действий, каждое из которых является следствием специфической операции доступа. Следующий список макроопределений действий объявлен в заголовочном файле ibase.h:

#define isc_blob_filter_open 0

#define isc„blob_filter_get_segment 1 #define isc_blob_filter_close 2

#define isc_blob_filter_create 3

#define isc_blob_filter_put_segment 4 #define isc_blob_filter_alloc 5

tdefine isc_blob_filter_free 6

#define isc_blob_filter_seek 7

Приводимая таблица описывает операции доступа к BLOB, которые соответствуют каждому действию (параметр action).

Таблица 6.10. Операции доступа к BLOB в зависимости от параметра action

Действие Условие вызова Назначение
isc_blob_filter_open Приложение открывает BLOB курсор на чтение Установка информационных полей управляющей структуры BLOB. Выполняет задачи инициализации, типа распределения памяти или открытия временных файлов. Устанавливает в случае необходимости переменную состояния. Значение переменной состояния становится возвращаемым значением функции фильтра
i sc_blob_filter_get_segment Приложение выполняет команду FETCH для BLOB Заполнение полей ctl_ buffer и ctlsegment _length управляющей структуры BLOB содержанием сегментов оттранслированных данных для возврата функцией фильтра. Выполняет конвертирование данных, если фильтр обрабатывает BLOB посегментно. Устанавливает переменную состояния. Ее значение становится возвращаемым значением функции фильтра
Действие Условие ■ вызоваt Назначение ■
isc_blob_filter_close Приложение закрывает' курсор ■ BLOBi Выполняется, задача выхода,, типа, освобождения ■ распределенной памяти, закрытия: или удаления ■ временных! файлов!
isc_blob_fflter_create ; Приложение открывает' курсор ■ вставки BLOB. Установка ■ информационных, полей управляющей структуры ■ BLOB'- Выполняются: задачи ■ инициализации,, типа, распределения; памяти или открытия; временных файлов. Устанавливается . в^ случае необходимости, переменная, состояния. Значение переменной состояния становится возвращаемым значением функции фильтра
isc_blob_filter_put_segment Приложение выполняет команду INSERT для BLOB, Выполняется конвертирование данных сегмента, переданных через управляющую, структуру BLO.B. ■Запись данных сегмента в^ базу данных.. Если процесс трансляции изменяет длину сегмента, новое значение длины должно быть отражено в параметрах, передаваемых функции записи. Устанавливает переменную состояния- Значение переменной состояния становится возвращаемым значением функции фильтра
isc_blob_filter_alloc InterBase инициализирует работу фильтра; не является результатом действия приложения Установка информационных полей управляющей структуры BLOB. Выполняются задачи инициализации, типа распределения памяти или открытия временных файлов. Установка в случае необходимости переменной состояния. Значение переменной состояния становится, возвращаемым значением функции фильтра
Действие Условие вызова Назначение
isc_blob_filter_free InterBase завершает обработку фильтра; не является результатом действия приложения Выполнение задачи выхода, типа освобождения распределенной памяти, закрытия или удаления временных файлов
isc_blob_filter_seek Зарезервировано для внутреннего использования фильтра; не используется внешними фильтрами

Следует сохранять указатели ресурсов, типа указателей памяти и дескриптора файла, созданных обработчиком isc_blob_filter_open, в поле ctl_data управляющей структуры isc_blob_ctl BLOB. Тогда при следующем вызове функции фильтра указатели ресурсов останутся доступными.

Контроль возвращаемых функцией значений Функция фильтра должна возвращать целое число, указывающее состояние операции, которую она выполнила. Можно построить функцию, возвращающую значения состояния InterBase, даваемые внутренней подпрограммой InterBase.

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

Таблица 6.12. Коды состояния, возвращаемые функциями фильтра

Константа Макроса Величина Содержание
SUCCESS 0 Указывает, что фильтр отработал успешно. При операции чтения BLOB (isc_blob_filter_get _segment) указывает, что сегмент прочитан полностью
FAILURE 1 Указывает на неудачную операцию. В большинстве случаев состояние более определенно указывает на тип ошибки
isc_uns_ext См. ibase.h Указывает, что предпринятое действие не поддерживается фильтром. Например, фильтр только для чтения возвратил бы isc uns ext для действия isc_blob_filter_put_segment
Константа Макроса Величина Содержание
isc_segment См. ibase.h Указывает, что при операции чтения BLOB выделенный буфер слишком мал для хранения оставшихся байтов текущего сегмента. В этом случае только ctlbufferlength байтов скопировано, а остаток сегмента должен быть получен через дополнительные запросы isc_blob_filter_get_segment
isc_segstr_eof См. ibase.h Указывает, что при операции чтения BLOB был достигнут конец BLOB и нет более никаких дополнительных сегментов для чтения

6.3. функции пользователя (udf) | Введение в InterBase | Глава 7 организация хранения метаданных - 7.1. назначение и порядок использования описаний данных


Введение в InterBase



Новости за месяц

  • Август
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс