From: Mikko Keinänen Date: Thu, 16 Dec 2010 21:52:45 +0000 (+0200) Subject: Imported more functionality from old db classes to new models. X-Git-Url: http://git.maemo.org/git/?p=emufront;a=commitdiff_plain;h=dd907588e885611b73077c0d7b70a468ab3b157f Imported more functionality from old db classes to new models. --- diff --git a/src/dialogs/mediaimagepathmaindialog.cpp b/src/dialogs/mediaimagepathmaindialog.cpp index 54b07f6..6b59f68 100644 --- a/src/dialogs/mediaimagepathmaindialog.cpp +++ b/src/dialogs/mediaimagepathmaindialog.cpp @@ -97,7 +97,7 @@ void MediaImagePathMainDialog::beginScanFilePath() progressDialog->show(); setUIEnabled(false); - int count = fileUtil->scanFilePath(fpo, l, dbMediaImageContainer, progressDialog); + int count = fileUtil->scanFilePath(fpo, l, progressDialog); progressDialog->hide(); QMessageBox msgBox; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 987361b..4a72a1a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -402,7 +402,7 @@ bool MainWindow::testDB(bool reset) else throw EmuFrontException("The current database is not compatible!" " Cannot continue."); } - + if (reset) { createDB(); } diff --git a/src/models/filemodel.cpp b/src/models/filemodel.cpp index 73d6add..5183932 100644 --- a/src/models/filemodel.cpp +++ b/src/models/filemodel.cpp @@ -57,3 +57,30 @@ EmuFrontObject* FileModel::recordToDataObject(const QSqlRecord *record) 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(); +} + diff --git a/src/models/filemodel.h b/src/models/filemodel.h index 313b502..a0fe5db 100644 --- a/src/models/filemodel.h +++ b/src/models/filemodel.h @@ -24,6 +24,8 @@ #include "emufrontquerymodel.h" +class EmuFrontFile; + class FileModel : public EmuFrontQueryModel { Q_OBJECT @@ -43,6 +45,8 @@ protected: // 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 diff --git a/src/models/mediaimagecontainermodel.cpp b/src/models/mediaimagecontainermodel.cpp index d26a8f8..905be13 100644 --- a/src/models/mediaimagecontainermodel.cpp +++ b/src/models/mediaimagecontainermodel.cpp @@ -23,10 +23,11 @@ #include "mediaimagecontainermodel.h" #include "filepathmodel.h" #include "mediaimagemodel.h" +#include "emufrontexception.h" #include MediaImageContainerModel::MediaImageContainerModel(QObject *parent) : - EmuFrontQueryModel(parent) + FileModel(parent) { } @@ -102,3 +103,125 @@ void MediaImageContainerModel::filterBySetup(int setupId) 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 lst, FilePathObject *fpo) +{ + foreach(MediaImageContainer *mic, lst) { + int micFileId = storeMediaImageContainer(mic); + } +} + +int MediaImageContainerModel::storeMediaImageContainer(EmuFrontObject *efo) +{ + MediaImageContainer *mic + = dynamic_cast(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 images = mic->getMediaImages(); + MediaImageModel miModel; + QList 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 mediaImages) +{ + if (micId < 0 || mediaImages.count() <= 0) + return; + + MediaImage *mi = 0; + foreach(EmuFrontObject *efo, mediaImages) { + mi = dynamic_cast(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(); +} + diff --git a/src/models/mediaimagecontainermodel.h b/src/models/mediaimagecontainermodel.h index cda6504..726be17 100644 --- a/src/models/mediaimagecontainermodel.h +++ b/src/models/mediaimagecontainermodel.h @@ -22,14 +22,20 @@ #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, FilePathObject*); + bool removeFromFilePath(int filePathId) const; enum { MIC_FileId, MIC_FileName, @@ -50,6 +56,11 @@ protected: // Implemented for EmuFrontQueryModel: virtual EmuFrontObject* recordToDataObject(const QSqlRecord* ); virtual QString constructFilterById(int id) const; +private: + int storeMediaImageContainer(EmuFrontObject *efo); + void linkMediaImagesWithContainer(int, QList); + bool linkMediaImageContainerToPath(const MediaImageContainer*) const; + bool linkMediaImageToMediaImageContainer(const MediaImage*, int micId) const; }; #endif // MEDIAIMAGECONTAINERMODEL_H diff --git a/src/models/mediaimagemodel.cpp b/src/models/mediaimagemodel.cpp index feb4246..7dd2572 100644 --- a/src/models/mediaimagemodel.cpp +++ b/src/models/mediaimagemodel.cpp @@ -55,3 +55,38 @@ QMap MediaImageModel::getMediaImages(int micId) } 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 MediaImageModel::storeMediaImages(QMap images) +{ + QList ids = QList(); + QMapIterator it(images); + MediaImage *mi = 0; + while(it.hasNext()) + { + it.next(); + mi = dynamic_cast(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 ids) +{ + // TODO + // go through the list of media image ids, + // if the media image with curr id doesn't have a container, delete it +} + + diff --git a/src/models/mediaimagemodel.h b/src/models/mediaimagemodel.h index 0610949..b41abfb 100644 --- a/src/models/mediaimagemodel.h +++ b/src/models/mediaimagemodel.h @@ -31,6 +31,8 @@ class MediaImageModel : public FileModel public: MediaImageModel(QObject *parent = 0); QMap getMediaImages(int id); + QList storeMediaImages(QMap images); + void removeOrphanedMediaImages(QList ids); protected: //virtual void refresh(); diff --git a/src/utils/fileutil.cpp b/src/utils/fileutil.cpp index d07ea38..22ed34c 100644 --- a/src/utils/fileutil.cpp +++ b/src/utils/fileutil.cpp @@ -18,6 +18,7 @@ ** You should have received a copy of the GNU General Public License ** along with EmuFront. If not, see . */ + #include #include #include @@ -30,7 +31,7 @@ #include "mediaimagecontainer.h" #include "mediatype.h" #include "platform.h" -#include "dbmediaimagecontainer.h" +#include "mediaimagecontainermodel.h" #include "unziphelper.h" FileUtil::FileUtil(QObject *parent) : QObject(parent) @@ -45,9 +46,7 @@ FileUtil::~FileUtil() } /* 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())); @@ -61,6 +60,11 @@ int FileUtil::scanFilePath(FilePathObject *fp, .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()) @@ -111,7 +115,7 @@ int FileUtil::scanFilePath(FilePathObject *fp, 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(); @@ -128,7 +132,7 @@ int FileUtil::scanFilePath(FilePathObject *fp, //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); diff --git a/src/utils/fileutil.h b/src/utils/fileutil.h index 42fe083..b79dbfb 100644 --- a/src/utils/fileutil.h +++ b/src/utils/fileutil.h @@ -17,7 +17,9 @@ ** ** You should have received a copy of the GNU General Public License ** along with EmuFront. If not, see . -*/#ifndef FILEUTIL_H +*/ + +#ifndef FILEUTIL_H #define FILEUTIL_H #include @@ -39,7 +41,7 @@ class FileUtil : public 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(); diff --git a/src/views/filepatheditview.cpp b/src/views/filepatheditview.cpp index 24504ed..ebdce64 100644 --- a/src/views/filepatheditview.cpp +++ b/src/views/filepatheditview.cpp @@ -18,13 +18,13 @@ ** You should have received a copy of the GNU General Public License ** along with EmuFront. If not, see . */ + #include "filepatheditview.h" #include "filepathmodel.h" #include "fileutil.h" #include "setupmodel.h" #include "comboboxdelegate.h" #include "filesystembrowsedelegate.h" -#include "dbmediaimagecontainer.h" #include FilePathEditView::FilePathEditView(QWidget *parent) : @@ -35,8 +35,6 @@ 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); @@ -74,6 +72,7 @@ void FilePathEditView::beginScanFilePath() 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) @@ -90,13 +89,9 @@ void FilePathEditView::beginScanFilePath() 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; diff --git a/src/views/filepatheditview.h b/src/views/filepatheditview.h index db199f6..695f0c0 100644 --- a/src/views/filepatheditview.h +++ b/src/views/filepatheditview.h @@ -18,6 +18,7 @@ ** You should have received a copy of the GNU General Public License ** along with EmuFront. If not, see . */ + #ifndef FILEPATHEDITVIEW_H #define FILEPATHEDITVIEW_H @@ -25,7 +26,6 @@ class FileUtil; class QProgressDialog; -class DbMediaImageContainer; class FilePathEditView : public EmuFrontEditView { @@ -42,7 +42,6 @@ private slots: private: QPushButton* scanButton; FileUtil *fileUtil; - DbMediaImageContainer *dbMediaImageContainer; QProgressDialog *progressDialog; void scanFilePath(const QString path, const QStringList filters); void initProgressDialog();