Spec-Zone.ru › Perl 5.34

DBM_Filter

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТЕКС
  • ОПИСАНИЕ
  • Что такое фильтр DBM?
    • Что нового?
  • МЕТОДЫ
    • $db->Filter_Push() / $db->Filter_Key_Push() / $db->Filter_Value_Push()
    • $db->Filter_Pop()
    • $db->Filtered()
  • Написание фильтра
    • Немедленные фильтры
    • Стандартные фильтры
  • Включённые фильтры
  • ПРИМЕЧАНИЯ
    • Поддержание целостности обратного пути
    • Не смешивайте отфильтрованные и неотфильтрованные данные в одном файле базы данных.
  • ПРИМЕР
  • СМОТРИТЕ ТАКЖЕ
  • АВТОР

ИМЯ

DBM_Filter -- Фильтрование ключей/значений DBM

СИНТЕКС

use DBM_Filter ;
use SDBM_File; # or DB_File, GDBM_File, NDBM_File, or ODBM_File

$db = tie %hash, ...

$db->Filter_Push(Fetch => sub {...},
                 Store => sub {...});

$db->Filter_Push('my_filter1');
$db->Filter_Push('my_filter2', params...);

$db->Filter_Key_Push(...) ;
$db->Filter_Value_Push(...) ;

$db->Filter_Pop();
$db->Filtered();

package DBM_Filter::my_filter1;

sub Store { ... }
sub Fetch { ... }

1;

package DBM_Filter::my_filter2;

sub Filter
{
    my @opts = @_;
    ...
    return (
        sub Store { ... },
        sub Fetch { ... } );
}

1;

ОПИСАНИЕ

Этот модуль предоставляет интерфейс, который позволяет применять фильтры к связанным хешам, ассоциированным с файлами DBM. Он основан на функциях фильтрации DBM, присутствующих во всех модулях *DB*_File, включённых в стандартное распределение Perl с версии 5.6.1 и выше. Помимо модулей *DB*_File, распространяемых с Perl, модуль BerkeleyDB, доступный на CPAN, поддерживает функции фильтрации DBM. Подробнее о функциях фильтрации DBM см. в perldbmfilter.

Что такое фильтр DBM?

Фильтр DBM позволяет изменять ключи и/или значения в связанном хеше с помощью некоторого пользовательского кода непосредственно перед записью в файл DBM и сразу после чтения из файла DBM. Например, этот фрагмент кода

$some_hash{"abc"} = 42;

может потенциально вызвать два фильтра, один для записи ключа "abc", а другой для записи значения 42. Аналогично, этот фрагмент

my ($key, $value) = each %some_hash

вызовет два фильтра, один для чтения ключа и один для чтения значения.

Как и существующая функциональность фильтрации DBM, этот модуль обеспечивает, что переменная $_ будет заполнена ключом или значением, который будет проверять фильтр. Обычно это означает, что большинство фильтров DBM имеют небольшой размер.

Что нового?

Основные улучшения по сравнению со стандартными функциями фильтрации DBM:

  • Более чистый интерфейс.

  • Возможность легко применять несколько фильтров к одному файлу DBM.

  • Возможность создания "стандартных" фильтров. Они позволяют упаковать часто используемые фильтры в отдельный модуль.

МЕТОДЫ

Этот модуль обеспечит наличие следующих методов через объект, возвращаемый вызовом tie.

$db->Filter_Push() / $db->Filter_Key_Push() / $db->Filter_Value_Push()

Добавляет фильтр в стек фильтров базы данных, $db. Три формата различаются только тем, применяется ли он к ключу DBM, значению DBM или к обоим.

Filter_Push

Фильтр применяется к оба ключам и значениям.

Filter_Key_Push

Фильтр применяется только к ключу.

Filter_Value_Push

Фильтр применяется только к значению.

$db->Filter_Pop()

Удаляет последний примененный фильтр к файлу DBM, связанному с $db, если таковой имеется.

$db->Filtered()

Возвращает ИСТИНА, если к DBM, связанному с $db, применены какие-либо фильтры. В противном случае возвращает ЛОЖЬ.

Написание фильтра

Фильтры можно создавать двумя основными способами

Немедленные фильтры

Немедленный фильтр позволяет указать код фильтра, который будет использоваться в момент применения фильтра к dbm. В этом режиме методы Filter_*_Push ожидают получения ровно двух параметров.

my $db = tie %hash, 'SDBM_File', ...
$db->Filter_Push( Store => sub { },
                  Fetch => sub { });

Ссылка на код, связанная с Store, будет вызвана до записи любого ключа/значения в базу данных, а ссылка на код, связанная с Fetch, будет вызвана после чтения любого ключа/значения из базы данных.

Например, вот пример фильтра, который добавляет завершающий символ NULL ко всем строкам перед записью в файл DBM и удаляет завершающий NULL при чтении из файла DBM

my $db = tie %hash, 'SDBM_File', ...
$db->Filter_Push( Store => sub { $_ .= "\x00" ; },
                  Fetch => sub { s/\x00$// ;    });

Примечания:

  1. Оба фильтра Store и Fetch обрабатывают $_.

Стандартные фильтры

Немедленные фильтры полезны для разовых ситуаций. Для более общих задач полезно упаковать фильтр в собственный модуль.

Использование стандартного фильтра:

$db->Filter_Push("name", params)

где

"name"

— имя загружаемого модуля. Если указанная строка не содержит символы разделителя пакетов "::", предполагается, что она относится к полному имени модуля "DBM_Filter::name". Это означает, что полные имена для стандартных фильтров, "null" и "utf8", включённые в этот модуль, это:

DBM_Filter::null
DBM_Filter::utf8
params

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

Модуль, реализующий стандартный фильтр, может иметь одну из двух форм. Вот шаблон для первого:

package DBM_Filter::null ;

use strict;
use warnings;

sub Store 
{
    # store code here    
}

sub Fetch
{
    # fetch code here
}

1;

Примечания:

  1. Имя пакета использует префикс DBM_Filter::.

  2. Модуль обязательно должен иметь методы Store и Fetch. Если присутствует только один метод или ни один, будет выброшено сообщение об ошибке.

Вторая форма позволяет фильтру хранить информацию о состоянии, используя замыкание, таким образом:

package DBM_Filter::encoding ;

use strict;
use warnings;

sub Filter
{
    my @params = @_ ;

    ...
    return {
        Store   => sub { $_ = $encoding->encode($_) },
        Fetch   => sub { $_ = $encoding->decode($_) }
        } ;
}

1;

В этом случае методы "Store" и "Fetch" инкапсулированы внутри метода "Filter".

Включённые фильтры

В этот модуль включено несколько стандартных фильтров. Они охватывают ряд основных областей, в которых фильтры необходимы при работе с файлами DBM. Они также служат шаблонами для ваших собственных фильтров.

Включённые фильтры:

  • utf8

    Этот модуль гарантирует, что все данные, записанные в DBM, будут закодированы в UTF-8.

    Для этого модуля нужен модуль Encode.

  • encode

    Позволяет выбрать кодировку символов, которая будет храниться в файле DBM.

  • compress

    Этот фильтр сжимает все данные перед записью в базу данных и распаковывает их при чтении.

    Для этого модуля нужен Compress::Zlib.

  • int32

    Этот модуль используется при взаимодействии с приложением C/C++, которое использует C int в качестве ключа и/или значения в файле DBM.

  • null

    Этот модуль гарантирует, что все данные, записанные в файл DBM, будут иметь завершающий символ null. Это полезно, когда у вас есть скрипт Perl, который должен взаимодействовать с файлом DBM, который также использует программа C. Довольно распространённая проблема заключается в том, что приложение C включает в строку завершающий null при записи в файл DBM. Этот фильтр гарантирует, что все данные, записанные в файл DBM, могут быть прочитаны приложением C.

ПРИМЕЧАНИЯ

Поддержание целостности обратного пути

При написании фильтра DBM очень важно гарантировать, что при наличии фильтра DBM можно получить все записанные данные. На практике это означает, что любая транформация, применяемая к данным в методе Store, должна иметь тоже обратное преобразование в методе Fetch.

Если вы не обеспечите точное обратное преобразование, код такого рода не будет работать так, как вы ожидаете.

while (my ($k, $v) = each %hash)
{
    ...
}

В зависимости от преобразования, может произойти одно или несколько из следующих:

  1. Цикл никогда не завершится.

  2. Будет получено слишком мало записей.

  3. Будет получено слишком много записей.

  4. Цикл будет работать правильно какое-то время, но неожиданно завершится с ошибкой.

Не смешивайте отфильтрованные и неотфильтрованные данные в одном файле базы данных.

Это просто повторение предыдущего раздела. Если вы не уверены в своих действиях, не смешивайте отфильтрованные и неотфильтрованные данные.

ПРИМЕР

Предположим, вам нужно взаимодействовать с устаревшей программой C, которая хранит ключи как целочисленные значения C, а значения — как строки UTF-8 с завершающим нулём. Вот как вы это настроите

my $db = tie %hash, 'SDBM_File', ...

$db->Filter_Key_Push('int32') ;

$db->Filter_Value_Push('utf8');
$db->Filter_Value_Push('null');

СМОТРИТЕ ТАКЖЕ

<DB_File>, GDBM_File, NDBM_File, ODBM_File, SDBM_File, perldbmfilter

АВТОР

Пол Маркесс <pmqs@cpan.org>

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/DBM_Filter

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API