Left off at adding album record to the database and retrieving the album record to assign the album id to the song record's album id foreign key

This commit is contained in:
kdeng00
2019-09-01 18:46:02 -04:00
parent ab3000c2a0
commit fafb39326b
17 changed files with 320 additions and 59 deletions
+5 -1
View File
@@ -6,7 +6,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(SOURCES
src/appComponent.hpp
src/database/albumRepository.cpp
src/database/artistRepository.cpp
src/database/base_repository.cpp
@@ -27,6 +26,7 @@ set(SOURCES
src/utilities/metadata_retriever.cpp
)
set(HEADERS
include/component/appComponent.hpp
include/controller/loginController.hpp
include/controller/songController.hpp
include/database/albumRepository.h
@@ -49,9 +49,13 @@ set(HEADERS
include/models/models.h
include/utilities/imageFile.h
include/utilities/metadata_retriever.h
include/types/albumFilter.h
include/types/artistFilter.h
include/types/coverFilter.h
include/types/genreFilter.h
include/types/scopes.h
include/types/songFilter.h
include/types/yearFilter.h
)
set (TAGLIB
+41 -1
View File
@@ -10,6 +10,34 @@ CREATE TABLE CoverArt (
PRIMARY KEY (CoverArtId)
);
CREATE TABLE Album (
AlbumId INT NOT NULL AUTO_INCREMENT,
Title TEXT NOT NULL,
Year INT NOT NULL,
PRIMARY KEY (AlbumId)
);
CREATE TABLE Artist (
ArtistId INT NOT NULL AUTO_INCREMENT,
Artist TEXT NOT NULL,
PRIMARY KEY (ArtistId)
);
CREATE TABLE Genre (
GenreId INT NOT NULL AUTO_INCREMENT,
Category TEXT NOT NULL,
PRIMARY KEY (GenreId)
);
CREATE TABLE Year (
YearId INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (YearId)
);
CREATE TABLE Song (
SongId INT NOT NULL AUTO_INCREMENT,
Title TEXT NOT NULL,
@@ -22,13 +50,25 @@ CREATE TABLE Song (
Disc INT NOT NULL,
SongPath TEXT NOT NULL,
CoverArtId INT NOT NULL,
ArtistId INT NOT NULL,
AlbumId INT NOT NULL,
GenreId INT NOT NULL,
YearId INT NOT NULL,
PRIMARY KEY (SongId),
CONSTRAINT FK_CoverArtId FOREIGN KEY (CoverArtId) REFERENCES CoverArt(CoverArtId)
CONSTRAINT FK_CoverArtId FOREIGN KEY (CoverArtId) REFERENCES CoverArt (CoverArtId),
CONSTRAINT FK_ArtistId FOREIGN KEY (ArtistId) REFERENCES Artist (ArtistId),
CONSTRAINT FK_AlbumId FOREIGN KEY (AlbumId) REFERENCES Album (AlbumId),
CONSTRAINT FK_GenreId FOREIGN KEY (GenreId) REFERENCES Genre (GenreId),
CONSTRAINT FK_YearId FOREIGN KEY (YearId) REFERENCES Year (YearId)
);
CREATE TABLE User (
UserId INT NOT NULL AUTO_INCREMENT,
Firstname TEXT NOT NULL,
Lastname TEXT NOT NULL,
Email TEXT NOT NULL,
Phone TEXT NOT NULL,
Username TEXT NOT NULL,
Password TEXT NOT NULL,
+38
View File
@@ -0,0 +1,38 @@
#ifndef APPCOMPONENT_H_
#define APPCOMPONENT_H_
#include <memory>
#include "oatpp/core/macro/component.hpp"
#include "oatpp/network/server/SimpleTCPConnectionProvider.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/HttpConnectionHandler.hpp"
namespace Component
{
class appComponent
{
public:
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(5002);
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
return oatpp::web::server::HttpRouter::createShared();
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::server::ConnectionHandler>, serverConnectionHandler)([] {
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
return oatpp::web::server::HttpConnectionHandler::createShared(router);
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
return oatpp::parser::json::mapping::ObjectMapper::createShared();
}());
private:
};
}
#endif
+11
View File
@@ -1,8 +1,11 @@
#ifndef ALBUMREPOSITORY_H_
#define ALBUMREPOSITORY_H_
#include <vector>
#include "database/base_repository.h"
#include "models/models.h"
#include "types/albumFilter.h"
namespace Database
{
@@ -10,7 +13,15 @@ namespace Database
{
public:
albumRepository(const Model::BinaryPath&);
std::vector<Model::Album> retrieveRecords();
Model::Album retrieveRecord(Model::Album&, Type::albumFilter);
void saveAlbum(const Model::Album&);
private:
std::vector<Model::Album> parseRecords(MYSQL_RES*);
Model::Album parseRecord(MYSQL_RES*);
};
}
+2
View File
@@ -9,6 +9,8 @@ namespace Manager
{
public:
albumManager(const Model::BinaryPath&);
void saveAlbum(const Model::Song&);
private:
Model::BinaryPath m_bConf;
};
+1
View File
@@ -22,6 +22,7 @@ namespace Manager
static void printSong(const Model::Song&);
private:
void saveSongTemp(Model::Song&);
void saveMisc(Model::Song&);
Model::BinaryPath m_bConf;
std::string exe_path;
+2
View File
@@ -92,6 +92,8 @@ namespace Model
struct BinaryPath
{
BinaryPath() = default;
BinaryPath(const char *p) : path(std::move(p)) { }
std::string path;
};
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef ALBUMFILTER_H_
#define ALBUMFILTER_H_
namespace Type
{
enum class albumFilter
{
id = 0,
title,
year
};
}
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef ARTISTFILTER_H_
#define ARTISTFILTER_H_
namespace Type
{
enum class artistFilter
{
id = 0,
artist
};
}
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef GENREFILTER_H_
#define GENREFILTER_H_
namespace Type
{
enum class genreFilter
{
id = 0,
category
};
}
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef YEARFILTER_H_
#define YEARFILTER_H_
namespace Type
{
enum class yearFilter
{
id = 0,
year
};
}
#endif
-34
View File
@@ -1,34 +0,0 @@
#ifndef APPCOMPONENT_H_
#define APPCOMPONENT_H_
#include <memory>
#include "oatpp/core/macro/component.hpp"
#include "oatpp/network/server/SimpleTCPConnectionProvider.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/HttpConnectionHandler.hpp"
class appComponent
{
public:
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
return oatpp::network::server::SimpleTCPConnectionProvider::createShared(5002);
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
return oatpp::web::server::HttpRouter::createShared();
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::server::ConnectionHandler>, serverConnectionHandler)([] {
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
return oatpp::web::server::HttpConnectionHandler::createShared(router);
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, apiObjectMapper)([] {
return oatpp::parser::json::mapping::ObjectMapper::createShared();
}());
private:
};
#endif
+117
View File
@@ -1,5 +1,122 @@
#include "database/albumRepository.h"
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <cstring>
Database::albumRepository::albumRepository(const Model::BinaryPath& bConf)
: base_repository(bConf)
{ }
// TODO: implement this later on
std::vector<Model::Album> Database::albumRepository::retrieveRecords()
{
std::vector<Model::Album> albums;
return albums;
}
Model::Album Database::albumRepository::retrieveRecord(Model::Album& album, Type::albumFilter filter)
{
std::stringstream qry;
auto conn = setup_mysql_connection();
qry << "SELECT alb.* FROM Album alb WHERE ";
std::unique_ptr<char*> param;
switch (filter) {
case Type::albumFilter::id:
qry << "alb.AlbumId = " << album.id;
break;
case Type::albumFilter::title:
param = std::make_unique<char*>(new char[album.title.size()]);
mysql_real_escape_string(conn, *param, album.title.c_str(), album.title.size());
qry << "alb.Title = '" << *param << "'";
break;
case Type::albumFilter::year:
break;
default:
break;
}
const std::string query = qry.str();
auto results = perform_mysql_query(conn, query);
album = parseRecord(results);
mysql_close(conn);
std::cout << "done" << std::endl;
return album;
}
void Database::albumRepository::saveAlbum(const Model::Album& album)
{
std::cout << "beginning to insert album record" << std::endl;
auto conn = setup_mysql_connection();
auto status = 0;
MYSQL_STMT *stmt = mysql_stmt_init(conn);
std::string query = "INSERT INTO Album(Title, Year) VALUES(?, ?)";
status = mysql_stmt_prepare(stmt, query.c_str(), query.size());
MYSQL_BIND params[2];
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].buffer = &titleLength;
params[0].is_null = 0;
params[1].buffer_type = MYSQL_TYPE_LONG;
params[1].buffer = (char*)&album.year;
params[1].length = 0;
params[1].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;
}
// TODO: implement this
std::vector<Model::Album> Database::albumRepository::parseRecords(MYSQL_RES* results)
{
std::vector<Model::Album> albums;
return albums;
}
Model::Album Database::albumRepository::parseRecord(MYSQL_RES* results)
{
Model::Album album;
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("AlbumId") == 0) {
album.id = std::stoi(row[i]);
}
if (field.compare("Title") == 0) {
album.title = row[i];
}
if (field.compare("Year") == 0) {
album.year = std::stoi(row[i]);
}
}
return album;
}
+1
View File
@@ -74,6 +74,7 @@ void Database::songRepository::deleteRecord(const Model::Song& song)
void Database::songRepository::saveRecord(const Model::Song& song)
{
std::cout << "beginning to insert song record" << std::endl;
auto conn = setup_mysql_connection();
auto status = 0;
+3 -6
View File
@@ -9,7 +9,7 @@
#include "oatpp/network/server/SimpleTCPConnectionProvider.hpp"
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "appComponent.hpp"
#include "component/appComponent.hpp"
#include "controller/loginController.hpp"
#include "controller/songController.hpp"
#include "database/base_repository.h"
@@ -20,7 +20,7 @@ namespace fs = std::filesystem;
//void run(const std::string& working_path)
void run(const Model::BinaryPath& bConf)
{
appComponent component;
Component::appComponent component;
OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
@@ -43,11 +43,8 @@ void run(const Model::BinaryPath& bConf)
int main(int argc, char **argv)
{
oatpp::base::Environment::init();
//const std::string working_path = argv[0];
Model::BinaryPath bConf;
bConf.path = argv[0];
Model::BinaryPath bConf(argv[0]);
//run(working_path);
run(bConf);
oatpp::base::Environment::destroy();
+14
View File
@@ -1,5 +1,19 @@
#include "managers/albumManager.h"
#include "database/albumRepository.h"
#include "models/models.h"
Manager::albumManager::albumManager(const Model::BinaryPath& bConf)
: m_bConf(bConf)
{ }
void Manager::albumManager::saveAlbum(const Model::Song& song)
{
Model::Album album;
album.title = song.album;
album.year = song.year;
Database::albumRepository albRepo(m_bConf);
albRepo.saveAlbum(album);
}
+32 -17
View File
@@ -8,8 +8,12 @@
#include "database/coverArtRepository.h"
#include "database/songRepository.h"
#include "managers/albumManager.h"
#include "managers/artistManager.h"
#include "managers/coverArtManager.h"
#include "managers/directory_manager.h"
#include "managers/genreManager.h"
#include "managers/yearManager.h"
#include "utilities/metadata_retriever.h"
namespace fs = std::filesystem;
@@ -31,25 +35,9 @@ void Manager::song_manager::saveSong(Model::Song& song)
song = meta.retrieve_metadata(song.songPath);
song.data = std::move(data);
coverArtManager covMgr(m_bConf);
auto pathConfigContent = Manager::directory_manager::pathConfigContent(m_bConf);
auto coverRootPath = pathConfigContent["cover_root_path"].get<std::string>();
auto musicRootPath = pathConfigContent["root_music_path"].get<std::string>();
auto stockCoverPath = Manager::directory_manager::configPath(m_bConf);
stockCoverPath.append("/CoverArt.png");
saveMisc(song);
auto cov = covMgr.saveCover(song, coverRootPath, stockCoverPath);
song.coverArtId = cov.id;
auto songPath = Manager::directory_manager::create_directory_process(song, musicRootPath);
songPath.append(song.title);
songPath.append(".mp3");
std::cout << "\n\ntemp path: " << song.songPath << std::endl;
std::cout << "new path: " << songPath << std::endl;
fs::copy(song.songPath, songPath);
fs::remove(song.songPath);
song.songPath = std::move(songPath);
printSong(song);
@@ -120,3 +108,30 @@ void Manager::song_manager::saveSongTemp(Model::Song& song)
song.songPath = tmp_song;
}
void Manager::song_manager::saveMisc(Model::Song& song)
{
coverArtManager covMgr(m_bConf);
auto pathConfigContent = Manager::directory_manager::pathConfigContent(m_bConf);
auto coverRootPath = pathConfigContent["cover_root_path"].get<std::string>();
auto musicRootPath = pathConfigContent["root_music_path"].get<std::string>();
auto stockCoverPath = Manager::directory_manager::configPath(m_bConf);
stockCoverPath.append("/CoverArt.png");
auto cov = covMgr.saveCover(song, coverRootPath, stockCoverPath);
song.coverArtId = cov.id;
auto songPath = Manager::directory_manager::create_directory_process(song, musicRootPath);
songPath.append(song.title);
songPath.append(".mp3");
std::cout << "\n\ntemp path: " << song.songPath << std::endl;
std::cout << "new path: " << songPath << std::endl;
fs::copy(song.songPath, songPath);
fs::remove(song.songPath);
song.songPath = std::move(songPath);
artistManager artMgr(m_bConf);
albumManager albMgr(m_bConf);
genreManager gnrMgr(m_bConf);
yearManager yrMgr(m_bConf);
}