Spec-Zone.ru › Perl 5.32

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

Возвращает TRUE, если к DBM, связанному с $db, применены какие-либо фильтры. В противном случае возвращает FALSE.

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

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

Непосредственные фильтры

Непосредственный фильтр позволяет указать код фильтра, который будет использоваться в точке применения фильтра к 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, завершаются нулём. Это полезно, когда у вас есть скрипт perl, которому необходимо взаимодействовать с файлом DBM, который также используется программой C. Довольно распространённая проблема заключается в том, что приложение C включает завершающий ноль в строку при записи в файл DBM. Этот фильтр гарантирует, что все данные, записанные в файл DBM, могут быть прочитаны приложением C.

ПРИМЕЧАНИЯ

Поддерживать целостность циклического обмена

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

Если вы не предоставите точную обратную трансформацию, вы обнаружите, что код, подобный этому, не будет вести себя так, как вы ожидаете.

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

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

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

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

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

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

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

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

ПРИМЕР

Предположим, вам нужно взаимодействовать со старым приложением C, которое хранит ключи в виде C int, а значения — в виде null-terminated 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

АВТОР

Paul Marquess <pmqs@cpan.org>

© 1993–2020 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.30.3/DBM_Filter

Spec-Zone.ru

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