Code cleanup

This commit is contained in:
kdeng00
2019-11-17 13:33:58 -05:00
parent ca1fcb801d
commit 69f5a37eb3
74 changed files with 4397 additions and 4717 deletions
+336 -348
View File
@@ -8,396 +8,384 @@
#include <cstring>
namespace database {
AlbumRepository::AlbumRepository(const model::BinaryPath& bConf)
: BaseRepository(bConf)
{ }
AlbumRepository::AlbumRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
std::vector<model::Album> AlbumRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
std::vector<model::Album> AlbumRepository::retrieveRecords() {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Album";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
const std::string query = "SELECT * FROM Album";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
auto albums = parseRecords(stmt);
auto albums = parseRecords(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
mysql_stmt_close(stmt);
mysql_close(conn);
return albums;
}
std::pair<model::Album, int> 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);
MYSQL_BIND params[1];
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 << "sng.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);
auto albWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return albWSC;
}
model::Album AlbumRepository::retrieveRecord(model::Album& album, type::AlbumFilter filter)
{
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 ";
auto titleLength = album.title.size();
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;
case type::AlbumFilter::title:
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;
return albums;
}
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::pair<model::Album, int> AlbumRepository::retrieveRecordWithSongCount(model::Album& album,
type::AlbumFilter filter = type::AlbumFilter::id) {
std::cout << "retrieving album with song count\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
album = parseRecord(stmt);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
mysql_stmt_close(stmt);
mysql_close(conn);
qry << "SELECT alb.*, COUNT(*) AS SongCount FROM Album alb LEFT JOIN ";
qry << "Song sng ON alb.AlbumId=sng.AlbumId WHERE ";
std::cout << "done" << std::endl;
switch (filter) {
case type::AlbumFilter::id:
qry << "sng.AlbumId = ?";
return album;
}
bool AlbumRepository::doesAlbumExists(const model::Album& album, type::AlbumFilter filter)
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
std::stringstream qry;
qry << "SELECT * FROM Album WHERE ";
auto titleLength = album.title.size();
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;
case type::AlbumFilter::title:
qry << "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 << " 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 AlbumRepository::saveAlbum(const model::Album& album)
{
std::cout << "beginning to insert album record" << std::endl;
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query = "INSERT INTO Album(Title, Artist, Year) VALUES(?, ?, ?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[3];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)album.title.c_str();
auto titleLength = album.title.size();
params[0].length= &titleLength;
params[0].is_null = 0;
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)album.artist.c_str();
auto artistLength = album.artist.size();
params[1].length = &artistLength;
params[1].is_null = 0;
params[2].buffer_type = MYSQL_TYPE_LONG;
params[2].buffer = (char*)&album.year;
params[2].length = 0;
params[2].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "done inserting album record" << std::endl;
}
void 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> AlbumRepository::parseRecords(MYSQL_STMT* stmt)
{
std::cout << "parsing album record" << std::endl;
mysql_stmt_store_result(stmt);
std::vector<model::Album> albums;
albums.reserve(mysql_stmt_num_rows(stmt));
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Album alb;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(alb, metaBuff);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
while (true) {
std::cout << "fetching statement result" << std::endl;
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA) {
break;
}
alb.title = std::get<0>(metaBuff);
alb.artist = std::get<1>(metaBuff);
albums.push_back(std::move(alb));
}
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;
}
std::cout << "fetching next result" << std::endl;
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);
auto albWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return albWSC;
}
return albums;
}
model::Album AlbumRepository::retrieveRecord(model::Album& album, type::AlbumFilter filter) {
std::cout << "retrieving album record\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
std::pair<model::Album, int> 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);
qry << "SELECT alb.* FROM Album alb WHERE ";
model::Album album;
auto metaBuff = metadataBuffer();
int songCount = 0;
auto val = valueBindWithSongCount(album, metaBuff, songCount);
auto titleLength = album.title.size();
switch (filter) {
case type::AlbumFilter::id:
qry << "alb.AlbumId = ?";
if (rowCount == 0) {
std::cout << "no results" << std::endl;
return std::make_pair(album, songCount);
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:
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 << " 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);
album = parseRecord(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "done\n";
return album;
}
auto status = mysql_stmt_bind_result(stmt, val.get());
status = mysql_stmt_fetch(stmt);
bool AlbumRepository::doesAlbumExists(const model::Album& album, type::AlbumFilter filter) {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
album.title = std::get<0>(metaBuff);
album.artist = std::get<1>(metaBuff);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
std::cout << "done parsing album record with song count" << std::endl;
std::stringstream qry;
qry << "SELECT * FROM Album WHERE ";
auto albWSC = std::make_pair(album, songCount);
auto titleLength = album.title.size();
switch (filter) {
case type::AlbumFilter::id:
qry << "AlbumId = ?";
return albWSC;
}
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:
qry << "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 << " 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\n";
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 AlbumRepository::saveAlbum(const model::Album& album) {
std::cout << "beginning to insert album record\n";
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query = "INSERT INTO Album(Title, Artist, Year) VALUES(?, ?, ?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[3];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)album.title.c_str();
auto titleLength = album.title.size();
params[0].length= &titleLength;
params[0].is_null = 0;
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)album.artist.c_str();
auto artistLength = album.artist.size();
params[1].length = &artistLength;
params[1].is_null = 0;
params[2].buffer_type = MYSQL_TYPE_LONG;
params[2].buffer = (char*)&album.year;
params[2].length = 0;
params[2].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "done inserting album record\n";
}
void AlbumRepository::deleteAlbum(const model::Album& album,
type::AlbumFilter filter = type::AlbumFilter::id) {
std::cout << "deleting album record\n";
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\n";
}
std::shared_ptr<MYSQL_BIND> AlbumRepository::valueBind(model::Album& album,
std::tuple<char*, char*>& metadata)
{
constexpr auto wordLen = 1024;
constexpr auto valueCount = 4;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(valueCount, sizeof(MYSQL_BIND)));
std::vector<model::Album> AlbumRepository::parseRecords(MYSQL_STMT* stmt) {
std::cout << "parsing album record\n";
mysql_stmt_store_result(stmt);
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&album.id;
std::vector<model::Album> albums;
albums.reserve(mysql_stmt_num_rows(stmt));
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(metadata);
values.get()[1].buffer_length = wordLen;
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(metadata);
values.get()[2].buffer_length = wordLen;
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Album alb;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(alb, metaBuff);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
values.get()[3].buffer_type = MYSQL_TYPE_LONG;
values.get()[3].buffer = (char*)&album.year;
while (true) {
std::cout << "fetching statement result\n";
status = mysql_stmt_fetch(stmt);
return values;
}
if (status == 1 || status == MYSQL_NO_DATA) break;
std::shared_ptr<MYSQL_BIND> AlbumRepository::valueBindWithSongCount(model::Album& album,
std::tuple<char*, char*>& metadata, int& songCount)
{
constexpr auto wordLen = 1024;
constexpr auto valueCount = 5;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(valueCount, sizeof(MYSQL_BIND)));
alb.title = std::get<0>(metaBuff);
alb.artist = std::get<1>(metaBuff);
albums.push_back(std::move(alb));
}
}
std::cout << "fetching next result\n";
}
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&album.id;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(metadata);
values.get()[1].buffer_length = wordLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(metadata);
values.get()[2].buffer_length = wordLen;
values.get()[3].buffer_type = MYSQL_TYPE_LONG;
values.get()[3].buffer = (char*)&album.year;
values.get()[4].buffer_type = MYSQL_TYPE_LONG;
values.get()[4].buffer = (char*)&songCount;
return values;
}
return albums;
}
std::tuple<char*, char*> AlbumRepository::metadataBuffer()
{
constexpr auto wordLen = 1024;
char title[wordLen];
char artist[wordLen];
std::pair<model::Album, int> AlbumRepository::parseRecordWithSongCount(MYSQL_STMT *stmt) {
std::cout << "parsing album record with song count\n";
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
return std::make_tuple(title, artist);
}
model::Album album;
auto metaBuff = metadataBuffer();
int songCount = 0;
auto val = valueBindWithSongCount(album, metaBuff, songCount);
if (rowCount == 0) {
std::cout << "no results\n";
return std::make_pair(album, songCount);
}
auto status = mysql_stmt_bind_result(stmt, val.get());
status = mysql_stmt_fetch(stmt);
album.title = std::get<0>(metaBuff);
album.artist = std::get<1>(metaBuff);
std::cout << "done parsing album record with song count\n";
auto albWSC = std::make_pair(album, songCount);
return albWSC;
}
model::Album AlbumRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing album record" << std::endl;
mysql_stmt_store_result(stmt);
auto rows = mysql_stmt_num_rows(stmt);
std::shared_ptr<MYSQL_BIND> AlbumRepository::valueBind(model::Album& album,
std::tuple<char*, char*>& metadata) {
constexpr auto wordLen = 1024;
constexpr auto valueCount = 4;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(valueCount, sizeof(MYSQL_BIND)));
model::Album album;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(album, metaBuff);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&album.id;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(metadata);
values.get()[1].buffer_length = wordLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(metadata);
values.get()[2].buffer_length = wordLen;
values.get()[3].buffer_type = MYSQL_TYPE_LONG;
values.get()[3].buffer = (char*)&album.year;
return values;
}
std::shared_ptr<MYSQL_BIND> AlbumRepository::valueBindWithSongCount(model::Album& album,
std::tuple<char*, char*>& metadata, int& songCount) {
constexpr auto wordLen = 1024;
constexpr auto valueCount = 5;
std::shared_ptr<MYSQL_BIND> values(
(MYSQL_BIND*) std::calloc(valueCount, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&album.id;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(metadata);
values.get()[1].buffer_length = wordLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(metadata);
values.get()[2].buffer_length = wordLen;
values.get()[3].buffer_type = MYSQL_TYPE_LONG;
values.get()[3].buffer = (char*)&album.year;
values.get()[4].buffer_type = MYSQL_TYPE_LONG;
values.get()[4].buffer = (char*)&songCount;
return values;
}
std::tuple<char*, char*> AlbumRepository::metadataBuffer() {
constexpr auto wordLen = 1024;
char title[wordLen];
char artist[wordLen];
return std::make_tuple(title, artist);
}
model::Album AlbumRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing album record\n";
mysql_stmt_store_result(stmt);
auto rows = mysql_stmt_num_rows(stmt);
model::Album album;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(album, metaBuff);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
album.title = std::get<0>(metaBuff);
album.artist = std::get<1>(metaBuff);
album.title = std::get<0>(metaBuff);
album.artist = std::get<1>(metaBuff);
std::cout << "done parsing album record" << std::endl;
std::cout << "done parsing album record\n";
return album;
}
return album;
}
}
+314 -369
View File
@@ -7,410 +7,355 @@
#include <cstring>
namespace database {
ArtistRepository::ArtistRepository(const model::BinaryPath& binConf)
: BaseRepository(binConf)
{
}
ArtistRepository::ArtistRepository(const model::BinaryPath& binConf) :
BaseRepository(binConf) { }
std::vector<model::Artist> ArtistRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Artist";
std::vector<model::Artist> ArtistRepository::retrieveRecords() {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Artist";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
auto artists = parseRecords(stmt);
auto artists = parseRecords(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
mysql_stmt_close(stmt);
mysql_close(conn);
return artists;
}
std::pair<model::Artist, int> 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 ArtistRepository::retrieveRecord(model::Artist& artist, type::ArtistFilter filter)
{
std::cout << "retrieving artist record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT art.* FROM Artist art WHERE ";
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
auto artistLength = artist.artist.size();
switch (filter) {
case type::ArtistFilter::id:
qry << "art.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 << "art.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);
artist = parseRecord(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved record" << std::endl;
return artist;
}
bool ArtistRepository::doesArtistExist(const model::Artist& artist, type::ArtistFilter filter)
{
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 (rowCount > 0) ? true : false;
}
void ArtistRepository::saveRecord(const model::Artist& artist)
{
std::cout << "inserting artist record" << std::endl;
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query = "INSERT INTO Artist(Artist) VALUES(?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)artist.artist.c_str();
auto artistLength = artist.artist.size();
params[0].length = &artistLength;
params[0].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout<< "inserted artist record" << std::endl;
}
void ArtistRepository::deleteArtist(const model::Artist& artist, type::ArtistFilter filter = type::ArtistFilter::id) {
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> ArtistRepository::parseRecords(MYSQL_STMT *stmt)
{
mysql_stmt_store_result(stmt);
std::vector<model::Artist> artists;
artists.reserve(mysql_stmt_num_rows(stmt));
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0" << std::endl;
return artists;
}
model::Artist art;
const auto valAmt = 2;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
std::pair<model::Artist, int> ArtistRepository::retrieveRecordWithSongCount(
model::Artist& artist, type::ArtistFilter filter = type::ArtistFilter::id) {
std::cout << "retrieving artist record with song count\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
auto res = mysql_stmt_result_metadata(stmt);
auto fields = mysql_fetch_fields(res);
const auto strLen = 1024;
qry << "SELECT art.*, COUNT(*) AS SongCount FROM Artist art LEFT JOIN ";
qry << "Song sng ON art.ArtistId=sng.ArtistId WHERE ";
char artist[strLen];
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
switch (filter) {
case type::ArtistFilter::id:
qry << "sng.ArtistId = ?";
MYSQL_BIND val[valAmt];
memset(val, 0, sizeof(val));
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;
}
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&art.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
qry << " GROUP BY art.ArtistId LIMIT 1";
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)artist;
val[1].buffer_length = strLen;
val[1].length = &len[1];
val[1].is_null = &nullRes[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);
for (auto status = mysql_stmt_bind_result(stmt, val); status == 0; ) {
std::cout << "fetching statement result" << std::endl;
std::cout << "Artist record with song count query ";
std::cout << "has been performed\n";
auto artWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return artWSC;
}
model::Artist ArtistRepository::retrieveRecord(model::Artist& artist,
type::ArtistFilter filter) {
std::cout << "retrieving artist record\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT art.* FROM Artist art WHERE ";
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
auto artistLength = artist.artist.size();
switch (filter) {
case type::ArtistFilter::id:
qry << "art.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 << "art.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);
artist = parseRecord(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved record\n";
return artist;
}
bool ArtistRepository::doesArtistExist(const model::Artist& artist, type::ArtistFilter filter) {
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\n";
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 ArtistRepository::saveRecord(const model::Artist& artist) {
std::cout << "inserting artist record\n";
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query = "INSERT INTO Artist(Artist) VALUES(?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)artist.artist.c_str();
auto artistLength = artist.artist.size();
params[0].length = &artistLength;
params[0].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout<< "inserted artist record\n";
}
void ArtistRepository::deleteArtist(const model::Artist& artist,
type::ArtistFilter filter = type::ArtistFilter::id) {
std::cout << "delete Artist record\n";
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\n";
}
std::vector<model::Artist> ArtistRepository::parseRecords(MYSQL_STMT *stmt) {
mysql_stmt_store_result(stmt);
std::vector<model::Artist> artists;
artists.reserve(mysql_stmt_num_rows(stmt));
constexpr auto valAmt = 2;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Artist art;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(art, metaBuff);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
std::cout << "fetching statement result\n";
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA) break;
art.artist = std::get<0>(metaBuff);
artists.push_back(art);
}
std::cout << "fetching next result\n";
}
return artists;
}
std::pair<model::Artist, int> ArtistRepository::parseRecordWithSongCount(MYSQL_STMT *stmt) {
std::cout << "parsing artist record with song count\n";
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
model::Artist artist;
auto metaBuff = metadataBuffer();
auto songCount = 0;
auto val = valueBindWithSongCount(artist, metaBuff, songCount);
if (rowCount == 0) {
std::cout << "no results\n";
return std::make_pair(artist, songCount);
}
auto status = mysql_stmt_bind_result(stmt, val.get());
status = mysql_stmt_fetch(stmt);
if (status == 0) {
art.artist = artist;
artists.push_back(std::move(art));
}
artist.artist = std::get<0>(metaBuff);
std::cout << "done parsing album record with song count\n";
return std::make_pair(artist, songCount);
}
return artists;
}
std::shared_ptr<MYSQL_BIND> ArtistRepository::valueBind(model::Artist& artist,
std::tuple<char*>& metadata) {
constexpr auto valueCount = 2;
constexpr auto wordLen = 1024;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
model::Artist ArtistRepository::parseRecord(MYSQL_RES* results)
{
std::cout << "parsing artist record" << std::endl;
model::Artist artist;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&artist.id;
auto fieldNum = mysql_num_fields(results);
auto row = mysql_fetch_row(results);
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(metadata);
values.get()[1].buffer_length = wordLen;
for (auto i = 0; i != fieldNum; ++i) {
const std::string field(mysql_fetch_field(results)->name);
if (field.compare("ArtistId") == 0) {
artist.id = std::stoi(row[i]);
}
if (field.compare("Artist") == 0) {
artist.artist = row[i];
}
return values;
}
std::cout << "parsed artist record" << std::endl;
std::shared_ptr<MYSQL_BIND> ArtistRepository::valueBindWithSongCount(model::Artist& artist,
std::tuple<char*>& metadata, int& songCount) {
constexpr auto valueCount = 3;
constexpr auto wordLen = 1024;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
return artist;
}
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&artist.id);
std::pair<model::Artist, int> ArtistRepository::parseRecordWithSongCount(MYSQL_STMT *stmt)
{
std::cout << "parsing artist record with song count" << std::endl;
mysql_stmt_store_result(stmt);
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = reinterpret_cast<char*>(std::get<0>(metadata));
values.get()[1].buffer_length = wordLen;
const auto strLen = 1024;
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
values.get()[2].buffer_type = MYSQL_TYPE_LONG;
values.get()[2].buffer = reinterpret_cast<char*>(&songCount);
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);
return values;
}
MYSQL_BIND params[valAmt];
std::memset(params, 0, sizeof(params));
char art[strLen];
std::tuple<char*> ArtistRepository::metadataBuffer() {
constexpr auto wordLen = 1024;
char artist[wordLen];
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 ArtistRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing artist record" << std::endl;
mysql_stmt_store_result(stmt);
model::Artist art;
auto status = 0;
auto time = 0;
auto valAmt = 2;
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 artist[strLen];
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&art.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)&artist;
val[1].buffer_length = strLen;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
status = mysql_stmt_bind_result(stmt, val);
mysql_stmt_store_result(stmt);
status = mysql_stmt_fetch(stmt);
art.artist = artist;
}
status = mysql_stmt_next_result(stmt);
return std::make_tuple(artist);
}
std::cout << "done parsing artist record" << std::endl;
return art;
}
model::Artist ArtistRepository::parseRecord(MYSQL_STMT *stmt) {
std::cout << "parsing artist record\n";
mysql_stmt_store_result(stmt);
model::Artist art;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(art, metaBuff);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
art.artist = std::get<0>(metaBuff);
std::cout << "done parsing artist record\n";
return art;
}
}
+63 -73
View File
@@ -7,92 +7,82 @@
#include "manager/DirectoryManager.h"
namespace database {
BaseRepository::BaseRepository()
{ }
BaseRepository::BaseRepository(const std::string& path) : path(path)
{
intitalizeDetails();
}
BaseRepository::BaseRepository(const model::BinaryPath& bConf)
{
initializeDetails(bConf);
}
bool BaseRepository::testConnection()
{
auto conn = mysql_init(nullptr);
if (!mysql_real_connect(conn, details.server.c_str(), details.username.c_str(),
details.password.c_str(), details.database.c_str(), 0,
nullptr, 0)) {
std::cout << "failed to connect to the database" << std::endl;
return false;
BaseRepository::BaseRepository(const std::string& path) : path(path) {
intitalizeDetails();
}
mysql_close(conn);
return true;
}
MYSQL* BaseRepository::setupMysqlConnection()
{
MYSQL *conn = mysql_init(nullptr);
if (!mysql_real_connect(conn, details.server.c_str(), details.username.c_str(),
details.password.c_str(), details.database.c_str(), 0, nullptr, 0)) {
std::cout << "connection error" << std::endl;
BaseRepository::BaseRepository(const model::BinaryPath& bConf) {
initializeDetails(bConf);
}
return conn;
}
MYSQL* BaseRepository::setupMysqlConnection(model::DatabaseConnection details)
{
MYSQL *connection = mysql_init(NULL);
bool BaseRepository::testConnection() {
auto conn = mysql_init(nullptr);
if (!mysql_real_connect(conn, details.server.c_str(), details.username.c_str(),
details.password.c_str(), details.database.c_str(), 0, nullptr, 0)) {
std::cout << "failed to connect to the database\n";
return false;
}
// connect to the database with the details attached.
if (!mysql_real_connect(connection,details.server.c_str(), details.username.c_str(), details.password.c_str(), details.database.c_str(), 0, NULL, 0)) {
printf("Conection error : %s\n", mysql_error(connection));
exit(1);
mysql_close(conn);
return true;
}
return connection;
}
MYSQL_RES* BaseRepository::performMysqlQuery(MYSQL *conn, const std::string& query)
{
// send the query to the database
if (mysql_query(conn, query.c_str()))
{
printf("MySQL query error : %s\n", mysql_error(conn));
exit(1);
}
MYSQL* BaseRepository::setupMysqlConnection() {
MYSQL *conn = mysql_init(nullptr);
return mysql_use_result(conn);
}
if (!mysql_real_connect(conn, details.server.c_str(), details.username.c_str(),
details.password.c_str(), details.database.c_str(), 0, nullptr, 0)) {
std::cout << "connection error\n";
}
return conn;
}
MYSQL* BaseRepository::setupMysqlConnection(model::DatabaseConnection details) {
MYSQL *connection = mysql_init(NULL);
// connect to the database with the details attached.
if (!mysql_real_connect(connection,details.server.c_str(), details.username.c_str(),
details.password.c_str(), details.database.c_str(), 0, NULL, 0)) {
std::cout << "Connection error: " << mysql_error(connection) << "\n";
std::exit(-1);
}
return connection;
}
void BaseRepository::intitalizeDetails()
{
auto databaseConfig = manager::DirectoryManager::databaseConfigContent(path);
MYSQL_RES* BaseRepository::performMysqlQuery(MYSQL *conn, const std::string& query) {
// send the query to the database
if (mysql_query(conn, query.c_str())) {
printf("MySQL query error : %s\n", mysql_error(conn));
std::cout << "MySQL query error : " << mysql_error(conn) << "\n";
std::exit(1);
}
return mysql_use_result(conn);
}
void BaseRepository::intitalizeDetails() {
auto databaseConfig = manager::DirectoryManager::databaseConfigContent(path);
details.database = databaseConfig["database"].get<std::string>();
details.password = databaseConfig["password"].get<std::string>();
details.server = databaseConfig["server"].get<std::string>();
details.username = databaseConfig["username"].get<std::string>();
}
void BaseRepository::initializeDetails(const model::BinaryPath& bConf)
{
auto databaseConfig = manager::DirectoryManager::databaseConfigContent(bConf);
details.database = databaseConfig["database"].get<std::string>();
details.password = databaseConfig["password"].get<std::string>();
details.server = databaseConfig["server"].get<std::string>();
details.username = databaseConfig["username"].get<std::string>();
}
void BaseRepository::initializeDetails(const model::BinaryPath& bConf)
{
auto databaseConfig = manager::DirectoryManager::databaseConfigContent(bConf);
details.database = databaseConfig["database"].get<std::string>();
details.server = databaseConfig["server"].get<std::string>();
details.username = databaseConfig["username"].get<std::string>();
details.password = databaseConfig["password"].get<std::string>();
details.database = databaseConfig["database"].get<std::string>();
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;
}
std::cout << "retrieved database details\n";
}
}
+253 -303
View File
@@ -7,370 +7,320 @@
#include <cstring>
namespace database {
CoverArtRepository::CoverArtRepository(const std::string& path) : BaseRepository(path)
{ }
CoverArtRepository::CoverArtRepository(const model::BinaryPath& bConf) : BaseRepository(bConf)
{ }
CoverArtRepository::CoverArtRepository(const model::BinaryPath& bConf) :
BaseRepository(bConf) { }
std::vector<model::Cover> CoverArtRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM CoverArt";
std::vector<model::Cover> CoverArtRepository::retrieveRecords() {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM CoverArt";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
auto coverArts = parseRecords(stmt);
auto coverArts = parseRecords(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
mysql_stmt_close(stmt);
mysql_close(conn);
return coverArts;
}
model::Cover CoverArtRepository::retrieveRecord(model::Cover& cov, type::CoverFilter filter = type::CoverFilter::id)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT * FROM CoverArt WHERE ";
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
auto songTitleLength = cov.songTitle.size();
switch (filter) {
case type::CoverFilter::id:
qry << "CoverArtId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&cov.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*)cov.songTitle.c_str();
params[0].length = &songTitleLength;
params[0].is_null = 0;
break;
default:
break;
return coverArts;
}
qry << " LIMIT 1";
model::Cover CoverArtRepository::retrieveRecord(model::Cover& cov,
type::CoverFilter filter = type::CoverFilter::id) {
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string 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);
qry << "SELECT * FROM CoverArt WHERE ";
auto covDb = parseRecord(stmt);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved cover art record" << std::endl;
auto songTitleLength = cov.songTitle.size();
switch (filter) {
case type::CoverFilter::id:
qry << "CoverArtId = ?";
return covDb;
}
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&cov.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*)cov.songTitle.c_str();
params[0].length = &songTitleLength;
params[0].is_null = 0;
break;
default:
break;
}
bool CoverArtRepository::doesCoverArtExist(const model::Cover& cover, type::CoverFilter filter)
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << " LIMIT 1";
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
const std::string 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::stringstream qry;
qry << "SELECT * FROM CoverArt WHERE ";
auto covDb = parseRecord(stmt);
auto titleLength = cover.songTitle.size();
switch (filter) {
case type::CoverFilter::id:
qry << "CoverArtId = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved cover art record\n";
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;
return covDb;
}
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);
bool CoverArtRepository::doesCoverArtExist(const model::Cover& cover,
type::CoverFilter filter) {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
std::cout << "the query has been performed" << std::endl;
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
std::stringstream qry;
qry << "SELECT * FROM CoverArt WHERE ";
mysql_stmt_close(stmt);
mysql_close(conn);
auto titleLength = cover.songTitle.size();
switch (filter) {
case type::CoverFilter::id:
qry << "CoverArtId = ?";
return (rowCount > 0) ? true : false;
}
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\n";
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return (rowCount > 0) ? true : false;
}
// TODO: change to prepared statement
void CoverArtRepository::deleteRecord(const model::Cover& cov)
{
auto conn = setupMysqlConnection();
const std::string query("DELETE FROM CoverArt WHERE CoverArtId = " + std::to_string(cov.id));
void CoverArtRepository::deleteRecord(const model::Cover& cov,
type::CoverFilter filter) {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
std::cout << "delete CoverArt record\n";
std::stringstream qry;
qry << "DELETE FROM CoverArt WHERE ";
auto result = performMysqlQuery(conn, query);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
mysql_close(conn);
}
switch (filter) {
case type::CoverFilter::id:
qry << "CoverArtId = ?";
void CoverArtRepository::saveRecord(const model::Cover& cov)
{
std::cout << "saving cover art record";
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&cov.id;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
MYSQL_BIND params[2];
memset(params, 0, sizeof(params));
my_bool isNull;
const auto query = qry.str();
const std::string query = "INSERT INTO CoverArt(SongTitle, ImagePath) VALUES(?, ?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_close(stmt);
mysql_close(conn);
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)cov.songTitle.c_str();
auto songTitleLength = cov.songTitle.size();
params[0].length = &songTitleLength;
params[0].is_null = 0;
std::cout << "deleted CoverArt record\n";
}
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)cov.imagePath.c_str();
auto imagePathLength = cov.imagePath.size();
params[1].length = &imagePathLength;
params[1].is_null = 0;
void CoverArtRepository::saveRecord(const model::Cover& cov) {
std::cout << "saving cover art record";
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
MYSQL_BIND params[2];
memset(params, 0, sizeof(params));
my_bool isNull;
mysql_stmt_close(stmt);
mysql_close(conn);
const std::string query = "INSERT INTO CoverArt(SongTitle, ImagePath) VALUES(?, ?)";
std::cout << "saved cover art record" << std::endl;
}
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
void CoverArtRepository::updateRecord(const model::Cover& cover)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)cov.songTitle.c_str();
auto songTitleLength = cov.songTitle.size();
params[0].length = &songTitleLength;
params[0].is_null = 0;
qry << "UPDATE CoverArt SET ";
qry << "SongTitle = ?, ";
qry << "ImagePath = ? ";
qry << "WHERE CoverArtId = ?";
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)cov.imagePath.c_str();
auto imagePathLength = cov.imagePath.size();
params[1].length = &imagePathLength;
params[1].is_null = 0;
MYSQL_BIND params[3];
memset(params, 0, sizeof(params));
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
auto songTitleLength = cover.songTitle.size();
auto imagePathLength = cover.imagePath.size();
mysql_stmt_close(stmt);
mysql_close(conn);
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)cover.songTitle.c_str();
params[0].length = &songTitleLength;
params[0].is_null = 0;
std::cout << "saved cover art record\n";
}
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)cover.imagePath.c_str();
params[1].length = &imagePathLength;
params[1].is_null = 0;
void CoverArtRepository::updateRecord(const model::Cover& cover) {
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
params[2].buffer_type = MYSQL_TYPE_LONG;
params[2].buffer = (char*)&cover.id;
params[2].length = 0;
params[2].is_null = 0;
qry << "UPDATE CoverArt SET ";
qry << "SongTitle = ?, ";
qry << "ImagePath = ? ";
qry << "WHERE CoverArtId = ?";
const std::string 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_BIND params[3];
memset(params, 0, sizeof(params));
mysql_stmt_close(stmt);
mysql_close(conn);
auto songTitleLength = cover.songTitle.size();
auto imagePathLength = cover.imagePath.size();
std::cout << "updated cover art record" << std::endl;
}
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)cover.songTitle.c_str();
params[0].length = &songTitleLength;
params[0].is_null = 0;
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char*)cover.imagePath.c_str();
params[1].length = &imagePathLength;
params[1].is_null = 0;
params[2].buffer_type = MYSQL_TYPE_LONG;
params[2].buffer = (char*)&cover.id;
params[2].length = 0;
params[2].is_null = 0;
const std::string 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 << "updated cover art record\n";
}
std::vector<model::Cover> CoverArtRepository::parseRecords(MYSQL_STMT *stmt)
{
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
std::cout << "number of results " << rowCount << std::endl;
std::vector<model::Cover> CoverArtRepository::parseRecords(MYSQL_STMT *stmt) {
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
std::cout << "number of results " << rowCount << "\n";
std::vector<model::Cover> coverArts;
coverArts.reserve(rowCount);
std::vector<model::Cover> coverArts;
coverArts.reserve(rowCount);
const auto valAmt = 3;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
constexpr auto valAmt = 3;
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Cover coverArt;
auto res = mysql_stmt_result_metadata(stmt);
auto fields = mysql_fetch_fields(res);
auto strLen = 1024;
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Cover cover;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(cover, metaBuff);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
MYSQL_BIND val[valAmt];
memset(val, 0, sizeof(val));
char songTitle[strLen];
char imagePath[strLen];
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&coverArt.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)songTitle;
val[1].buffer_length = strLen;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
val[2].buffer_type = MYSQL_TYPE_STRING;
val[2].buffer = (char*)imagePath;
val[2].buffer_length = strLen;
val[2].length = &len[2];
val[2].is_null = &nullRes[2];
status = mysql_stmt_bind_result(stmt, val);
while (true) {
std::cout << "fetching statement result" << std::endl;
std::cout << "fetching statement result\n";
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA) {
break;
}
if (status == 1 || status == MYSQL_NO_DATA) break;
coverArt.songTitle = songTitle;
coverArt.imagePath = imagePath;
coverArts.push_back(std::move(coverArt));
cover.songTitle = std::get<0>(metaBuff);
cover.imagePath = std::get<1>(metaBuff);
coverArts.push_back(cover);
}
}
std::cout << "fetching next result" << std::endl;
}
return coverArts;
}
model::Cover CoverArtRepository::parseRecord(MYSQL_RES *results)
{
std::cout << "parsing record" << std::endl;
model::Cover cov;
auto fieldNum = mysql_num_fields(results);
MYSQL_ROW row = mysql_fetch_row(results);
for (auto i = 0; i != fieldNum; ++i) {
switch (i) {
case 0:
cov.id = std::stoi(row[i]);
break;
case 1:
cov.songTitle = row[i];
break;
case 2:
cov.imagePath = row[i];
break;
}
}
std::cout << "done parsing record" << std::endl;
return cov;
}
model::Cover CoverArtRepository::parseRecord(MYSQL_STMT *stmt)
{
std::cout << "parsing cover art record" << std::endl;
mysql_stmt_store_result(stmt);
model::Cover cover;
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 songTitle[strLen];
char imagePath[strLen];
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&cover.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
val[1].buffer_type = MYSQL_TYPE_STRING;
val[1].buffer = (char*)&songTitle;
val[1].buffer_length = strLen;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
val[2].buffer_type = MYSQL_TYPE_STRING;
val[2].buffer = (char*)&imagePath;
val[2].buffer_length = strLen;
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);
cover.songTitle = songTitle;
cover.imagePath = imagePath;
std::cout << "fetching next result\n";
}
status = mysql_stmt_next_result(stmt);
return coverArts;
}
std::cout << "done parsing cover art record" << std::endl;
return cover;
}
std::shared_ptr<MYSQL_BIND> CoverArtRepository::valueBind(model::Cover& cover,
std::tuple<char*, char*>& metadata) {
constexpr auto valueCount = 3;
constexpr auto wordLen = 1024;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&cover.id);
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = reinterpret_cast<char*>(std::get<0>(metadata));
values.get()[1].buffer_length = wordLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = reinterpret_cast<char*>(std::get<1>(metadata));
values.get()[2].buffer_length = wordLen;
return values;
}
std::tuple<char*, char*> CoverArtRepository::metadataBuffer() {
constexpr auto wordLen = 1024;
char songTitle[wordLen];
char imagePath[wordLen];
return std::make_pair(songTitle, imagePath);
}
model::Cover CoverArtRepository::parseRecord(MYSQL_STMT *stmt) {
std::cout << "parsing cover art record\n";
mysql_stmt_store_result(stmt);
model::Cover cover;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(cover, metaBuff);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
cover.songTitle = std::get<0>(metaBuff);
cover.imagePath = std::get<1>(metaBuff);
std::cout << "done parsing cover art record\n";
return cover;
}
}
+318 -325
View File
@@ -6,357 +6,350 @@
#include <cstring>
namespace database {
GenreRepository::GenreRepository(const model::BinaryPath& bConf)
: BaseRepository(bConf)
{ }
GenreRepository::GenreRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
std::vector<model::Genre> GenreRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Genre";
std::vector<model::Genre> GenreRepository::retrieveRecords() {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Genre";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
auto genres = parseRecords(stmt);
auto genres = parseRecords(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
mysql_stmt_close(stmt);
mysql_close(conn);
return genres;
}
std::pair<model::Genre, int> 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;
return genres;
}
qry << " GROUP BY gnr.GenreId LIMIT 1";
std::pair<model::Genre, int> GenreRepository::retrieveRecordWithSongCount(
model::Genre& genre, type::GenreFilter filter = type::GenreFilter::id) {
std::cout << "retrieving genre record with song count\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const auto query = qry.str();
qry << "SELECT gnr.*, COUNT(*) AS SongCount FROM Genre gnr LEFT JOIN ";
qry << "Song sng ON gnr.GenreId=sng.GenreId WHERE ";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
auto gnrWSC = parseRecordWithSongCount(stmt);
switch (filter) {
case type::GenreFilter::id:
qry << "sng.GenreId = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
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;
}
std::cout << "retrieved genre record with song count" << std::endl;
qry << " GROUP BY gnr.GenreId LIMIT 1";
return gnrWSC;
}
const auto query = qry.str();
model::Genre GenreRepository::retrieveRecord(model::Genre& genre, type::GenreFilter filter)
{
// TODO: change to prepared statement
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\n";
return gnrWSC;
}
model::Genre GenreRepository::retrieveRecord(model::Genre& genre, type::GenreFilter filter) {
std::cout << "retrieving genre record\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT gnr.* FROM Genre gnr WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
auto categoryLength = genre.category.size();
switch (filter) {
case type::GenreFilter::id:
qry << "gnr.GenreId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = reinterpret_cast<char*>(&genre.id);
params[0].length = 0;
params[0].is_null = 0;
break;
case type::GenreFilter::category:
qry << "gnr.Category = ?";
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = const_cast<char*>(genre.category.c_str());
params[0].length = &categoryLength;
params[0].is_null = 0;
break;
default:
break;
}
qry << " ORDER BY GenreId DESC 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);
genre = parseRecord(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved record\n";
return genre;
}
bool GenreRepository::doesGenreExist(const model::Genre& genre, type::GenreFilter filter) {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
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\n";
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 GenreRepository::saveRecord(const model::Genre& genre) {
std::cout << "inserting genre record\n";
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query("INSERT INTO Genre(Category) VALUES(?)");
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)genre.category.c_str();
auto categoryLength = genre.category.size();
params[0].length = &categoryLength;
params[0].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "inserted record\n";
}
void GenreRepository::deleteRecord(const model::Genre& genre,
type::GenreFilter filter = type::GenreFilter::id) {
std::cout << "deleting genre record\n";
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\n";
}
std::vector<model::Genre> GenreRepository::parseRecords(MYSQL_STMT *stmt) {
mysql_stmt_store_result(stmt);
std::vector<model::Genre> genres;
genres.reserve(mysql_stmt_num_rows(stmt));
constexpr auto valAmt = 2;
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Genre genre;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(genre, metaBuff);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
std::cout << "fetching statement result\n";
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA) break;
genre.category = std::get<0>(metaBuff);
genres.push_back(genre);
}
std::cout << "fetching statement result\n";
}
return genres;
}
std::pair<model::Genre, int> GenreRepository::parseRecordWithSongCount(MYSQL_STMT *stmt) {
std::cout << "parsing genre record with song count\n";
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
model::Genre genre;
int songCount = 0;
auto metaBuff = metadataBuffer();
auto val = valueBindWithSongCount(genre, metaBuff, songCount);
if (rowCount == 0) {
std::cout << "no results\n";
return std::make_pair(genre, songCount);
}
auto status = mysql_stmt_bind_result(stmt, val.get());
status = mysql_stmt_fetch(stmt);
genre.category = std::get<0>(metaBuff);
std::cout << "parsed genre record with song count\n";
return std::make_pair(genre, songCount);
}
std::shared_ptr<MYSQL_BIND> GenreRepository::valueBind(model::Genre& genre,
std::tuple<char*>& metadata) {
constexpr auto valueCount = 2;
constexpr auto wordLen = 1024;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&genre.id);
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = reinterpret_cast<char*>(std::get<0>(metadata));
values.get()[1].buffer_length = wordLen;
return values;
}
std::cout << "retrieving genre record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
qry << "SELECT gnr.* FROM Genre gnr WHERE ";
std::shared_ptr<MYSQL_BIND> GenreRepository::valueBindWithSongCount(model::Genre& genre,
std::tuple<char*>& metadata, int& songCount) {
constexpr auto valueCount = 3;
constexpr auto wordLen = 1024;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
std::unique_ptr<char*> param;
switch (filter) {
case type::GenreFilter::id:
qry << "gnr.GenreId = " << genre.id;
break;
case type::GenreFilter::category:
param = std::make_unique<char*>(new char[genre.category.size()]);
mysql_real_escape_string(conn, *param, genre.category.c_str(), genre.category.size());
qry << "gnr.Category ='" << *param << "'";
break;
default:
break;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&genre.id);
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = reinterpret_cast<char*>(std::get<0>(metadata));
values.get()[1].buffer_length = wordLen;
values.get()[2].buffer_type = MYSQL_TYPE_LONG;
values.get()[2].buffer = reinterpret_cast<char*>(&songCount);
return values;
}
qry << " ORDER BY GenreId DESC LIMIT 1";
const auto query = qry.str();
auto results = performMysqlQuery(conn, query);
std::tuple<char*> GenreRepository::metadataBuffer() {
constexpr auto wordLen = 1024;
char category[wordLen];
genre = parseRecord(results);
mysql_close(conn);
std::cout << "retrieved record" << std::endl;
return genre;
}
bool GenreRepository::doesGenreExist(const model::Genre& genre, type::GenreFilter filter)
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
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;
return std::make_tuple(category);
}
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);
model::Genre GenreRepository::parseRecord(MYSQL_STMT *stmt) {
std::cout << "parsing genre record\n";
mysql_stmt_store_result(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 GenreRepository::saveRecord(const model::Genre& genre)
{
std::cout << "inserting genre record" << std::endl;
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
const std::string query("INSERT INTO Genre(Category) VALUES(?)");
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)genre.category.c_str();
auto categoryLength = genre.category.size();
params[0].length = &categoryLength;
params[0].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "inserted record" << std::endl;
}
void 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> GenreRepository::parseRecords(MYSQL_STMT *stmt)
{
mysql_stmt_store_result(stmt);
std::vector<model::Genre> genres;
genres.reserve(mysql_stmt_num_rows(stmt));
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0" << std::endl;
return genres;
}
model::Genre gnr;
const auto valAmt = 2;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
auto res = mysql_stmt_result_metadata(stmt);
auto fields = mysql_fetch_fields(res);
const auto strLen = 1024;
char category[strLen];
MYSQL_BIND val[valAmt];
memset(val, 0, sizeof(val));
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&gnr.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];
for (auto status = mysql_stmt_bind_result(stmt, val); status == 0;) {
std::cout << "fetching statement result" << std::endl;
model::Genre genre;
auto metaBuff = metadataBuffer();
auto bindedValues = valueBind(genre, metaBuff);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
if (status == 0) {
gnr.category = category;
genres.push_back(std::move(gnr));
}
genre.category = std::get<0>(metaBuff);
std::cout << "done parsing genre record\n";
return genre;
}
return genres;
}
std::pair<model::Genre, int> 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 GenreRepository::parseRecord(MYSQL_RES* results)
{
std::cout << "parsing genre record" << std::endl;
model::Genre genre;
auto fieldNum = mysql_num_fields(results);
auto row = mysql_fetch_row(results);
for (auto i =0; i != fieldNum; ++i) {
const std::string field(mysql_fetch_field(results)->name);
if (field.compare("GenreId") == 0) {
genre.id = std::stoi(row[i]);
}
if (field.compare("Category") == 0) {
genre.category = row[i];
}
}
std::cout << "parsed genre record" << std::endl;
return genre;
}
model::Genre GenreRepository::parseRecord(MYSQL_STMT *stmt)
{
// TODO: implement this
model::Genre genre;
return genre;
}
}
File diff suppressed because it is too large Load Diff
+261 -270
View File
@@ -7,358 +7,349 @@
namespace database {
UserRepository::UserRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
UserRepository::UserRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
model::User UserRepository::retrieveUserRecord(model::User& user,
type::UserFilter filter = type::UserFilter::username)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
model::User UserRepository::retrieveUserRecord(model::User& user,
type::UserFilter filter = type::UserFilter::username) {
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT * FROM User WHERE ";
qry << "SELECT * FROM User WHERE ";
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
auto userLength = user.username.size();
switch (filter) {
case type::UserFilter::id:
qry << "UserId = ?";
auto userLength = user.username.size();
switch (filter) {
case type::UserFilter::id:
qry << "UserId = ?";
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&user.id;
params[0].length = nullptr;
params[0].is_null = 0;
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&user.id;
params[0].length = nullptr;
params[0].is_null = 0;
break;
case type::UserFilter::username:
qry << "Username = ?";
break;
case type::UserFilter::username:
qry << "Username = ?";
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)user.username.c_str();
params[0].length = &userLength;
params[0].is_null = 0;
break;
default:
break;
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)user.username.c_str();
params[0].length = &userLength;
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);
user = parseRecord(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
return user;
}
qry << " LIMIT 1";
model::PassSec UserRepository::retrieverUserSaltRecord(model::PassSec& userSec,
type::SaltFilter filter) {
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
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);
qry << "SELECT * FROM Salt WHERE ";
user = parseRecord(stmt);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
mysql_stmt_close(stmt);
mysql_close(conn);
switch (filter) {
case type::SaltFilter::userId:
qry << "UserId = ?";
return user;
}
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&userSec.userId;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
model::PassSec UserRepository::retrieverUserSaltRecord(model::PassSec& userSec, type::SaltFilter filter)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << " LIMIT 1";
qry << "SELECT * FROM Salt WHERE ";
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_BIND params[1];
std::memset(params, 0, sizeof(params));
userSec = parseSaltRecord(stmt);
switch (filter) {
case type::SaltFilter::userId:
qry << "UserId = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&userSec.userId;
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
return userSec;
}
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);
bool UserRepository::doesUserRecordExist(const model::User& user, type::UserFilter filter) {
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
userSec = parseSaltRecord(stmt);
qry << "SELECT * FROM User WHERE ";
mysql_stmt_close(stmt);
mysql_close(conn);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
return userSec;
}
auto userLength = user.username.size();
switch (filter) {
case type::UserFilter::username:
qry << "Username = ?";
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)user.username.c_str();
params[0].length = &userLength;
params[0].is_null = 0;
break;
default:
break;
}
bool UserRepository::doesUserRecordExist(const model::User& user, type::UserFilter filter)
{
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << " LIMIT 1";
qry << "SELECT * FROM User WHERE ";
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_BIND params[1];
std::memset(params, 0, sizeof(params));
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
auto userLength = user.username.size();
switch (filter) {
case type::UserFilter::username:
qry << "Username = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char*)user.username.c_str();
params[0].length = &userLength;
params[0].is_null = 0;
break;
default:
break;
return (rowCount > 0) ? true : false;
}
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);
void UserRepository::saveUserRecord(const model::User& user) {
std::cout << "inserting user record\n";
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
std::stringstream qry;
qry << "INSERT INTO User(Firstname, Lastname, Phone, Email, Username, Password) ";
qry << "VALUES(?, ?, ?, ?, ?, ?)";
mysql_stmt_close(stmt);
mysql_close(conn);
const auto query = qry.str();
auto sizes = fetchUserLengths(user);
auto params = insertUserValues(user, sizes);
return (rowCount > 0) ? true : false;
}
void UserRepository::saveUserRecord(const model::User& user)
{
std::cout << "inserting user record" << std::endl;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params.get());
status = mysql_stmt_execute(stmt);
std::stringstream qry;
qry << "INSERT INTO User(Firstname, Lastname, Phone, Email, Username, Password) ";
qry << "VALUES(?, ?, ?, ?, ?, ?)";
mysql_stmt_close(stmt);
mysql_close(conn);
}
const auto query = qry.str();
void UserRepository::saveUserSalt(const model::PassSec& userSec) {
std::cout << "inserting user salt record\n";
auto sizes = fetchUserLengths(user);
auto params = insertUserValues(user, sizes);
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params.get());
status = mysql_stmt_execute(stmt);
std::stringstream qry;
qry << "INSERT INTO Salt(Salt, UserId) VALUES(?,?)";
mysql_stmt_close(stmt);
mysql_close(conn);
}
const auto query = qry.str();
void UserRepository::saveUserSalt(const model::PassSec& userSec)
{
std::cout << "inserting user salt record" << std::endl;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
auto sizes = fetchSaltLengths(userSec);
auto values = insertSaltValues(userSec, sizes);
std::stringstream qry;
qry << "INSERT INTO Salt(Salt, UserId) VALUES(?,?)";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, values.get());
status = mysql_stmt_execute(stmt);
const auto query = qry.str();
auto sizes = fetchSaltLengths(userSec);
auto values = insertSaltValues(userSec, sizes);
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, values.get());
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
}
mysql_stmt_close(stmt);
mysql_close(conn);
}
std::shared_ptr<MYSQL_BIND> UserRepository::insertUserValues(const model::User& user,
std::shared_ptr<UserRepository::UserLengths> lengths)
{
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(6, sizeof(MYSQL_BIND)));
std::shared_ptr<MYSQL_BIND> UserRepository::insertUserValues(const model::User& user,
std::shared_ptr<UserRepository::UserLengths> lengths) {
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(6, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_STRING;
values.get()[0].buffer = (char*)user.firstname.c_str();
values.get()[0].length = &(lengths->firstnameLength);
values.get()[0].is_null = 0;
values.get()[0].buffer_type = MYSQL_TYPE_STRING;
values.get()[0].buffer = (char*)user.firstname.c_str();
values.get()[0].length = &(lengths->firstnameLength);
values.get()[0].is_null = 0;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)user.lastname.c_str();
values.get()[1].length = &(lengths->lastnameLength);
values.get()[1].is_null = 0;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)user.lastname.c_str();
values.get()[1].length = &(lengths->lastnameLength);
values.get()[1].is_null = 0;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)user.phone.c_str();
values.get()[2].length = &(lengths->phoneLength);
values.get()[2].is_null = 0;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)user.phone.c_str();
values.get()[2].length = &(lengths->phoneLength);
values.get()[2].is_null = 0;
values.get()[3].buffer_type = MYSQL_TYPE_STRING;
values.get()[3].buffer = (char*)user.email.c_str();
values.get()[3].length = &(lengths->emailLength);
values.get()[3].is_null = 0;
values.get()[3].buffer_type = MYSQL_TYPE_STRING;
values.get()[3].buffer = (char*)user.email.c_str();
values.get()[3].length = &(lengths->emailLength);
values.get()[3].is_null = 0;
values.get()[4].buffer_type = MYSQL_TYPE_STRING;
values.get()[4].buffer = (char*)user.username.c_str();
values.get()[4].length = &(lengths->usernameLength);
values.get()[4].is_null = 0;
values.get()[4].buffer_type = MYSQL_TYPE_STRING;
values.get()[4].buffer = (char*)user.username.c_str();
values.get()[4].length = &(lengths->usernameLength);
values.get()[4].is_null = 0;
values.get()[5].buffer_type = MYSQL_TYPE_STRING;
values.get()[5].buffer = (char*)user.password.c_str();
values.get()[5].length = &(lengths->passwordLength);
values.get()[5].is_null = 0;
values.get()[5].buffer_type = MYSQL_TYPE_STRING;
values.get()[5].buffer = (char*)user.password.c_str();
values.get()[5].length = &(lengths->passwordLength);
values.get()[5].is_null = 0;
return values;
}
return values;
}
std::shared_ptr<MYSQL_BIND> UserRepository::insertSaltValues(const model::PassSec& passSec,
std::shared_ptr<UserRepository::SaltLengths> lengths)
{
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(6, sizeof(MYSQL_BIND)));
std::shared_ptr<MYSQL_BIND> UserRepository::insertSaltValues(const model::PassSec& passSec,
std::shared_ptr<UserRepository::SaltLengths> lengths) {
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(6, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_STRING;
values.get()[0].buffer = (char*)passSec.hashPassword.c_str();
values.get()[0].length = &(lengths->saltLength);
values.get()[0].buffer_type = MYSQL_TYPE_STRING;
values.get()[0].buffer = (char*)passSec.hashPassword.c_str();
values.get()[0].length = &(lengths->saltLength);
values.get()[1].buffer_type = MYSQL_TYPE_LONG;
values.get()[1].buffer = (char*)&passSec.userId;
values.get()[1].buffer_type = MYSQL_TYPE_LONG;
values.get()[1].buffer = (char*)&passSec.userId;
return values;
}
return values;
}
std::shared_ptr<MYSQL_BIND> UserRepository::valueBind(model::User& user,
std::tuple<char*, char*, char*, char*, char*, char*>& us) {
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(7, sizeof(MYSQL_BIND)));
constexpr auto strLen = 1024;
std::shared_ptr<MYSQL_BIND> UserRepository::valueBind(model::User& user,
std::tuple<char*, char*, char*, char*, char*, char*>& us)
{
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(7, sizeof(MYSQL_BIND)));
constexpr auto strLen = 1024;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&user.id;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&user.id;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(us);
values.get()[1].buffer_length = strLen;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)std::get<0>(us);
values.get()[1].buffer_length = strLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(us);
values.get()[2].buffer_length = strLen;
values.get()[2].buffer_type = MYSQL_TYPE_STRING;
values.get()[2].buffer = (char*)std::get<1>(us);
values.get()[2].buffer_length = strLen;
values.get()[3].buffer_type = MYSQL_TYPE_STRING;
values.get()[3].buffer = (char*)std::get<2>(us);
values.get()[3].buffer_length = strLen;
values.get()[3].buffer_type = MYSQL_TYPE_STRING;
values.get()[3].buffer = (char*)std::get<2>(us);
values.get()[3].buffer_length = strLen;
values.get()[4].buffer_type = MYSQL_TYPE_STRING;
values.get()[4].buffer = (char*)std::get<3>(us);
values.get()[4].buffer_length = strLen;
values.get()[4].buffer_type = MYSQL_TYPE_STRING;
values.get()[4].buffer = (char*)std::get<3>(us);
values.get()[4].buffer_length = strLen;
values.get()[5].buffer_type = MYSQL_TYPE_STRING;
values.get()[5].buffer = (char*)std::get<4>(us);
values.get()[5].buffer_length = strLen;
values.get()[5].buffer_type = MYSQL_TYPE_STRING;
values.get()[5].buffer = (char*)std::get<4>(us);
values.get()[5].buffer_length = strLen;
values.get()[6].buffer_type = MYSQL_TYPE_STRING;
values.get()[6].buffer = (char*)std::get<5>(us);
values.get()[6].buffer_length = strLen;
values.get()[6].buffer_type = MYSQL_TYPE_STRING;
values.get()[6].buffer = (char*)std::get<5>(us);
values.get()[6].buffer_length = strLen;
return values;
}
return values;
}
std::shared_ptr<MYSQL_BIND> UserRepository::saltValueBind(model::PassSec& userSalt, char *salt)
{
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(3, sizeof(MYSQL_BIND)));
constexpr auto strLen = 1024;
std::shared_ptr<MYSQL_BIND> UserRepository::saltValueBind(model::PassSec& userSalt,
char *salt) {
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*) std::calloc(3, sizeof(MYSQL_BIND)));
constexpr auto strLen = 1024;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&userSalt.id;
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = (char*)&userSalt.id;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)salt;
values.get()[1].buffer_length = strLen;
values.get()[1].buffer_type = MYSQL_TYPE_STRING;
values.get()[1].buffer = (char*)salt;
values.get()[1].buffer_length = strLen;
values.get()[2].buffer_type = MYSQL_TYPE_LONG;
values.get()[2].buffer = (char*)&userSalt.userId;
values.get()[2].buffer_type = MYSQL_TYPE_LONG;
values.get()[2].buffer = (char*)&userSalt.userId;
return values;
}
return values;
}
std::shared_ptr<UserRepository::UserLengths> UserRepository::fetchUserLengths(const model::User& user)
{
auto userLen = std::make_shared<UserLengths>();
userLen->firstnameLength = user.firstname.size();
userLen->lastnameLength = user.lastname.size();
userLen->phoneLength = user.phone.size();
userLen->emailLength = user.email.size();
userLen->usernameLength = user.username.size();
userLen->passwordLength = user.password.size();
std::shared_ptr<UserRepository::UserLengths> UserRepository::fetchUserLengths(
const model::User& user) {
auto userLen = std::make_shared<UserLengths>();
userLen->firstnameLength = user.firstname.size();
userLen->lastnameLength = user.lastname.size();
userLen->phoneLength = user.phone.size();
userLen->emailLength = user.email.size();
userLen->usernameLength = user.username.size();
userLen->passwordLength = user.password.size();
return userLen;
}
return userLen;
}
std::shared_ptr<UserRepository::SaltLengths> UserRepository::fetchSaltLengths(const model::PassSec& passSec)
{
auto saltLen = std::make_shared<SaltLengths>();
saltLen->saltLength = passSec.salt.size();
std::shared_ptr<UserRepository::SaltLengths> UserRepository::fetchSaltLengths(
const model::PassSec& passSec) {
auto saltLen = std::make_shared<SaltLengths>();
saltLen->saltLength = passSec.salt.size();
return saltLen;
}
return saltLen;
}
std::tuple<char*, char*, char*, char*, char*, char*> UserRepository::fetchUV()
{
char firstname[1024];
char lastname[1024];
char phone[1024];
char email[1024];
char username[1024];
char password[1024];
std::tuple<char*, char*, char*, char*, char*, char*> UserRepository::fetchUV() {
char firstname[1024];
char lastname[1024];
char phone[1024];
char email[1024];
char username[1024];
char password[1024];
return std::make_tuple(firstname, lastname, phone, email, username, password);
}
return std::make_tuple(firstname, lastname, phone, email, username, password);
}
model::User UserRepository::parseRecord(MYSQL_STMT *stmt)
{
model::User user;
auto usv = fetchUV();
model::User UserRepository::parseRecord(MYSQL_STMT *stmt) {
model::User user;
auto usv = fetchUV();
auto bindedValues = valueBind(user, usv);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
auto bindedValues = valueBind(user, usv);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
user.firstname = std::get<0>(usv);
user.lastname = std::get<1>(usv);
user.email = std::get<2>(usv);
user.phone = std::get<3>(usv);
user.username = std::get<4>(usv);
user.password = std::get<5>(usv);
user.firstname = std::get<0>(usv);
user.lastname = std::get<1>(usv);
user.email = std::get<2>(usv);
user.phone = std::get<3>(usv);
user.username = std::get<4>(usv);
user.password = std::get<5>(usv);
return user;
}
model::PassSec UserRepository::parseSaltRecord(MYSQL_STMT* stmt)
{
model::PassSec userSalt;
char saltKey[1024];
auto bindedValues = saltValueBind(userSalt, saltKey);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
userSalt.salt = saltKey;
return userSalt;
}
return user;
}
model::PassSec UserRepository::parseSaltRecord(MYSQL_STMT* stmt) {
model::PassSec userSalt;
char saltKey[1024];
auto bindedValues = saltValueBind(userSalt, saltKey);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
userSalt.salt = saltKey;
return userSalt;
}
}
+271 -270
View File
@@ -7,335 +7,336 @@
#include <cstring>
namespace database {
YearRepository::YearRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
YearRepository::YearRepository(const model::BinaryPath& bConf) : BaseRepository(bConf) { }
std::vector<model::Year> YearRepository::retrieveRecords()
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Year";
std::vector<model::Year> YearRepository::retrieveRecords() {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const std::string query = "SELECT * FROM Year";
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
mysql_stmt_prepare(stmt, query.c_str(), query.size());
mysql_stmt_execute(stmt);
auto yearRecs = parseRecords(stmt);
auto yearRecs = parseRecords(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
mysql_stmt_close(stmt);
mysql_close(conn);
return yearRecs;
}
std::pair<model::Year, int> 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;
return yearRecs;
}
qry << " GROUP BY yr.YearId LIMIT 1";
std::pair<model::Year, int> YearRepository::retrieveRecordWithSongCount(model::Year& year,
type::YearFilter filter) {
std::cout << "retrieving year record with song count\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const auto query = qry.str();
qry << "SELECT yr.*, COUNT(*) AS SongCount FROM Year yr LEFT JOIN ";
qry << "Song sng ON yr.YearId=sng.YearId WHERE ";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
auto yearWSC = parseRecordWithSongCount(stmt);
switch (filter) {
case type::YearFilter::id:
qry << "sng.YearId = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
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;
}
std::cout << "retrieved year record with song count" << std::endl;
qry << " GROUP BY yr.YearId LIMIT 1";
return yearWSC;
}
const auto query = qry.str();
model::Year YearRepository::retrieveRecord(model::Year& year, type::YearFilter filter)
{
// TODO: switch to prepared statements
std::cout << "retrieving year record" << std::endl;
std::stringstream qry;
auto conn = setupMysqlConnection();
qry << "SELECT yr.* FROM Year yr WHERE ";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
switch (filter) {
case type::YearFilter::id:
qry << "yr.YearId = " << year.id;
break;
case type::YearFilter::year:
qry << "yr.Year = " << year.year;
break;
default:
break;
auto yearWSC = parseRecordWithSongCount(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "retrieved year record with song count\n";
return yearWSC;
}
qry << " ORDER BY yr.YearId DESC LIMIT 1";
model::Year YearRepository::retrieveRecord(model::Year& year, type::YearFilter filter) {
std::cout << "retrieving year record\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
qry << "SELECT yr.* FROM Year yr WHERE ";
const auto query = qry.str();
auto results = performMysqlQuery(conn, query);
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(0));
year = parseRecord(results);
switch (filter) {
case type::YearFilter::id:
qry << "yr.YearId = ?";
mysql_close(conn);
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = reinterpret_cast<char*>(&year.id);
params[0].length = 0;
params[0].is_null = 0;
break;
case type::YearFilter::year:
qry << "yr.Year = ?";
std::cout << "retrieved record" << std::endl;
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = reinterpret_cast<char*>(&year.year);
params[0].length = 0;
params[0].is_null = 0;
break;
default:
break;
}
return year;
}
qry << " ORDER BY yr.YearId DESC LIMIT 1";
bool YearRepository::doesYearExist(const model::Year& year, type::YearFilter filter)
{
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
const auto query = qry.str();
std::stringstream qry;
qry << "SELECT * FROM Year WHERE ";
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
year = parseRecord(stmt);
switch (filter) {
case type::YearFilter::id:
qry << "YearId = ?";
mysql_stmt_close(stmt);
mysql_close(conn);
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 = ?";
std::cout << "retrieved record\n";
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;
return year;
}
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);
bool YearRepository::doesYearExist(const model::Year& year, type::YearFilter filter) {
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
std::cout << "the query has been performed" << std::endl;
std::stringstream qry;
qry << "SELECT * FROM Year WHERE ";
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
MYSQL_BIND params[1];
memset(params, 0, sizeof(params));
mysql_stmt_close(stmt);
mysql_close(conn);
switch (filter) {
case type::YearFilter::id:
qry << "YearId = ?";
return (rowCount > 0) ? true : false;
}
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 = ?";
void YearRepository::saveRecord(const model::Year& year)
{
std::cout << "saving year record" << std::endl;
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;
}
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
qry << " LIMIT 1";
const std::string query("INSERT INTO Year(Year) VALUES(?)");
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 status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
std::cout << "the query has been performed\n";
MYSQL_BIND params[1];
memset(params, 0 , sizeof(params));
mysql_stmt_store_result(stmt);
auto rowCount = mysql_stmt_num_rows(stmt);
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&year.year;
params[0].length = 0;
params[0].is_null = 0;
mysql_stmt_close(stmt);
mysql_close(conn);
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "saved record" << std::endl;
}
void 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;
return (rowCount > 0) ? true : false;
}
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);
void YearRepository::saveRecord(const model::Year& year) {
std::cout << "saving year record\n";
mysql_stmt_close(stmt);
mysql_close(conn);
auto conn = setupMysqlConnection();
MYSQL_STMT *stmt = mysql_stmt_init(conn);
std::cout << "deleted year record" << std::endl;
}
const std::string query("INSERT INTO Year(Year) VALUES(?)");
std::vector<model::Year> YearRepository::parseRecords(MYSQL_STMT *stmt)
{
mysql_stmt_store_result(stmt);
auto status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
std::vector<model::Year> yearRecs;
yearRecs.reserve(mysql_stmt_num_rows(stmt));
MYSQL_BIND params[1];
memset(params, 0 , sizeof(params));
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0" << std::endl;
return yearRecs;
params[0].buffer_type = MYSQL_TYPE_LONG;
params[0].buffer = (char*)&year.year;
params[0].length = 0;
params[0].is_null = 0;
status = mysql_stmt_bind_param(stmt, params);
status = mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
mysql_close(conn);
std::cout << "saved record\n";
}
model::Year yearRec;
const auto valAmt = 2;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
void YearRepository::deleteYear(const model::Year& year,
type::YearFilter filter) {
std::cout << "deleting year record\n";
std::stringstream qry;
auto conn = setupMysqlConnection();
auto stmt = mysql_stmt_init(conn);
auto res = mysql_stmt_result_metadata(stmt);
qry << "DELETE FROM Year WHERE ";
MYSQL_BIND val[valAmt];
memset(val, 0, sizeof(val));
MYSQL_BIND params[1];
std::memset(params, 0, sizeof(params));
val[0].buffer_type = MYSQL_TYPE_LONG;
val[0].buffer = (char*)&yearRec.id;
val[0].length = &len[0];
val[0].is_null = &nullRes[0];
switch (filter) {
case type::YearFilter::id:
qry << "YearId = ?";
val[1].buffer_type = MYSQL_TYPE_LONG;
val[1].buffer = (char*)&yearRec.year;
val[1].length = &len[1];
val[1].is_null = &nullRes[1];
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;
}
for (auto status = mysql_stmt_bind_result(stmt, val); status == 0;) {
std::cout << "fetching statement result" << std::endl;
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\n";
}
std::vector<model::Year> YearRepository::parseRecords(MYSQL_STMT *stmt) {
mysql_stmt_store_result(stmt);
const auto rowCount = mysql_stmt_num_rows(stmt);
std::vector<model::Year> yearRecs;
yearRecs.reserve(rowCount);
if (mysql_stmt_field_count(stmt) == 0) {
std::cout << "field count is 0\n";
return yearRecs;
}
const auto valAmt = 2;
unsigned long len[valAmt];
my_bool nullRes[valAmt];
for (auto status = 0; status == 0; status = mysql_stmt_next_result(stmt)) {
if (mysql_stmt_field_count(stmt) > 0) {
model::Year yearRec;
std::cout << "fetching statement result\n";
auto bindedValues = valueBind(yearRec);
status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
if (status == 1 || status == MYSQL_NO_DATA) break;
yearRecs.push_back(yearRec);
}
std::cout << "fetching next result\n";
}
return yearRecs;
}
std::pair<model::Year, int> YearRepository::parseRecordWithSongCount(MYSQL_STMT *stmt) {
std::cout << "parsing year record\n";
mysql_stmt_store_result(stmt);
model::Year year;
int songCount = 0;
if (mysql_stmt_num_rows(stmt) == 0) {
std::cout << "no results\n";
return std::make_pair(year, songCount);
}
auto val = valueBindWithSongCount(year, songCount);
auto status = mysql_stmt_bind_result(stmt, val.get());
status = mysql_stmt_fetch(stmt);
std::cout << "parsed year record from the database\n";
return std::make_pair(year, songCount);
}
std::shared_ptr<MYSQL_BIND> YearRepository::valueBind(model::Year& year) {
constexpr auto valueCount = 2;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&year.id);
values.get()[1].buffer_type = MYSQL_TYPE_LONG;
values.get()[1].buffer = reinterpret_cast<char*>(&year.year);
return values;
}
std::shared_ptr<MYSQL_BIND> YearRepository::valueBindWithSongCount(model::Year& year,
int& songCount) {
constexpr auto valueCount = 3;
std::shared_ptr<MYSQL_BIND> values((MYSQL_BIND*)
std::calloc(valueCount, sizeof(MYSQL_BIND)));
values.get()[0].buffer_type = MYSQL_TYPE_LONG;
values.get()[0].buffer = reinterpret_cast<char*>(&year.id);
values.get()[1].buffer_type = MYSQL_TYPE_LONG;
values.get()[1].buffer = reinterpret_cast<char*>(&year.year);
values.get()[2].buffer_type = MYSQL_TYPE_LONG;
values.get()[2].buffer = reinterpret_cast<char*>(&songCount);
return values;
}
model::Year YearRepository::parseRecord(MYSQL_STMT *stmt) {
std::cout << "parsing year record\n";
mysql_stmt_store_result(stmt);
model::Year year;
auto bindedValues = valueBind(year);
auto status = mysql_stmt_bind_result(stmt, bindedValues.get());
status = mysql_stmt_fetch(stmt);
if (status == 0) {
yearRecs.push_back(std::move(yearRec));
}
std::cout << "done parsing year record\n";
return year;
}
return yearRecs;
}
std::pair<model::Year, int> 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 YearRepository::parseRecord(MYSQL_RES *results)
{
std::cout << "parsing year record" << std::endl;
model::Year year;
auto fieldNum = mysql_num_fields(results);
auto row = mysql_fetch_row(results);
for (auto i = 0; i != fieldNum; ++i) {
const std::string field(mysql_fetch_field(results)->name);
if (field.compare("YearId") == 0) {
year.id= std::stoi(row[i]);
}
if (field.compare("Year") == 0) {
year.year = std::stoi(row[i]);
}
}
std::cout << "parse year record" << std::endl;
return year;
}
model::Year YearRepository::parseRecord(MYSQL_STMT *stmt)
{
// TODO: imeplement this
// I really thought that I had already done this
model::Year year;
return year;
}
}