Imported more functionality from old db classes to new models.
authorMikko Keinänen <mikko.keinanen@gmail.com>
Thu, 16 Dec 2010 21:52:45 +0000 (23:52 +0200)
committerMikko Keinänen <mikko.keinanen@gmail.com>
Thu, 16 Dec 2010 21:52:45 +0000 (23:52 +0200)
12 files changed:
src/dialogs/mediaimagepathmaindialog.cpp
src/mainwindow.cpp
src/models/filemodel.cpp
src/models/filemodel.h
src/models/mediaimagecontainermodel.cpp
src/models/mediaimagecontainermodel.h
src/models/mediaimagemodel.cpp
src/models/mediaimagemodel.h
src/utils/fileutil.cpp
src/utils/fileutil.h
src/views/filepatheditview.cpp
src/views/filepatheditview.h

index 54b07f6..6b59f68 100644 (file)
@@ -97,7 +97,7 @@ void MediaImagePathMainDialog::beginScanFilePath()
         progressDialog->show();
 
         setUIEnabled(false);
-        int count = fileUtil->scanFilePath(fpo, l, dbMediaImageContainer, progressDialog);
+        int count = fileUtil->scanFilePath(fpo, l, progressDialog);
         progressDialog->hide();
 
         QMessageBox msgBox;
index 987361b..4a72a1a 100644 (file)
@@ -402,7 +402,7 @@ bool MainWindow::testDB(bool reset)
             else throw EmuFrontException("The current database is not compatible!"
                                          " Cannot continue.");
         }
-
+    
         if (reset) {
             createDB();
         }
index 73d6add..5183932 100644 (file)
@@ -57,3 +57,30 @@ EmuFrontObject* FileModel::recordToDataObject(const QSqlRecord *record)
     int type = record->value(File_FileType).toInt();
     return new EmuFrontFile(id, name, checksum, size, type);
 }
+
+/* Returns id of inserted data item after succesful insert, -1 if insert failed */
+int FileModel::insertDataObject(const EmuFrontFile *fi)
+{
+    QSqlQuery q;
+    q.prepare("INSERT INTO file "
+              "(id, name, type, checksum, size, updatetime) "
+              "VALUES (NULL, :name, :type, :checksum, :size, :updatetime)");
+    q.bindValue(":name", fi->getName());
+    q.bindValue(":type", fi->getType());
+    q.bindValue(":checksum", fi->getCheckSum());
+    q.bindValue(":size", fi->getSize());
+    q.bindValue(":updatetime", getCurrentTimeStamp());
+    int id = -1;
+    if (q.exec())
+        id = q.lastInsertId().toInt();
+    return id;
+}
+
+bool FileModel::deleteDataObject(int id) const
+{
+    QSqlQuery q;
+    q.prepare(QString("DELETE FROM file WHERE id=:id"));
+    q.bindValue(":id", id);
+    return q.exec();
+}
+
index 313b502..a0fe5db 100644 (file)
@@ -24,6 +24,8 @@
 
 #include "emufrontquerymodel.h"
 
+class EmuFrontFile;
+
 class FileModel : public EmuFrontQueryModel
 {
     Q_OBJECT
@@ -43,6 +45,8 @@ protected:
     // Implemented for EmuFrontQueryModel:
     virtual EmuFrontObject* recordToDataObject(const QSqlRecord* );
     virtual QString constructFilterById(int id) const;
+    virtual int insertDataObject(const EmuFrontFile *ob);
+    bool deleteDataObject(int id) const;
 };
 
 #endif // FILEMODEL_H
index d26a8f8..905be13 100644 (file)
 #include "mediaimagecontainermodel.h"
 #include "filepathmodel.h"
 #include "mediaimagemodel.h"
+#include "emufrontexception.h"
 #include <QtSql>
 
 MediaImageContainerModel::MediaImageContainerModel(QObject *parent) :
-    EmuFrontQueryModel(parent)
+    FileModel(parent)
 {
 }
 
@@ -102,3 +103,125 @@ void MediaImageContainerModel::filterBySetup(int setupId)
     filters.append(QString("setup.id = %1").arg(setupId));
     filterDataObjects(filters);
 }
+
+bool MediaImageContainerModel::removeFromFilePath(int filePathId) const
+{
+    QSqlQuery q;
+    q.prepare("DELETE FROM mediaimagecontainer_filepath "
+        "WHERE filepathid=:filepathid");
+    q.bindValue(":filepathid", filePathId);
+    return q.exec();
+}
+
+void MediaImageContainerModel::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
+{
+    foreach(MediaImageContainer *mic, lst) {
+        int micFileId = storeMediaImageContainer(mic);
+    }
+}
+
+int MediaImageContainerModel::storeMediaImageContainer(EmuFrontObject *efo)
+{
+    MediaImageContainer *mic
+        = dynamic_cast<MediaImageContainer *>(efo);
+
+    if (!mic->getFilePath())
+        throw EmuFrontException("Cannot install media image "
+            "container to database without a file path object!");
+
+    // multiple media image containers with matching checksum will be stored
+    //       if each instance is in a different file path
+
+    int fileId = -1;
+    QMap<QString, EmuFrontObject*> images = mic->getMediaImages();
+    MediaImageModel miModel;
+    QList<int> ids = miModel.storeMediaImages(images);
+
+    //qDebug() << "Stored " << ids.count() << " media images.";
+
+    if (ids.count() <= 0)
+        return -1;
+
+    /* Contained Media images successfully stored to db,
+        storing media image container also */
+
+    try {
+
+        // Insert MediaImageContainer first as a EmuFrontFile object to file table.
+
+        // File id is used to store the media image container instance to database,
+        // file id is also the media image container id
+
+        // TODO: if this fails, the remove the media images in ids
+        fileId = insertDataObject(mic);
+
+        //qDebug() << "Inserted media image container to file table with id " << fileId << ".";
+
+        if (fileId < 0) {
+            // TODO: note we most surely need to catch the exception
+            // in the calling code block and clean
+            // all the media image and ...containers from
+            // the memory!
+            throw EmuFrontException(
+                    QString(tr("Inserting media image container %1 to file database failed"))
+                    .arg(mic->getName()));
+        }
+
+        mic->setId(fileId);
+
+        if (!linkMediaImageContainerToPath(mic)){
+            deleteDataObject(fileId);
+            throw EmuFrontException("Failed inserting media image to database!");
+        }
+        //qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
+        linkMediaImagesWithContainer(fileId, images.values());
+        //qDebug() << "Linked media image container with media images.";
+    } catch (EmuFrontException e) {
+        miModel.removeOrphanedMediaImages(ids);
+        throw e;
+    }
+
+    return fileId;
+}
+
+/* Throws EmuFrontException */
+void MediaImageContainerModel::linkMediaImagesWithContainer(int micId, QList<EmuFrontObject*> mediaImages)
+{
+    if (micId < 0 || mediaImages.count() <= 0)
+        return;
+
+    MediaImage *mi = 0;
+    foreach(EmuFrontObject *efo, mediaImages) {
+        mi = dynamic_cast<MediaImage*>(efo);
+        /*qDebug() << "Linking media image container " << micId
+            << " to media image " << mi->getId()  << ", " << mi->getName() << ".";*/
+        if (!linkMediaImageToMediaImageContainer(mi, micId)) {
+                throw EmuFrontException(QString("Failed linking media "
+                                                    "image container %1 to a media image %2").arg(micId).arg(mi->getId()));
+        }
+    }
+}
+
+bool MediaImageContainerModel::linkMediaImageContainerToPath(const MediaImageContainer *mic) const
+{
+    QSqlQuery q;
+    q.prepare("INSERT INTO mediaimagecontainer_filepath "
+              "(fileid, filepathid, updatetime) "
+              "VALUES (:fileid, :filepathid, :updatetime)");
+    q.bindValue(":fileid", mic->getId());
+    q.bindValue(":filepathid", mic->getFilePath()->getId());
+    q.bindValue(":updatetime", getCurrentTimeStamp());
+    return q.exec();
+}
+
+bool MediaImageContainerModel::linkMediaImageToMediaImageContainer(const MediaImage *mi, int micId) const
+{
+    QSqlQuery q;
+    q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
+        "(mediaimagecontainerid, mediaimageid) "
+        "VALUES (:micid, :miid) ");
+    q.bindValue(":micid", micId);
+    q.bindValue(":miid", mi->getId());
+    return q.exec();
+}
+
index cda6504..726be17 100644 (file)
 #ifndef MEDIAIMAGECONTAINERMODEL_H
 #define MEDIAIMAGECONTAINERMODEL_H
 
-#include "emufrontquerymodel.h"
+#include "filemodel.h"
 
-class MediaImageContainerModel : public EmuFrontQueryModel
+class MediaImage;
+class MediaImageContainer;
+class FilePathObject;
+
+class MediaImageContainerModel : public FileModel
 {
     Q_OBJECT
 public:
     MediaImageContainerModel(QObject *parent = 0);
     void filterBySetup(int setupId);
+    void storeContainers(QList<MediaImageContainer*>, FilePathObject*);
+    bool removeFromFilePath(int filePathId) const;
     enum {
         MIC_FileId,
         MIC_FileName,
@@ -50,6 +56,11 @@ protected:
     // Implemented for EmuFrontQueryModel:
     virtual EmuFrontObject* recordToDataObject(const QSqlRecord* );
     virtual QString constructFilterById(int id) const;
+private:
+    int storeMediaImageContainer(EmuFrontObject *efo);
+    void linkMediaImagesWithContainer(int, QList<EmuFrontObject*>);
+    bool linkMediaImageContainerToPath(const MediaImageContainer*) const;
+    bool linkMediaImageToMediaImageContainer(const MediaImage*, int micId) const;
 };
 
 #endif // MEDIAIMAGECONTAINERMODEL_H
index feb4246..7dd2572 100644 (file)
@@ -55,3 +55,38 @@ QMap<QString, EmuFrontObject*> MediaImageModel::getMediaImages(int micId)
     }
     return list;
 }
+
+/* Stores a list of media images to the database.
+   Returns a list of media image id corresponding to the given list of media
+   images inserted to the database or already in the database.
+*/
+QList<int> MediaImageModel::storeMediaImages(QMap<QString, EmuFrontObject*> images)
+{
+    QList<int> ids  = QList<int>();
+    QMapIterator<QString, EmuFrontObject*> it(images);
+    MediaImage *mi = 0;
+    while(it.hasNext())
+    {
+        it.next();
+        mi = dynamic_cast<MediaImage*>(it.value());
+        int id = insertDataObject(mi);
+        if (id < 0) {
+            // TODO: Build an error message of failed inserts
+            qDebug() << "Failed inserting media image" << mi->getName();
+        }
+        else if (id >= 0) {
+            ids.append(id);
+            mi->setId(id);
+        }
+    }
+    return ids;
+}
+
+void MediaImageModel::removeOrphanedMediaImages(QList<int> ids)
+{
+    // TODO
+    // go through the list of media image ids,
+    // if the media image with curr id doesn't have a container, delete it
+}
+
+
index 0610949..b41abfb 100644 (file)
@@ -31,6 +31,8 @@ class MediaImageModel : public FileModel
 public:
     MediaImageModel(QObject *parent = 0);
     QMap<QString, EmuFrontObject*> getMediaImages(int id);
+    QList<int> storeMediaImages(QMap<QString, EmuFrontObject*> images);
+    void removeOrphanedMediaImages(QList<int> ids);
 
 protected:
     //virtual void refresh();
index d07ea38..22ed34c 100644 (file)
@@ -18,6 +18,7 @@
 ** You should have received a copy of the GNU General Public License
 ** along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
 */
+
 #include <QDir>
 #include <QDebug>
 #include <QProcess>
@@ -30,7 +31,7 @@
 #include "mediaimagecontainer.h"
 #include "mediatype.h"
 #include "platform.h"
-#include "dbmediaimagecontainer.h"
+#include "mediaimagecontainermodel.h"
 #include "unziphelper.h"
 
 FileUtil::FileUtil(QObject *parent) : QObject(parent)
@@ -45,9 +46,7 @@ FileUtil::~FileUtil()
 }
 
 /* Throws EmuFrontException */
-int FileUtil::scanFilePath(FilePathObject *fp,
-    QStringList filters, DbMediaImageContainer *dbMic,
-    QProgressDialog *progressDialog)
+int FileUtil::scanFilePath(FilePathObject *fp, QStringList filters, QProgressDialog *progressDialog)
 {
     if (!fp->getSetup()){
         throw EmuFrontException(tr("Setup not available with %1.").arg(fp->getName()));
@@ -61,6 +60,11 @@ int FileUtil::scanFilePath(FilePathObject *fp,
             .arg(fp->getSetup()->getName()));
     }
 
+    MediaImageContainerModel micModel;
+
+    // Remove old instances scanned from this file path
+    micModel.removeFromFilePath(fp->getId());
+
     int count = 0;
     /*qDebug() << QString("We have a platform %1, media type %2")
         .arg(fp->getSetup()->getPlatform()->getName())
@@ -111,7 +115,7 @@ int FileUtil::scanFilePath(FilePathObject *fp,
                 if (containers.count() >= MIC_BUFFER_SIZE)  {
                     //qDebug() << "We have " << containers.count() << " containers .. storing to db.";
                     showDbUpdating(progressDialog);
-                    dbMic->storeContainers(containers, fp);
+                    micModel.storeContainers(containers, fp);
                     hideDbUpdating(progressDialog);
                     qDeleteAll(containers);
                     containers.clear();
@@ -128,7 +132,7 @@ int FileUtil::scanFilePath(FilePathObject *fp,
             //qDebug() << "Storing the rest " << containers.count() << " containers.";
             //emit dbUpdateInProgress();
             showDbUpdating(progressDialog);
-            dbMic->storeContainers(containers, fp);
+            micModel.storeContainers(containers, fp);
             hideDbUpdating(progressDialog);
             //emit dbUpdateFinished();
             qDeleteAll(containers);
index 42fe083..b79dbfb 100644 (file)
@@ -17,7 +17,9 @@
 **
 ** You should have received a copy of the GNU General Public License
 ** along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
-*/#ifndef FILEUTIL_H
+*/
+
+#ifndef FILEUTIL_H
 #define FILEUTIL_H
 
 #include <QObject>
@@ -39,7 +41,7 @@ class FileUtil : public QObject
 public:
     FileUtil(QObject *parent);
     ~FileUtil();
-    int scanFilePath(FilePathObject *fpo, const QStringList filters, DbMediaImageContainer *mic, QProgressDialog *);
+    int scanFilePath(FilePathObject *fpo, const QStringList filters, QProgressDialog *);
 signals:
     void dbUpdateInProgress();
     void dbUpdateFinished();
index 24504ed..ebdce64 100644 (file)
 ** You should have received a copy of the GNU General Public License
 ** along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
 */
+
 #include "filepatheditview.h"
 #include "filepathmodel.h"
 #include "fileutil.h"
 #include "setupmodel.h"
 #include "comboboxdelegate.h"
 #include "filesystembrowsedelegate.h"
-#include "dbmediaimagecontainer.h"
 #include <QtGui>
 
 FilePathEditView::FilePathEditView(QWidget *parent) :
@@ -35,8 +35,6 @@ FilePathEditView::FilePathEditView(QWidget *parent) :
     fileUtil = new FileUtil(this);
     initProgressDialog();
 
-    dbMediaImageContainer = new DbMediaImageContainer(this);
-
     model = new FilePathModel(this);
     objectList->setModel(model);
     SetupModel *stupMdl = new SetupModel(this);
@@ -74,6 +72,7 @@ void FilePathEditView::beginScanFilePath()
     if (QMessageBox::question(this,
         tr("Confirm"),
         tr("Do you want to continue? "
+        "Re-scanning file path removes old entries for selected path. "
         "If you have tons of huge files this may take even hours! "
         "If you are low on battery power, consider carefully!"),
         QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::No)
@@ -90,13 +89,9 @@ void FilePathEditView::beginScanFilePath()
         QStringList l;
         l << "*.zip"; // TODO set filters in a global constant class
 
-        // Remove old instances scanned from this file path
-        dbMediaImageContainer->removeFromFilePath(fpo->getId());
-
         progressDialog->show();
-
         //setUIEnabled(false);
-        int count = fileUtil->scanFilePath(fpo, l, dbMediaImageContainer, progressDialog);
+        int count = fileUtil->scanFilePath(fpo, l, progressDialog);
         progressDialog->hide();
 
         QMessageBox msgBox;
index db199f6..695f0c0 100644 (file)
@@ -18,6 +18,7 @@
 ** You should have received a copy of the GNU General Public License
 ** along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
 */
+
 #ifndef FILEPATHEDITVIEW_H
 #define FILEPATHEDITVIEW_H
 
@@ -25,7 +26,6 @@
 
 class FileUtil;
 class QProgressDialog;
-class DbMediaImageContainer;
 
 class FilePathEditView : public EmuFrontEditView
 {
@@ -42,7 +42,6 @@ private slots:
 private:
     QPushButton* scanButton;
     FileUtil *fileUtil;
-    DbMediaImageContainer *dbMediaImageContainer;
     QProgressDialog *progressDialog;
     void scanFilePath(const QString path, const QStringList filters);
     void initProgressDialog();