2 // Copyright 2010 Mikko Keinänen
4 // This file is part of EmuFront.
7 // EmuFront is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as published by
9 // the Free Software Foundation and appearing in the file gpl.txt included in the
10 // packaging of this file.
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.
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/>.
23 #include <QSqlRelationalTableModel>
25 #include "dbmediaimagecontainer.h"
26 #include "dbmediaimage.h"
27 //#include "dbsetup.h"
28 #include "dbfilepath.h"
30 DbMediaImageContainer::DbMediaImageContainer(QObject *parent)
33 dbMediaImage = new DbMediaImage(parent);
34 dbFilePath = new DbFilePath(parent);
35 tableName = DbMediaImageContainer::DB_TABLE_MEDIAIMAGECONTAINER;
38 bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
44 /* Throws EmuFrontException */
45 int DbMediaImageContainer::storeMediaImageContainer(EmuFrontObject *efo)
47 MediaImageContainer *mic
48 = dynamic_cast<MediaImageContainer *>(efo);
50 if (!mic->getFilePath())
51 throw EmuFrontException("Cannot install media image "
52 "container to database without a file path object!");
54 // multiple media image containers with matching checksum will be stored
55 // if each instance is in a different file path
58 QMap<QString, EmuFrontObject*> images = mic->getMediaImages();
59 QList<int> ids = dbMediaImage->storeMediaImages(images);
61 //qDebug() << "Stored " << ids.count() << " media images.";
66 /* Contained Media images successfully stored to db,
67 storing media image container also */
71 // Insert MediaImageContainer first as a EmuFrontFile object to file table.
73 // File id is used to store the media image container instance to database,
74 // file id is also the media image container id
76 // TODO: if this fails, the remove the media images in ids
77 fileId = insertDataObjectToModel(mic);
79 //qDebug() << "Inserted media image container to file table with id " << fileId << ".";
82 // TODO: note we most surely need to catch the exception
83 // in the calling code block and clean
84 // all the media image and ...containers from
86 throw EmuFrontException(
87 QString(tr("Inserting media image container %1 to file database failed"))
88 .arg(mic->getName()));
93 if (!linkMediaImageContainerToPath(mic)){
94 DbFile::deleteDataObject(fileId);
95 throw EmuFrontException("Failed inserting media image to database!");
97 //qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
98 linkMediaImagesWithContainer(fileId, images.values());
99 //qDebug() << "Linked media image container with media images.";
100 } catch (EmuFrontException e) {
101 dbMediaImage->removeOrphanedMediaImages(ids);
108 bool DbMediaImageContainer::deleteDataObjectFromModel(QModelIndex *i)
114 QString DbMediaImageContainer::constructSelect(QString whereClause) const
116 // TODO, for a usual search we need a "light" version of this select
117 // and MediaImageContainer (only id, name)
118 QString select = QString("SELECT file.id, file.name, file.checksum, file.size, "
119 " filepath.id, filepath.name, "
121 " platform.id, platform.name, "
122 " mediatype.id, mediatype.name "
124 "INNER JOIN mediaimagecontainer_filepath ON mediaimagecontainer_filepath.fileid = file.id "
125 "INNER JOIN filepath ON mediaimagecontainer_filepath.filepathid = filepath.id "
126 "INNER JOIN setup ON filepath.setupid = setup.id "
127 "INNER JOIN platform ON setup.platformid = platform.id "
128 "INNER JOIN mediatype ON setup.mediatypeid = mediatype.id "
130 "ORDER BY file.name").arg(whereClause);
131 //qDebug() << select;
135 QString DbMediaImageContainer::constructFilterById(int id) const
137 return QString("file.id = %1").arg(id);
140 QString DbMediaImageContainer::constructSelectById(int id) const
142 return constructSelect(
143 QString("WHERE %1").arg(constructFilterById(id))
147 /* Throws EmuFrontException */
148 EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *rec)
151 MediaImageContainer *mic = 0;
152 if (!rec) return mic;
153 int id = rec->value(MIC_FileId).toInt();
154 QString name = rec->value(MIC_FileName).toString();
155 QString checksum = rec->value(MIC_FileCheckSum).toString();
156 int size = rec->value(MIC_FileSize).toInt();
157 int fpId = rec->value(MIC_FilePathId).toInt();
159 = dynamic_cast<FilePathObject*>(dbFilePath->getDataObject(fpId)); /* Throws EmuFrontException */
160 //int supId = rec->value(MIC_SetupId).toInt();
161 //Setup *sup = dbSetup->getDataObject(supId)
162 QMap<QString, EmuFrontObject*> images = dbMediaImage->getMediaImages(id);
164 mic = new MediaImageContainer(
165 id, name, checksum, size, images, fpo
170 QSqlQueryModel* DbMediaImageContainer::getData()
172 QSqlQueryModel *model = new QSqlQueryModel(this);
174 model->setQuery(sqlTableModel->query());
177 model->setQuery(constructSelect());
178 model->setHeaderData(MIC_FileId, Qt::Horizontal, tr("File id"));
179 model->setHeaderData(MIC_FileName, Qt::Horizontal, tr("File Name"));
180 model->setHeaderData(MIC_FileCheckSum, Qt::Horizontal, tr("File checksum"));
181 model->setHeaderData(MIC_FileSize, Qt::Horizontal, tr("File Size"));
182 model->setHeaderData(MIC_FilePathId, Qt::Horizontal, tr("File path id"));
183 model->setHeaderData(MIC_FilePathName, Qt::Horizontal, tr("File path name"));
184 model->setHeaderData(MIC_SetupId, Qt::Horizontal, tr("Setup id"));
185 model->setHeaderData(MIC_PlatformId, Qt::Horizontal, tr("Platform id"));
186 model->setHeaderData(MIC_PlatformName, Qt::Horizontal, tr("Platform name"));
187 model->setHeaderData(MIC_MediaTypeId, Qt::Horizontal, tr("Media type id"));
188 model->setHeaderData(MIC_MediaTypeName, Qt::Horizontal, tr("Media type name"));
192 /* Returns the id of a media image container with a given cheksum or -1 if not found */
193 int DbMediaImageContainer::getMediaImageContainer(QString checksum) const
196 q.prepare("SELECT id FROM file WHERE checksum=:checksum");
197 q.bindValue(":checksum", checksum);
200 id = q.value(0).toInt();
206 * Stores media image containers, including the media images included
209 * Throws EmuFrontException
211 void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
213 foreach(MediaImageContainer *mic, lst)
215 //qDebug() << "Media image container " << mic->getName();
216 int micFileId = storeMediaImageContainer(mic);
220 /* Throws EmuFrontException */
221 void DbMediaImageContainer::linkMediaImagesWithContainer(int micId, QList<EmuFrontObject*> mediaImages)
223 if (micId < 0 || mediaImages.count() <= 0)
227 foreach(EmuFrontObject *efo, mediaImages) {
228 mi = dynamic_cast<MediaImage*>(efo);
229 /*qDebug() << "Linking media image container " << micId
230 << " to media image " << mi->getId() << ", " << mi->getName() << ".";*/
231 if (!linkMediaImageToMediaImageContainer(mi, micId)) {
232 throw EmuFrontException(QString("Failed linking media "
233 "image container %1 to a media image %2").arg(micId).arg(mi->getId()));
238 void DbMediaImageContainer::filter(int mediaTypeId, int platformId)
240 /*qDebug() << "Filtering media images with media type " << mediaTypeId
241 << " and platform " << platformId;*/
242 QList<QString> filters;
243 if (mediaTypeId >= 0)
244 filters.append(QString("mediatype.id=%1").arg(mediaTypeId));
246 filters.append(QString("platform.id=%1").arg(platformId));
247 filterDataObjects(filters);
250 QString DbMediaImageContainer::getCountRefsSelect(int id) const
252 /* we need to count file references to give media image container */
254 select count(*) from mediaimagecontainer
255 INNER JOIN mediaimagecontainer_mediaimage
256 ON mediaimagecontainer_mediaimage.mediaimagecontainerid
257 = mediaimagecontainer.fileid
258 WHERE mediaimagecontainer.fileid=589;
260 return QString("SELECT count(*) FROM mediaimagecontainer "
261 "INNER JOIN mediaimagecontainer_mediaimage "
262 "ON mediaimagecontainer_mediaimage.mediaimagecontainerid "
263 " =mediaimagecontainer.fileid "
264 "WHERE mediaimagecontainer.fileid=%1").arg(id);
267 QString DbMediaImageContainer::getDeleteObjectSql() const
269 // The trigger will take care of deleting
270 // the reference from the mediaimagecontainer
271 // and mediaimage_mediaimagecontainer tables.
272 // there is also a trigger that will delete
273 // all the files linked to mediaimagecontainer
274 // using mediaimage_mediaimagecontainer (the actual
276 return QString("DELETE FROM file WHERE id=:id");
279 /* Throws EmuFrontException */
280 EmuFrontObject* DbMediaImageContainer::getMediaImageContainerByChecksum(QString checksum)
282 return getDataObject(QString("file.checksum LIKE '%1'").arg(checksum));
285 bool DbMediaImageContainer::linkMediaImageContainerToPath(const MediaImageContainer *mic) const
288 q.prepare("INSERT INTO mediaimagecontainer_filepath "
289 "(fileid, filepathid, updatetime) "
290 "VALUES (:fileid, :filepathid, :updatetime)");
291 q.bindValue(":fileid", mic->getId());
292 q.bindValue(":filepathid", mic->getFilePath()->getId());
293 q.bindValue(":updatetime", DatabaseManager::getCurrentTimeStamp());
297 bool DbMediaImageContainer::linkMediaImageToMediaImageContainer(const MediaImage *mi, int micId) const
300 q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
301 "(mediaimagecontainerid, mediaimageid) "
302 "VALUES (:micid, :miid) ");
303 q.bindValue(":micid", micId);
304 q.bindValue(":miid", mi->getId());
308 bool DbMediaImageContainer::removeFromFilePath(int filePathId) const
311 q.prepare("DELETE FROM mediaimagecontainer_filepath "
312 "WHERE filepathid=:filepathid");
313 q.bindValue(":filepathid", filePathId);