Эффективный внешний реестр с помощью MySQL и ejabberd

Вопрос

Обратите внимание, что решение этой проблемы находится непосредственно ниже, используя идею представления Евгения!

Я пишу модуль чата для сайта, управляемого пользователем PHP/MySQL -, который позволяет двум пользователям подружиться, и выбрал eJabberd для системы чата.

Я успешно настроил внешнюю аутентификацию с помощью демона PHP, и теперь мне удалось добавить друзей в eJabberd, используя mod_roster_odbcи заполнив таблицу MySQL rosterusersвручную. После долгих поисков мне удалось найти этот конкретный комментарий , очень полезный для понимания того, что нужно установить для каждого столбца, чтобы представить эту дружбу в списке друзей для модуля чата.

Мой текущий метод обработки дружеских отношений заключается в вставке двух строк в таблицу rosterusers:

# Relationship user1 => user2
INSERT INTO rosterusers (username, jid, subscription, ask, server, type)
VALUES ('user1', 'user2@myserver.org', 'B', 'N', 'B', 'item');

# Relationship user2 => user1
INSERT INTO rosterusers (username, jid, subscription, ask, server, type)
VALUES ('user2', 'user1@myserver.org', 'B', 'N', 'B', 'item');

. Меня это не слишком устраивает, потому что для взаимной дружбы требуется два ряда.

Я понимаю, что XMPP по стандарту допускает одиночные и двойные ссылки между пользователями. Как можно догадаться по характеру моего вопроса, система друзей моего собственного приложения использует одну строку для представления дружбы.

Мои основные вопросы:

  1. Можно ли укрепить эту дружбу всего в один ряд? Я пробовал некоторые комбинации из этой неофициальной документации , но безуспешно. Я тестирую, подключаясь к моему серверу XMPP с клиентом Pidgin.
  2. Как лучше всего синхронизировать две базы данных -friends и список XMPP -? Я думаю, что MySQL TRIGGERможет быть самым чистым вариантом на данный момент.

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

Код решения

Я создал представление, как предложил Евгений. Код не самый элегантный, но я протестировал его, и он работает с eJabberd 2.1 на MySQL 5.5.

Моя точная установка использует две базы данных, поэтому я явно ссылаюсь на базу данных моего основного приложения, используя main_database.table_name.

Код представляет собой объединение двух запросов -, первый из которых принимает User, Friend, а второй вставляет Friend, User. Я использую UNION ALLдля скорости и пропуска "дубликатов".

Я думаю, что это действительно отличный способ справиться с проблемой, поскольку никаких изменений в приложении не требуется, и оно мгновенно обновляется.

CREATE VIEW rosterusers AS

SELECT LCASE(ua1.Username) AS `username`, CONCAT(LCASE(ua2.Username), '@myserver.org') AS `jid`,
'B' AS `subscription`,
'N' AS `ask`,
'N' AS `server`,
'item' AS `type`,
'B' AS `subscribe`,
d1.Created AS `created_at`,
ua2.Username AS `nick`,
'' AS `askmessage`

FROM main_database.User_Friend AS `d1`

INNER JOIN main_database.User AS `ua1` ON `d1`.UserID = `ua1`.ID
INNER JOIN main_database.User AS `ua2` ON `d1`.FriendID = `ua2`.ID

WHERE d1.IsApproved = 1

UNION ALL

SELECT LCASE(ub2.Username) AS `username`, CONCAT(LCASE(ub1.Username), '@myserver.org') AS `jid`,
'B' AS `subscription`,
'N' AS `ask`,
'N' AS `server`,
'item' AS `type`,
'B' AS `subscribe`,
d2.Created AS `created_at`,
ub1.Username AS `nick`,
'' AS `askmessage`

FROM main_database.User_Friend AS `d2`

INNER JOIN main_database.User AS `ub1` ON `d2`.UserID = `ub1`.ID
INNER JOIN main_database.User AS `ub2` ON `d2`.FriendID = `ub2`.ID

WHERE d2.IsApproved = 1;
9
задан Will Morgan 9 January 2014 в 10:44
поделиться