3 ** Copyright 2010 Mikko Keinänen
5 ** This file is part of EmuFront.
8 ** EmuFront is free software: you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License version 2 as published by
10 ** the Free Software Foundation and appearing in the file gpl.txt included in the
11 ** packaging of this file.
13 ** EmuFront is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
18 ** You should have received a copy of the GNU General Public License
19 ** along with EmuFront. If not, see <http://www.gnu.org/licenses/>.
24 #include <QSqlRelationalTableModel>
26 #include "dbmediaimagecontainer.h"
27 #include "dbmediaimage.h"
28 //#include "dbsetup.h"
29 #include "dbfilepath.h"
31 DbMediaImageContainer::DbMediaImageContainer(QObject *parent)
34 dbMediaImage = new DbMediaImage(parent);
35 dbFilePath = new DbFilePath(parent);
36 tableName = DbMediaImageContainer::DB_TABLE_MEDIAIMAGECONTAINER;
39 bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
45 /* Throws EmuFrontException */
46 int DbMediaImageContainer::storeMediaImageContainer(EmuFrontObject *efo)
48 MediaImageContainer *mic
49 = dynamic_cast<MediaImageContainer *>(efo);
51 if (!mic->getFilePath())
52 throw EmuFrontException("Cannot install media image "
53 "container to database without a file path object!");
55 // multiple media image containers with matching checksum will be stored
56 // if each instance is in a different file path
59 QMap<QString, EmuFrontObject*> images = mic->getMediaImages();
60 QList<int> ids = dbMediaImage->storeMediaImages(images);
62 //qDebug() << "Stored " << ids.count() << " media images.";
67 /* Contained Media images successfully stored to db,
68 storing media image container also */
72 // Insert MediaImageContainer first as a EmuFrontFile object to file table.
74 // File id is used to store the media image container instance to database,
75 // file id is also the media image container id
77 // TODO: if this fails, the remove the media images in ids
78 fileId = insertDataObjectToModel(mic);
80 //qDebug() << "Inserted media image container to file table with id " << fileId << ".";
83 // TODO: note we most surely need to catch the exception
84 // in the calling code block and clean
85 // all the media image and ...containers from
87 throw EmuFrontException(
88 QString(tr("Inserting media image container %1 to file database failed"))
89 .arg(mic->getName()));
94 if (!linkMediaImageContainerToPath(mic)){
95 DbFile::deleteDataObject(fileId);
96 throw EmuFrontException("Failed inserting media image to database!");
98 //qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
99 linkMediaImagesWithContainer(fileId, images.values());
100 //qDebug() << "Linked media image container with media images.";
101 } catch (EmuFrontException e) {
102 dbMediaImage->removeOrphanedMediaImages(ids);
109 bool DbMediaImageContainer::deleteDataObjectFromModel(QModelIndex *i)
115 QString DbMediaImageContainer::constructSelect(QString whereClause) const
117 // TODO, for a usual search we need a "light" version of this select
118 // and MediaImageContainer (only id, name)
119 QString select = QString("SELECT file.id, file.name, file.checksum, file.size, "
120 " filepath.id, filepath.name, "
122 " platform.id, platform.name, "
123 " mediatype.id, mediatype.name "
125 "INNER JOIN mediaimagecontainer_filepath ON mediaimagecontainer_filepath.fileid = file.id "
126 "INNER JOIN filepath ON mediaimagecontainer_filepath.filepathid = filepath.id "
127 "INNER JOIN setup ON filepath.setupid = setup.id "
128 "INNER JOIN platform ON setup.platformid = platform.id "
129 "INNER JOIN mediatype ON setup.mediatypeid = mediatype.id "
131 "ORDER BY file.name").arg(whereClause);
132 //qDebug() << select;
136 QString DbMediaImageContainer::constructFilterById(int id) const
138 return QString("file.id = %1").arg(id);
141 QString DbMediaImageContainer::constructSelectById(int id) const
143 return constructSelect(
144 QString("WHERE %1").arg(constructFilterById(id))
148 /* Throws EmuFrontException */
149 EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *rec)
152 MediaImageContainer *mic = 0;
153 if (!rec) return mic;
154 int id = rec->value(MIC_FileId).toInt();
155 QString name = rec->value(MIC_FileName).toString();
156 QString checksum = rec->value(MIC_FileCheckSum).toString();
157 int size = rec->value(MIC_FileSize).toInt();
158 int fpId = rec->value(MIC_FilePathId).toInt();
160 = dynamic_cast<FilePathObject*>(dbFilePath->getDataObject(fpId)); /* Throws EmuFrontException */
161 //int supId = rec->value(MIC_SetupId).toInt();
162 //Setup *sup = dbSetup->getDataObject(supId)
163 QMap<QString, EmuFrontObject*> images = dbMediaImage->getMediaImages(id);
165 mic = new MediaImageContainer(
166 id, name, checksum, size, images, fpo
171 QSqlQueryModel* DbMediaImageContainer::getData()
173 QSqlQueryModel *model = new QSqlQueryModel(this);
175 model->setQuery(sqlTableModel->query());
178 model->setQuery(constructSelect());
179 model->setHeaderData(MIC_FileId, Qt::Horizontal, tr("File id"));
180 model->setHeaderData(MIC_FileName, Qt::Horizontal, tr("File Name"));
181 model->setHeaderData(MIC_FileCheckSum, Qt::Horizontal, tr("File checksum"));
182 model->setHeaderData(MIC_FileSize, Qt::Horizontal, tr("File Size"));
183 model->setHeaderData(MIC_FilePathId, Qt::Horizontal, tr("File path id"));
184 model->setHeaderData(MIC_FilePathName, Qt::Horizontal, tr("File path name"));
185 model->setHeaderData(MIC_SetupId, Qt::Horizontal, tr("Setup id"));
186 model->setHeaderData(MIC_PlatformId, Qt::Horizontal, tr("Platform id"));
187 model->setHeaderData(MIC_PlatformName, Qt::Horizontal, tr("Platform name"));
188 model->setHeaderData(MIC_MediaTypeId, Qt::Horizontal, tr("Media type id"));
189 model->setHeaderData(MIC_MediaTypeName, Qt::Horizontal, tr("Media type name"));
193 /* Returns the id of a media image container with a given cheksum or -1 if not found */
194 int DbMediaImageContainer::getMediaImageContainer(QString checksum) const
197 q.prepare("SELECT id FROM file WHERE checksum=:checksum");
198 q.bindValue(":checksum", checksum);
201 id = q.value(0).toInt();
207 * Stores media image containers, including the media images included
210 * Throws EmuFrontException
212 void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
214 foreach(MediaImageContainer *mic, lst)
216 //qDebug() << "Media image container " << mic->getName();
217 int micFileId = storeMediaImageContainer(mic);
221 /* Throws EmuFrontException */
222 void DbMediaImageContainer::linkMediaImagesWithContainer(int micId, QList<EmuFrontObject*> mediaImages)
224 if (micId < 0 || mediaImages.count() <= 0)
228 foreach(EmuFrontObject *efo, mediaImages) {
229 mi = dynamic_cast<MediaImage*>(efo);
230 /*qDebug() << "Linking media image container " << micId
231 << " to media image " << mi->getId() << ", " << mi->getName() << ".";*/
232 if (!linkMediaImageToMediaImageContainer(mi, micId)) {
233 throw EmuFrontException(QString("Failed linking media "
234 "image container %1 to a media image %2").arg(micId).arg(mi->getId()));
239 void DbMediaImageContainer::filter(int mediaTypeId, int platformId)
241 /*qDebug() << "Filtering media images with media type " << mediaTypeId
242 << " and platform " << platformId;*/
243 QList<QString> filters;
244 if (mediaTypeId >= 0)
245 filters.append(QString("mediatype.id=%1").arg(mediaTypeId));
247 filters.append(QString("platform.id=%1").arg(platformId));
248 filterDataObjects(filters);
251 QString DbMediaImageContainer::getCountRefsSelect(int id) const
253 /* we need to count file references to give media image container */
255 select count(*) from mediaimagecontainer
256 INNER JOIN mediaimagecontainer_mediaimage
257 ON mediaimagecontainer_mediaimage.mediaimagecontainerid
258 = mediaimagecontainer.fileid
259 WHERE mediaimagecontainer.fileid=589;
261 return QString("SELECT count(*) FROM mediaimagecontainer "
262 "INNER JOIN mediaimagecontainer_mediaimage "
263 "ON mediaimagecontainer_mediaimage.mediaimagecontainerid "
264 " =mediaimagecontainer.fileid "
265 "WHERE mediaimagecontainer.fileid=%1").arg(id);
268 QString DbMediaImageContainer::getDeleteObjectSql() const
270 // The trigger will take care of deleting
271 // the reference from the mediaimagecontainer
272 // and mediaimage_mediaimagecontainer tables.
273 // there is also a trigger that will delete
274 // all the files linked to mediaimagecontainer
275 // using mediaimage_mediaimagecontainer (the actual
277 return QString("DELETE FROM file WHERE id=:id");
280 /* Throws EmuFrontException */
281 EmuFrontObject* DbMediaImageContainer::getMediaImageContainerByChecksum(QString checksum)
283 return getDataObject(QString("file.checksum LIKE '%1'").arg(checksum));
286 bool DbMediaImageContainer::linkMediaImageContainerToPath(const MediaImageContainer *mic) const
289 q.prepare("INSERT INTO mediaimagecontainer_filepath "
290 "(fileid, filepathid, updatetime) "
291 "VALUES (:fileid, :filepathid, :updatetime)");
292 q.bindValue(":fileid", mic->getId());
293 q.bindValue(":filepathid", mic->getFilePath()->getId());
294 q.bindValue(":updatetime", DatabaseManager::getCurrentTimeStamp());
298 bool DbMediaImageContainer::linkMediaImageToMediaImageContainer(const MediaImage *mi, int micId) const
301 q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
302 "(mediaimagecontainerid, mediaimageid) "
303 "VALUES (:micid, :miid) ");
304 q.bindValue(":micid", micId);
305 q.bindValue(":miid", mi->getId());
309 bool DbMediaImageContainer::removeFromFilePath(int filePathId) const
312 q.prepare("DELETE FROM mediaimagecontainer_filepath "
313 "WHERE filepathid=:filepathid");
314 q.bindValue(":filepathid", filePathId);