mirror of
https://github.com/QuasarApp/SoundBand.git
synced 2025-04-27 07:44:31 +00:00
497 lines
13 KiB
C++
497 lines
13 KiB
C++
#include "mysql.h"
|
|
#include <QSqlQuery>
|
|
#include <QtSql>
|
|
#include "exaptions.h"
|
|
#include <QSettings>
|
|
#include <QMediaPlaylist>
|
|
|
|
namespace syncLib{
|
|
|
|
MySql::MySql(const QString &databasename):
|
|
db(nullptr),
|
|
qyery(nullptr)
|
|
{
|
|
initDB(databasename);
|
|
}
|
|
|
|
bool MySql::exec(QSqlQuery *sq,const QString& sqlFile){
|
|
QFile f(sqlFile);
|
|
bool result=true;
|
|
if(f.open(QIODevice::ReadOnly)){
|
|
QString temp,delimiter=";";
|
|
QTextStream stream(&f);
|
|
stream.setCodec("UTF8");
|
|
while(!stream.atEnd()){
|
|
temp+=stream.readLine();
|
|
if(temp.lastIndexOf("delimiter",-1,Qt::CaseInsensitive)>-1){
|
|
temp.remove("delimiter",Qt::CaseInsensitive);
|
|
int last=temp.indexOf(QRegularExpression("[^ \f\n\r\t\v]"))+1;
|
|
int begin=temp.lastIndexOf(QRegularExpression("[^ \f\n\r\t\v]"));
|
|
delimiter=temp.mid(begin,last-begin);
|
|
temp="";
|
|
}else{
|
|
if(temp.lastIndexOf(delimiter)>-1){
|
|
temp.remove(delimiter);
|
|
(result=result&&sq->exec(temp));
|
|
temp="";
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
void MySql::initDB(const QString &database){
|
|
if(db) return;
|
|
dataBaseName = database;
|
|
QSettings settings;
|
|
songDir = settings.value(MAIN_FOLDER_KEY, QDir::homePath() + "/soundBand").toString();
|
|
db = new QSqlDatabase();
|
|
*db = QSqlDatabase::addDatabase("QSQLITE", database);
|
|
QDir d(QString("./%0").arg(dataBaseName));
|
|
db->setDatabaseName(d.absolutePath());
|
|
if(db->open()){
|
|
qyery = new QSqlQuery(*db);
|
|
|
|
QString qyer = QString("CREATE TABLE IF NOT EXISTS songs("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"name VARCHAR(100), "
|
|
"size INT NOT NULL, "
|
|
"data TEXT NOT NULL "
|
|
")");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
throw InitDBError();
|
|
delete db;
|
|
return;
|
|
}
|
|
|
|
|
|
qyer = QString("CREATE UNIQUE INDEX IF NOT EXISTS isongs ON songs(name,size)");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
throw InitDBError();
|
|
delete db;
|
|
return;
|
|
}
|
|
|
|
qyer = QString("CREATE TABLE IF NOT EXISTS playlists("
|
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
"name VARCHAR(50) NOT NULL UNIQUE, "
|
|
"description VARCHAR(1000) DEFAULT 'without description', "
|
|
"image BLOB "
|
|
")");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
throw InitDBError();
|
|
delete db;
|
|
return;
|
|
}
|
|
|
|
qyer = QString("CREATE TABLE IF NOT EXISTS playlistsdata("
|
|
"playlist INT NOT NULL,"
|
|
"song INT NOT NULL,"
|
|
"FOREIGN KEY(playlist) REFERENCES playlists(name)"
|
|
" ON UPDATE CASCADE"
|
|
" ON DELETE CASCADE,"
|
|
"FOREIGN KEY(song) REFERENCES songs(id)"
|
|
" ON UPDATE CASCADE"
|
|
" ON DELETE CASCADE"
|
|
")");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
throw InitDBError();
|
|
delete db;
|
|
return;
|
|
}
|
|
|
|
qyer = QString("CREATE UNIQUE INDEX IF NOT EXISTS iplaylistsdata ON "
|
|
"playlistsdata(playlist,song)");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
throw InitDBError();
|
|
delete db;
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
bool MySql::find(const QMediaContent &song, SongStorage &response){
|
|
QList<SongStorage> songs;
|
|
|
|
if(!updateAvailableSongs(songs)){
|
|
return false;
|
|
}
|
|
|
|
for(SongStorage &i: songs){
|
|
if(i == song){
|
|
response = i;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool MySql::find(const QMediaContent &song, SongHeader &response){
|
|
QList<SongStorage> songs;
|
|
|
|
if(!updateAvailableSongs(songs)){
|
|
return false;
|
|
}
|
|
|
|
for(SongStorage &i: songs){
|
|
if(i == song){
|
|
response = (SongHeader&)i;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool MySql::find(const SongHeader &song, QMediaContent &response){
|
|
QList<SongStorage> songs;
|
|
|
|
if(!updateAvailableSongs(songs)){
|
|
return false;
|
|
}
|
|
|
|
for(SongStorage &i: songs){
|
|
if((SongHeader&)i == song){
|
|
response = i.toMedia();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MySql::setSoundDir(const QString &str){
|
|
songDir = str;
|
|
QSettings().setValue(MAIN_FOLDER_KEY, songDir);
|
|
}
|
|
|
|
bool MySql::saveToStorage(QUrl &url, const Song &song) const{
|
|
if(!song.isValid()){
|
|
return false;
|
|
}
|
|
|
|
QFile file(songDir + "/" + song.name);
|
|
|
|
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
|
|
return false;
|
|
}
|
|
|
|
file.write(song.source.data(), song.source.length());
|
|
file.close();
|
|
|
|
url = QUrl::fromLocalFile(songDir + "/" + song.name);
|
|
|
|
return url.isValid();
|
|
|
|
}
|
|
|
|
void MySql::sqlErrorLog(const QString &qyery)const{
|
|
#ifdef QT_DEBUG
|
|
qDebug()<< qyery << ": fail:\n " <<this->qyery->lastError();
|
|
#endif
|
|
}
|
|
|
|
int MySql::save(const Song &song , bool onlyDataBase){
|
|
QString qyer = QString("SELECT id from songs where name='%0' and size=%1").arg(song.name,
|
|
QString::number(song.size));
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return -1;
|
|
}
|
|
|
|
if(qyery->next()){
|
|
return qyery->value(0).toInt();
|
|
}
|
|
|
|
QUrl url;
|
|
if(!onlyDataBase && !saveToStorage(url, song)){
|
|
return false;
|
|
}
|
|
|
|
qyer = QString("INSERT INTO songs (name,size,data) VALUES"
|
|
"('%0',%1,'%2')").arg(song.name,
|
|
QString::number(song.size),
|
|
url.path());
|
|
|
|
if(!qyery->exec()){
|
|
sqlErrorLog(qyer);
|
|
return -1;
|
|
}
|
|
if(!qyery->exec(QString("SELECT MAX(id) from songs"))){
|
|
sqlErrorLog(qyer);
|
|
return -1;
|
|
}
|
|
if(!qyery->next())
|
|
return -1;
|
|
|
|
int result = qyery->value(0).toInt();
|
|
return result;
|
|
}
|
|
|
|
int MySql::save(const QString &url){
|
|
|
|
SongStorage song(QUrl::fromLocalFile(url));
|
|
|
|
if(!song.isNameValid()){
|
|
return -1;
|
|
}
|
|
|
|
return save(song, true);
|
|
|
|
}
|
|
|
|
bool MySql::load(const SongHeader &song, SongStorage &result){
|
|
if(song.id > -1){
|
|
QString qyer = QString("SELECT * from songs where id=%0").arg(song.id);
|
|
if(!qyery->exec(qyer)){
|
|
return false;
|
|
}
|
|
}else if(!song.name.isEmpty() && song.size > 0){
|
|
QString qyer = QString("SELECT * from songs where name='%0' and size=%1").arg(song.name).arg(song.size);
|
|
if(!qyery->exec(qyer)){
|
|
return false;
|
|
}
|
|
}else {
|
|
return false;
|
|
}
|
|
|
|
if(!qyery->next()){
|
|
return false;
|
|
}
|
|
|
|
result.id = qyery->value(0).toInt();
|
|
result.name = qyery->value(1).toString();
|
|
result.size = qyery->value(2).toInt();
|
|
result.url = qyery->value(3).toUrl();
|
|
return true;
|
|
}
|
|
|
|
bool MySql::updateAvailableSongs(QList<SongStorage>& list, const QString& playList, bool forEditing){
|
|
QString qyer;
|
|
|
|
if(playList.isEmpty() || playList == ALL_SONGS_LIST || forEditing){
|
|
qyer = QString("SELECT * from songs");
|
|
}else{
|
|
qyer = QString("SELECT * from songs where "
|
|
"id in (select song from playlistsdata where "
|
|
"playlist='%0')").arg(playList);
|
|
}
|
|
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
|
|
list.clear();
|
|
|
|
while(qyery->next()){
|
|
SongStorage song;
|
|
song.isSelected = !forEditing || playList == ALL_SONGS_LIST;
|
|
song.id = qyery->value(0).toInt();
|
|
song.name = qyery->value(1).toString();
|
|
song.size = qyery->value(2).toInt();
|
|
song.url = qyery->value(3).toUrl();
|
|
|
|
list.push_back(song);
|
|
}
|
|
|
|
if(forEditing && list.size() > 0 && playList != ALL_SONGS_LIST){
|
|
QString qyer;
|
|
qyer = QString("select song from playlistsdata where "
|
|
" playlist='%0'").arg(playList);
|
|
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
|
|
while(qyery->next()){
|
|
for(SongStorage& item:list){
|
|
int id = qyery->value(0).toInt();
|
|
if(item.id == id){
|
|
item.isSelected = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MySql::updateAvailableSongs(QMediaPlaylist& list, const QString& playList){
|
|
|
|
QList<SongStorage> tempList;
|
|
|
|
if(!updateAvailableSongs(tempList, playList))
|
|
return false;
|
|
|
|
for(SongStorage &header : tempList){
|
|
list.addMedia(header.toMedia());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool MySql::removeSong(const SongHeader &header){
|
|
if(header.id > -1){
|
|
QString qyer = QString("DELETE from songs where id=%0").arg(header.id);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else if(!header.name.isEmpty() && header.size > 0){
|
|
QString qyer = QString("DELETE from songs where name='%0'"
|
|
" and size=%1").arg(header.name).arg(header.size);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MySql::addPlayList(const QString &newPlayList, const QString& desc){
|
|
if(newPlayList == ALL_SONGS_LIST)
|
|
return false;
|
|
|
|
QString qyer = QString("INSERT INTO playlists(name, description)"
|
|
" VALUES('%0', '%1')").arg(newPlayList, desc);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MySql::addToPlayList(const SongHeader &header, const QString &newPlaylist){
|
|
if(newPlaylist == ALL_SONGS_LIST)
|
|
return false;
|
|
|
|
if(header.id > -1){
|
|
QString qyer = QString("INSERT INTO playlistsdata(song, playlist)"
|
|
" VALUES(%0,'%1')").arg(header.id).arg(newPlaylist);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else if(!header.name.isEmpty() && header.size > 0){
|
|
QString qyer = QString("INSERT INTO playlistsdata(song, playlist) "
|
|
"VALUES((SELECT id from songs where name='%0'"
|
|
" and size='%1'),'%2')")
|
|
.arg(header.name).arg(header.size).arg(newPlaylist);
|
|
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MySql::removeFromPlayList(const SongHeader &header, const QString &playList){
|
|
if(playList == ALL_SONGS_LIST)
|
|
return false;
|
|
|
|
if(header.id > -1){
|
|
QString qyer = QString("DELETE from playlistsdata where song=%0 and playlist='%1'").arg(header.id).arg(playList);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else if(!header.name.isEmpty() && header.size > 0){
|
|
QString qyer = QString("DELETE from playlistsdata where "
|
|
"song=(SELECT id from songs where name='%0' and size='%1')"
|
|
" and playlist='%2'")
|
|
.arg(header.name).arg(header.size).arg(playList);
|
|
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
}else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MySql::removePlayList(const QString &playList){
|
|
if(playList == ALL_SONGS_LIST)
|
|
return false;
|
|
|
|
QString qyer = QString("DELETE from playlists where name='%0'").arg(playList);
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool MySql::getPlayLists(QStringList &list)const{
|
|
QString qyer = QString("SELECT name from playlists");
|
|
if(!qyery->exec(qyer)){
|
|
sqlErrorLog(qyer);
|
|
return false;
|
|
}
|
|
|
|
list.clear();
|
|
|
|
list.push_back(ALL_SONGS_LIST);
|
|
|
|
while(qyery->next()){
|
|
list.push_back(qyery->value(0).toString());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int MySql::getSongId(const QString &name){
|
|
if(name.isEmpty()){
|
|
return -1;
|
|
}
|
|
|
|
QString qyer = QString("SELECT id from songs where name='%0'").arg(name);
|
|
if(!qyery->exec(qyer)){
|
|
return -1;
|
|
}
|
|
|
|
if(qyery->size() != 1){
|
|
throw DataBaseError();
|
|
}
|
|
|
|
if(!qyery->next()){
|
|
return -1;
|
|
}
|
|
|
|
return qyery->value(0).toInt();;
|
|
}
|
|
|
|
void MySql::clear(){
|
|
qyery->exec("vacuum");
|
|
}
|
|
|
|
MySql::~MySql(){
|
|
delete db;
|
|
QSqlDatabase::removeDatabase(dataBaseName);
|
|
|
|
}
|
|
}
|
|
|