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"
31 DbMediaImageContainer::DbMediaImageContainer(QObject *parent)
32 : DbFile(parent) // DbQueryModelManager(parent)
34 dbMediaImage = new DbMediaImage(parent);
35 dbFilePath = new DbFilePath(parent);
36 tableName = DbMediaImageContainer::DB_TABLE_MEDIAIMAGECONTAINER;
37 //dbFile = new DbFile(parent);
40 bool DbMediaImageContainer::updateDataObjectToModel(const EmuFrontObject *efo)
46 int DbMediaImageContainer::insertDataObjectToModel(const EmuFrontObject *efo)
48 const MediaImageContainer *mic
49 = dynamic_cast<const MediaImageContainer *>(efo);
51 if (!mic->getFilePath())
52 throw new EmuFrontException("Cannot install media image "
53 "container to database without a file path object!");
55 // check if this media image container is already in the database
57 // Two possible solutions:
58 // * multiple media image containers with matching checksum will not be stored at all
59 // (only the first instance will be stored)
60 // * multiple media image containers with matching checksum will be stored
61 // if each instance is in a different file path
63 EmuFrontObject *o = getFileByChecksum(mic->getCheckSum());
64 int fileId = o ? o->getId() : -1;
66 // ok, we have a matching file, we could still create a new media image instance to the database
67 qDebug() << "Media image container already in db with id " << fileId << ".";
72 QMap<QString, EmuFrontObject*> images = mic->getMediaImages();
73 QList<int> ids = dbMediaImage->storeMediaImages(images);
75 qDebug() << "Stored " << ids.count() << " media images.";
80 /* Contained Media images successfully stored to db,
81 storing media image container also */
85 // Insert MediaImageContainer first as a EmuFrontFile object to file table.
87 // File id is used to store the media image container instance to database,
88 // file id is also the media image container id
89 fileId = DbFile::insertDataObjectToModel(mic);
91 qDebug() << "Inserted media image container to file table with id " << fileId << ".";
94 // TODO: note we most surely need to catch the exception
95 // in the calling code block and clean
96 // all the media image and ...containers from
98 throw new EmuFrontException(
99 QString(tr("Inserting media image container %1 to file database failed"))
100 .arg(mic->getName()));
103 // Insert to mediaimagecontainer table
106 q.prepare("INSERT INTO mediaimagecontainer "
107 "(fileid, filepathid, updatetime) "
108 "VALUES (:fileid, :filepathid, :updatetime)");
109 q.bindValue(":fileid", fileId);
110 q.bindValue(":filepathid", mic->getFilePath()->getId());
111 q.bindValue(":updatetime", DatabaseManager::getCurrentTimeStamp());
113 DbFile::deleteDataObject(fileId);
114 throw new EmuFrontException("Failed inserting media image to database!");
116 qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
117 linkMediaImagesWithContainer(fileId, ids);
118 qDebug() << "Linked media image container with media images.";
119 } catch (EmuFrontException e) {
120 dbMediaImage->removeOrphanedMediaImages(ids);
127 bool DbMediaImageContainer::deleteDataObjectFromModel(QModelIndex *i)
133 QString DbMediaImageContainer::constructSelect(QString whereClause) const
135 // TODO, for a usual search we need a "light" version of this select
136 // and MediaImageContainer (only id, name)
137 QString select = QString("SELECT file.id, file.name, file.checksum, file.size, "
138 " filepath.id, filepath.name, "
140 " platform.id, platform.name, "
141 " mediatype.id, mediatype.name "
142 "FROM mediaimagecontainer "
143 "INNER JOIN file ON mediaimagecontainer.fileid = file.id "
144 "INNER JOIN filepath ON mediaimagecontainer.filepathid = filepath.id "
145 "INNER JOIN setup ON filepath.setupid = setup.id "
146 "INNER JOIN platform ON setup.platformid = platform.id "
147 "INNER JOIN mediatype ON setup.mediatypeid = mediatype.id "
149 "ORDER BY file.name").arg(whereClause);
154 QString DbMediaImageContainer::constructFilterById(int id) const
156 return QString("file.id = %1").arg(id);
159 QString DbMediaImageContainer::constructSelectById(int id) const
161 return constructSelect(
162 QString("WHERE %1").arg(constructFilterById(id))
166 EmuFrontObject* DbMediaImageContainer::recordToDataObject(const QSqlRecord *rec)
169 MediaImageContainer *mic = 0;
170 if (!rec) return mic;
171 int id = rec->value(MIC_FileId).toInt();
172 QString name = rec->value(MIC_FileName).toString();
173 QString checksum = rec->value(MIC_FileCheckSum).toString();
174 int size = rec->value(MIC_FileSize).toInt();
175 int fpId = rec->value(MIC_FilePathId).toInt();
177 = dynamic_cast<FilePathObject*>(dbFilePath->getDataObject(fpId));
178 //int supId = rec->value(MIC_SetupId).toInt();
179 //Setup *sup = dbSetup->getDataObject(supId)
180 QMap<QString, EmuFrontObject*> images = dbMediaImage->getMediaImages(id);
182 mic = new MediaImageContainer(
183 id, name, checksum, size, images, fpo
188 QSqlQueryModel* DbMediaImageContainer::getData()
190 QSqlQueryModel *model = new QSqlQueryModel(this);
192 model->setQuery(sqlTableModel->query());
195 model->setQuery(constructSelect());
196 model->setHeaderData(MIC_FileId, Qt::Horizontal, tr("File id"));
197 model->setHeaderData(MIC_FileName, Qt::Horizontal, tr("File Name"));
198 model->setHeaderData(MIC_FileCheckSum, Qt::Horizontal, tr("File checksum"));
199 model->setHeaderData(MIC_FileSize, Qt::Horizontal, tr("File Size"));
200 model->setHeaderData(MIC_FilePathId, Qt::Horizontal, tr("File path id"));
201 model->setHeaderData(MIC_FilePathName, Qt::Horizontal, tr("File path name"));
202 model->setHeaderData(MIC_SetupId, Qt::Horizontal, tr("Setup id"));
203 model->setHeaderData(MIC_PlatformId, Qt::Horizontal, tr("Platform id"));
204 model->setHeaderData(MIC_PlatformName, Qt::Horizontal, tr("Platform name"));
205 model->setHeaderData(MIC_MediaTypeId, Qt::Horizontal, tr("Media type id"));
206 model->setHeaderData(MIC_MediaTypeName, Qt::Horizontal, tr("Media type name"));
210 /* Returns the id of a media image container with a given cheksum or -1 if not found */
211 int DbMediaImageContainer::getMediaImageContainer(QString checksum) const
214 q.prepare("SELECT id FROM file WHERE checksum=:checksum");
215 q.bindValue(":checksum", checksum);
218 id = q.value(0).toInt();
224 * Stores media image containers, including the media images included
227 void DbMediaImageContainer::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
229 qDebug() << "Storing media image containers to database.";
230 foreach(MediaImageContainer *mic, lst)
232 qDebug() << "Media image container " << mic->getName();
233 int micFileId = insertDataObjectToModel(mic);
237 void DbMediaImageContainer::linkMediaImagesWithContainer(int micId, QList<int> miIds)
239 if (micId < 0 || miIds.count() <= 0)
243 q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
244 "(mediaimagecontainerid, mediaimageid) "
245 "VALUES (:micid, :miid) ");
246 q.bindValue(":micid", micId);
248 foreach(int miid, miIds) {
249 qDebug() << "Linking media image container " << micId << " to media image " << miid << ".";
250 q.bindValue(":miid", miid);
252 throw new EmuFrontException(QString("Failed linking media "
253 "image container %1 to a media image %2").arg(micId).arg(miid));
258 void DbMediaImageContainer::filter(int mediaTypeId, int platformId)
260 qDebug() << "Filtering media images with media type " << mediaTypeId
261 << " and platform " << platformId;
262 QList<QString> filters;
263 if (mediaTypeId >= 0)
264 filters.append(QString("mediatype.id=%1").arg(mediaTypeId));
266 filters.append(QString("platform.id=%1").arg(platformId));
267 filterDataObjects(filters);
270 QString DbMediaImageContainer::getCountRefsSelect(int id) const
272 /* we need to count file references to give media image container */
274 select count(*) from mediaimagecontainer
275 INNER JOIN mediaimagecontainer_mediaimage
276 ON mediaimagecontainer_mediaimage.mediaimagecontainerid
277 = mediaimagecontainer.fileid
278 WHERE mediaimagecontainer.fileid=589;
280 return QString("SELECT count(*) FROM mediaimagecontainer "
281 "INNER JOIN mediaimagecontainer_mediaimage "
282 "ON mediaimagecontainer_mediaimage.mediaimagecontainerid "
283 " =mediaimagecontainer.fileid "
284 "WHERE mediaimagecontainer.fileid=%1").arg(id);
287 QString DbMediaImageContainer::getDeleteObjectSql() const
289 // The trigger will take care of deleting
290 // the reference from the mediaimagecontainer
291 // and mediaimage_mediaimagecontainer tables.
292 // there is also a trigger that will delete
293 // all the files linked to mediaimagecontainer
294 // using mediaimage_mediaimagecontainer (the actual
296 return QString("DELETE FROM file WHERE id=:id");