ocarina/design/library.txt

206 lines
5.6 KiB
Plaintext

== Files ==
ocarina/include/
library.h
ocarina/lib/
library.cpp
$HOME/.ocarina{-debug}/
album.db
artist.db
genre.db
library.db
track.db
== Depends ==
idle database playlist filter
Library: (lib/library.cpp)
The library manages databases containing track information added by the
user. Ocarina 6 splits the library into multiple database tables for
storing content. The library will exist in a library namespace to
to make functions and classes more unique.
- Databases:
enum DB_Type {
DB_ALBUM,
DB_ARTIST,
DB_GENRE,
DB_LIBRARY,
DB_TRACK,
};
- Album:
class library :: Album : public DatabaseEntry {
public:
/* primary_key = "$name.$year.$artist_id" */
string name;
string name_lower;
unsigned int year;
unsigned int artist_id;
};
File << artist_id << year << name
- Artist and Genre:
class library :: AGInfo : public DatabaseEntry {
public:
string name; /* primary key */
string name_lower;
};
File << name
- Library:
class library :: Library : public DatabaseEntry {
public:
string root_path; /* primary_key */
unsigned int count;
bool enabled;
};
File << enabled << root_path
- Track:
The primary key for a track is the full filepath (library.root_path +
track.filepath)
class library :: Track : public DatabaseEntry {
public:
/* primary_key = library.root_path + "/" + filepath */
unsigned int library_id;
unsigned int artist_id;
unsigned int album_id;
unsigned int genre_id;
unsigned int track;
unsigned int last_year;
unsigned int last_month;
unsigned int last_day;
unsigned int play_count;
unsigned int length;
string length_str;
string title;
string title_lower;
string filepath;
};
File << library_id << artist_id << album_id << genre_id;
File << track << last_year << last_month << last_day << play_count;
File << length << length_str << endl
File << title << endl;
File << filepath << endl;
- Song:
struct Song {
library :: Album *album;
library :: AGInfo *artist;
library :: AGInfo *genre;
library :: Library *library;
library :: Track *track;
};
- Databases:
Database<library :: Album> album_db(album.db);
Database<library :: AGInfo> artist_db(artist.db);
Database<library :: AGInfo> genre_db(genre.db);
Database<library :: Library> library_db(library.db);
Database<library :: Track> track_db(track.db);
- Updating algorithm:
1) Use a single IdleTask to loop over each track in the library, check
if the track still exists in the filesystem and remove it from
library_db if not.
2) For each directory in the scan directory, create an IdleTask to
scan the next level of directories.
3) For each file in the scan directory, check if the file already
exists in the track_db and add it to the database if not. Save
each database after adding files.
The taglib library should be used for finding artist, album, etc. tags
for each track.
- Importing
Ocarina 5.11 stores library files in ~/.ocarina/library/. Importing
involves reading each file and adding them to the database. If the file
describes a path already in the database then DO NOT overwrite the
current path and instead move on to the next file. If version != 2 then
move on to the next file.
File format:
File << version << endl; /* version == 2 */
File << path << endl;
File << id << enabled << next_track_id << size << endl;
File << <track list>
Track format:
File << filepath << endl;
File << title << endl;
File << artist << endl;
File << album << endl;
File << comment << endl;
File << genre << endl;
File << lenstr << endl;
File << id << year << track << count;
File << last_day << last_month << last_year;
File << length << bitrate << sample << channels << banned << endl;
- Testing:
The script tests/library/gen_library.sh will create a sample library
in the /tmp/ directory for testing purposes. All the track files are
complete silence, but the script will fake up tags for each file.
To test importing, create several mock library files and copy them to
~/.ocarina-test/library/ and attempt to read them in.
- API
void library :: init();
Initialize databases and read files from disk. While reading
the library:
- Update the count of tracks in each library path
- Find the lowercase text of artist, album, genre, track
void library :: add_path(string dir);
If dir is not a directory:
throw -EINVAL
Trigger the on_library_add() callback on success.
void library :: del_path(unsigned int lib_id);
Invalidate a library_db row and all tracks owned by that path
if lib_id is not valid, throw -EEXIST.
void library :: update_path(lib_id);
Update the given library_db row.
If lib_id is not valid, throw -EEXIST.
Trigger the on_library_update() callback.
void library :: update_all();
Update all library paths.
Trigger the on_library_update() callback for each path.
void library :: set_enabled(unsigned int id, bool enabled);
Either enable or disable a library path. Trigger
on_library_track_del() for each track disabled this way.
struct Song library :: lookup(track_id);
Fill out a Song structure for the provided track_id.
Throw -EEXIST if there is no track mapping to track_id.
struct library :: Library *library :: lookup_path(unsigned int id);
Return the library path with index id.
Throw -EEXIST if there is no such path.
void library :: import();
Call this function to import an Ocarina 5.11 style library,
following the "Importing" section above.
#ifdef CONFIG_TEST
void library :: print_db(DB_Type);
Print the database corresponding to DB_Type
void library :: reset();
Clear all databases, returning the library to an empty state.
endif /* CONFIG_TEST */