Data filtering changes.
[emufront] / src / db / dbmediaimagecontainer.cpp
index 8888ade..dab5472 100644 (file)
 // along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <QDebug>
+#include <QSqlRecord>
+#include <QSqlQuery>
+#include <QSqlRelationalTableModel>
+#include <QSqlError>
 #include "dbmediaimagecontainer.h"
 
 DbMediaImageContainer::DbMediaImageContainer(QObject *parent)
-    : DbQueryModelManager(parent)
+    : DbFile(parent) // DbQueryModelManager(parent)
 {
     dbMediaImage = new DbMediaImage(parent);
+    //dbFile = new DbFile(parent);
 }
 
 bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
@@ -32,10 +37,77 @@ bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
     return false;
 }
 
-bool DbMediaImageContainer::insertDataObjectToModel(const EmuFrontObject *efo)
+int DbMediaImageContainer::insertDataObjectToModel(const EmuFrontObject *efo)
 {
-    // TODO
-    return false;
+    const MediaImageContainer *mic
+        = dynamic_cast<const MediaImageContainer *>(efo);
+
+    // check if this media image container is already in the database
+    EmuFrontObject *o = getFileByChecksum(mic->getCheckSum());
+    int fileId = o ? o->getId() : -1;
+    /*int fileId = getMediaImageContainer(mic->getCheckSum());*/
+    if (fileId >= 0) {
+        qDebug() << "Media image container already in db with id " << fileId << ".";
+        return fileId;
+   }
+
+    if (!mic->getFilePath())
+        throw new EmuFrontException("Cannot install media image "
+            "container to database without a file path object!");
+
+    QList<MediaImage*> images = mic->getMediaImages();
+    QList<int> ids = dbMediaImage->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
+        fileId = DbFile::insertDataObjectToModel(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 new EmuFrontException(
+                    QString(tr("Inserting media image container %1 to file database failed"))
+                    .arg(mic->getName()));
+        }
+
+        // Insert to mediaimagecontainer table
+
+        QSqlQuery q;
+        q.prepare("INSERT INTO mediaimagecontainer "
+                  "(fileid, filepathid, updatetime) "
+                  "VALUES (:fileid, :filepathid, :updatetime)");
+        q.bindValue(":fileid", fileId);
+        q.bindValue(":filepathid", mic->getFilePath()->getId());
+        q.bindValue(":updatetime", DatabaseManager::getCurrentTimeStamp());
+        if (!q.exec()){
+            DbFile::deleteDataObject(fileId);
+            throw new EmuFrontException("Failed inserting media image to database!");
+        }
+        qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
+        linkMediaImagesWithContainer(fileId, ids);
+        qDebug() << "Linked media image container with media images.";
+    } catch (EmuFrontException e) {
+        dbMediaImage->removeOrphanedMediaImages(ids);
+        throw e;
+    }
+
+    return fileId;
 }
 
 bool DbMediaImageContainer::deleteDataObjectFromModel(QModelIndex *i)
@@ -52,54 +124,100 @@ int DbMediaImageContainer::countDataObjectRefs(int id) const
 
 QString DbMediaImageContainer::constructSelect(QString whereClause) const
 {
-    // TODO
+    // TODO, for a usual search we need a "light" version of this select
+    // and MediaImageContainer (only id, name)
+    /*
+        SELECT file.id, file.name, file.checksum, file.size,
+            filepath.id, filepath.name,
+            setup.id,
+            platform.id, platform.name,
+            mediatype.id, mediatype.name
+        FROM mediaimagecontainer
+        INNER JOIN file ON mediaimagecontainer.fileid = file.id
+        INNER JOIN filepath ON mediaimagecontainer.filepathid = filepath.id
+        INNER JOIN setup ON filepath.setupid = setup.id
+        INNER JOIN platform ON setup.platformid = platform.id
+        INNER JOIN mediatype ON setup.mediatypeid = mediatype.id
+        */
     return "";
+    //return DbFile::constructSelect(whereClause);
+}
+
+QString DbMediaImageContainer::constructFilterById(int id) const
+{
+    return DbFile::constructFilterById(id);
 }
 
 QString DbMediaImageContainer::constructSelectById(int id) const
 {
-    // TODO
-    return "";
+    return DbFile::constructSelectById(id);
 }
 
-EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *)
+EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *rec)
 {
-    // TODO
-    return 0;
+    return DbFile::recordToDataObject(rec);
 }
 
 QSqlQueryModel* DbMediaImageContainer::getData()
 {
-    // TODO
-    return 0;
+    return DbFile::getData();
 }
 
+/* Returns the id of a media image container with a given cheksum or -1 if not found */
 int DbMediaImageContainer::getMediaImageContainer(QString checksum) const
 {
-    // TODO
-    return -1;
+    QSqlQuery q;
+    q.prepare("SELECT id FROM file WHERE checksum=:checksum");
+    q.bindValue(":checksum", checksum);
+    int id = -1;
+    if (q.next())
+        id = q.value(0).toInt();
+    return id;
 }
 
-void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst)
+
+/**
+* Stores media image containers, including the media images included
+* to database.
+*/
+void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
 {
     qDebug() << "Storing media image containers to database.";
     foreach(MediaImageContainer *mic, lst)
     {
         qDebug() << "Media image container " << mic->getName();
-        QList<MediaImage*> images = mic->getMediaImages();
-        if (getMediaImageContainer(mic->getCheckSum()) >= 0)
-            continue;
-        // this is a new media image container, lets build a list
-        // of media image id's for this container
-        QList<int> ids = dbMediaImage->storeMediaImages(images);
+        int micFileId = insertDataObjectToModel(mic);
+    }
+}
 
-        if (ids.count() > 0)
-        {
-            // store media image to id
+void DbMediaImageContainer::linkMediaImagesWithContainer(int micId, QList<int> miIds)
+{
+    if (micId < 0 || miIds.count() <= 0)
+        return;
 
-            // get last insert id of stored media image
+    QSqlQuery q;
+    q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
+        "(mediaimagecontainerid, mediaimageid) "
+        "VALUES (:micid, :miid) ");
+    q.bindValue(":micid", micId);
 
-            // link all the ids in ids-list to media image id
+    foreach(int miid, miIds) {
+        qDebug() << "Linking media image container " << micId << " to media image " << miid  << ".";
+        q.bindValue(":miid", miid);
+        if (!q.exec()) {
+            throw new EmuFrontException(QString("Failed linking media "
+                "image container %1 to a media image %2").arg(micId).arg(miid));
         }
     }
 }
+
+void DbMediaImageContainer::filter(int mediaTypeId, int platformId)
+{
+    QList<QString> filters;
+    if (mediaTypeId >= 0)
+        filters.append(QString("mediatype.id=%1").arg(mediaTypeId));
+    if (platformId >= 0)
+        filters.append(QString("platform.id=%1").arg(platformId));
+    filterDataObjects(filters);
+}
+