From 1ef62656c07db448026ab2ae3ccbb0e1d7e322a1 Mon Sep 17 00:00:00 2001
From: Andrei <EndrIIMail@gmail.com>
Date: Sun, 25 Mar 2018 23:01:44 +0300
Subject: [PATCH] added first change of song database

---
 sync/config.h  |  3 ++
 sync/mysql.cpp | 59 +++++++++++++++++++++++-------------
 sync/mysql.h   | 15 ++++++++++
 sync/song.cpp  | 81 +++++++++++++++++---------------------------------
 sync/song.h    |  9 +++---
 sync/sync.h    |  3 +-
 6 files changed, 91 insertions(+), 79 deletions(-)

diff --git a/sync/config.h b/sync/config.h
index f8f81ec..4988bef 100644
--- a/sync/config.h
+++ b/sync/config.h
@@ -3,6 +3,9 @@
 
 // general otions
 #define CURRENT_PLAYLIST_KEY        "currentPlayList"
+#define MAIN_FOLDER_KEY             "songsfolder"
+#define MAIN_FOLDER                 "soundBand"
+
 
 // LIB VERSION
 #define MAJOR_VERSION               0
diff --git a/sync/mysql.cpp b/sync/mysql.cpp
index f7693ea..3972de0 100644
--- a/sync/mysql.cpp
+++ b/sync/mysql.cpp
@@ -2,6 +2,7 @@
 #include <QSqlQuery>
 #include <QtSql>
 #include "exaptions.h"
+#include <QSettings>
 
 namespace syncLib{
 
@@ -44,6 +45,8 @@ bool MySql::exec(QSqlQuery *sq,const QString& sqlFile){
 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));
@@ -51,23 +54,11 @@ void MySql::initDB(const QString &database){
     if(db->open()){
         qyery = new QSqlQuery(*db);
 
-//        /*
-//         *https://stackoverflow.com/questions/40863216/sqlite-why-is-foreign-key-constraint-not-working-here
-//        */
-
-//        QString qyer = QString("PRAGMA foreign_keys = ON");
-//        if(!qyery->exec(qyer)){
-//            sqlErrorLog(qyer);
-//            throw InitDBError();
-//            delete db;
-//            return;
-//        }
-
         QString qyer = QString("CREATE TABLE IF NOT EXISTS songs("
                      "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                      "name VARCHAR(100), "
                      "size INT NOT NULL, "
-                     "data BLOB NOT NULL "
+                     "data TEXT NOT NULL "
                      ")");
         if(!qyery->exec(qyer)){
             sqlErrorLog(qyer);
@@ -127,6 +118,31 @@ void MySql::initDB(const QString &database){
     }
 }
 
+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();
@@ -145,15 +161,16 @@ int MySql::save(const Song &song){
         return qyery->value(0).toInt();
     }
 
-    qyer = QString("INSERT INTO songs (name,size,data) VALUES"
-                           "('%0',%1,:val)").arg(song.name,
-                                                 QString::number(song.size));
-    if(!qyery->prepare(qyer)){
-        sqlErrorLog(qyer + " prepare error");
-        return -1;
+    QUrl url;
+    if(!saveToStorage(url, song)){
+        return false;
     }
 
-    qyery->bindValue(":val",song.source);
+    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;
@@ -176,7 +193,7 @@ int MySql::save(const QString &url){
     }
     QByteArray bytes = f.readAll();
     f.close();
-    QString name = url.right(url.lastIndexOf(QRegularExpression("[\\/]"))); // meby [[\\\/]]
+    QString name = url.right(url.lastIndexOf(QRegularExpression("[\\\/]")));
     Song song;
     song.name = name;
     song.size = bytes.size();
diff --git a/sync/mysql.h b/sync/mysql.h
index 125defa..bd85046 100644
--- a/sync/mysql.h
+++ b/sync/mysql.h
@@ -14,6 +14,7 @@ private:
     QSqlDatabase *db;
     QSqlQuery *qyery;
     QString dataBaseName;
+    QString songDir;
 
     /**
      * @brief sqlErrorLog show sql error
@@ -21,6 +22,14 @@ private:
      */
     void sqlErrorLog(const QString& qyery) const;
 
+    /**
+     * @brief saveToStorage save song as file into hdd
+     * @param url - url of song after save
+     * @param song - saved song
+     * @return true if all done
+     */
+    bool saveToStorage(QUrl& url, const Song& song)const;
+
 public:
     MySql(const QString& databasename);
     /**
@@ -28,6 +37,12 @@ public:
      */
     void initDB(const QString& database = DATABASE_NAME );
 
+    /**
+     * @brief setSoundDir
+     * @param str
+     */
+    void setSoundDir(const QString& str);
+
     /**
      * @brief load song of database;
      * @brief song -
diff --git a/sync/song.cpp b/sync/song.cpp
index 234e9e7..4911503 100644
--- a/sync/song.cpp
+++ b/sync/song.cpp
@@ -1,5 +1,7 @@
 #include "song.h"
 #include <QStringList>
+#include <QRegularExpression>
+
 namespace syncLib{
 
 static const QStringList ValidSongs = {".mp3", ".wav", ".ogg"};
@@ -11,6 +13,17 @@ SongHeader::SongHeader()
     this->size = 0;
 }
 
+bool SongHeader::getName(QString & name, const QUrl &url) const {
+    if(url.isLocalFile() && url.isValid()){
+        name = url.fileName();
+        name = name.right(name.lastIndexOf(QRegularExpression("[\\\/]")));
+        return true;
+    }
+
+    return false;
+
+}
+
 SongHeader& SongHeader::operator =(const SongHeader& right){
     this->id = right.id;
     this->name = right.name;
@@ -18,15 +31,25 @@ SongHeader& SongHeader::operator =(const SongHeader& right){
     return *this;
 }
 
+SongHeader& SongHeader::operator =(const QMediaContent& right){
+    this->id = -1;
+    if(!getName(name, right.canonicalUrl())){
+        name.clear();
+    }
+    this->size = right.canonicalResource().dataSize();
+    return *this;
+}
+
 bool SongHeader::operator ==(const SongHeader& right){
     return this->name == right.name && this->size == right.size;
 }
 
-unsigned int SongHeader::getSize() const{
-    QByteArray size;
-    QDataStream stream(size);
-    stream << id << name << this->size;
-    return size.size();
+bool SongHeader::operator ==(const QMediaContent& right){
+    QString name;
+    if(!getName(name, right.canonicalUrl())){
+        return false;
+    }
+    return this->name == name && this->size == right.canonicalResource().dataSize();
 }
 
 bool SongHeader::isNameValid() const{
@@ -58,50 +81,6 @@ QDataStream& operator >> (QDataStream& stream, SongHeader& song){
     return stream;
 }
 
-SongStorage::SongStorage():
-    SongHeader()
-{
-    url.clear();
-}
-
-SongStorage::SongStorage(const SongHeader& from)
-    :SongStorage::SongStorage()
-{
-    this->id = from.id;
-    this->name = from.name;
-    this->size = from.size;
-}
-
-unsigned int SongStorage::getSize() const{
-    return SongHeader::getSize();
-}
-
-const QUrl& SongStorage::getSource()const{
-    return url;
-}
-
-QMediaContent SongStorage::toMedia()const{
-    return QMediaContent(url);
-}
-
-bool SongStorage::isValid() const{
-
-    return SongHeader::isValid() && url.isValid();
-}
-
-SongStorage::~SongStorage(){}
-
-QDataStream& operator << (QDataStream& stream,const SongStorage& song){
-    stream << static_cast<const SongHeader&>(song);
-    stream << song.url;
-    return stream;
-}
-
-QDataStream& operator >> (QDataStream& stream, SongStorage& song){
-    stream >> static_cast<SongHeader&>(song);
-    stream >> song.url;
-    return stream;
-}
 
 Song::Song():
     SongHeader()
@@ -121,10 +100,6 @@ void Song::clear(){
     source.clear();
 }
 
-unsigned int Song::getSize() const{
-    return SongHeader::getSize() + source.size();
-}
-
 const QByteArray& Song::getSource()const{
     return source;
 }
diff --git a/sync/song.h b/sync/song.h
index eaeb5c5..bd4acb8 100644
--- a/sync/song.h
+++ b/sync/song.h
@@ -25,7 +25,8 @@ struct Syncer
  * (id,size and name)
  */
 class SongHeader{
-
+protected:
+    bool getName(QString &name, const QUrl& url)const;
 public:
     bool isSelected;
     int id;
@@ -33,8 +34,10 @@ public:
     int size;
     SongHeader();
     SongHeader& operator = (const SongHeader& right);
+    SongHeader& operator = (const QMediaContent& right);
+
     bool operator == (const SongHeader& right);
-    virtual unsigned int getSize() const;
+    bool operator == (const QMediaContent& right);
     bool isNameValid() const;
     virtual bool isValid() const;
     virtual ~SongHeader();
@@ -62,7 +65,6 @@ public:
     SongStorage(const SongHeader& from);
     const QUrl& getSource()const;
     QMediaContent toMedia()const;
-    unsigned int getSize() const;
     bool isValid() const;
     ~SongStorage();
     friend QDataStream& operator << (QDataStream& stream, const SongStorage& song);
@@ -82,7 +84,6 @@ public:
     Song(const SongHeader& from);
     void clear();
     const QByteArray& getSource()const;
-    unsigned int getSize() const;
     bool isValid() const;
     ~Song();
     friend QDataStream& operator << (QDataStream& stream, const Song& song);
diff --git a/sync/sync.h b/sync/sync.h
index 62eb1cd..a3acf93 100644
--- a/sync/sync.h
+++ b/sync/sync.h
@@ -6,6 +6,7 @@
 #include <chrono>
 #include "config.h"
 #include "mysql.h"
+#include <QMediaPlaylist>
 #include "player.h"
 
 namespace syncLib {
@@ -27,7 +28,7 @@ class Sync : public QObject
 private:
     Node *node;
     Player *player;
-    QList<SongHeader> playList;
+    QMediaPlaylist playList;
     QString lastUsedPlayList;
     int currentSongIndex;
     QList<ETcpSocket*> servers;