Exception handling.
[emufront] / src / db / databasemanager.cpp
index b741c4c..faca76e 100644 (file)
@@ -1,41 +1,81 @@
+// EmuFront
+// Copyright 2010 Mikko Keinänen
+//
+// This file is part of EmuFront.
+//
+//
+// EmuFront is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation and appearing in the file gpl.txt included in the
+// packaging of this file.
+//
+// EmuFront is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
+
 #include "databasemanager.h"
 #include <QObject>
 #include <QSqlDatabase>
+#include <QSqlTableModel>
 #include <QSqlError>
 #include <QSqlQuery>
+#include <QSqlRecord>
 #include <QFile>
 #include <QDir>
 #include <QVariant>
-#include <iostream>
+#include <QDebug>
+#include <QDateTime>
 
-const QString DatabaseManager::DB_FILENAME = QString("my.db.sqlite");
+const QString DatabaseManager::DB_FILENAME = QString("emufront.db.sqlite");
+const QString DatabaseManager::DATABASE = QString("QSQLITE");
+const QString DatabaseManager::DB_TABLE_NAME_MEDIATYPE = QString("mediatype");
+const QString DatabaseManager::DB_TABLE_NAME_PLATFORM = QString("platform");
+const QString DatabaseManager::DB_TABLE_NAME_FILE= QString("file");
+const QString DatabaseManager::DB_TABLE_NAME_FILEPATH = QString("filepath");
+const QString DatabaseManager::DB_TABLE_NAME_SETUP = QString("setup");
+const QString DatabaseManager::DB_TABLE_MEDIAIMAGECONTAINER = QString("mediaimagecontainer");
+const QString DatabaseManager::DB_TABLE_MEDIAIMAGECONTAINER_MEDIAIMAGE = QString("mediaimagecontainer_mediaimage");
+const QString DatabaseManager::DB_TABLE_EXECUTABLE = QString("executable");
 
 DatabaseManager::DatabaseManager(QObject *parent)
        : QObject(parent)
-{}
+{
+    sqlTableModel = 0;
+}
 
 DatabaseManager::~DatabaseManager()
-{}
-
-bool DatabaseManager::openDB()
 {
-       db = QSqlDatabase::addDatabase("QSQLITE");
-       db.setDatabaseName(getDbPath());
-       return db.open();
+    // no need to explicitily destroy sqlTableModel
+    // because it is parented QObject and will
+    // be destroyed when parent is destroyed
 }
 
-QSqlError DatabaseManager::lastError()
+/*
+ You may wanna set the possible filters (filterDataObjects) before calling getDataModel.
+ After filtering do not set update to true. Data model is already updated.
+*/
+QSqlQueryModel* DatabaseManager::getDataModel(bool update)
 {
-       return db.lastError();
+    if (!sqlTableModel) {
+        sqlTableModel = getData();
+    }
+    else if (update)
+        clearFilters();
+    return sqlTableModel;
 }
 
-bool DatabaseManager::deleteDB()
+bool DatabaseManager::openDB()
 {
-       db.close();
-       return QFile::remove(getDbPath());
+    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName(DatabaseManager::getDbPath());
+    return db.open();
 }
 
-QString DatabaseManager::getDbPath() const
+QString DatabaseManager::getDbPath()
 {
        QString path;
 #ifdef Q_OS_LINUX
@@ -47,79 +87,80 @@ QString DatabaseManager::getDbPath() const
        return path;
 }
 
-/**
- * Check if database already exists.
- * Returns false if doesn't or we don't have a connection.
-*/ 
-bool DatabaseManager::dbExists() const
+void DatabaseManager::resetModel()
 {
-       using namespace std;
-       if (!db.isOpen()) 
-       {
-               cerr << "Database is not connected!" << endl;
-               return false;
-       }
-       QSqlQuery query;
-       query.exec("SELECT name FROM sqlite_master WHERE name='person'");
-       return query.next();
+    if (!sqlTableModel) return;
+    clearFilters();
 }
 
-bool DatabaseManager::createDB() const
+// sql must return a count(*) value
+int DatabaseManager::countRows(QString tableName, QString columnName, int id) const
 {
-       bool ret = false;
-       if (db.isOpen())
-       {
-               QSqlQuery query;
-               ret = query.exec("create table platform "
-                               "(id integer primary key, "
-                               "name varchar(30), "
-                               "filename varchar(125))");
-               /*ret = query.exec("create table media "
-                                               "(id integer primary key, "
-                                               "name varchar(30), "
-                                               "filename varchar(125))");*/
-       }
-       return ret;
+    QString sql = QString("SELECT COUNT(*) FROM %1 WHERE %2 = %3")
+        .arg(tableName).arg(columnName).arg(id);
+    int numEntries = 0;
+    QSqlQuery query(sql);
+    if (query.next())
+        numEntries = query.value(0).toInt();
+    return numEntries;
 }
 
-int DatabaseManager::insertPlatform(QString name, QString filename) const
+
+/* Throws EmuFrontException if filtered data was not found. */
+EmuFrontObject* DatabaseManager::getDataObject(int id)
 {
-       int newId = -1;
-       bool ret = false;
-       if (db.isOpen())
-       {
-               //http://www.sqlite.org/autoinc.html
-               // NULL = is the keyword for the autoincrement to generate next value
-               QSqlQuery query;
-               query.prepare("insert into platform (id, name, filename) "
-                                               "values (NULL, :name, :filename)");
-               query.bindValue(":name", name);
-               query.bindValue(":filename", filename);
-               ret = query.exec();
+    filterById(id);
+    return getFilteredDataObject();
+}
 
-               /*ret = query.exec(QString("insert into person values(NULL,'%1','%2',%3)")
-                               .arg(firstname).arg(lastname).arg(age));*/
-               // Get database given autoincrement value
-               if (ret)
-               {
-                       // http://www.sqlite.org/c3ref/last_insert_rowid.html  
-                       QVariant var = query.lastInsertId();
-                       if (var.isValid()) newId = var.toInt();
-               }
-       }
-       return newId;
+/* Throws EmuFrontException if filtered data was not found. */
+EmuFrontObject* DatabaseManager::getDataObject(QString filter)
+{
+    QList<QString> filters;
+    filters.append(filter);
+    filterDataObjects(filters);
+    return getFilteredDataObject();
 }
 
-QString DatabaseManager::getPlatform(int id) const
+/* Throws EmuFrontException if filtered data was not found. */
+EmuFrontObject* DatabaseManager::getFilteredDataObject()
+{
+    EmuFrontObject *plf = 0;
+    // TODO: if record has more than one the first instance is returned
+    // ... check if this is ok in all cases!
+    if (sqlTableModel->rowCount() >= 1)
+    {
+        QSqlRecord record = sqlTableModel->record(0);
+        if (record.isEmpty()) {
+            throw EmuFrontException(tr("No filtered data available"));
+        }
+        else plf = recordToDataObject(&record);
+    }
+     return plf;
+}
+/* Throws EmuFrontException */
+EmuFrontObject* DatabaseManager::getDataObjectFromModel(QModelIndex *index)
 {
-       QString name;
-       QSqlQuery query(QString("select firstname, lastname from person where id = %1").arg(id));
+    if (!sqlTableModel) sqlTableModel = getDataModel();
+    QSqlRecord record = sqlTableModel->record(index->row());
+    return recordToDataObject(&record);
+}
 
-       if (query.next())
-       {
-               name.append(query.value(0).toString());
-               name.append(query.value(1).toString());
-       }
-       return name;
+int DatabaseManager::getCurrentTimeStamp() {
+    return QDateTime::currentDateTime().toTime_t();
 }
 
+int DatabaseManager::countDataObjectRefs(int id) const
+{
+    int ret = 0;
+    QSqlQuery q;
+    q.prepare(getCountRefsSelect(id));
+    q.exec();
+    QSqlRecord rec;
+    if (q.next()) {
+        rec = q.record();
+        ret = rec.value(0).toInt();
+    }
+    qDebug() << "Found " << ret << " references.";
+    return ret;
+}