Archive / / / / / Database.cc
2008-10-21 13:22:46 UTC
previous next
/* Echo Media Player * Copyright (C) 2008 Shane O'Connell * * [ The original file includes a copyright header in this location describing * the file as being released under the terms of the GNU General Public * License. It has been removed in order to display the file as part of the * archive. ] */ #include "Database.h" #include <sys/stat.h> #include <giomm.h> #include <cstdlib> #include <cassert> #include <iostream> using namespace std; Database* Database::m_instance = 0; void Database::init() { assert(!m_instance); m_instance = new Database(); SQLstmt stmt; m_instance->db.prepare(stmt, "SELECT LibraryID, LibraryName, LibraryIcon " "FROM Libraries ORDER BY LibraryID"); while (stmt.step()) { m_instance->m_libraries.push_back(LibraryRef(new Library( stmt.get_column_int(0), stmt.get_column_text(1), stmt.get_column_text(2)))); } } Database::Database() { // TODO handle various Gio errors Glib::RefPtr<Gio::File> db_file; char* xdg_config_dir_env = getenv("XDG_CONFIG_HOME"); if (xdg_config_dir_env) db_file = Gio::File::create_for_path(xdg_config_dir_env); if (!xdg_config_dir_env || !db_file->query_exists() || !db_file->is_native()) { char* home_dir_env = getenv("HOME"); assert(home_dir_env != NULL); // TODO show a friendly error message instead of this db_file = Gio::File::create_for_path(home_dir_env); assert(db_file->query_exists() && db_file->is_native()); // TODO show a better error message db_file = db_file->get_child(".config"); } if (!db_file->query_exists()) { db_file->make_directory(); chmod(db_file->get_path().c_str(), 0700); } db_file = db_file->get_child("echo"); if (!db_file->query_exists()) { db_file->make_directory(); chmod(db_file->get_path().c_str(), 0700); } db_file = db_file->get_child("echo.db"); bool new_db = !db_file->query_exists(); db.open(db_file->get_path()); if (new_db) chmod(db_file->get_path().c_str(), 0600); db.run("CREATE TEMPORARY TABLE MemoryPlaylists (" " PlaylistID INTEGER PRIMARY KEY," " PlaylistName TEXT" ")"); db.run("CREATE TEMPORARY TABLE MemoryPlaylistTracks (" " PlaylistID INTEGER," " PlaylistIndex INTEGER," " ArtistName TEXT," " AlbumName TEXT," " AlbumReleaseDate INTEGER," " TrackName TEXT," " TrackNumber INTEGER," " TrackURI TEXT UNIQUE" ")"); db.run("CREATE TABLE IF NOT EXISTS Config (" " Name TEXT," " Value TEXT" ")"); db.run("CREATE TABLE IF NOT EXISTS Artists (" " ArtistID INTEGER PRIMARY KEY," " ArtistName TEXT UNIQUE" ")"); db.prepare(m_get_artist_id_stmt, "SELECT ArtistID FROM Artists WHERE ArtistName = ?"); db.prepare(m_add_artist_id_stmt, "INSERT INTO Artists (ArtistName) VALUES(?)"); db.run("CREATE TABLE IF NOT EXISTS Albums (" " AlbumID INTEGER PRIMARY KEY," " ArtistID INTEGER," " AlbumName TEXT," " AlbumReleaseDate INTEGER" ")"); db.prepare(m_get_album_id_stmt, "SELECT AlbumID FROM Albums WHERE ArtistID = ? AND AlbumName = ?"); db.prepare(m_add_album_id_stmt, "INSERT INTO Albums (ArtistID, AlbumName) VALUES(?,?)"); db.run("CREATE TABLE IF NOT EXISTS Tracks (" " TrackID INTEGER PRIMARY KEY," " AlbumID INTEGER," " TrackName TEXT," " TrackNumber INTEGER," " TrackRating INTEGER," " TrackURI TEXT UNIQUE ON CONFLICT REPLACE" ")"); db.prepare(m_get_track_id_stmt, "SELECT TrackID FROM Tracks WHERE TrackURI = ?"); //m_add_track_id_stmt = m_db.prepare("INSERT INTO Albums (ArtistID, AlbumName) VALUES(?,?)"); db.run("CREATE TABLE IF NOT EXISTS Libraries (" " LibraryID INTEGER PRIMARY KEY," " LibraryName TEXT," " LibraryIcon TEXT," " LibraryURI TEXT" ")"); if (get_row_count("Libraries") == 0) { db.run("INSERT INTO Libraries (LibraryName, LibraryIcon, LibraryURI) " "VALUES('Music Library', 'audio-x-generic', 'file:/home/shane/library/music/albums')"); db.run("INSERT INTO Libraries (LibraryName, LibraryIcon, LibraryURI) " "VALUES('Video Library', 'video-x-generic', 'file:/home/shane/library/television')"); } db.run("CREATE TABLE IF NOT EXISTS LibraryTracks (" " LibraryID INTEGER," " TrackID INTEGER," " UNIQUE(LibraryID, TrackID) ON CONFLICT REPLACE" ")"); db.run("CREATE TABLE IF NOT EXISTS Playlists (" " PlaylistID INTEGER PRIMARY KEY," " PlaylistName TEXT" ")"); db.run("CREATE TABLE IF NOT EXISTS PlaylistTracks (" " PlaylistID INTEGER," " TrackID INTEGER," " PlaylistOrder INTEGER" ")"); SQLstmt stmt; db.prepare(stmt, "SELECT ArtistID, ArtistName FROM Artists"); while (stmt.step()) m_artist_id_lookup[stmt.get_column_int(0)] = StringRef( new Glib::ustring(stmt.get_column_text(1))); db.prepare(stmt, "SELECT AlbumID, AlbumName FROM Albums"); while (stmt.step()) m_album_id_lookup[stmt.get_column_int(0)] = StringRef( new Glib::ustring(stmt.get_column_text(1))); } int Database::get_row_count(const Glib::ustring& table) { SQLstmt stmt; db.prepare(stmt, Glib::ustring::compose("SELECT COUNT(*) FROM %1", table)); bool is_row = stmt.step(); assert(is_row); return stmt.get_column_int(0); } long long Database::get_artist_id(const Glib::ustring& artist_name) { m_get_artist_id_stmt.bind(1, artist_name); if (m_get_artist_id_stmt.step()) { long long artist_id = m_get_artist_id_stmt.get_column_int(0); m_get_artist_id_stmt.reset(); return artist_id; } else { m_get_artist_id_stmt.reset(); m_add_artist_id_stmt.bind(1, artist_name); m_add_artist_id_stmt.step(); m_add_artist_id_stmt.reset(); return db.last_rowid(); } } long long Database::get_album_id(long long artist_id, const Glib::ustring& album_name) { m_get_album_id_stmt.bind(1, artist_id); m_get_album_id_stmt.bind(2, album_name); if (m_get_album_id_stmt.step()) { long long album_id = m_get_album_id_stmt.get_column_int(0); m_get_album_id_stmt.reset(); return album_id; } else { m_get_album_id_stmt.reset(); m_add_album_id_stmt.bind(1, artist_id); m_add_album_id_stmt.bind(2, album_name); m_add_album_id_stmt.step(); m_add_album_id_stmt.reset(); return db.last_rowid(); } } long long Database::get_track_id(const Glib::ustring& uri) { m_get_track_id_stmt.bind(1, uri); if (m_get_track_id_stmt.step()) { long long track_id = m_get_track_id_stmt.get_column_int(0); m_get_track_id_stmt.reset(); return track_id; } else { m_get_track_id_stmt.reset(); return -1; } }