Implemented deletion functionality, and lingering records are removed fixes #49

This commit is contained in:
kdeng00
2019-09-10 22:27:28 -04:00
parent 8c1c2340b2
commit a00a70029e
17 changed files with 489 additions and 17 deletions
+12 -11
View File
@@ -32,6 +32,7 @@ std::vector<model::Album> database::AlbumRepository::retrieveRecords()
std::pair<model::Album, int> database::AlbumRepository::retrieveRecordWithSongCount(model::Album& album, type::AlbumFilter filter = type::AlbumFilter::id)
{
std::cout << "retrieving album with song count" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
@@ -44,7 +45,7 @@ std::pair<model::Album, int> database::AlbumRepository::retrieveRecordWithSongCo
switch (filter) {
case type::AlbumFilter::id:
qry << "alb.AlbumId = ?";
qry << "sng.AlbumId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&album.id;
@@ -62,15 +63,11 @@ std::pair<model::Album, int> database::AlbumRepository::retrieveRecordWithSongCo
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;
}
@@ -337,10 +334,14 @@ std::pair<model::Album, int> database::AlbumRepository::parseRecordWithSongCount
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;
int songCount = 0;
if (rowCount == 0) {
std::cout << "no results" << std::endl;
return std::make_pair(album, songCount);
}
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0, must be an incorrect query" << std::endl;
@@ -348,8 +349,8 @@ std::pair<model::Album, int> database::AlbumRepository::parseRecordWithSongCount
}
auto res = mysql_stmt_result_metadata(stmt);
const auto valAmt = 4;
const auto strLen = 1024;
constexpr auto valAmt = 4;
constexpr auto strLen = 1024;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
@@ -376,8 +377,8 @@ std::pair<model::Album, int> database::AlbumRepository::parseRecordWithSongCount
val[3].buffer_type = MYSQL_TYPE_LONG;
val[3].buffer = (char*)&songCount;
val[3].length = &len[2];
val[3].is_null = &nullRes[2];
val[3].length = &len[3];
val[3].is_null = &nullRes[3];
auto status = mysql_stmt_bind_result(stmt, val);
status = mysql_stmt_fetch(stmt);
+128
View File
@@ -29,6 +29,49 @@ std::vector<model::Artist> database::ArtistRepository::retrieveRecords()
return artists;
}
std::pair<model::Artist, int> database::ArtistRepository::retrieveRecordWithSongCount(model::Artist& artist, type::ArtistFilter filter = type::ArtistFilter::id)
{
std::cout << "retrieving artist record with song count" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT art.*, COUNT(*) AS SongCount FROM Artist art LEFT JOIN ";
qry << "Song sng ON art.ArtistId=sng.ArtistId WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::ArtistFilter::id:
qry << "sng.ArtistId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&artist.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
qry << " GROUP BY art.ArtistId 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 << "Artist record with song count query ";
std::cout << "has been performed" << std::endl;
auto artWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return artWSC;
}
model::Artist database::ArtistRepository::retrieveRecord(model::Artist& artist, type::ArtistFilter filter)
{
@@ -160,6 +203,42 @@ void database::ArtistRepository::saveRecord(const model::Artist& artist)
std::cout<< "inserted artist record" << std::endl;
}
void database::ArtistRepository::deleteArtist(const model::Artist& artist, type::ArtistFilter filter = type::ArtistFilter::id) {
// TODO: implement this
std::cout << "delete Artist record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "DELETE FROM Artist WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::ArtistFilter::id:
qry << "ArtistId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&artist.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);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "deleted artist record" << std::endl;
}
std::vector<model::Artist> database::ArtistRepository::parseRecords(MYSQL_STMT *stmt)
{
@@ -236,6 +315,55 @@ model::Artist database::ArtistRepository::parseRecord(MYSQL_RES* results)
return artist;
}
std::pair<model::Artist, int> database::ArtistRepository::parseRecordWithSongCount(MYSQL_STMT *stmt)
{
std::cout << "parsing artist record with song count" << std::endl;
mysql_stmt_store_result(stmt);
const auto strLen = 1024;
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
model::Artist artist;
int songCount = 0;
if (mysql_stmt_num_rows(stmt) == 0) {
std::cout << "no results" << std::endl;
return std::make_pair(artist, songCount);
}
MYSQL_BIND params[valAmt];
std::memset(params, 0, sizeof(params));
char art[strLen];
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&artist.id;
params[0].length = &len[0];
params[0].is_null = &nullRes[0];
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)art;
params[1].buffer_length = strLen;
params[1].length = &len[1];
params[1].is_null = &nullRes[1];
params[2].buffer_type = MYSQL_TYPE_LONG;
params[2].buffer = (char*)&songCount;
params[2].length = &len[2];
params[2].is_null = &nullRes[2];
mysql_stmt_bind_result(stmt, params);
mysql_stmt_fetch(stmt);
artist.artist = std::move(art);
std::cout << "parsed artist record with song count" << std::endl;
return std::make_pair(artist, songCount);
}
model::Artist database::ArtistRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing artist record" << std::endl;
+130
View File
@@ -27,6 +27,49 @@ std::vector<model::Genre> database::GenreRepository::retrieveRecords()
return genres;
}
std::pair<model::Genre, int> database::GenreRepository::retrieveRecordWithSongCount(model::Genre& genre, type::GenreFilter filter = type::GenreFilter::id)
{
std::cout << "retrieving genre record with song count" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT gnr.*, COUNT(*) AS SongCount FROM Genre gnr LEFT JOIN ";
qry << "Song sng ON gnr.GenreId=sng.GenreId WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::GenreFilter::id:
qry << "sng.GenreId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&genre.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
qry << " GROUP BY gnr.GenreId 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);
auto gnrWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved genre record with song count" << std::endl;
return gnrWSC;
}
model::Genre database::GenreRepository::retrieveRecord(model::Genre& genre, type::GenreFilter filter)
{
@@ -145,6 +188,44 @@ void database::GenreRepository::saveRecord(const model::Genre& genre)
std::cout << "inserted record" << std::endl;
}
void database::GenreRepository::deleteRecord(const model::Genre& genre, type::GenreFilter filter = type::GenreFilter::id)
{
// TODO: implement this
std::cout << "deleting genre record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "DELETE FROM Genre WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::GenreFilter::id:
qry << "GenreId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&genre.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);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "deleted genre record" << std::endl;
}
std::vector<model::Genre> database::GenreRepository::parseRecords(MYSQL_STMT *stmt)
{
@@ -196,6 +277,55 @@ std::vector<model::Genre> database::GenreRepository::parseRecords(MYSQL_STMT *st
return genres;
}
std::pair<model::Genre, int> database::GenreRepository::parseRecordWithSongCount(MYSQL_STMT *stmt)
{
std::cout << "parsing genre record with song count" << std::endl;
mysql_stmt_store_result(stmt);
const auto strLen = 1024;
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
model::Genre genre;
int songCount = 0;
if (mysql_stmt_num_rows(stmt) == 0) {
std::cout << "no results" << std::endl;
return std::make_pair(genre, songCount);
}
MYSQL_BIND val[valAmt];
std::memset(val, 0, sizeof(val));
char category[strLen] ;
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&genre.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)category;
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*)&songCount;
val[2].length = &len[2];
val[2].is_null = &nullRes[2];
mysql_stmt_bind_result(stmt, val);
mysql_stmt_fetch(stmt);
genre.category = std::move(category);
std::cout << "parsed genre record with song count" << std::endl;
return std::make_pair(genre, songCount);
}
model::Genre database::GenreRepository::parseRecord(MYSQL_RES* results)
{
std::cout << "parsing genre record" << std::endl;
+4 -1
View File
@@ -13,6 +13,7 @@ database::SongRepository::SongRepository(const std::string& path) : BaseReposito
database::SongRepository::SongRepository(const model::BinaryPath& bConf) : BaseRepository(bConf)
{ }
std::vector<model::Song> database::SongRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
@@ -134,7 +135,7 @@ bool database::SongRepository::doesSongExist(const model::Song& song, type::Song
return (rowCount > 0) ? true : false;
}
void database::SongRepository::deleteRecord(const model::Song& song)
bool database::SongRepository::deleteRecord(const model::Song& song)
{
auto conn = setupMysqlConnection();
auto status = 0;
@@ -144,6 +145,8 @@ void database::SongRepository::deleteRecord(const model::Song& song)
auto result = performMysqlQuery(conn, query);
mysql_close(conn);
return (result == 0) ? true : false;
}
void database::SongRepository::saveRecord(const model::Song& song)
+123
View File
@@ -29,6 +29,50 @@ std::vector<model::Year> database::YearRepository::retrieveRecords()
return yearRecs;
}
std::pair<model::Year, int> database::YearRepository::retrieveRecordWithSongCount(model::Year& year, type::YearFilter filter = type::YearFilter::id)
{
std::cout << "retrieving year record with song count" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT yr.*, COUNT(*) AS SongCount FROM Year yr LEFT JOIN ";
qry << "Song sng ON yr.YearId=sng.YearId WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::YearFilter::id:
qry << "sng.YearId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&year.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
qry << " GROUP BY yr.YearId 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);
auto yearWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved year record with song count" << std::endl;
return yearWSC;
}
model::Year database::YearRepository::retrieveRecord(model::Year& year, type::YearFilter filter)
{
// TODO: switch to prepared statements
@@ -140,6 +184,42 @@ void database::YearRepository::saveRecord(const model::Year& year)
std::cout << "saved record" << std::endl;
}
void database::YearRepository::deleteYear(const model::Year& year, type::YearFilter filter = type::YearFilter::id)
{
std::cout << "deleting year record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "DELETE FROM Year WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::YearFilter::id:
qry << "YearId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&year.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);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "deleted year record" << std::endl;
}
std::vector<model::Year> database::YearRepository::parseRecords(MYSQL_STMT *stmt)
{
@@ -185,6 +265,49 @@ std::vector<model::Year> database::YearRepository::parseRecords(MYSQL_STMT *stmt
return yearRecs;
}
std::pair<model::Year, int> database::YearRepository::parseRecordWithSongCount(MYSQL_STMT *stmt)
{
std::cout << "parsing year record" << std::endl;
mysql_stmt_store_result(stmt);
constexpr auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
model::Year year;
int songCount = 0;
if (mysql_stmt_num_rows(stmt) == 0) {
std::cout << "no results" << std::endl;
return std::make_pair(year, songCount);
}
MYSQL_BIND val[valAmt];
std::memset(val, 0, sizeof(val));
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&year.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_LONG;
val[1].buffer = (char*)&year.year;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
val[2].buffer_type = MYSQL_TYPE_LONG;
val[2].buffer = (char*)&songCount;
val[2].length = &len[2];
val[2].is_null = &nullRes[2];
mysql_stmt_bind_result(stmt, val);
mysql_stmt_fetch(stmt);
std::cout << "parsed year record from the database" << std::endl;
return std::make_pair(year, songCount);
}
model::Year database::YearRepository::parseRecord(MYSQL_RES *results)
{
std::cout << "parsing year record" << std::endl;
+17
View File
@@ -36,6 +36,23 @@ model::Artist manager::ArtistManager::saveArtist(const model::Song& song)
return artist;
}
void manager::ArtistManager::deleteArtist(const model::Song& song)
{
model::Artist artist(song);
database::ArtistRepository artRepo(m_bConf);
auto artWSC = artRepo.retrieveRecordWithSongCount(artist, type::ArtistFilter::id);
if (artWSC.second > 1) {
std::cout << "artist still contain songs related to it";
std::cout << ", not delete" << std::endl;
return;
}
std::cout << "safe to delete the artist record" << std::endl;
artRepo.deleteArtist(artist, type::ArtistFilter::id);
}
void manager::ArtistManager::printArtist(const model::Artist& artist)
{
std::cout << "\nartist record" << std::endl;
+1 -1
View File
@@ -89,7 +89,7 @@ void manager::DirectoryManager::deleteCoverArtFile(const std::string& covPath, c
}
void manager::DirectoryManager::deleteDirectories(model::Song song, const std::string& rootPath)
{
std::cout << "checking to for empty directories to delete" << std::endl;
std::cout << "checking for empty directories to delete" << std::endl;
const std::string art(rootPath + std::string("/") + song.artist);
const std::string alb(art + "/" + song.album);
+17
View File
@@ -33,6 +33,23 @@ model::Genre manager::GenreManager::saveGenre(const model::Song& song)
return genre;
}
void manager::GenreManager::deleteGenre(const model::Song& song)
{
model::Genre genre(song);
database::GenreRepository gnrRepo(m_bConf);
auto gnrWSC = gnrRepo.retrieveRecordWithSongCount(genre, type::GenreFilter::id);
if (gnrWSC.second > 1) {
std::cout << "genre still contain songs related to it";
std::cout << ", will not delete" << std::endl;
return;
}
std::cout << "safe to delete the genre record" << std::endl;
gnrRepo.deleteRecord(genre, type::GenreFilter::id);
}
void manager::GenreManager::printGenre(const model::Genre& genre)
{
std::cout << "genre record" << std::endl;
+15 -3
View File
@@ -50,15 +50,24 @@ void manager::SongManager::deleteSong(model::Song& song)
// is deleted
database::SongRepository songRepo(m_bConf);
if (!songRepo.doesSongExist(song, type::SongFilter::id)) {
std::cout << "song does not exist" << std::endl;
return;
}
song = songRepo.retrieveRecord(song, type::SongFilter::id);
auto paths = manager::DirectoryManager::pathConfigContent(m_bConf);
auto deleted = songRepo.deleteRecord(song);
if (!deleted) {
std::cout << "song not deleted from databases" << std::endl;
return;
}
deleteMisc(song);
songRepo.deleteRecord(song);
fs::remove(song.songPath);
manager::DirectoryManager::deleteDirectories(song, paths["root_music_path"].get<std::string>());
}
@@ -163,8 +172,11 @@ void manager::SongManager::deleteMisc(const model::Song& song)
albMgr.deleteAlbum(song);
manager::ArtistManager artMgr(m_bConf);
artMgr.deleteArtist(song);
manager::GenreManager gnrMgr(m_bConf);
gnrMgr.deleteGenre(song);
manager::YearManager yrMgr(m_bConf);
yrMgr.deleteYear(song);
}
+17
View File
@@ -33,6 +33,23 @@ model::Year manager::YearManager::saveYear(const model::Song& song)
return year;
}
void manager::YearManager::deleteYear(const model::Song& song)
{
model::Year year(song);
database::YearRepository yrRepo(m_bConf);
auto yrWSC = yrRepo.retrieveRecordWithSongCount(year, type::YearFilter::id);
if (yrWSC.second > 1) {
std::cout << "year still contain songs related to it";
std::cout << ", will not delete" << std::endl;
return;
}
std::cout << "safe to delete the year record" << std::endl;
yrRepo.deleteYear(year, type::YearFilter::id);
}
void manager::YearManager::printYear(const model::Year& year)
{
std::cout << "\nyear record" << std::endl;