+ # caching $sth ourselves is faster than prepare_cached
+ my $sth = $self->{-get_art} //= $self->connect->prepare(<<'');
+SELECT num,tid,ds,ts,ddd FROM over WHERE num = ? LIMIT 1
+
+ $sth->execute($num);
+ my $smsg = $sth->fetchrow_hashref;
+ $smsg ? load_from_row($smsg) : undef;
+}
+
+sub next_by_mid {
+ my ($self, $mid, $id, $prev) = @_;
+ my $dbh = $self->connect;
+
+ unless (defined $$id) {
+ my $sth = $dbh->prepare_cached(<<'', undef, 1);
+ SELECT id FROM msgid WHERE mid = ? LIMIT 1
+
+ $sth->execute($mid);
+ $$id = $sth->fetchrow_array;
+ defined $$id or return;
+ }
+ my $sth = $dbh->prepare_cached(<<"", undef, 1);
+SELECT num FROM id2num WHERE id = ? AND num > ?
+ORDER BY num ASC LIMIT 1
+
+ $$prev ||= 0;
+ $sth->execute($$id, $$prev);
+ my $num = $sth->fetchrow_array or return;
+ $$prev = $num;
+ get_art($self, $num);
+}
+
+# IMAP search, this is limited by callers to UID_SLICE size (50K)
+sub uid_range {
+ my ($self, $beg, $end, $sql) = @_;