DJabberd-RosterStorage-SQLite
view release on metacpan or search on metacpan
lib/DJabberd/RosterStorage/SQLite.pm view on Meta::CPAN
return;
}
$dbh->begin_work or
$logger->logdie("Failed to begin work");
my $fail = sub {
my $reason = shift;
die "Failing to addupdate: $reason";
$dbh->rollback;
$cb->error($reason);
return;
};
my $exist_row = $dbh->selectrow_hashref("SELECT * FROM roster WHERE userid=? AND contactid=?",
undef, $userid, $contactid);
my %in_group; # groupname -> 1
if ($exist_row) {
my @groups = $self->_groups_of_contactid($userid, $contactid);
my %to_del; # groupname -> groupid
foreach my $g (@groups) {
$in_group{$g->[1]} = 1;
$to_del {$g->[1]} = $g->[0];
}
foreach my $gname ($ritem->groups) {
delete $to_del{$gname};
}
if (my $in = join(",", values %to_del)) {
$dbh->do("DELETE FROM groupitem WHERE groupid IN ($in) AND contactid=?",
undef, $contactid);
}
# by default, don't change subscription, unless we're being called
# via set_roster_item.
my $sub_value = "subscription";
if ($_respect_subscription) {
$sub_value = $ritem->subscription->as_bitmask;
$logger->debug(" sub_value = $sub_value");
} else {
# but let's set our subscription in $ritem (since it comes to
# us as 'none') because we have to pass it back with the real
# value.
$ritem->set_subscription(DJabberd::Subscription->from_bitmask($exist_row->{subscription}));
}
my $sql = "UPDATE roster SET name=?, subscription=$sub_value WHERE userid=? AND contactid=?";
my @args = ($ritem->name, $userid, $contactid);
$dbh->do($sql, undef, @args);
} else {
$dbh->do("INSERT INTO roster (userid, contactid, name, subscription) ".
"VALUES (?,?,?,?)", undef,
$userid, $contactid, $ritem->name, $ritem->subscription->as_bitmask)
}
# add to groups
foreach my $gname ($ritem->groups) {
next if $in_group{$gname}; # already in this group, skip
my $gid = $self->_groupid_alloc($userid, $gname);
$dbh->do("INSERT OR IGNORE INTO groupitem (groupid, contactid) VALUES (?,?)",
undef, $gid, $contactid);
}
$dbh->commit
or return $fail->();
$cb->done($ritem);
}
# returns ([groupid, groupname], ...)
sub _groups_of_contactid {
my ($self, $userid, $contactid) = @_;
my @ret;
my $sql = qq{
SELECT rg.groupid, rg.name
FROM rostergroup rg, groupitem gi
WHERE rg.userid=? AND gi.groupid=rg.groupid AND gi.contactid=?
};
my $sth = $self->{dbh}->prepare($sql);
$sth->execute($userid, $contactid);
while (my ($gid, $name) = $sth->fetchrow_array) {
push @ret, [$gid, $name];
}
return @ret;
}
sub delete_roster_item {
my ($self, $cb, $jid, $ritem) = @_;
$logger->debug("delete roster item!");
my $dbh = $self->{dbh};
my $userid = $self->_jidid_alloc($jid);
my $contactid = $self->_jidid_alloc($ritem->jid);
unless ($userid && $contactid) {
$cb->error("no userid/contactid in delete");
return;
}
$dbh->begin_work;
my $fail = sub {
$dbh->rollback;
$cb->error;
return;
};
my @groups = $self->_groups_of_contactid($userid, $contactid);
if (my $in = join(",", map { $_->[0] } @groups)) {
$dbh->do("DELETE FROM groupitem WHERE groupid IN ($in) AND contactid=?",
undef, $contactid);
}
$dbh->do("DELETE FROM roster WHERE userid=? AND contactid=?",
undef, $userid, $contactid)
or return $fail->();
$dbh->commit or $fail->();
$cb->done;
}
sub load_roster_item {
my ($self, $jid, $contact_jid, $cb) = @_;
my $dbh = $self->{dbh};
my $userid = $self->_jidid_alloc($jid);
my $contactid = $self->_jidid_alloc($contact_jid);
unless ($userid && $contactid) {
$cb->error("no userid/contactid in load");
return;
}
my $row = $dbh->selectrow_hashref("SELECT name, subscription FROM roster ".
"WHERE userid=? AND contactid=?",
undef, $userid, $contactid);
unless ($row) {
$cb->set(undef);
return;
( run in 1.585 second using v1.01-cache-2.11-cpan-5735350b133 )