Răsfoiți Sursa

Merge pull request #14 from fiffty-50/devel-db-new

Implementation of experimental::DB
Felix Turowsky 4 ani în urmă
părinte
comite
bb2f05dc94

+ 115 - 1
src/experimental/Db.cpp

@@ -2,7 +2,7 @@
 
 using namespace experimental;
 
-bool DB::init()
+bool DB::connect()
 {
     const QString driver("QSQLITE");
 
@@ -32,3 +32,117 @@ bool DB::init()
     }
     return true;
 }
+
+bool DB::commit(Entry entry)
+{
+    if (exists(entry)) {
+        return update(entry);
+    } else {
+        return insert(entry);
+    }
+}
+
+bool DB::remove(Entry entry)
+{
+    if (!exists(entry)) {
+        DEB("Error: Entry does not exist.");
+        return false;
+    }
+
+    QString statement = "DELETE FROM " + entry.position.first +
+            " WHERE _rowid_=" + QString::number(entry.position.second);
+    QSqlQuery q(statement);
+    //check result.
+    if (q.lastError().type() == QSqlError::NoError)
+    {
+        DEB("Entry " << entry.position.first << entry.position.second << " removed.");
+        return true;
+    } else {
+        DEB("Unable to delete.");
+        DEB("Query: " << statement);
+        DEB("Query Error: " << q.lastError().text());
+        return false;
+    }
+}
+
+bool DB::exists(Entry entry)
+{
+    if (entry.position.second == 0)
+        return false;
+
+    //Check database for row id
+    QString statement = "SELECT COUNT(*) FROM " + entry.position.first +
+            " WHERE _rowid_=" + QString::number(entry.position.second);
+    //this returns either 1 or 0 since row ids are unique
+    QSqlQuery q(statement);
+    q.next();
+    int rowId = q.value(0).toInt();
+    if (rowId) {
+        DEB("Entry exists with row ID: " << rowId);
+        return true;
+    } else {
+        DEB("Entry does not exist.");
+        return false;
+    }
+}
+
+
+bool DB::update(Entry updated_entry)
+{
+    auto data = updated_entry.getData();
+    QString statement = "UPDATE " + updated_entry.position.first + " SET ";
+    for (auto i = data.constBegin(); i != data.constEnd(); ++i) {
+        if (i.key() != QString()) {
+            statement += i.key() + QLatin1String("='") + i.value() + QLatin1String("', ");
+        } else {
+            DEB(i.key() << "is empty key. skipping.");
+        }
+    }
+    statement.chop(2); // Remove last comma
+    statement.append(QLatin1String(" WHERE _rowid_=") + QString::number(updated_entry.position.second));
+
+    DEB("UPDATE QUERY: " << statement);
+    QSqlQuery q(statement);
+    //check result.
+    if (q.lastError().type() == QSqlError::NoError)
+    {
+        DEB("Entry successfully committed.");
+        return true;
+    } else {
+        DEB("Unable to commit.");
+        DEB("Query: " << statement);
+        DEB("Query Error: " << q.lastError().text());
+        return false;
+    }
+}
+
+bool DB::insert(Entry newEntry)
+{
+    auto data = newEntry.getData();
+    DEB("Inserting...");
+    QString statement = "INSERT INTO " + newEntry.position.first + QLatin1String(" (");
+    QMap<QString, QString>::iterator i;
+    for (i = data.begin(); i != data.end(); ++i) {
+        statement += i.key() + QLatin1String(", ");
+    }
+    statement.chop(2);
+    statement += QLatin1String(") VALUES (");
+    for (i = data.begin(); i != data.end(); ++i) {
+        statement += QLatin1String("'") + i.value() + QLatin1String("', ");
+    }
+    statement.chop(2);
+    statement += QLatin1String(")");
+
+    QSqlQuery q(statement);
+    //check result.
+    if (q.lastError().type() == QSqlError::NoError)
+    {
+        DEB("Entry successfully committed.");
+        return true;
+    } else {
+        DEB("Unable to commit.");
+        DEB("Query: " << statement);
+        DEB("Query Error: " << q.lastError().text());
+        return false;
+    }
+}

+ 39 - 91
src/experimental/Db.h

@@ -34,14 +34,15 @@ auto const DEFAULT_PILOT_POSITION = DataPosition("pilots", 0);
  */
 class Entry {
 public:
-    const DataPosition position;
+    DataPosition position;
 protected:
-    TableData table_data;
+    TableData tableData;
 public:
-    Entry() = delete;
+    Entry() {};
+    Entry(const Entry&) = default;
     Entry(DataPosition position_) : position(position_) {}
-    void populate_data(TableData data) { table_data = data; }
-    const TableData& data() { return table_data; }
+    void setData(TableData data) { tableData = data; }
+    const TableData& getData() { return tableData; }
 };
 
 // [George]: Either with polymorphism or simple functions the result will be the same.
@@ -50,44 +51,14 @@ public:
 // the only difference will be that we will subclass Entry to have specialised
 // constructor
 class PilotEntry : public Entry {
-    PilotEntry() = delete;
+public:
+    PilotEntry() {};
+    PilotEntry(const PilotEntry&) = default;
     PilotEntry(int row_id) : Entry::Entry(DataPosition("pilots", row_id)) {}
-};
-
-Entry newPilotEntry(int row_id) { return Entry(DataPosition("pilots", row_id)); }
-
-static
-bool insertPilot(UserInput& uin)
-{
-    DEB("Inserting...");
-    auto data = uin.all();
-    auto position = DEFAULT_PILOT_POSITION;
-
-    if (data.isEmpty()) {
-        DEB("Object Contains no data. Aborting.");
-        return false;
-    }
-    QString statement = "INSERT INTO " + position.first + QLatin1String(" (");
-    for (auto i = data.cbegin(); i != data.cend(); ++i) {
-        statement += i.key() + QLatin1String(", ");
+    PilotEntry(TableData fromNewPilotDialog) : Entry::Entry(DataPosition("pilots", 0)) {
+        setData(fromNewPilotDialog);
     }
-    statement.chop(2);
-    statement += QLatin1String(") VALUES (");
-    for (auto i = data.cbegin(); i != data.cend(); ++i) {
-        statement += QLatin1String("'") + i.value() + QLatin1String("', ");
-    }
-    statement.chop(2);
-    statement += QLatin1String(")");
-
-    QSqlQuery q(statement);
-    if (q.lastError().type() == QSqlError::NoError) {
-        DEB("Entry successfully committed.");
-        return true;
-    } else {
-        DEB("Unable to commit. Query Error: " << q.lastError().text());
-        return false;
-    }
-}
+};
 
 /*!
  * \brief The DB class encapsulates the SQL database by providing fast access
@@ -95,68 +66,45 @@ bool insertPilot(UserInput& uin)
  */
 class DB {
 private:
-    static QStringList tableNames;
-    static QMap<TableName, QStringList> tableColumns;
+    static inline QStringList                   tableNames;
+    static inline QMap<TableName, QStringList>  tableColumns;
 public:
     /*!
-     * \brief Initialise DB class and populate columns.
+     * \brief Connect to the database and populate database information.
      */
-    static bool init();
+    static bool connect();
 
     /*!
-     * \brief Create new entry in the databse based on UserInput
+     * \brief closes the database connection.
      */
-    static
-    bool insert(UserInput uin)
-    {
-        switch (uin.meta_tag)
-        {
-        case UserInput::MetaTag::Pilot:
-            DEB("Inserting NEW Pilot...");
-            return insertPilot(uin);
-        case UserInput::MetaTag::Flight:
-        case UserInput::MetaTag::Aircraft:
-        default:
-            DEB("FALLTHROUGH in cases. Missing implementations");
-            return false;
-        }
-    }
+    static bool disconnect();
+
+    /*!
+     * \brief Checks if an entry exists in the database, based on position data
+     */
+    static bool exists(Entry entry);
 
-    static bool remove(UserInput uin) { return false; }
+    /*!
+     * \brief commits an entry to the database, calls either insert or update,
+     * based on position data
+     */
+    static bool commit(Entry entry);
 
-    static bool exists(UserInput uin) { return false; }
+    /*!
+     * \brief Create new entry in the databse based on UserInput
+     */
+    static bool insert(Entry newEntry);
 
     /*!
      * \brief Updates entry in database from existing entry tweaked by the user.
-     * New entry data is verified before commiting.
      */
-    static bool update(Entry updated_entry)
-    {
-        auto position = updated_entry.position;
-        auto data = updated_entry.data();
-        QString statement = "UPDATE " + position.first + " SET ";
-        for (auto i = data.constBegin(); i != data.constEnd(); ++i) {
-            if (i.key() != QString()) {
-                statement += i.key() + QLatin1String("='") + i.value() + QLatin1String("', ");
-            } else {
-                DEB(i.key() << "is empty key. skipping.");
-            }
-        }
-        statement.chop(2); // Remove last comma
-        statement.append(QLatin1String(" WHERE _rowid_=") + QString::number(position.second));
-
-        DEB("UPDATE QUERY: " << statement);
-        QSqlQuery q(statement);
-        //check result. Upon success, error should be " "
-        if (q.lastError().type() == QSqlError::NoError)
-        {
-            DEB("Entry successfully committed.");
-            return true;
-        } else {
-            DEB("Unable to commit. Query Error: " << q.lastError().text());
-            return false;
-        }
-    }
+    static bool update(Entry updated_entry);
+
+    /*!
+     * \brief deletes an entry from the database.
+     */
+    static bool remove(Entry entry);
+
 };
 
 }  // namespace experimental

+ 22 - 18
src/gui/dialogues/newpilotdialog.cpp

@@ -20,7 +20,6 @@
 #include "debug.h"
 
 #include "src/experimental/Db.h"
-#include "src/experimental/UserInput.h"
 
 /* Examples for names around the world:
  * José Eduardo Santos Tavares Melo Silva
@@ -84,6 +83,14 @@ NewPilotDialog::NewPilotDialog(Pilot existingEntry, Db::editRole edRole, QWidget
     ui->piclastnameLineEdit->setFocus();
 }
 
+NewPilotDialog::NewPilotDialog(experimental::PilotEntry oldEntry, Db::editRole, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::NewPilot)
+{
+    oldPilotEntry = oldEntry;
+    //to do
+}
+
 NewPilotDialog::~NewPilotDialog()
 {
     DEB("Deleting New NewPilotDialog\n");
@@ -149,16 +156,14 @@ void NewPilotDialog::submitForm()
     DEB("Creating Database Object...");
     QMap<QString, QString> newData;
 
-    auto line_edits = parent()->findChildren<QLineEdit *>();
+    auto line_edits = this->findChildren<QLineEdit *>();
 
-    for (const auto &le : line_edits) {
-        QString key = le->objectName();
-        key.chop(8);//remove "LineEdit"
-        QString value = le->text();
-        if (!key.isEmpty()) {
-            newData.insert(key, value);
-        }
+    for(auto& le : line_edits) {
+        auto key = le->objectName().remove("LineEdit");
+        auto value = le->text();
+        newData.insert(key, value);
     }
+
     QString displayName;
     displayName.append(ui->piclastnameLineEdit->text());
     displayName.append(QLatin1String(", "));
@@ -167,18 +172,17 @@ void NewPilotDialog::submitForm()
     newData.insert("displayname",displayName);
 
     using namespace experimental;
-    auto uin = newPilotInput(newData);
 
     switch (role) {
-    case Db::createNew:
-        DEB("New Object: " << newData);
-        /// [George]: we should check if db operation was succesful
-        /// if not i assume we should just emit inputRejected or smth?
-        if(!DB::insert(uin)) emit QDialog::rejected();
-        break;
     case Db::editExisting:
-        DEB("updating entry with: " << newData);
-        if(!DB::update(uin)) emit QDialog::rejected();
+        oldEntry.setData(newData);
+        DB::commit(oldPilotEntry);
+        // to do: handle unsuccessful commit
+        break;
+    case Db::createNew:
+        auto newEntry = PilotEntry(newData);
+        DB::commit(newEntry);
+        // to do: handle unsuccessful commit
         break;
     }
 }

+ 4 - 0
src/gui/dialogues/newpilotdialog.h

@@ -25,6 +25,7 @@
 #include <QCompleter>
 #include "src/classes/pilot.h"
 #include "src/classes/completionlist.h"
+#include "src/experimental/Db.h"
 
 namespace Ui {
 class NewPilot;
@@ -37,6 +38,7 @@ class NewPilotDialog : public QDialog
 public:
     explicit NewPilotDialog(Db::editRole, QWidget *parent = nullptr);
     explicit NewPilotDialog(Pilot, Db::editRole, QWidget *parent = nullptr);
+    explicit NewPilotDialog(experimental::PilotEntry oldEntry, Db::editRole, QWidget *parent = nullptr);
     ~NewPilotDialog();
 
 private slots:
@@ -49,6 +51,8 @@ private:
 
     Pilot oldEntry;
 
+    experimental::PilotEntry oldPilotEntry;
+
     void setupValidators();
 
     void setupCompleter();