Hello everyone,
To use jabberd2 with my pre-existing contacts database, I started
writing a roster module with customisable MySQL requests (I mailed this
list a while back about it, but I just started actual work). It uses
prepared statements, and config file looks like :
<user_loaditems>SELECT `jid`, `name`, `to`, `from`, `ask`,
`object-sequence` FROM `roster-items` WHERE `collection-owner` =
CONCAT(?1,'@',?2)</user_loaditems> <!-- ?1:node ?2:domain -->
<contact_set>UPDATE `roster-items` SET `name`=?4, `to`=?5, `from`=?6,
`ask`=?7 WHERE `collection-owner`=CONCAT(?1,'@',?2) AND `jid`=?3
</contact_set>
(I'm not yet at ease with GIT and Github, but I think you can see
the code here : https://github.com/Gugli/jabberd2 )
My module does not rely on the storage facilities anymore. And it's
still work in progress.
I would gladly take any input/feedbacks on this.
I have some questions, thanks in advance for any help :
- In order to make simpler custom databases, I wanted to remove the
"pkt->type == pkt_S10N_UN" / "item->ask == 2" mechanism. According to a
comment "there is no ask='unsubscribe' in RFC bis anymore ". Would
anyone advise against it ?
- something that seems weird to me : I was expecting item->ver to be
incremented each time the item is updated (for example in
_roster_save_item),
but couldn't find such code. It there something I don't grasp ?
- Also, in order to minimise database requests, I've rewritten the
groups update loop in _rostercustom_set_item, and removed the groups
update in _rostercustom_save_item. My code matches groups as possible,
minimizing mallocs and frees. I thought it would be good to do the same
thing in the regular roster, but I couldn't find a way to remove a
specific os_object_t. Is there a way to do that ?
Anyway here's what the code could look like, with TODOs :
elem = nad_find_elem(pkt->nad, elem, NAD_ENS(pkt->nad, elem), "group", 1);
elemindex = 0;
while(elem >= 0)
{
/* empty group tags get skipped */
if(NAD_CDATA_L(pkt->nad, elem) >= 0)
{
if(item->groups && item->ngroups > elemindex )
{
// enough room in the array
// check if the group is already here
for(i = elemindex; i < item->ngroups; i++)
{
if( strncmp(NAD_CDATA(pkt->nad, elem), item->groups[i],
NAD_CDATA_L(pkt->nad, elem) ) == 0 )
{
break;
}
}
if(i < item->ngroups)
{
// the group exist in the array, we swap and do nothing more
tempswapstr = item->groups[i];
item->groups[i] = item->groups[elemindex];
item->groups[elemindex] = tempswapstr;
}
else
{
// TODO : remove group item->groups[elemindex] from
Storage
item->groups[elemindex] = (const char *) realloc(
(void*)item->groups[elemindex], sizeof(char) * (NAD_CDATA_L(pkt->nad, elem) + 1));
sprintf((char *)(item->groups[elemindex]), "%.*s",
NAD_CDATA_L(pkt->nad, elem), NAD_CDATA(pkt->nad, elem));
// TODO : add group item->groups[elemindex] to Storage
}
}
else
{
// makes room
item->groups = (const char **) realloc(item->groups, sizeof(char *) *
(item->ngroups + 1));
item->ngroups++;
// copy the group name
item->groups[elemindex] = (const char *) malloc(sizeof(char) *
(NAD_CDATA_L(pkt->nad, elem) + 1));
sprintf((char *)(item->groups[elemindex]), "%.*s", NAD_CDATA_L(pkt->nad,
elem), NAD_CDATA(pkt->nad, elem));
// TODO : add group item->groups[elemindex] to Storage
}
elemindex++;
}
elem = nad_find_elem(pkt->nad, elem, NAD_ENS(pkt->nad, elem), "group", 0);
}
/* free the old groups */
if(item->ngroups > elemindex)
{
for(i = elemindex; i < item->ngroups; i++)
{
// TODO : remove group item->groups[i] from Storage
free((void*)item->groups[i]);
}
if(elemindex == 0)
{
free(item->groups);
item->groups = 0;
}
else
{
item->groups = (const char **) realloc(item->groups, sizeof(char *) *
elemindex);
}
}
item->ngroups = elemindex;
--
Sylvain "Gugli" Guglielmi
Gamedev@Nadeo@Ubisoft