Spec-Zone.ru › Perl 5.36

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, завершаются символом 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

АВТОР

Paul Marquess <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.36.0/DBM_Filter

Spec-Zone.ru

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