progressDialog->show();
setUIEnabled(false);
- int count = fileUtil->scanFilePath(fpo, l, dbMediaImageContainer, progressDialog);
+ int count = fileUtil->scanFilePath(fpo, l, progressDialog);
progressDialog->hide();
QMessageBox msgBox;
else throw EmuFrontException("The current database is not compatible!"
" Cannot continue.");
}
-
+
if (reset) {
createDB();
}
int type = record->value(File_FileType).toInt();
return new EmuFrontFile(id, name, checksum, size, type);
}
+
+/* Returns id of inserted data item after succesful insert, -1 if insert failed */
+int FileModel::insertDataObject(const EmuFrontFile *fi)
+{
+ QSqlQuery q;
+ q.prepare("INSERT INTO file "
+ "(id, name, type, checksum, size, updatetime) "
+ "VALUES (NULL, :name, :type, :checksum, :size, :updatetime)");
+ q.bindValue(":name", fi->getName());
+ q.bindValue(":type", fi->getType());
+ q.bindValue(":checksum", fi->getCheckSum());
+ q.bindValue(":size", fi->getSize());
+ q.bindValue(":updatetime", getCurrentTimeStamp());
+ int id = -1;
+ if (q.exec())
+ id = q.lastInsertId().toInt();
+ return id;
+}
+
+bool FileModel::deleteDataObject(int id) const
+{
+ QSqlQuery q;
+ q.prepare(QString("DELETE FROM file WHERE id=:id"));
+ q.bindValue(":id", id);
+ return q.exec();
+}
+
#include "emufrontquerymodel.h"
+class EmuFrontFile;
+
class FileModel : public EmuFrontQueryModel
{
Q_OBJECT
// Implemented for EmuFrontQueryModel:
virtual EmuFrontObject* recordToDataObject(const QSqlRecord* );
virtual QString constructFilterById(int id) const;
+ virtual int insertDataObject(const EmuFrontFile *ob);
+ bool deleteDataObject(int id) const;
};
#endif // FILEMODEL_H
#include "mediaimagecontainermodel.h"
#include "filepathmodel.h"
#include "mediaimagemodel.h"
+#include "emufrontexception.h"
#include <QtSql>
MediaImageContainerModel::MediaImageContainerModel(QObject *parent) :
- EmuFrontQueryModel(parent)
+ FileModel(parent)
{
}
filters.append(QString("setup.id = %1").arg(setupId));
filterDataObjects(filters);
}
+
+bool MediaImageContainerModel::removeFromFilePath(int filePathId) const
+{
+ QSqlQuery q;
+ q.prepare("DELETE FROM mediaimagecontainer_filepath "
+ "WHERE filepathid=:filepathid");
+ q.bindValue(":filepathid", filePathId);
+ return q.exec();
+}
+
+void MediaImageContainerModel::storeContainers(QList<MediaImageContainer *> lst, FilePathObject *fpo)
+{
+ foreach(MediaImageContainer *mic, lst) {
+ int micFileId = storeMediaImageContainer(mic);
+ }
+}
+
+int MediaImageContainerModel::storeMediaImageContainer(EmuFrontObject *efo)
+{
+ MediaImageContainer *mic
+ = dynamic_cast<MediaImageContainer *>(efo);
+
+ if (!mic->getFilePath())
+ throw EmuFrontException("Cannot install media image "
+ "container to database without a file path object!");
+
+ // multiple media image containers with matching checksum will be stored
+ // if each instance is in a different file path
+
+ int fileId = -1;
+ QMap<QString, EmuFrontObject*> images = mic->getMediaImages();
+ MediaImageModel miModel;
+ QList<int> ids = miModel.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
+
+ // TODO: if this fails, the remove the media images in ids
+ fileId = insertDataObject(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 EmuFrontException(
+ QString(tr("Inserting media image container %1 to file database failed"))
+ .arg(mic->getName()));
+ }
+
+ mic->setId(fileId);
+
+ if (!linkMediaImageContainerToPath(mic)){
+ deleteDataObject(fileId);
+ throw EmuFrontException("Failed inserting media image to database!");
+ }
+ //qDebug() << "Inserted media image container " << fileId << " to mediaimagecontainer table.";
+ linkMediaImagesWithContainer(fileId, images.values());
+ //qDebug() << "Linked media image container with media images.";
+ } catch (EmuFrontException e) {
+ miModel.removeOrphanedMediaImages(ids);
+ throw e;
+ }
+
+ return fileId;
+}
+
+/* Throws EmuFrontException */
+void MediaImageContainerModel::linkMediaImagesWithContainer(int micId, QList<EmuFrontObject*> mediaImages)
+{
+ if (micId < 0 || mediaImages.count() <= 0)
+ return;
+
+ MediaImage *mi = 0;
+ foreach(EmuFrontObject *efo, mediaImages) {
+ mi = dynamic_cast<MediaImage*>(efo);
+ /*qDebug() << "Linking media image container " << micId
+ << " to media image " << mi->getId() << ", " << mi->getName() << ".";*/
+ if (!linkMediaImageToMediaImageContainer(mi, micId)) {
+ throw EmuFrontException(QString("Failed linking media "
+ "image container %1 to a media image %2").arg(micId).arg(mi->getId()));
+ }
+ }
+}
+
+bool MediaImageContainerModel::linkMediaImageContainerToPath(const MediaImageContainer *mic) const
+{
+ QSqlQuery q;
+ q.prepare("INSERT INTO mediaimagecontainer_filepath "
+ "(fileid, filepathid, updatetime) "
+ "VALUES (:fileid, :filepathid, :updatetime)");
+ q.bindValue(":fileid", mic->getId());
+ q.bindValue(":filepathid", mic->getFilePath()->getId());
+ q.bindValue(":updatetime", getCurrentTimeStamp());
+ return q.exec();
+}
+
+bool MediaImageContainerModel::linkMediaImageToMediaImageContainer(const MediaImage *mi, int micId) const
+{
+ QSqlQuery q;
+ q.prepare("INSERT INTO mediaimagecontainer_mediaimage "
+ "(mediaimagecontainerid, mediaimageid) "
+ "VALUES (:micid, :miid) ");
+ q.bindValue(":micid", micId);
+ q.bindValue(":miid", mi->getId());
+ return q.exec();
+}
+
#ifndef MEDIAIMAGECONTAINERMODEL_H
#define MEDIAIMAGECONTAINERMODEL_H
-#include "emufrontquerymodel.h"
+#include "filemodel.h"
-class MediaImageContainerModel : public EmuFrontQueryModel
+class MediaImage;
+class MediaImageContainer;
+class FilePathObject;
+
+class MediaImageContainerModel : public FileModel
{
Q_OBJECT
public:
MediaImageContainerModel(QObject *parent = 0);
void filterBySetup(int setupId);
+ void storeContainers(QList<MediaImageContainer*>, FilePathObject*);
+ bool removeFromFilePath(int filePathId) const;
enum {
MIC_FileId,
MIC_FileName,
// Implemented for EmuFrontQueryModel:
virtual EmuFrontObject* recordToDataObject(const QSqlRecord* );
virtual QString constructFilterById(int id) const;
+private:
+ int storeMediaImageContainer(EmuFrontObject *efo);
+ void linkMediaImagesWithContainer(int, QList<EmuFrontObject*>);
+ bool linkMediaImageContainerToPath(const MediaImageContainer*) const;
+ bool linkMediaImageToMediaImageContainer(const MediaImage*, int micId) const;
};
#endif // MEDIAIMAGECONTAINERMODEL_H
}
return list;
}
+
+/* Stores a list of media images to the database.
+ Returns a list of media image id corresponding to the given list of media
+ images inserted to the database or already in the database.
+*/
+QList<int> MediaImageModel::storeMediaImages(QMap<QString, EmuFrontObject*> images)
+{
+ QList<int> ids = QList<int>();
+ QMapIterator<QString, EmuFrontObject*> it(images);
+ MediaImage *mi = 0;
+ while(it.hasNext())
+ {
+ it.next();
+ mi = dynamic_cast<MediaImage*>(it.value());
+ int id = insertDataObject(mi);
+ if (id < 0) {
+ // TODO: Build an error message of failed inserts
+ qDebug() << "Failed inserting media image" << mi->getName();
+ }
+ else if (id >= 0) {
+ ids.append(id);
+ mi->setId(id);
+ }
+ }
+ return ids;
+}
+
+void MediaImageModel::removeOrphanedMediaImages(QList<int> ids)
+{
+ // TODO
+ // go through the list of media image ids,
+ // if the media image with curr id doesn't have a container, delete it
+}
+
+
public:
MediaImageModel(QObject *parent = 0);
QMap<QString, EmuFrontObject*> getMediaImages(int id);
+ QList<int> storeMediaImages(QMap<QString, EmuFrontObject*> images);
+ void removeOrphanedMediaImages(QList<int> ids);
protected:
//virtual void refresh();
** You should have received a copy of the GNU General Public License
** along with EmuFront. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include <QDir>
#include <QDebug>
#include <QProcess>
#include "mediaimagecontainer.h"
#include "mediatype.h"
#include "platform.h"
-#include "dbmediaimagecontainer.h"
+#include "mediaimagecontainermodel.h"
#include "unziphelper.h"
FileUtil::FileUtil(QObject *parent) : QObject(parent)
}
/* Throws EmuFrontException */
-int FileUtil::scanFilePath(FilePathObject *fp,
- QStringList filters, DbMediaImageContainer *dbMic,
- QProgressDialog *progressDialog)
+int FileUtil::scanFilePath(FilePathObject *fp, QStringList filters, QProgressDialog *progressDialog)
{
if (!fp->getSetup()){
throw EmuFrontException(tr("Setup not available with %1.").arg(fp->getName()));
.arg(fp->getSetup()->getName()));
}
+ MediaImageContainerModel micModel;
+
+ // Remove old instances scanned from this file path
+ micModel.removeFromFilePath(fp->getId());
+
int count = 0;
/*qDebug() << QString("We have a platform %1, media type %2")
.arg(fp->getSetup()->getPlatform()->getName())
if (containers.count() >= MIC_BUFFER_SIZE) {
//qDebug() << "We have " << containers.count() << " containers .. storing to db.";
showDbUpdating(progressDialog);
- dbMic->storeContainers(containers, fp);
+ micModel.storeContainers(containers, fp);
hideDbUpdating(progressDialog);
qDeleteAll(containers);
containers.clear();
//qDebug() << "Storing the rest " << containers.count() << " containers.";
//emit dbUpdateInProgress();
showDbUpdating(progressDialog);
- dbMic->storeContainers(containers, fp);
+ micModel.storeContainers(containers, fp);
hideDbUpdating(progressDialog);
//emit dbUpdateFinished();
qDeleteAll(containers);
**
** You should have received a copy of the GNU General Public License
** along with EmuFront. If not, see <http://www.gnu.org/licenses/>.
-*/#ifndef FILEUTIL_H
+*/
+
+#ifndef FILEUTIL_H
#define FILEUTIL_H
#include <QObject>
public:
FileUtil(QObject *parent);
~FileUtil();
- int scanFilePath(FilePathObject *fpo, const QStringList filters, DbMediaImageContainer *mic, QProgressDialog *);
+ int scanFilePath(FilePathObject *fpo, const QStringList filters, QProgressDialog *);
signals:
void dbUpdateInProgress();
void dbUpdateFinished();
** You should have received a copy of the GNU General Public License
** along with EmuFront. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "filepatheditview.h"
#include "filepathmodel.h"
#include "fileutil.h"
#include "setupmodel.h"
#include "comboboxdelegate.h"
#include "filesystembrowsedelegate.h"
-#include "dbmediaimagecontainer.h"
#include <QtGui>
FilePathEditView::FilePathEditView(QWidget *parent) :
fileUtil = new FileUtil(this);
initProgressDialog();
- dbMediaImageContainer = new DbMediaImageContainer(this);
-
model = new FilePathModel(this);
objectList->setModel(model);
SetupModel *stupMdl = new SetupModel(this);
if (QMessageBox::question(this,
tr("Confirm"),
tr("Do you want to continue? "
+ "Re-scanning file path removes old entries for selected path. "
"If you have tons of huge files this may take even hours! "
"If you are low on battery power, consider carefully!"),
QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::No)
QStringList l;
l << "*.zip"; // TODO set filters in a global constant class
- // Remove old instances scanned from this file path
- dbMediaImageContainer->removeFromFilePath(fpo->getId());
-
progressDialog->show();
-
//setUIEnabled(false);
- int count = fileUtil->scanFilePath(fpo, l, dbMediaImageContainer, progressDialog);
+ int count = fileUtil->scanFilePath(fpo, l, progressDialog);
progressDialog->hide();
QMessageBox msgBox;
** You should have received a copy of the GNU General Public License
** along with EmuFront. If not, see <http://www.gnu.org/licenses/>.
*/
+
#ifndef FILEPATHEDITVIEW_H
#define FILEPATHEDITVIEW_H
class FileUtil;
class QProgressDialog;
-class DbMediaImageContainer;
class FilePathEditView : public EmuFrontEditView
{
private:
QPushButton* scanButton;
FileUtil *fileUtil;
- DbMediaImageContainer *dbMediaImageContainer;
QProgressDialog *progressDialog;
void scanFilePath(const QString path, const QStringList filters);
void initProgressDialog();