Spec-Zone.ru › Perl 5.38

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. Смотрите perldbmfilter для получения более подробной информации об обработчиках фильтров DBM.

Что такое фильтр 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, если к ассоциированному с $db DBM применены какие-либо фильтры. В противном случае возвращает 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. Цикл какое-то время будет работать правильно, но неожиданно завершится с ошибкой.

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

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

ПРИМЕР

Предположим, вам нужно взаимодействовать с устаревшей программой C, которая хранит ключи как C int, а значения — как строки 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–2023 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.38.0/DBM_Filter

Spec-Zone.ru

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