Code cleanup
This commit is contained in:
+336
-348
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+485
-498
File diff suppressed because it is too large
Load Diff
+261
-270
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user