Шрифт:
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