use v6.d;
unit class MaildirIndexer::Store;
use MaildirIndexer::LogTimelineSchema;
use MaildirIndexer::Index;
use MaildirIndexer::Parser;
use MaildirIndexer::ScanDir;
has Lock $!lock .= new;
has MaildirIndexer::Index @.indices is required;
has Channel $.file-channel is required;
has Int $.workers = 10;
method dump(--> Nil) {
$!lock.protect: {
.dump() for @!indices;
}
}
method start(--> Nil) {
for ^$.workers {
start react {
CATCH { warn $_ };
whenever $.file-channel -> $file {
when $file ~~ MaildirIndexer::ScanDir::End {
MaildirIndexer::LogTimelineSchema::Scan::End.log();
}
when $file ~~ :e & :f {
MaildirIndexer::LogTimelineSchema::Store::Add.log: :file($file.path), -> {
self.add-file($file);
}
}
when $file ~~ :!e {
MaildirIndexer::LogTimelineSchema::Store::Rm.log: :file($file.path), -> {
self.del-file($file);
}
}
}
}
}
}
method add-file(IO:D $file --> Nil) {
my $mailbox = mailbox-from-path($file.path) or return;
my $email = parse-email($file,:headers-only) or return;
CATCH { warn $_ };
$!lock.protect: {
.add-mail($email,$mailbox) for @!indices;
}
return;
}
method del-file(IO:D $file --> Nil) {
my $mailbox = mailbox-from-path($file.path) or return;
$!lock.protect: {
.del-path($file,$mailbox) for @!indices;
}
return;
}
method mailbox-for-email(MaildirIndexer::Email:D $email --> Str) {
my Str $result;
MaildirIndexer::LogTimelineSchema::Store::Find.log: {
for @!indices -> $index {
with $index.mailbox-for-email($email) { $result = $_; last };
}
}
return $result;
}
sub mailbox-from-path(Str() $path --> Str) {
$path ~~ m{'/' (<-[/]>+?) '/' [cur|new|tmp] '/'} and return ~$/[0];
return Nil;
}