NAME

App::DrivePlayer::DB - SQLite database facade for the DrivePlayer library

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;
my @albums  = $db->all_albums;
my $count   = $db->track_count;

DESCRIPTION

A thin Moo facade over a App::DrivePlayer::Schema (DBIx::Class) schema. Handles database creation on first use and exposes a simple hashref-based API so the rest of the application never touches DBIx::Class directly.

All query methods return plain hashrefs (or lists of hashrefs), never DBIx::Class row objects.

ATTRIBUTES

path

is: ro, isa: Str, required: 1

Filesystem path to the SQLite database file. The parent directory is created automatically if it does not exist.

schema

is: lazy, isa: App::DrivePlayer::Schema

The underlying DBIx::Class schema object. Built automatically on first access; the database file and tables are created at that point if needed.

METHODS

new

my $db = App::DrivePlayer::DB->new(path => $path);

Constructor. The schema (and the SQLite file) is initialised immediately.

upsert_scan_folder

my $hashref = $db->upsert_scan_folder($drive_id, $name);

Insert or update a top-level scan folder record. Returns the row as a hashref with at least id, drive_id, and name.

get_scan_folder_by_drive_id

my $hashref = $db->get_scan_folder_by_drive_id($drive_id);

Returns the scan folder hashref, or undef if not found.

all_scan_folders

my @hashrefs = $db->all_scan_folders;

Returns all scan folders ordered alphabetically by name.

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.

upsert_folder

my $hashref = $db->upsert_folder(%fields);

Insert or update a subfolder record. Required keys: drive_id, name, path, scan_folder_id. Optional: parent_drive_id.

get_folder_by_drive_id

my $hashref = $db->get_folder_by_drive_id($drive_id);

Returns the folder hashref, or undef if not found.

folders_for_scan_folder

my @hashrefs = $db->folders_for_scan_folder($scan_folder_id);

Returns all folders belonging to a scan folder, ordered by path.

upsert_track

$db->upsert_track(%fields);

Insert or update a track record keyed on drive_id. Common fields: drive_id, title, artist, album, track_number, year, duration_ms, size, mime_type, modified_time, folder_id, folder_path.

get_track

my $hashref = $db->get_track($id);

Look up a track by its integer primary key. Returns undef if not found.

get_track_by_drive_id

my $hashref = $db->get_track_by_drive_id($drive_id);

Look up a track by its Google Drive file ID. Returns undef if not found.

all_tracks

my @hashrefs = $db->all_tracks;

Returns every track, ordered by artist, album, track_number, title (all comparisons case-insensitive, NULLs last).

tracks_by_artist

my @hashrefs = $db->tracks_by_artist($artist);

Case-insensitive artist match, ordered by album -> track_number -> title.

tracks_by_album

my @hashrefs = $db->tracks_by_album($album);

Case-insensitive album match, ordered by track_number -> title.

tracks_by_folder

my @hashrefs = $db->tracks_by_folder($folder_id);

All tracks in the given folder, ordered by track_number -> title.

search_tracks

my @hashrefs = $db->search_tracks($query);

Case-insensitive substring search across title, artist, and album fields. Ordered as per "all_tracks".

all_artists

my @strings = $db->all_artists;

Distinct, non-empty artist names ordered case-insensitively.

all_albums

my @strings = $db->all_albums;

Distinct, non-empty album names ordered case-insensitively.

top_folders

my @hashrefs = $db->top_folders;

Returns folders that sit at the top level of a scan folder (i.e. whose parent is the scan-folder root), ordered by path.

track_count

my $n = $db->track_count;

Total number of tracks in the database.

clear_scan_folder_tracks

$db->clear_scan_folder_tracks($scan_folder_id);

Deletes all tracks and folders belonging to $scan_folder_id. Used before a rescan to remove stale data.