Working on HTTP endpoint to delete songs. Finished with album. Need to work on the Artist, Genre, and Year aspects

This commit is contained in:
kdeng00
2019-09-09 21:57:04 -04:00
parent 19ddb9be0b
commit 8c1c2340b2
10 changed files with 247 additions and 15 deletions
+6
View File
@@ -1,6 +1,7 @@
#ifndef ALBUMREPOSITORY_H_
#define ALBUMREPOSITORY_H_
#include <utility>
#include <vector>
#include "database/BaseRepository.h"
@@ -16,14 +17,19 @@ namespace database
std::vector<model::Album> retrieveRecords();
std::pair<model::Album, int> retrieveRecordWithSongCount(model::Album&, type::AlbumFilter);
model::Album retrieveRecord(model::Album&, type::AlbumFilter);
bool doesAlbumExists(const model::Album&, type::AlbumFilter);
void saveAlbum(const model::Album&);
void deleteAlbum(const model::Album&, type::AlbumFilter);
private:
std::vector<model::Album> parseRecords(MYSQL_STMT*);
std::pair<model::Album, int> parseRecordWithSongCount(MYSQL_STMT*);
// TODO: after parseRecord(MYSQL_STMT*) is implemented remove
// parseRecord(MYSQL_RES*)
model::Album parseRecord(MYSQL_RES*);
+2
View File
@@ -13,6 +13,8 @@ namespace manager
model::Album retrieveAlbum(model::Album&);
model::Album saveAlbum(const model::Song&);
void deleteAlbum(const model::Song&);
static void printAlbum(const model::Album&);
private:
model::BinaryPath m_bConf;
+2
View File
@@ -14,6 +14,8 @@ namespace manager
CoverArtManager(const model::BinaryPath& bConf);
model::Cover saveCover(const model::Song&, std::string&, const std::string&);
void deleteCover(const model::Song&);
private:
model::BinaryPath m_bConf;
std::string path;
+1
View File
@@ -23,6 +23,7 @@ namespace manager
private:
void saveSongTemp(model::Song&);
void saveMisc(model::Song&);
void deleteMisc(const model::Song&);
model::BinaryPath m_bConf;
std::string exe_path;
+26
View File
@@ -32,6 +32,11 @@ namespace model
struct Artist
{
Artist() = default;
Artist(const Song& song)
{
id = song.artistId;
artist = song.artist;
}
Artist(const int id) : id(id) { }
int id;
@@ -41,6 +46,12 @@ namespace model
struct Album
{
Album() = default;
Album(const Song& song)
{
id = song.albumId;
title = song.album;
year = song.year;
}
Album(const int id) : id(id) { }
int id;
@@ -52,6 +63,11 @@ namespace model
struct Genre
{
Genre() = default;
Genre(const Song& song)
{
id = song.genreId;
category = song.genre;
}
Genre(const int id) : id(id) { }
int id;
@@ -62,6 +78,11 @@ namespace model
struct Year
{
Year() = default;
Year(const Song& song)
{
id = song.yearId;
year = song.year;
}
Year(const int id) : id(id) { }
int id;
@@ -71,6 +92,11 @@ namespace model
struct Cover
{
Cover() = default;
Cover(const Song& song)
{
id = song.coverArtId;
songTitle = song.title;
}
Cover(const int id) : id(id) { }
int id;
+141
View File
@@ -29,6 +29,51 @@ std::vector<model::Album> database::AlbumRepository::retrieveRecords()
return albums;
}
std::pair<model::Album, int> database::AlbumRepository::retrieveRecordWithSongCount(model::Album& album, type::AlbumFilter filter = type::AlbumFilter::id)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
MYSQL_BIND params[4];
std::memset(params, 0, sizeof(params));
qry << "SELECT alb.*, COUNT(*) AS SongCount FROM Album alb LEFT JOIN ";
qry << "Song sng ON alb.AlbumId=sng.AlbumId WHERE ";
switch (filter) {
case type::AlbumFilter::id:
qry << "alb.AlbumId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&album.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
qry << " GROUP BY alb.AlbumId LIMIT 1";
const auto query = qry.str();
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
std::cout << "query has been performed" << std::endl;
auto albWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "record has been parsed" << std::endl;
return albWSC;
}
model::Album database::AlbumRepository::retrieveRecord(model::Album& album, type::AlbumFilter filter)
{
std::cout << "retrieving album record" << std::endl;
@@ -165,9 +210,45 @@ void database::AlbumRepository::saveAlbum(const model::Album& album)
std::cout << "done inserting album record" << std::endl;
}
void database::AlbumRepository::deleteAlbum(const model::Album& album, type::AlbumFilter filter = type::AlbumFilter::id)
{
std::cout << "deleting album record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
qry << "DELETE FROM Album WHERE ";
switch (filter) {
case type::AlbumFilter::id:
qry << "AlbumId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&album.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
const auto query = qry.str();
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
std::cout << "execute delete query" << std::endl;
}
std::vector<model::Album> database::AlbumRepository::parseRecords(MYSQL_STMT* stmt)
{
std::cout << "parsing album record" << std::endl;
mysql_stmt_store_result(stmt);
std::vector<model::Album> albums;
@@ -225,6 +306,7 @@ std::vector<model::Album> database::AlbumRepository::parseRecords(MYSQL_STMT* st
return albums;
}
// TODO: check to see if this is not used, if not then remove it
model::Album database::AlbumRepository::parseRecord(MYSQL_RES* results)
{
std::cout << "parsing album record" << std::endl;
@@ -250,6 +332,65 @@ model::Album database::AlbumRepository::parseRecord(MYSQL_RES* results)
return album;
}
std::pair<model::Album, int> database::AlbumRepository::parseRecordWithSongCount(MYSQL_STMT *stmt)
{
std::cout << "parsing album record with song count" << std::endl;
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
std::cout << "result count " << rowCount << std::endl;
model::Album album;
int songCount;
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0, must be an incorrect query" << std::endl;
return std::make_pair(model::Album(), 0);
}
auto res = mysql_stmt_result_metadata(stmt);
const auto valAmt = 4;
const auto strLen = 1024;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
MYSQL_BIND val[valAmt];
std::memset(val, 0, sizeof(val));
char title[strLen];
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&album.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)title;
val[1].buffer_length = strLen;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
val[2].buffer_type = MYSQL_TYPE_LONG;
val[2].buffer = (char*)&album.year;
val[2].length = &len[2];
val[2].is_null = &nullRes[2];
val[3].buffer_type = MYSQL_TYPE_LONG;
val[3].buffer = (char*)&songCount;
val[3].length = &len[2];
val[3].is_null = &nullRes[2];
auto status = mysql_stmt_bind_result(stmt, val);
status = mysql_stmt_fetch(stmt);
album.title = std::move(title);
std::cout << "done parsing album record with song count" << std::endl;
auto albWSC = std::make_pair(album, songCount);
return albWSC;
}
model::Album database::AlbumRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing album record" << std::endl;
+1
View File
@@ -211,6 +211,7 @@ model::Year database::YearRepository::parseRecord(MYSQL_RES *results)
model::Year database::YearRepository::parseRecord(MYSQL_STMT *stmt)
{
// TODO: imeplement this
// I really thought that I had already done this
model::Year year;
+17
View File
@@ -36,6 +36,23 @@ model::Album manager::AlbumManager::saveAlbum(const model::Song& song)
return album;
}
void manager::AlbumManager::deleteAlbum(const model::Song& song)
{
model::Album album(song);
database::AlbumRepository albRepo(m_bConf);
auto albWSC = albRepo.retrieveRecordWithSongCount(album, type::AlbumFilter::id);
if (albWSC.second > 1) {
std::cout << "album still contain songs related to it, will not delete" << std::endl;
return;
}
std::cout << "safe to delete the album record" << std::endl;
albRepo.deleteAlbum(album, type::AlbumFilter::id);
}
void manager::AlbumManager::printAlbum(const model::Album& album)
{
std::cout << "\nalbum record" << std::endl;
+32
View File
@@ -1,9 +1,15 @@
#include "manager/CoverArtManager.h"
#include <iostream>
#include <filesystem>
#include "database/CoverArtRepository.h"
#include "manager/DirectoryManager.h"
#include "type/CoverFilter.h"
#include "utility/MetadataRetriever.h"
namespace fs = std::filesystem;
manager::CoverArtManager::CoverArtManager(const std::string& configPath) : path(configPath)
{ }
@@ -32,3 +38,29 @@ model::Cover manager::CoverArtManager::saveCover(const model::Song& song, std::s
return cov;
}
void manager::CoverArtManager::deleteCover(const model::Song& song)
{
database::CoverArtRepository covRepo(m_bConf);
model::Cover cov(song.coverArtId);
cov = covRepo.retrieveRecord(cov, type::CoverFilter::id);
covRepo.deleteRecord(cov);
auto paths = manager::DirectoryManager::pathConfigContent(m_bConf);
const auto coverArtPath = paths["cover_root_path"].get<std::string>();
std::string stockCoverArtPath = coverArtPath;
stockCoverArtPath.append("CoverArt.png");
if (stockCoverArtPath.compare(cov.imagePath) != 0) {
fs::remove(cov.imagePath);
std::cout << "deleting cover art" << std::endl;
} else {
std::cout << "song contains the stock cover art, will not delete" << std::endl;
}
manager::DirectoryManager::deleteDirectories(song, coverArtPath);
}
+19 -15
View File
@@ -48,30 +48,18 @@ void manager::SongManager::deleteSong(model::Song& song)
// TODO: handle what happens to miscellanes records
// like Album, Artist, Genre, etc. when a song
// is deleted
database::CoverArtRepository covRepo(m_bConf);
database::SongRepository songRepo(m_bConf);
song = songRepo.retrieveRecord(song, type::SongFilter::id);
songRepo.deleteRecord(song);
model::Cover cov;
cov.id = song.coverArtId;
cov = covRepo.retrieveRecord(cov, type::CoverFilter::id);
covRepo.deleteRecord(cov);
auto paths = manager::DirectoryManager::pathConfigContent(m_bConf);
const auto coverArtPath = paths["cover_root_path"].get<std::string>();
std::string stockCoverArtPath = coverArtPath;
stockCoverArtPath.append("CoverArt.png");
deleteMisc(song);
songRepo.deleteRecord(song);
if (stockCoverArtPath.compare(cov.imagePath) != 0) {
fs::remove(cov.imagePath);
std::cout << "deleting cover art" << std::endl;
}
fs::remove(song.songPath);
manager::DirectoryManager::deleteDirectories(song, paths["root_music_path"].get<std::string>());
manager::DirectoryManager::deleteDirectories(song, coverArtPath);
}
void manager::SongManager::printSong(const model::Song& song)
@@ -111,6 +99,7 @@ void manager::SongManager::saveSongTemp(model::Song& song)
song.songPath = tmpSongPath;
}
void manager::SongManager::saveMisc(model::Song& song)
{
CoverArtManager covMgr(m_bConf);
@@ -164,3 +153,18 @@ void manager::SongManager::saveMisc(model::Song& song)
std::cout << "done with miscellaneous database records" << std::endl;
}
void manager::SongManager::deleteMisc(const model::Song& song)
{
manager::CoverArtManager covMgr(m_bConf);
covMgr.deleteCover(song);
manager::AlbumManager albMgr(m_bConf);
albMgr.deleteAlbum(song);
manager::ArtistManager artMgr(m_bConf);
manager::GenreManager gnrMgr(m_bConf);
manager::YearManager yrMgr(m_bConf);
}