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::cout << "retrieving album record" << std::endl;
|
||||||
std::stringstream qry;
|
std::stringstream qry;
|
||||||
auto conn = setupMysqlConnection();
|
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 ";
|
qry << "SELECT alb.* FROM Album alb WHERE ";
|
||||||
|
|
||||||
std::unique_ptr<char*> param;
|
auto titleLength = album.title.size();
|
||||||
switch (filter) {
|
switch (filter) {
|
||||||
case type::AlbumFilter::id:
|
case type::AlbumFilter::id:
|
||||||
qry << "alb.AlbumId = " << album.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;
|
break;
|
||||||
case type::AlbumFilter::title:
|
case type::AlbumFilter::title:
|
||||||
param = std::make_unique<char*>(new char[album.title.size()]);
|
qry << "alb.Title = ?";
|
||||||
mysql_real_escape_string(conn, *param, album.title.c_str(), album.title.size());
|
|
||||||
qry << "alb.Title = '" << *param << "'";
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qry << " ORDER BY AlbumId DESC LIMIT 1";
|
qry << " LIMIT 1";
|
||||||
|
|
||||||
const std::string query = qry.str();
|
const auto query = qry.str();
|
||||||
auto results = performMysqlQuery(conn, query);
|
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);
|
mysql_close(conn);
|
||||||
std::cout << "done" << std::endl;
|
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)
|
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 conn = setupMysqlConnection();
|
||||||
auto stmt = mysql_stmt_init(conn);
|
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)
|
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;
|
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;
|
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)
|
bool database::ArtistRepository::doesArtistExist(const model::Artist& artist, type::ArtistFilter filter)
|
||||||
{
|
{
|
||||||
// TODO: implement this
|
auto conn = setupMysqlConnection();
|
||||||
|
auto stmt = mysql_stmt_init(conn);
|
||||||
|
|
||||||
return false;
|
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 (rowCount > 0) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::ArtistRepository::saveRecord(const model::Artist& artist)
|
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.server = databaseConfig["server"].get<std::string>();
|
||||||
details.username = databaseConfig["username"].get<std::string>();
|
details.username = databaseConfig["username"].get<std::string>();
|
||||||
details.password = databaseConfig["password"].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)
|
bool database::CoverArtRepository::doesCoverArtExist(const model::Cover& cover, type::CoverFilter filter)
|
||||||
{
|
{
|
||||||
// TODO: implement this
|
auto conn = setupMysqlConnection();
|
||||||
return false;
|
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)
|
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)
|
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)
|
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)
|
bool database::YearRepository::doesYearExist(const model::Year& year, type::YearFilter filter)
|
||||||
{
|
{
|
||||||
// TODO: implement this
|
// 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)
|
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)
|
model::Artist manager::ArtistManager::retrieveArtist(model::Artist& artist)
|
||||||
{
|
{
|
||||||
|
std::cout << "retrieving artist record" << std::endl;
|
||||||
database::ArtistRepository artRepo(m_bConf);
|
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);
|
artist = artRepo.retrieveRecord(artist, type::ArtistFilter::artist);
|
||||||
|
|
||||||
return artist;
|
return artist;
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ void manager::SongManager::saveMisc(model::Song& song)
|
|||||||
ArtistManager artMgr(m_bConf);
|
ArtistManager artMgr(m_bConf);
|
||||||
auto artist = artMgr.saveArtist(song);
|
auto artist = artMgr.saveArtist(song);
|
||||||
artist = artMgr.retrieveArtist(artist);
|
artist = artMgr.retrieveArtist(artist);
|
||||||
|
std::cout << "out" << std::endl;
|
||||||
manager::ArtistManager::printArtist(artist);
|
manager::ArtistManager::printArtist(artist);
|
||||||
|
|
||||||
GenreManager gnrMgr(m_bConf);
|
GenreManager gnrMgr(m_bConf);
|
||||||
@@ -160,4 +161,6 @@ void manager::SongManager::saveMisc(model::Song& song)
|
|||||||
song.artistId = artist.id;
|
song.artistId = artist.id;
|
||||||
song.genreId = genre.id;
|
song.genreId = genre.id;
|
||||||
song.yearId = year.id;
|
song.yearId = year.id;
|
||||||
|
|
||||||
|
std::cout << "done with miscellaneous database records" << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user