]> vaikene.ee Git - evaf/blobdiff - src/apps/PswGen/Storage/module.cpp
Warning fixes and copyright update.
[evaf] / src / apps / PswGen / Storage / module.cpp
index b0fd6afed017eefccd102ab98a2f96e11c96f5db..8e65360d2c8a29e323b090113a77e56a34565796 100644 (file)
@@ -3,7 +3,7 @@
  * @brief Implementation of the iStorage interface
  * @author Enar Vaikene
  *
- * Copyright (c) 2011 Enar Vaikene
+ * Copyright (c) 2011-2019 Enar Vaikene
  *
  * This file is part of the eVaf C++ cross-platform application development framework.
  *
  */
 
 #include "module.h"
-#include "version.h"
 
 #include <Common/Globals>
 #include <Common/iLogger>
 #include <Common/iRegistry>
-#include <Common/iEnv>
+#include <Common/iApp>
 
 #include <QtCore>
 #include <QtSql/QtSql>
+#include <QtSql/QSqlDatabase>
+
 
 VER_EXPORT_VERSION_INFO()
-Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::PswGen::Storage::Module)
 
 using namespace eVaf;
 using namespace eVaf::PswGen;
@@ -57,7 +57,7 @@ Module::~Module()
 
 bool Module::init(QString const & args)
 {
-    Q_UNUSED(args);
+    Q_UNUSED(args)
 
     if (!mStorage->init())
         return false;
@@ -102,56 +102,71 @@ StorageImpl::~StorageImpl()
 
 bool StorageImpl::init()
 {
-    EVAF_INFO("%s initialized", qPrintable(objectName()));
-
     // Open the database
+    QSqlDatabase db;
     if (!QSqlDatabase::contains(DbConnectionName)) {
         // No database connection yet
-        mDb = QSqlDatabase::addDatabase("QSQLITE", DbConnectionName);
-        mDb.setDatabaseName(Common::iEnv::instance()->dataRootDir() + DbName);
-        if (!mDb.open()) {
-            QSqlError err = mDb.lastError();
+        db = QSqlDatabase::addDatabase("QSQLITE", DbConnectionName);
+        EVAF_INFO("Added database %s", DbConnectionName);
+        db.setDatabaseName(Common::iApp::instance()->dataRootDir() + DbName);
+        if (!db.open()) {
+            QSqlError err = db.lastError();
             EVAF_ERROR("Failed to open database : %s", qPrintable(err.text()));
             return false;
         }
     }
     else {
         // Database connection already exists
-        mDb = QSqlDatabase::database(DbConnectionName);
+        db = QSqlDatabase::database(DbConnectionName);
     }
 
     // Create tables if necessary
-    if (!createTables())
+    if (!createTables(db))
         return false;
 
     // Load data
-    if (!loadData())
+    if (!loadData(db))
         return false;
 
     /// Register our interface
     Common::iRegistry::instance()->registerInterface("iStorage", this);
 
+    EVAF_INFO("%s initialized", qPrintable(objectName()));
+
     return true;
 }
 
 void StorageImpl::done()
 {
     mData.clear();
+    if (QSqlDatabase::contains(DbConnectionName))
+    {
+        QSqlDatabase::removeDatabase(DbConnectionName);
+        EVAF_INFO("Removed database %s", DbConnectionName);
+    }
     EVAF_INFO("%s finalized", qPrintable(objectName()));
 }
 
 bool StorageImpl::save(QString const & name, QExplicitlySharedDataPointer<Storage::Data> data)
 {
-    EVAF_TEST_X(data, "Data cannot be null");
-    EVAF_TEST_X(!name.isEmpty(), "Name cannot be empty");
+    EVAF_TEST_X(data, "Data cannot be null")
+    EVAF_TEST_X(!name.isEmpty(), "Name cannot be empty")
+
+    if (!QSqlDatabase::contains(DbConnectionName))
+    {
+        EVAF_ERROR("Failed to get DB connection");
+        return false;
+    }
+    QSqlDatabase db = QSqlDatabase::database(DbConnectionName);
 
     // Is it an update or a new data record?
     if (mData.constFind(name) != mData.constEnd()) {
         // This is an update
         if (data->modified()) {
-            QSqlQuery q(mDb);
-            if (!q.exec(QString("UPDATE data SET length = \'%1\', flags = \'%2\' WHERE name = \'%3\';").arg(data->length()).arg(data->flags()).arg(name))) {
-                QSqlError err = mDb.lastError();
+            QSqlQuery q(db);
+            if (!q.exec(QString("UPDATE data SET suffix = \'%1\', length = \'%2\', flags = \'%3\' WHERE name = \'%4\';")
+                            .arg(data->suffix()).arg(data->length()).arg(data->flags()).arg(name))) {
+                QSqlError err = db.lastError();
                 EVAF_ERROR("Failed to update \'%s\' : %s", qPrintable(name), qPrintable(err.text()));
                 return false;
             }
@@ -159,18 +174,20 @@ bool StorageImpl::save(QString const & name, QExplicitlySharedDataPointer<Storag
     }
     else {
         // Store to the database
-        QSqlQuery q(mDb);
-        if (!q.exec(QString("INSERT INTO data (name, length, flags) VALUES ('\%1\', %2, %3);").arg(name).arg(data->length()).arg(int(data->flags())))) {
-            QSqlError err = mDb.lastError();
+        QSqlQuery q(db);
+        if (!q.exec(QString("INSERT INTO data (name, suffix, length, flags) VALUES (\'%1\', \'%2\', %3, %4);")
+                            .arg(name).arg(data->suffix()).arg(data->length())
+                            .arg(int(data->flags())))) {
+            QSqlError err = db.lastError();
             EVAF_ERROR("Failed to insert \'%s\' : %s", qPrintable(name), qPrintable(err.text()));
             return false;
         }
 
         // Store also into the local hash
+        beginResetModel();
         mData.insert(name, data);
+        endResetModel();
 
-        // Reset the model
-        reset();
     }
 
     data->reset();
@@ -198,21 +215,23 @@ QVariant StorageImpl::data(QModelIndex const & index, int role) const
     return QVariant();
 }
 
-bool StorageImpl::createTables()
+bool StorageImpl::createTables(QSqlDatabase & db)
 {
-    QSqlQuery q(mDb);
+    QSqlQuery q(db);
     if (!q.exec("SELECT name FROM sqlite_master WHERE type=\'table\' AND name=\'data\';")) {
-        QSqlError err = mDb.lastError();
+        QSqlError err = db.lastError();
         EVAF_ERROR("Failed to query database : %s", qPrintable(err.text()));
         return false;
     }
 
-    if (q.isActive() && q.isSelect() && q.first())
-        return true; // We already have a table called 'data'
+    if (q.isActive() && q.isSelect() && q.first()) {
+        // Check if the table needs to be upgraded
+        return upgradeTables(db);
+    }
 
     // Create the 'data' table
-    if (!q.exec("CREATE TABLE data (name text primary key not null, length integer, flags integer);")) {
-        QSqlError err = mDb.lastError();
+    if (!q.exec("CREATE TABLE data (name text primary key not null, suffix text, length integer, flags integer);")) {
+        QSqlError err = db.lastError();
         EVAF_ERROR("Failed to create table \'data\' : %s", qPrintable(err.text()));
         return false;
     }
@@ -220,22 +239,42 @@ bool StorageImpl::createTables()
     return true;
 }
 
-bool StorageImpl::loadData()
+bool StorageImpl::upgradeTables(QSqlDatabase & db)
 {
-    QSqlQuery q(mDb);
-    if (!q.exec("SELECT name, length, flags FROM data;")) {
-        QSqlError err = mDb.lastError();
+    QSqlQuery q(db);
+
+    // Check if the 'suffix' column exists
+    if (q.exec("SELECT suffix from data;")) {
+        return true;
+    }
+
+    // Add the 'suffix' columnt
+    if (!q.exec("ALTER TABLE data ADD COLUMN suffix TEXT;")) {
+        QSqlError err = db.lastError();
+        EVAF_ERROR("Failed to upgrade table \'data\' : %s", qPrintable(err.text()));
+        return false;
+    }
+
+    return true;
+}
+
+bool StorageImpl::loadData(QSqlDatabase & db)
+{
+    QSqlQuery q(db);
+    if (!q.exec("SELECT name, suffix, length, flags FROM data;")) {
+        QSqlError err = db.lastError();
         EVAF_ERROR("Failed to query database : %s", qPrintable(err.text()));
         return false;
     }
 
+    beginResetModel();
     while (q.next()) {
         QString name = q.value(0).toString();
-        QExplicitlySharedDataPointer<Storage::Data> data(new Storage::Data(q.value(1).toInt(), uint(q.value(2).toInt())));
+        QExplicitlySharedDataPointer<Storage::Data> data(
+                    new Storage::Data(name, q.value(1).toString(), q.value(2).toInt(), uint(q.value(3).toInt())));
         mData.insert(name, data);
     }
-
-    reset();
+    endResetModel();
 
     return true;
 }