fix for duplicate records being saved. I'm going to continually monitor it, some minor changes might need to be made. The changes are changing to prepared statements for queries
This commit is contained in:
@@ -24,29 +24,45 @@ model::Album database::AlbumRepository::retrieveRecord(model::Album& album, type
|
||||
std::cout << "retrieving album record" << std::endl;
|
||||
std::stringstream qry;
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
MYSQL_BIND params[1];
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
qry << "SELECT alb.* FROM Album alb WHERE ";
|
||||
|
||||
std::unique_ptr<char*> param;
|
||||
auto titleLength = album.title.size();
|
||||
switch (filter) {
|
||||
case type::AlbumFilter::id:
|
||||
qry << "alb.AlbumId = " << album.id;
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_LONG;
|
||||
params[0].buffer = (char*)&album.id;
|
||||
params[0].length = 0;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
case type::AlbumFilter::title:
|
||||
param = std::make_unique<char*>(new char[album.title.size()]);
|
||||
mysql_real_escape_string(conn, *param, album.title.c_str(), album.title.size());
|
||||
qry << "alb.Title = '" << *param << "'";
|
||||
qry << "alb.Title = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_STRING;
|
||||
params[0].buffer = (char*)album.title.c_str();
|
||||
params[0].length = &titleLength;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qry << " ORDER BY AlbumId DESC LIMIT 1";
|
||||
qry << " LIMIT 1";
|
||||
|
||||
const std::string query = qry.str();
|
||||
auto results = performMysqlQuery(conn, query);
|
||||
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);
|
||||
|
||||
album = parseRecord(results);
|
||||
album = parseRecord(stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(conn);
|
||||
std::cout << "done" << std::endl;
|
||||
|
||||
@@ -55,14 +71,6 @@ model::Album database::AlbumRepository::retrieveRecord(model::Album& album, type
|
||||
|
||||
bool database::AlbumRepository::doesAlbumExists(const model::Album& album, type::AlbumFilter filter)
|
||||
{
|
||||
// TODO: continue working on this part.
|
||||
// Reason: there should be a check to see if an album record already exists
|
||||
// at the moment there is no check and every time a song is uploaded
|
||||
// a new album record is created, even for songs that are on the
|
||||
// same album. This should not happen. There should be one album
|
||||
// record for songs on the same album. After fixing this, do the
|
||||
// same for Artist, Genre, and Year records
|
||||
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
@@ -182,8 +190,56 @@ model::Album database::AlbumRepository::parseRecord(MYSQL_RES* results)
|
||||
|
||||
model::Album database::AlbumRepository::parseRecord(MYSQL_STMT *stmt)
|
||||
{
|
||||
// TODO: implement this
|
||||
std::cout << "parsing album record" << std::endl;
|
||||
mysql_stmt_store_result(stmt);
|
||||
auto rows = mysql_stmt_num_rows(stmt);
|
||||
|
||||
model::Album album;
|
||||
auto status = 0;
|
||||
auto time = 0;
|
||||
auto valAmt = 3;
|
||||
unsigned long len[valAmt];
|
||||
my_bool nullRes[valAmt];
|
||||
|
||||
while (status == 0) {
|
||||
if (mysql_stmt_field_count(stmt) > 0) {
|
||||
auto res = mysql_stmt_result_metadata(stmt);
|
||||
auto fields = mysql_fetch_fields(res);
|
||||
auto strLen = 1024;
|
||||
|
||||
MYSQL_BIND val[valAmt];
|
||||
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];
|
||||
|
||||
status = mysql_stmt_bind_result(stmt, val);
|
||||
mysql_stmt_store_result(stmt);
|
||||
|
||||
status = mysql_stmt_fetch(stmt);
|
||||
|
||||
album.title = title;
|
||||
}
|
||||
|
||||
status = mysql_stmt_next_result(stmt);
|
||||
}
|
||||
|
||||
std::cout << "done parsing album record" << std::endl;
|
||||
|
||||
return album;
|
||||
}
|
||||
|
||||
@@ -49,9 +49,53 @@ model::Artist database::ArtistRepository::retrieveRecord(model::Artist& artist,
|
||||
|
||||
bool database::ArtistRepository::doesArtistExist(const model::Artist& artist, type::ArtistFilter filter)
|
||||
{
|
||||
// TODO: implement this
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
MYSQL_BIND params[1];
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
std::stringstream qry;
|
||||
qry << "SELECT * FROM Artist WHERE ";
|
||||
|
||||
auto artistLength = artist.artist.size();
|
||||
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;
|
||||
case type::ArtistFilter::artist:
|
||||
qry << "Artist = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_STRING;
|
||||
params[0].buffer = (char*)artist.artist.c_str();
|
||||
params[0].length = &artistLength;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qry << " 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 << "the query has been performed" << std::endl;
|
||||
|
||||
mysql_stmt_store_result(stmt);
|
||||
auto rowCount = mysql_stmt_num_rows(stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(conn);
|
||||
|
||||
return false;
|
||||
return (rowCount > 0) ? true : false;
|
||||
}
|
||||
|
||||
void database::ArtistRepository::saveRecord(const model::Artist& artist)
|
||||
|
||||
@@ -70,4 +70,6 @@ void database::BaseRepository::initializeDetails(const model::BinaryPath& bConf)
|
||||
details.server = databaseConfig["server"].get<std::string>();
|
||||
details.username = databaseConfig["username"].get<std::string>();
|
||||
details.password = databaseConfig["password"].get<std::string>();
|
||||
|
||||
std::cout << "retrieved database details" << std::endl;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,53 @@ model::Cover database::CoverArtRepository::retrieveRecord(model::Cover& cov, typ
|
||||
|
||||
bool database::CoverArtRepository::doesCoverArtExist(const model::Cover& cover, type::CoverFilter filter)
|
||||
{
|
||||
// TODO: implement this
|
||||
return false;
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
MYSQL_BIND params[1];
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
std::stringstream qry;
|
||||
qry << "SELECT * FROM CoverArt WHERE ";
|
||||
|
||||
auto titleLength = cover.songTitle.size();
|
||||
switch (filter) {
|
||||
case type::CoverFilter::id:
|
||||
qry << "CoverArtId = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_LONG;
|
||||
params[0].buffer = (char*)&cover.id;
|
||||
params[0].length = 0;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
case type::CoverFilter::songTitle:
|
||||
qry << "SongTitle = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_STRING;
|
||||
params[0].buffer = (char*)cover.songTitle.c_str();
|
||||
params[0].length = &titleLength;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qry << " 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 << "the query has been performed" << std::endl;
|
||||
|
||||
mysql_stmt_store_result(stmt);
|
||||
auto rowCount = mysql_stmt_num_rows(stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(conn);
|
||||
|
||||
return (rowCount > 0) ? true : false;
|
||||
}
|
||||
|
||||
void database::CoverArtRepository::deleteRecord(const model::Cover& cov)
|
||||
|
||||
@@ -47,9 +47,53 @@ model::Genre database::GenreRepository::retrieveRecord(model::Genre& genre, type
|
||||
|
||||
bool database::GenreRepository::doesGenreExist(const model::Genre& genre, type::GenreFilter filter)
|
||||
{
|
||||
// TODO: implement this
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
return false;
|
||||
std::stringstream qry;
|
||||
qry << "SELECT * FROM Genre WHERE ";
|
||||
|
||||
MYSQL_BIND params[1];
|
||||
memset(params, 0, sizeof(params));
|
||||
|
||||
auto categoryLength = genre.category.size();
|
||||
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;
|
||||
case type::GenreFilter::category:
|
||||
qry << "Category = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_STRING;
|
||||
params[0].buffer = (char*)genre.category.c_str();
|
||||
params[0].length = &categoryLength;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qry << " 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 << "the query has been performed" << std::endl;
|
||||
|
||||
mysql_stmt_store_result(stmt);
|
||||
auto rowCount = mysql_stmt_num_rows(stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(conn);
|
||||
|
||||
return (rowCount > 0) ? true : false;
|
||||
}
|
||||
|
||||
void database::GenreRepository::saveRecord(const model::Genre& genre)
|
||||
|
||||
@@ -47,8 +47,52 @@ model::Year database::YearRepository::retrieveRecord(model::Year& year, type::Ye
|
||||
bool database::YearRepository::doesYearExist(const model::Year& year, type::YearFilter filter)
|
||||
{
|
||||
// TODO: implement this
|
||||
auto conn = setupMysqlConnection();
|
||||
auto stmt = mysql_stmt_init(conn);
|
||||
|
||||
return false;
|
||||
std::stringstream qry;
|
||||
qry << "SELECT * FROM Year WHERE ";
|
||||
|
||||
MYSQL_BIND params[1];
|
||||
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;
|
||||
case type::YearFilter::year:
|
||||
qry << "Year = ?";
|
||||
|
||||
params[0].buffer_type = MYSQL_TYPE_LONG;
|
||||
params[0].buffer = (char*)&year.year;
|
||||
params[0].length = 0;
|
||||
params[0].is_null = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qry << " 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 << "the query has been performed" << std::endl;
|
||||
|
||||
mysql_stmt_store_result(stmt);
|
||||
auto rowCount = mysql_stmt_num_rows(stmt);
|
||||
|
||||
mysql_stmt_close(stmt);
|
||||
mysql_close(conn);
|
||||
|
||||
return (rowCount > 0) ? true : false;
|
||||
}
|
||||
|
||||
void database::YearRepository::saveRecord(const model::Year& year)
|
||||
|
||||
@@ -12,7 +12,10 @@ manager::ArtistManager::ArtistManager(const model::BinaryPath& bConf)
|
||||
|
||||
model::Artist manager::ArtistManager::retrieveArtist(model::Artist& artist)
|
||||
{
|
||||
std::cout << "retrieving artist record" << std::endl;
|
||||
database::ArtistRepository artRepo(m_bConf);
|
||||
std::cout << "initialized artist repo" << std::endl;
|
||||
std::cout << artist.artist << std::endl;
|
||||
artist = artRepo.retrieveRecord(artist, type::ArtistFilter::artist);
|
||||
|
||||
return artist;
|
||||
|
||||
@@ -143,6 +143,7 @@ void manager::SongManager::saveMisc(model::Song& song)
|
||||
ArtistManager artMgr(m_bConf);
|
||||
auto artist = artMgr.saveArtist(song);
|
||||
artist = artMgr.retrieveArtist(artist);
|
||||
std::cout << "out" << std::endl;
|
||||
manager::ArtistManager::printArtist(artist);
|
||||
|
||||
GenreManager gnrMgr(m_bConf);
|
||||
@@ -160,4 +161,6 @@ void manager::SongManager::saveMisc(model::Song& song)
|
||||
song.artistId = artist.id;
|
||||
song.genreId = genre.id;
|
||||
song.yearId = year.id;
|
||||
|
||||
std::cout << "done with miscellaneous database records" << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user