b09aea89910bdda25dc7177d5e14a27fda8bc493
[emufront] / src / db / dbmediaimagecontainer.cpp
1 // EmuFront
2 // Copyright 2010 Mikko Keinänen
3 //
4 // This file is part of EmuFront.
5 //
6 //
7 // EmuFront is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // EmuFront is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
19
20 #include <QDebug>
21 #include <QSqlRecord>
22 #include <QSqlQuery>
23 #include <QSqlRelationalTableModel>
24 #include <QSqlError>
25 #include "dbmediaimagecontainer.h"
26
27 DbMediaImageContainer::DbMediaImageContainer(QObject *parent)
28     : DbFile(parent) // DbQueryModelManager(parent)
29 {
30     dbMediaImage = new DbMediaImage(parent);
31     //dbFile = new DbFile(parent);
32 }
33
34 bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
35 {
36     // TODO
37     return false;
38 }
39
40 int DbMediaImageContainer::insertDataObjectToModel(const EmuFrontObject *efo)
41 {
42     const MediaImageContainer *mic
43         = dynamic_cast<const MediaImageContainer *>(efo);
44
45     // check if this media image container is already in the database
46     EmuFrontObject *o = getFileByChecksum(mic->getCheckSum());
47     int fileId = o ? o->getId() : -1;
48     /*int fileId = getMediaImageContainer(mic->getCheckSum());*/
49     if (fileId >= 0) {
50         qDebug() << "Media image container already in db with id " << fileId << ".";
51         return fileId;
52    }
53
54     if (!mic->getFilePath())
55         throw new EmuFrontException("Cannot install media image "
56             "container to database without a file path object!");
57
58     QList<MediaImage*> images = mic->getMediaImages();
59     QList<int> ids = dbMediaImage->storeMediaImages(images);
60
61     qDebug() << "Stored " << ids.count() << " media images.";
62
63     if (ids.count() <= 0)
64         return -1;
65
66     /* Contained Media images successfully stored to db,
67         storing media image container also */
68
69     try {
70
71         // Insert MediaImageContainer first as a EmuFrontFile object to file table.
72
73         // File id is used to store the media image container instance to database,
74         // file id is also the media image container id
75         fileId = DbFile::insertDataObjectToModel(mic);
76
77         qDebug() << "Inserted media image container to file table with id " << fileId << ".";
78
79         if (fileId < 0) {
80             // TODO: note we most surely need to catch the exception
81             // in the calling code block and clean
82             // all the media image and ...containers from
83             // the memory!
84             throw new EmuFrontException(
85                     QString(tr("Inserting media image container %1 to file database failed"))
86                     .arg(mic->getName()));
87         }
88
89         // Insert to mediaimagecontainer table
90
91         QSqlQuery q;
92         q.prepare("INSERT INTO mediaimagecontainer "
93                   "(fileid, filepathid, updatetime) "
94                   "VALUES (:fileid, :filepathid, :updatetime)");
95         q.bindValue(":fileid", fileId);
96         q.bindValue(":filepathid", mic->getFilePath()->getId());
97         q.bindValue(":updatetime", DatabaseManager::getCurrentTimeStamp());
98         if (!q.exec()){
99             DbFile::deleteDataObject(fileId);
100             throw new EmuFrontException("Failed inserting media image to database!");
101         }
102         qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
103         linkMediaImagesWithContainer(fileId, ids);
104         qDebug() << "Linked media image container with media images.";
105     } catch (EmuFrontException e) {
106         dbMediaImage->removeOrphanedMediaImages(ids);
107         throw e;
108     }
109
110     return fileId;
111 }
112
113 bool DbMediaImageContainer::deleteDataObjectFromModel(QModelIndex *i)
114 {
115     // TODO
116     return false;
117 }
118
119 int DbMediaImageContainer::countDataObjectRefs(int id) const
120 {
121     // TODO
122     return -1;
123 }
124
125 QString DbMediaImageContainer::constructSelect(QString whereClause) const
126 {
127     // TODO, for a usual search we need a "light" version of this select
128     // and MediaImageContainer (only id, name)
129     return QString("SELECT file.id, file.name, file.checksum, file.size, "
130                 "        filepath.id, filepath.name, "
131                 "        setup.id, "
132                 "        platform.id, platform.name, "
133                 "        mediatype.id, mediatype.name "
134                 "FROM mediaimagecontainer "
135                 "INNER JOIN file ON mediaimagecontainer.fileid = file.id "
136                 "INNER JOIN filepath ON mediaimagecontainer.filepathid = filepath.id "
137                 "INNER JOIN setup ON filepath.setupid = setup.id "
138                 "INNER JOIN platform ON setup.platformid = platform.id "
139                 "INNER JOIN mediatype ON setup.mediatypeid = mediatype.id "
140                 "%1 "
141                 "ORDER BY file.name").arg(whereClause);
142 }
143
144 QString DbMediaImageContainer::constructFilterById(int id) const
145 {
146     return DbFile::constructFilterById(id);
147 }
148
149 QString DbMediaImageContainer::constructSelectById(int id) const
150 {
151     return DbFile::constructSelectById(id);
152 }
153
154 EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *rec)
155 {
156     return DbFile::recordToDataObject(rec);
157 }
158
159 QSqlQueryModel* DbMediaImageContainer::getData()
160 {
161     return DbFile::getData();
162 }
163
164 /* Returns the id of a media image container with a given cheksum or -1 if not found */
165 int DbMediaImageContainer::getMediaImageContainer(QString checksum) const
166 {
167     QSqlQuery q;
168     q.prepare("SELECT id FROM file WHERE checksum=:checksum");
169     q.bindValue(":checksum", checksum);
170     int id = -1;
171     if (q.next())
172         id = q.value(0).toInt();
173     return id;
174 }
175
176
177 /**
178 * Stores media image containers, including the media images included
179 * to database.
180 */
181 void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
182 {
183     qDebug() << "Storing media image containers to database.";
184     foreach(MediaImageContainer *mic, lst)
185     {
186         qDebug() << "Media image container " << mic->getName();
187         int micFileId = insertDataObjectToModel(mic);
188     }
189 }
190
191 void DbMediaImageContainer::linkMediaImagesWithContainer(int micId, QList<int> miIds)
192 {
193     if (micId < 0 || miIds.count() <= 0)
194         return;
195
196     QSqlQuery q;
197     q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
198         "(mediaimagecontainerid, mediaimageid) "
199         "VALUES (:micid, :miid) ");
200     q.bindValue(":micid", micId);
201
202     foreach(int miid, miIds) {
203         qDebug() << "Linking media image container " << micId << " to media image " << miid  << ".";
204         q.bindValue(":miid", miid);
205         if (!q.exec()) {
206             throw new EmuFrontException(QString("Failed linking media "
207                 "image container %1 to a media image %2").arg(micId).arg(miid));
208         }
209     }
210 }
211
212 void DbMediaImageContainer::filter(int mediaTypeId, int platformId)
213 {
214     QList<QString> filters;
215     if (mediaTypeId >= 0)
216         filters.append(QString("mediatype.id=%1").arg(mediaTypeId));
217     if (platformId >= 0)
218         filters.append(QString("platform.id=%1").arg(platformId));
219     filterDataObjects(filters);
220 }
221