Чтение онлайн

ЖАНРЫ

Asterisk™: будущее телефонии Второе издание
Шрифт:

PostgreSQL необходимо показать, как работать с большими объектами. Сюда относится и создание триггера для очистки данных при удалении из базы данных записи, которая ссылается на большой объект. Установим соединение с базой данных из консоли как пользователь asterisk:

# psql -h localhost -U asterisk asterisk

Password:

Чтобы создать большой объект, выполним следующий сценарий в консоли PostgreSQL:

CREATE FUNCTION loin (cstring) RETURNS lo AS 'oidin' LANGUAGE internal IMMUTABLE STRICT;

CREATE FUNCTION loout (lo) RETURNS cstring AS 'oidout' LANGUAGE internal IMMUTABLE STRICT;

CREATE FUNCTION lorecv (internal) RETURNS lo AS 'oidrecv' LANGUAGE internal IMMUTABLE STRICT;

CREATE FUNCTION losend (lo) RETURNS bytea AS 'oidrecv' LANGUAGE internal IMMUTABLE STRICT;

CREATE TYPE lo ( INPUT = loin, OUTPUT = loout, RECEIVE = lorecv, SEND = losend,

INTERNALLENGTH = 4, PASSEDBYVALUE );

CREATE CAST (lo AS oid) WITHOUT FUNCTION AS IMPLICIT;

CREATE CAST (oid AS lo) WITHOUT FUNCTION AS IMPLICIT;

Для

создания функции будем использовать процедурный язык Postgre- SQL, называемый pgSQL/PL. Эта функция будет вызываться из триггера, который выполняется при любом изменении или удалении записи из таблицы, применяемой для хранения голосовой почты. Таким образом, происходит очистка данных и в базе данных не остается висячих (несвязанных) строк:

CREATE FUNCTION vm_lo_cleanup RETURNS "trigger" AS $$ declare

msgcount INTEGER; begin

– - raise notice 'Starting lo_cleanup function for large object with old

%',old.recording; [118]– - Если это действие обновления, но поле BLOB (lo) не было изменено,

не делаем ничего if (TG_OP = 'UPDATE') then if ((old.recording = new.recording) or (old.recording is NULL)) then raise notice 'Not cleaning up the large object table, as recording has not changed'; [119] return new; end if; end if;

if (old.recording IS NOT NULL) then SELECT INTO msgcount COUNT(*) AS COUNT FROM voicemessages WHERE recording = old.recording; if (msgcount > 0) then

118

Запускаем функцию lo_cleanup для большого объекта с идентификатором объекта %.
Примеч. перев.

119

Не проводим очистку в таблице больших объектов, поскольку записи не менялись.
Примеч. перев.

raise notice 'Not deleting record from the large object table, as object is still referenced'; [120] return new; else

perform lo_unlink(old.recording); if found then

raise notice 'Cleaning up the large object table'; [121] return new; else

raise exception 'Failed to cleanup the large object table'; [122] return old; end if; end if;

else

raise notice 'No need to cleanup the large object table, no recording on old row'; [123] return new; end if; end$$

120

Запись не удаляется из таблицы больших объектов, поскольку по-прежнему существуют ссылки на объект.
Примеч. перев.

121

Очищаем таблицу больших объектов.
Примеч. перев.

122

Не удалось провести очистку в таблице больших объектов.
Примеч. перев.

123

Нет

необходимости в очистке таблицы больших объектов, перезапись старой строки не выполняется.
Примеч. перев.

LANGUAGE plpgsql;

Мы собираемся создать таблицу voicemessages (сообщения голосовой почты), в которой будет храниться информация голосовой почты:

CREATE TABLE voicemessages (

uniqueid serial PRIMARY KEY, msgnum int4, dir varchar(80), context varchar(80), macrocontext varchar(80), callerid varchar(40), origtime varchar(40), duration varchar(20), mailboxuser varchar(80), mailboxcontext varchar(80), recording lo, label varchar(30), "read" bool DEFAULT false

);

И теперь надо связать триггер с этой вновь созданной таблицей, чтобы выполнять очистку при любом внесении изменения или удалении из таблицы voicemessages:

CREATE TRIGGER vm_cleanup AFTER DELETE OR UPDATE ON voicemessages FOR EACH ROW EXECUTE

PROCEDURE vm_lo_cleanup;

Конфигурация voicemail.conf для ODBC-хранилища

Чтобы сделать возможным хранение голосовой почты с использованием ODBC, файл voicemail.conf не придется подвергать очень большим изменениям. Фактически в него надо добавить всего три строки! Как правило, в разделе [general] файла voicemail.conf описывается несколько типов форматов, однако нам необходимо определить всего один. Формат wav49 - это формат записи WAV-файлов со сжатием, которые должны воспроизводиться как в настольных системах Linux, так и в Microsoft Windows.

Опция odbcstorage указывает на имя, заданное в файле res_odbc.conf (если вы внимательно читали данную главу, это было имя asterisk). Опция odbctable ссылается на таблицу, в которую должна сохраняться информация голосовой почты. В примерах данной главы использовалась таблица voicemessages:

[general] format=wav49 odbcstorage=asterisk odbctable=voicemessages

Для голосовой почты можно создать отдельный контекст или использовать контекст по умолчанию:

[default]

1000 => 1000,J.P. Wiser

Теперь подключаемся к консоли Asterisk и выгружаем, а затем повторно загружаем модуль app_voicemail.so:

*CLI> module unload app_voicemail.so == Unregistered application 'VoiceMail' == Unregistered application 'VoiceMailMain' == Unregistered application 'MailboxExists' == Unregistered application 'VMAuthenticate'

*CLI> module load app_voicemail.so

Loaded /usr/lib/asterisk/modules/app_voicemail.so => (Comedian Mail (Voicemail System))

== Registered application 'VoiceMail' == Registered application 'VoiceMailMain' == Registered application 'MailboxExists' == Registered application 'VMAuthenticate' == Parsing '/etc/asterisk/voicemail.conf': Found

И проверяем успешность загрузки нового почтового ящика:

*CLI> voicemail show users for default Context Mbox User Zone NewMsg

default 1000 J.P. Wiser 0

Тестирование голосовой почты с использованием ODBC

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

[odbc_vm_test]

exten => 100,1,Voicemail(1000@default) ; оставляем сообщение голосовой почты exten => 200,1,VoicemailMain(1000@default) ; извлекаем сообщение голосовой

; почты

После обновления файла extensions.conf не забудьте перезагрузить диалплан:

*CLI> dialplan reload Можно или включить (с помощью выражения include) контекст odbc_ vm_test в контекст, доступный существующему пользователю, или создать отдельного пользователя для тестирования. Если выбран второй вариант, нового SIP-пользователя можно описать в файле sip.conf следующим образом (при условии, что телефон подключен к локальной сети LAN): [odbc_test_user] type=friend secret=supersecret context=odbc_vm_test host=dynamic qualify=yes disallow=all allow=ulaw allow=gsm

Поделиться с друзьями: