package AniDB::Datastore;
use 5.024;
use experimental 'signatures';
use Moo;
use Path::Tiny;
use AniDB::Hashing;
use namespace::clean;
has database => ( is => 'ro', required => 1 );
has dbh => ( is => 'ro', lazy => 1 );
sub _build_dbh($self) {
require DBI;
return DBI->connect(
'dbi:SQLite:dbname='.$self->database,
'', '',
{
AutoCommit => 1,
RaiseError => 1,
PrintError => 0,
},
);
}
sub update($self,$path) {
my $stat = $path->stat;
return 0 unless $self->_has_changed($path,$stat);
my $hash = AniDB::Hashing::hash_fd($path->openr_raw);
$self->_update_path_info(
$path => {
size => $stat->size,
mtime => $stat->mtime,
hash => $hash,
},
);
return 1;
}
sub _has_changed($self,$path,$stat) {
my $path_info = $self->path_info_for($path);
return (
$path_info->{size} == $stat->size
&& $path_info->{mtime} == $stat->mtime
);
}
sub rename($self,$path,$new_path) {
$self->dbh->do(
q{UPDATE path_info SET name=? WHERE name=?},
$path->stringify,$new_path->stringify,
);
}
sub full_info_for($self,$path) {
my $path_info = $self->path_info_for($path);
my $episode_info = $self->episode_info_for(
$path_info,
);
my $anime_info = $self->anime_info_for(
$episode_info,
);
return {
path => $path_info,
episode => $episode_info,
anime => $anime_info,
};
}
sub path_info_for($self,$path) {
my $ret = $self->dbh->selectall_arrayref(
qr{SELECT * FROM path_info WHERE name=?},
{ Slice => {} },
$path->stringify,
);
return $ret->[0];
}
sub episode_info_for($self,$args) {
my $ret = $self->dbh->selectall_arrayref(
qr{SELECT * FROM episode_info WHERE hash=? AND size=?},
{ Slice => {} },
@{$args}{qw(hash size)},
);
return $ret->[0];
}
sub anime_info_for($self,$args) {
my $ret = $self->dbh->selectall_arrayref(
qr{SELECT * FROM anime_info WHERE aid=?},
{ Slice => {} },
@{$args}{qw(aid)},
);
return $ret->[0];
}
1;