App-DrivePlayer
view release on metacpan or search on metacpan
lib/App/DrivePlayer/DB.pm view on Meta::CPAN
}
sub all_scan_folders {
my ($self) = @_;
return map { _row_to_hash($_) }
$self->_rs('ScanFolder')->search({}, { order_by => 'name' })->all;
}
sub delete_scan_folder {
my ($self, $drive_id) = @_;
# cascade_delete on the has_many relationship removes child folders+tracks
my $row = $self->_rs('ScanFolder')->find({ drive_id => $drive_id });
$row->delete if $row;
}
# ---------- folders ----------
sub upsert_folder {
my ($self, %f) = @_;
my $row = $self->_rs('Folder')->update_or_create(
{
lib/App/DrivePlayer/DB.pm view on Meta::CPAN
album => undef,
album => '',
year => undef,
],
})->update_all({ metadata_fetched => 0 });
}
sub clear_scan_folder_tracks {
my ($self, $scan_folder_id) = @_;
# Collect folder IDs, then bulk-delete tracks and folders.
# (Relies on foreign_keys=ON cascade for correctness; explicit here for speed.)
my @folder_ids = $self->_rs('Folder')
->search({ scan_folder_id => $scan_folder_id })
->get_column('id')->all;
if (@folder_ids) {
$self->_rs('Track')->search({ folder_id => \@folder_ids })->delete;
}
$self->_rs('Folder')->search({ scan_folder_id => $scan_folder_id })->delete;
}
lib/App/DrivePlayer/DB.pm view on Meta::CPAN
=head1 SYNOPSIS
use App::DrivePlayer::DB;
my $db = App::DrivePlayer::DB->new(path => '/path/to/music.db');
# Scan-folder management
my $sf = $db->upsert_scan_folder($drive_id, 'My Music');
my @sfs = $db->all_scan_folders;
$db->delete_scan_folder($drive_id); # cascades to folders + tracks
# Track queries
my @tracks = $db->all_tracks;
my @tracks = $db->search_tracks('zeppelin');
my @tracks = $db->tracks_by_artist('Queen');
my @tracks = $db->tracks_by_album('Led Zeppelin IV');
my $track = $db->get_track_by_drive_id($drive_id);
my $track = $db->get_track($id);
my @artists = $db->all_artists;
lib/App/DrivePlayer/DB.pm view on Meta::CPAN
=head2 all_scan_folders
my @hashrefs = $db->all_scan_folders;
Returns all scan folders ordered alphabetically by name.
=head2 delete_scan_folder
$db->delete_scan_folder($drive_id);
Deletes the scan folder and, via cascaded foreign-key constraints, all of
its child folders and tracks.
=head2 upsert_folder
my $hashref = $db->upsert_folder(%fields);
Insert or update a subfolder record. Required keys: C<drive_id>, C<name>,
C<path>, C<scan_folder_id>. Optional: C<parent_drive_id>.
=head2 get_folder_by_drive_id
lib/App/DrivePlayer/Schema/Result/Folder.pm view on Meta::CPAN
__PACKAGE__->add_unique_constraint( unique_drive_id => ['drive_id'] );
__PACKAGE__->belongs_to(
scan_folder => 'App::DrivePlayer::Schema::Result::ScanFolder',
'scan_folder_id',
);
__PACKAGE__->has_many(
tracks => 'App::DrivePlayer::Schema::Result::Track',
'folder_id',
{ cascade_delete => 1 },
);
sub sqlt_deploy_hook {
my ($self, $sqlt_table) = @_;
$sqlt_table->add_index( name => 'idx_folders_scan_folder', fields => ['scan_folder_id'] );
}
1;
__END__
=head1 NAME
App::DrivePlayer::Schema::Result::Folder - DBIx::Class result for the folders table
=head1 DESCRIPTION
Represents a Drive folder (root or subfolder) encountered during a scan.
Belongs to a L<App::DrivePlayer::Schema::Result::ScanFolder> and has many
L<App::DrivePlayer::Schema::Result::Track> children (cascade-deleted with the
folder).
Columns: C<id>, C<drive_id>, C<name>, C<parent_drive_id>, C<path>,
C<scan_folder_id>.
=cut
lib/App/DrivePlayer/Schema/Result/ScanFolder.pm view on Meta::CPAN
is_nullable => 0,
},
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->add_unique_constraint( unique_drive_id => ['drive_id'] );
__PACKAGE__->has_many(
folders => 'App::DrivePlayer::Schema::Result::Folder',
'scan_folder_id',
{ cascade_delete => 1 },
);
1;
__END__
=head1 NAME
App::DrivePlayer::Schema::Result::ScanFolder - DBIx::Class result for the scan_folders table
=head1 DESCRIPTION
Represents a top-level Google Drive folder that the user has configured for
scanning. Has many L<App::DrivePlayer::Schema::Result::Folder> children
(cascade-deleted when the scan folder is removed).
Columns: C<id>, C<drive_id>, C<name>.
=cut
t/unit/Test/DrivePlayer/DB.pm view on Meta::CPAN
$self->db->upsert_scan_folder('id_z', 'Zzz Folder');
$self->db->upsert_scan_folder('id_a', 'Aaa Folder');
$self->db->upsert_scan_folder('id_m', 'Mmm Folder');
my @folders = $self->db->all_scan_folders;
is scalar @folders, 3, 'all_scan_folders returns all rows';
is $folders[0]{name}, 'Aaa Folder', 'scan_folders ordered by name';
}
sub delete_scan_folder_cascade : Tests(3) {
my ($self) = @_;
my $sf = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));
$self->db->upsert_track(sample_track(folder_id => $fld->{id}));
is $self->db->track_count, 1, 'track exists before delete';
$self->db->delete_scan_folder(FAKE_FOLDER_ID);
is $self->db->schema->resultset('ScanFolder')->count, 0, 'scan_folder deleted';
is $self->db->track_count, 0, 'tracks cascade-deleted';
}
# ---- folders ----
sub upsert_folder_create : Tests(5) {
my ($self) = @_;
my $sf = $self->db->upsert_scan_folder(FAKE_FOLDER_ID, FAKE_FOLDER_NAME);
my $fld = $self->db->upsert_folder(sample_folder(scan_folder_id => $sf->{id}));
( run in 0.580 second using v1.01-cache-2.11-cpan-e93a5daba3e )