浏览代码

cleaned up database api and rework of flight class. See class entry

fiffty-50 4 年之前
父节点
当前提交
4ab7642181

二进制
assets/database/logbook.db


+ 3 - 2
mainwindow.cpp

@@ -119,7 +119,7 @@ void MainWindow::on_actionAircraft_triggered()
 
 void MainWindow::on_actionNewAircraft_triggered()
 {
-    auto nt = new NewTail(QString(), sql::createNew,this);
+    auto nt = new NewTail(QString(), db::createNew,this);
     nt->show();
 }
 
@@ -130,5 +130,6 @@ void MainWindow::on_actionPilots_triggered()
 
 void MainWindow::on_actionNewPilot_triggered()
 {
-    nope();
+    auto np = new NewPilot(db::createNew,this);
+    np->show();
 }

+ 2 - 0
mainwindow.h

@@ -31,6 +31,8 @@
 #include "src/gui/widgets/settingswidget.h"
 #include "src/gui/widgets/logbookwidget.h"
 #include "src/gui/widgets/aircraftwidget.h"
+#include "src/gui/dialogues/newtail.h"
+#include "src/gui/dialogues/newpilot.h"
 
 QT_BEGIN_NAMESPACE
 namespace Ui { class MainWindow; }

+ 7 - 0
openPilotLog.pro

@@ -22,10 +22,13 @@ SOURCES += \
     src/classes/calc.cpp \
     src/classes/completionlist.cpp \
     src/classes/flight.cpp \
+    src/classes/pilot.cpp \
     src/classes/stat.cpp \
     src/classes/strictregularexpressionvalidator.cpp \
     src/database/db.cpp \
     src/database/dbinfo.cpp \
+    src/database/entry.cpp \
+    src/gui/dialogues/newpilot.cpp \
     src/gui/dialogues/newtail.cpp \
     src/gui/widgets/aircraftwidget.cpp \
     src/gui/widgets/homewidget.cpp \
@@ -38,10 +41,13 @@ HEADERS += \
     src/classes/calc.h \
     src/classes/completionlist.h \
     src/classes/flight.h \
+    src/classes/pilot.h \
     src/classes/stat.h \
     src/classes/strictregularexpressionvalidator.h \
     src/database/db.h \
     src/database/dbinfo.h \
+    src/database/entry.h \
+    src/gui/dialogues/newpilot.h \
     src/gui/dialogues/newtail.h \
     src/gui/widgets/aircraftwidget.h \
     src/gui/widgets/homewidget.h \
@@ -50,6 +56,7 @@ HEADERS += \
 
 FORMS += \
     mainwindow.ui \
+    src/gui/dialogues/newpilot.ui \
     src/gui/dialogues/newtail.ui \
     src/gui/widgets/aircraftwidget.ui \
     src/gui/widgets/homewidget.ui \

+ 1 - 1
openPilotLog.pro.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.11.0, 2020-10-31T21:02:50. -->
+<!-- Written by QtCreator 4.11.0, 2020-11-01T21:06:17. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>

+ 0 - 112
src/classes/aircraft.cpp

@@ -21,116 +21,4 @@
 #define DEB(expr) \
     qDebug() << "aircraft ::" << __func__ << "\t" << expr
 
-aircraft::aircraft()
-{
 
-}
-
-/*!
- * \brief aircraft::aircraft creates an aircraft object from the database.
- * \param database_id primary key in database
- * \param db either database::tails or database::acft
- */
-aircraft::aircraft(int database_id, aircraft::database table)
-{
-    QVector<QString> columns = {
-        "tail_id", "registration", "company",
-        "make", "model", "variant",
-        "singlepilot", "multipilot", "singleengine", "multiengine",
-        "unpowered", "piston", "turboprop",
-        "jet", "light", "medium", "heavy", "super"
-    };
-    QString checkColumn;
-    QString tableName;
-
-    switch (table) {
-    case database::tail:
-        //DEB("tails:" << columns);
-        tableName.append("tails");
-        checkColumn.append("tail_id");
-        break;
-    case database::acft:
-        columns.replace(0,"aircraft_id");
-        columns.remove(1,2);
-        //DEB("acft:" << columns;)
-        tableName.append("aircraft");
-        checkColumn.append("aircraft_id");
-        break;
-    }
-
-    auto vector = db::multiSelect(columns,tableName,checkColumn,QString::number(database_id),sql::exactMatch);
-
-    if(vector.length() < 2){
-        id = "invalid";
-    }else{
-        switch (table) {
-        case database::tail:
-            id = vector[0];
-            registration = vector[1];
-            company = vector[2];
-            make = vector[3];
-            model = vector[4];
-            variant = vector[5];
-            //bool
-            singlepilot = vector[6].toInt();
-            multipilot = vector[7].toInt();
-            singleengine = vector[8].toInt();
-            multiengine = vector[9].toInt();
-            unpowered = vector[10].toInt();
-            piston = vector[11].toInt();
-            turboprop = vector[12].toInt();
-            jet = vector[13].toInt();
-            light = vector[14].toInt();
-            medium = vector[15].toInt();
-            heavy = vector[16].toInt();
-            super = vector[17].toInt();
-            break;
-        case database::acft:
-            id = vector[0];
-            make = vector[1];
-            model = vector[2];
-            variant = vector[3];
-            //bool
-            singlepilot = vector[4].toInt();
-            multipilot = vector[5].toInt();
-            singleengine = vector[6].toInt();
-            multiengine = vector[7].toInt();
-            unpowered = vector[8].toInt();
-            piston = vector[9].toInt();
-            turboprop = vector[10].toInt();
-            jet = vector[11].toInt();
-            light = vector[12].toInt();
-            medium = vector[13].toInt();
-            heavy = vector[14].toInt();
-            super = vector[15].toInt();
-            break;
-        }
-    }
-}
-
-/*!
- * \brief aircraft::print Debug output
- */
-void aircraft::print()
-{
-    QTextStream cout(stdout, QIODevice::WriteOnly);
-
-    cout << "\t\033[38;2;0;255;0;48;2;0;0;0m Aircraft Object \033[0m\n";
-    cout << "ID: \t\t" << id << "\n";
-    cout << "Reg: \t\t" << registration<< "\n";
-    cout << "Company: \t" << company<< "\n";
-    cout << "Type:\t\t" << make << " " << model << " " <<  variant<< "\n";
-    cout << "SP:\t\t" << singlepilot << "\tMP:\t" << multipilot << "\t"
-         << "SE:\t" << singleengine << "\tME:\t" << multiengine << "\n";
-    cout << "UNP:\t\t" << unpowered << "\tPIS:\t" << piston << "\t"
-         << "TPR:\t" << turboprop << "\tJET:\t" << jet << "\n";
-    cout << "Light:\t" << light << "\tMedium:\t" << medium;
-    cout << "Heavy:\t" << heavy << "\tSuper:\t" << super << "\n";
-
-}
-
-QString aircraft::debug()
-{
-    print();
-    return QString();
-}

+ 4 - 35
src/classes/aircraft.h

@@ -18,48 +18,17 @@
 #ifndef AIRCRAFT_H
 #define AIRCRAFT_H
 #include <QCoreApplication>
-#include <QVector>
-#include "src/database/db.h"
+#include "src/database/entry.h"
 
 /*!
  * \brief The aircraft class
  *
  */
-class aircraft
+class aircraft : public entry
 {
+using entry::entry;
 public:
-    enum database {tail, acft};
-
-    aircraft();
-    aircraft(int database_id, database table);
-    aircraft(QString registration);
-
-    QString id;
-    QString registration;
-    QString company;
-    QString make;
-    QString model;
-    QString variant;
-    bool singlepilot    = false;
-    bool multipilot     = false;
-    bool singleengine   = false;
-    bool multiengine    = false;
-    bool unpowered      = false;
-    bool piston         = false;
-    bool turboprop      = false;
-    bool jet            = false;
-    bool light          = false;
-    bool medium         = false;
-    bool heavy          = false;
-    bool super          = false;
-
-    // Functions
-    static QVector<QString> toVector(aircraft);
-
-    // Debug functionality
-    void print();
-    QString debug();
-    operator QString() { return debug(); } //overload for compatibility with qDebug()
+    void verify();
 };
 
 #endif // AIRCRAFT_H

+ 5 - 5
src/classes/calc.cpp

@@ -179,15 +179,15 @@ double calc::greatCircleDistance(double lat1, double lon1, double lat2, double l
  */
 double calc::greatCircleDistanceBetweenAirports(QString dept, QString dest)
 {
-    //db::multiSelect("airports", columns, "EDDF", "icao", sql::exactMatch);
+    //db::multiSelect("airports", columns, "EDDF", "icao", db::exactMatch);
     /*if(dbAirport::retreiveIcaoCoordinates(dept).isEmpty() || dbAirport::retreiveIcaoCoordinates(dest).isEmpty()){
         qWarning() << "greatCircleDistance - invalid input. aborting.";
         return 0;
     }*/
 
     QVector<QString> columns = {"lat", "long"};
-    QVector<QString> deptCoordinates = db::multiSelect(columns,"airports", "icao", dept, sql::exactMatch);
-    QVector<QString> destCoordinates = db::multiSelect(columns,"airports", "icao", dest, sql::exactMatch);
+    QVector<QString> deptCoordinates = db::multiSelect(columns,"airports", "icao", dept, db::exactMatch);
+    QVector<QString> destCoordinates = db::multiSelect(columns,"airports", "icao", dest, db::exactMatch);
 
     if(deptCoordinates.isEmpty() || destCoordinates.isEmpty()
        )
@@ -331,8 +331,8 @@ double calc::solarElevation(QDateTime utc_time_point, double lat, double lon)
 int calc::calculateNightTime(QString dept, QString dest, QDateTime departureTime, int tblk)
 {
     QVector<QString> columns = {"lat", "long"};
-    QVector<QString> deptCoordinates = db::multiSelect(columns,"airports", "icao", dept, sql::exactMatch);
-    QVector<QString> destCoordinates = db::multiSelect(columns,"airports", "icao", dest, sql::exactMatch);
+    QVector<QString> deptCoordinates = db::multiSelect(columns,"airports", "icao", dept, db::exactMatch);
+    QVector<QString> destCoordinates = db::multiSelect(columns,"airports", "icao", dest, db::exactMatch);
 
     if(deptCoordinates.isEmpty() || destCoordinates.isEmpty()
        )

+ 0 - 252
src/classes/flight.cpp

@@ -16,255 +16,3 @@
  *along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 #include "flight.h"
-
-flight::flight()
-{
-    isValid = false;
-    invalidItems.append( {                      // Upon verification, verified entries are removed from the list
-        "doft", "dept", "dest", "tofb",
-        "tonb", "pic",  "acft", "tblk"
-    });
-
-    id      = -1;                         //[1] Primary Key in Database, needed for retreival but not for commiting (sqlite autoincrement)
-    doft    = QDate();                    //[2] Date of Flight, initialised invalid
-    dept    = "";                         //[3] Departure, initialised invalid
-    dest    = "";                         //[4] Destination, initialised invalid
-    tofb    = QTime();                    //[5] Time off blocks (UTC), initialised invalid
-    tonb    = QTime();                    //[6] Time on blocks (UTC), initialised invalid
-    pic     = "";                         //[7] Pilot in command (ID), initialised invalid
-    acft    = "";                         //[8] Aircraft Registration (ID), initialised invalid
-
-    tblk    = QTime();                    //[9] Total Blocktime, initialised invalid
-    tSPSE   = QTime(0,0);                 //[10] optional times initialised as 0
-    tSPME   = QTime(0,0);                 //[11]
-    tMP     = QTime(0,0);                 //[12]
-    tNIGHT  = QTime(0,0);                 //[13]
-    tIFR    = QTime(0,0);                 //[14]
-
-    tPIC    = QTime(0,0);                 //[15]
-    tPICUS  = QTime(0,0);                 //[16]
-    tSIC    = QTime(0,0);                 //[17]
-    tDUAL   = QTime(0,0);                 //[18]
-    tFI     = QTime(0,0);                 //[19]
-
-    tSIM    = QTime(0,0);                 //[20]
-}
-
-flight::flight(QVector<QString> details)
-{
-    isValid = false;
-    invalidItems.append({                      // Upon verification, verified entries are removed from the list
-        "doft", "dept", "dest", "tofb",
-        "tonb", "pic",  "acft", "tblk"
-    });
-    if(details.length() != 32){
-        qWarning() << __PRETTY_FUNCTION__ << "Vector needs to be of size 32.";
-        qWarning() << __PRETTY_FUNCTION__ << "Unable to create object.";
-        details = QVector<QString>(32);
-    }
-
-    id      = details[1].toInt();
-    doft    = QDate::fromString(details[2],Qt::ISODate);
-    dept    = details[3];
-    dest    = details[4];
-    tofb    = QTime::fromString(details[5],"hh:mm");
-    tonb    = QTime::fromString(details[6],"hh:mm");
-    pic     = details[7];
-    acft    = details[8];
-    tblk    = QTime::fromString(details[9],"hh:mm");
-    tSPSE   = QTime::fromString(details[10],"hh:mm");
-    tSPME   = QTime::fromString(details[11],"hh:mm");
-    tMP     = QTime::fromString(details[12],"hh:mm");
-    tNIGHT  = QTime::fromString(details[13],"hh:mm");
-    tIFR    = QTime::fromString(details[14],"hh:mm");
-
-    tPIC    = QTime::fromString(details[15],"hh:mm");
-    tPICUS  = QTime::fromString(details[16],"hh:mm");
-    tSIC    = QTime::fromString(details[17],"hh:mm");
-    tDUAL   = QTime::fromString(details[18],"hh:mm");
-    tFI     = QTime::fromString(details[19],"hh:mm");
-    tSIM    = QTime::fromString(details[20],"hh:mm");
-
-    pilotFlying  = details[21].toInt();
-    toDay        = details[22].toInt();
-    toNight      = details[23].toInt();
-    ldgDay       = details[24].toInt();
-    ldgNight     = details[25].toInt();
-    autoland     = details[26].toInt();
-
-    secondPilot  = details[27];
-    thirdPilot   = details[28];
-    approachType = details[29];
-    flightNumber = details[30];
-    remarks      = details[31];
-}
-
-/*!
- * \brief flight::printFlight Displays basic data for debugging
- */
-void flight::print()
-{
-    QTextStream cout(stdout, QIODevice::WriteOnly);
-
-    if(id != -1){
-        cout << "Flight ID:\t\t" + QString::number(id) + "\n";
-    }else{
-        cout << "Flight ID:\t\tnot set\n";
-    }
-
-    if(doft.toString(Qt::ISODate).length()){
-        cout << "Date of Flight:\t" + doft.toString(Qt::ISODate) + "\n";
-    }else{
-        cout << "Date of Flight:\tnot set\n";
-    }
-
-   if(dept != QStringLiteral("INVA")){
-       cout << "Departure:\t\t" + dept  + "\n";
-    }else{
-       cout << "Departure:\t\tnot set\n";
-    }
-
-   if(dest != QStringLiteral("INVA")){
-       cout << "Destination:\t\t" + dest  + "\n";
-    }else{
-       cout << "Destination:\t\tnot set\n";
-    }
-
-   if(tofb.toString("hh:mm").length()){
-       cout << "Departure Time:\t" + tofb.toString("hh:mm") + "\n";
-   }else{
-       cout << "Departure Time:\tnot set\n";
-   }
-
-   if(tonb.toString("hh:mm").length()){
-       cout << "Arrival Time:\t" + tonb.toString("hh:mm") + "\n";
-   }else{
-       cout << "Arrival Time:\tnot set\n";
-   }
-
-    if(pic != QStringLiteral("INVA")){
-        cout << "Pilot in Command:\t" + pic + "\n";
-    }else{
-       cout << "Pilot in Command:\tnot set\n";
-    }
-
-    if(acft != QStringLiteral("INVA")){
-        cout << "Aircraft:\t\t" + acft + "\n";
-    }else{
-       cout << "Aircraft:\t\tnot set\n";
-    }
-
-    if(tblk.isValid()){
-        cout << "Blocktime:\t\t" + tblk.toString("hh:mm") + "\n";
-    }else{
-       cout << "Blocktime:\t\tnot set\n";
-    }
-
-    if(isValid){
-        cout << "Object status:\t\033[38;2;0;255;0;48;2;0;0;0m VERIFIED \033[0m\n";
-    }else{
-        cout << "Object status:\t\033[38;2;255;0;0;48;2;0;0;0m UNVERIFIED \033[0m\n";
-    }
-    if(!invalidItems.isEmpty()){
-        cout << "Invalid items:\t";
-        for(auto const& item : invalidItems){
-            cout << item + QLatin1Char(' ');
-        }
-        cout << "\n";
-    }
-}
-/*!
- * \brief flight::debug Provides compatibility with qDebug
- * \return
- */
-QString flight::debug()
-{
-    print();
-    return QString();
-}
-
-flight flight::fromVector(QVector<QString> details)
-{
-    if(details.length() != 32){
-        qWarning() << __PRETTY_FUNCTION__ << "Invalid Input. Aborting.";
-        return flight();
-    }
-    flight object;
-    object.id      = details[1].toInt();
-    object.doft    = QDate::fromString(details[2],Qt::ISODate);
-    object.dept    = details[3];
-    object.dest    = details[4];
-    object.tofb    = QTime::fromString(details[5],"hh:mm");
-    object.tonb    = QTime::fromString(details[6],"hh:mm");
-    object.pic     = details[7];
-    object.acft    = details[8];
-    object.tblk    = QTime::fromString(details[9],"hh:mm");
-    object.tSPSE   = QTime::fromString(details[10],"hh:mm");
-    object.tSPME   = QTime::fromString(details[11],"hh:mm");
-    object.tMP     = QTime::fromString(details[12],"hh:mm");
-    object.tNIGHT  = QTime::fromString(details[13],"hh:mm");
-    object.tIFR    = QTime::fromString(details[14],"hh:mm");
-
-    object.tPIC    = QTime::fromString(details[15],"hh:mm");
-    object.tPICUS  = QTime::fromString(details[16],"hh:mm");
-    object.tSIC    = QTime::fromString(details[17],"hh:mm");
-    object.tDUAL   = QTime::fromString(details[18],"hh:mm");
-    object.tFI     = QTime::fromString(details[19],"hh:mm");
-    object.tSIM    = QTime::fromString(details[20],"hh:mm");
-
-    object.pilotFlying  = details[21].toInt();
-    object.toDay        = details[22].toInt();
-    object.toNight      = details[23].toInt();
-    object.ldgDay       = details[24].toInt();
-    object.ldgNight     = details[25].toInt();
-    object.autoland     = details[26].toInt();
-
-    object.secondPilot  = details[27];
-    object.thirdPilot   = details[28];
-    object.approachType = details[29];
-    object.flightNumber = details[30];
-    object.remarks      = details[31];
-
-    return object;
-}
-
-QVector<QString> flight::toVector(flight object)
-{
-    QVector<QString> vecOut(32);
-
-    vecOut [1]  = QString::number(object.id);
-    vecOut [2]  = object.doft.toString(Qt::ISODate);
-    vecOut [3]  = object.dept;
-    vecOut [4]  = object.dest;
-    vecOut [5]  = object.tofb.toString("hh:mm");
-    vecOut [6]  = object.tonb.toString("hh:mm");
-    vecOut [7]  = object.pic;
-    vecOut [8]  = object.acft;
-    vecOut [9]  = object.tblk.toString("hh:mm");
-
-    vecOut [10] = object.tSPSE.toString("hh:mm");
-    vecOut [11] = object.tSPME.toString("hh:mm");
-    vecOut [12] = object.tMP.toString("hh:mm");
-    vecOut [13] = object.tNIGHT.toString("hh:mm");
-    vecOut [14] = object.tIFR.toString("hh:mm");
-    vecOut [15] = object.tPIC.toString("hh:mm");
-    vecOut [16] = object.tPICUS.toString("hh:mm");
-    vecOut [17] = object.tSIC.toString("hh:mm");
-    vecOut [18] = object.tDUAL.toString("hh:mm");
-    vecOut [19] = object.tFI.toString("hh:mm");
-    vecOut [20] = object.tSIM.toString("hh:mm");
-
-    vecOut [21] = QString::number(object.pilotFlying);
-    vecOut [22] = QString::number(object.toDay);
-    vecOut [23] = QString::number(object.toNight);
-    vecOut [24] = QString::number(object.ldgDay);
-    vecOut [25] = QString::number(object.ldgNight);
-    vecOut [26] = QString::number(object.autoland);
-    vecOut [27] = object.secondPilot;
-    vecOut [28] = object.thirdPilot;
-    vecOut [29] = object.approachType;
-    vecOut [30] = object.flightNumber;
-    vecOut [31] = object.remarks;
-
-    return vecOut;
-}

+ 5 - 61
src/classes/flight.h

@@ -21,70 +21,14 @@
 #include <QCoreApplication>
 #include <QDateTime>
 #include <QDebug>
+#include "src/database/entry.h"
 
-/*!
- * \brief The flight class is a container class for a logbook entry. It contains all the
- * entries relevant to a flight. There are 8 mandatory entries which are initalized
- * invalid and need to be set before the flight can be committed. The other entries
- * are optional and can be empty, null or any other value.
- * All time entries in a flight object shall be UTC.
- */
-class flight
-{
-public:
-
-    bool        isValid;
-    QStringList invalidItems;             // Upon verification, verified entries are removed from the list
-
-    int         id;                       //[1] Primary Key in Database, needed for retreival but not for commiting (sqlite autoincrement)
-    QDate       doft;                     //[2] Date of Flight, initialised invalid
-    QString     dept;                     //[3] Departure, initialised invalid
-    QString     dest;                     //[4] Destination, initialised invalid
-    QTime       tofb;                     //[5] Time off blocks (UTC), initialised invalid
-    QTime       tonb;                     //[6] Time on blocks (UTC), initialised invalid
-    QString     pic;                      //[7] Pilot in command (ID), initialised invalid
-    QString     acft;                     //[8] Aircraft Registration (ID), initialised invalid
-
-    QTime       tblk;                     //[9] Total Blocktime, initialised invalid
-    QTime       tSPSE;                    //[10] optional times initialised as 0
-    QTime       tSPME;                    //[11]
-    QTime       tMP;                      //[12]
-    QTime       tNIGHT;                   //[13]
-    QTime       tIFR;                     //[14]
-
-    QTime       tPIC;                     //[15]
-    QTime       tPICUS;                   //[16]
-    QTime       tSIC;                     //[17]
-    QTime       tDUAL;                    //[18]
-    QTime       tFI;                      //[19]
 
-    QTime       tSIM;                     //[20]
-
-    int         pilotFlying;                          //[21]
-    int         toDay;                                //[22]
-    int         toNight;                              //[23]
-    int         ldgDay;                               //[24]
-    int         ldgNight;                             //[25]
-    int         autoland;                             //[26]
-
-    QString     secondPilot;                          //[27]
-    QString     thirdPilot;                           //[28]
-    QString     approachType;                         //[29]
-    QString     flightNumber;                         //[30]
-    QString     remarks;                              //[31]
-
-    flight();
-    flight(QVector<QString>);
-
-
-    // Functions
-    static flight           fromVector(QVector<QString>);
-    static QVector<QString> toVector(flight);
+class flight : public entry
+{
+    using entry::entry;
 
-    // Debug functionality
-    void print();
-    QString debug();
-    operator QString() { return debug(); }
+    bool verify();
 };
 
 #endif // FLIGHT_H

+ 19 - 0
src/classes/pilot.cpp

@@ -0,0 +1,19 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "pilot.h"
+

+ 30 - 0
src/classes/pilot.h

@@ -0,0 +1,30 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef PILOT_H
+#define PILOT_H
+#include "src/database/entry.h"
+
+
+class pilot : public entry
+{
+    using entry::entry;
+public:
+    void verify();
+};
+
+#endif // PILOT_H

+ 17 - 288
src/database/db.cpp

@@ -20,90 +20,8 @@
 
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "db ::" << __func__ << "\t" << expr
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
 
-db::db()
-{
-
-}
-
-db::db(sql::tableName tn, int row_ID)
-{
-    switch (tn) {
-    case sql::flights:
-        table = "flights";
-        break;
-    case sql::pilots:
-        table = "pilots";
-        break;
-    case sql::aircraft:
-        table = "aircraft";
-        break;
-    case sql::tails:
-        table = "tails";
-        break;
-    case sql::airports:
-        table = "airports";
-        break;
-    }
-    row_id = row_ID;
-
-
-    QString statement = "SELECT COUNT(*) FROM " + table + " WHERE _rowid_="+QString::number(row_id);
-    QSqlQuery q(statement);
-    q.exec();
-    q.next();
-    int rows = q.value(0).toInt();
-    if(rows==0){
-        DEB("No entry found for row id: " << row_ID );
-    }else{
-        DEB("Retreiving data for row id: " << row_id);
-        isValid = retreiveData();
-    }
-}
-
-db::db(sql::tableName tn, QMap<QString, QString> newData)
-{
-    switch (tn) {
-    case sql::flights:
-        table = "flights";
-        break;
-    case sql::pilots:
-        table = "pilots";
-        break;
-    case sql::aircraft:
-        table = "aircraft";
-        break;
-    case sql::tails:
-        table = "tails";
-        break;
-    case sql::airports:
-        table = "airports";
-        break;
-    }
-    //Do some checks
-    auto in = dbInfo();
-    auto columns = in.format.value(table);
-    QMap<QString,QString>::iterator i;
-    for (i = newData.begin(); i != newData.end(); ++i){
-        if(!columns.contains(i.key())){
-            DEB(newData);
-            DEB(i.key()<< i.value() << "Not in column list for " << table <<". Removing.");
-            newData.remove(i.key());
-        }
-    }
-    data = newData;
-}
-
-void db::setData(const QMap<QString, QString> &value)
-{
-    data = value;
-}
-
-/*!
- * \brief db::connect connects to the database via the default connection.
- * Can then be accessed globally with QSqlDatabase::database("qt_sql_default_connection")
- */
 void db::connect()
 {
     const QString driver("QSQLITE");
@@ -124,35 +42,6 @@ void db::connect()
         DEB("DatabaseConnect - ERROR: no driver " << driver << " available");
     }
 }
-
-/*!
- * \brief db::retreiveData retreives data from the database.
- * \return
- */
-bool db::retreiveData()
-{
-    const auto info = dbInfo();
-
-    QString statement = "SELECT * FROM " + table + " WHERE _rowid_="+QString::number(row_id);
-    DEB("Executing SQL...");
-    DEB(statement);
-
-    QSqlQuery q(statement);
-    q.exec();
-    q.next();
-    for(int i=0; i < info.format.value(table).length(); i++){
-        data.insert(info.format.value(table)[i],q.value(i).toString());
-    }
-
-
-    QString error = q.lastError().text();
-    if(error.length() > 2){
-        DEB("Error: " << q.lastError().text());
-        return false;
-    }else{return true;}
-}
-
-
 /*!
  * \brief db::exists checks if a certain value exists in the database with a sqlite WHERE statement
  * \param table - Name of the table
@@ -160,16 +49,16 @@ bool db::retreiveData()
  * \param value - The value to be checked
  * \return
  */
-bool db::exists(QString column, QString table, QString checkColumn, QString value, sql::matchType match)
+bool db::exists(QString column, QString table, QString checkColumn, QString value, db::matchType match)
 {
     bool output = false;
     QString statement = "SELECT " + column + " FROM " + table + " WHERE " + checkColumn;
 
     switch (match) {
-    case sql::exactMatch:
+    case db::exactMatch:
         statement += " = '" + value + QLatin1Char('\'');
         break;
-    case sql::partialMatch:
+    case db::partialMatch:
         value.append(QLatin1Char('%'));
         value.prepend(QLatin1Char('%'));
         statement.append(" LIKE '" + value + QLatin1Char('\''));
@@ -206,19 +95,19 @@ bool db::exists(QString column, QString table, QString checkColumn, QString valu
  * \param table - Name of the table
  * \param column - Name of the column
  * \param value - Identifier for WHERE statement
- * \param match - enum sql::exactMatch or sql::partialMatch
+ * \param match - enum db::exactMatch or db::partialMatch
  * \return QString
  */
-QString db::singleSelect(QString column, QString table, QString checkColumn, QString value, sql::matchType match)
+QString db::singleSelect(QString column, QString table, QString checkColumn, QString value, db::matchType match)
 {
     QString statement = "SELECT " + column + " FROM " + table + " WHERE " + checkColumn;
     QString result;
 
     switch (match) {
-    case sql::exactMatch:
+    case db::exactMatch:
         statement += " = '" + value + QLatin1Char('\'');
         break;
-    case sql::partialMatch:
+    case db::partialMatch:
         value.append(QLatin1Char('%'));
         value.prepend(QLatin1Char('%'));
         statement.append(" LIKE '" + value + QLatin1Char('\''));
@@ -250,10 +139,10 @@ QString db::singleSelect(QString column, QString table, QString checkColumn, QSt
  * \param columns - QVector<QString> Names of the columns to be queried
  * \param value - Identifier for WHERE statement
  * \param checkColumn - column to match value to
- * \param match - enum sql::exactMatch or sql::partialMatch
+ * \param match - enum db::exactMatch or db::partialMatch
  * \return QVector<QString>
  */
-QVector<QString> db::multiSelect(QVector<QString> columns, QString table, QString checkColumn, QString value, sql::matchType match)
+QVector<QString> db::multiSelect(QVector<QString> columns, QString table, QString checkColumn, QString value, db::matchType match)
 {
     QString statement = "SELECT ";
     for(const auto& column : columns)
@@ -267,10 +156,10 @@ QVector<QString> db::multiSelect(QVector<QString> columns, QString table, QStrin
     statement.append(" FROM " + table + " WHERE " + checkColumn);
 
     switch (match) {
-    case sql::exactMatch:
+    case db::exactMatch:
         statement += " = '" + value + QLatin1Char('\'');
         break;
-    case sql::partialMatch:
+    case db::partialMatch:
         value.append(QLatin1Char('%'));
         value.prepend(QLatin1Char('%'));
         statement.append(" LIKE '" + value + QLatin1Char('\''));
@@ -300,8 +189,7 @@ QVector<QString> db::multiSelect(QVector<QString> columns, QString table, QStrin
     }
 }
 /*!
- * \brief db::multiSelect Returns a complete column(s) for a given table. Useful for creating
- * lists for QCompleter
+ * \brief db::multiSelect Returns a complete column(s) for a given table.
  * \param column
  * \param table
  * \return
@@ -350,20 +238,20 @@ QVector<QString> db::multiSelect(QVector<QString> columns, QString table)
  * \param checkColumn Name of the column for WHERE statement
  * \param value The value to be set
  * \param checkvalue The value for the WHERE statement
- * \param match enum sql::exactMatch or sql::partialMatch
+ * \param match enum db::exactMatch or db::partialMatch
  * \return true on success, otherwise error messages in debug out
  */
-bool db::singleUpdate(QString table, QString column, QString value, QString checkColumn, QString checkvalue, sql::matchType match)
+bool db::singleUpdate(QString table, QString column, QString value, QString checkColumn, QString checkvalue, db::matchType match)
 {
     QString statement = "UPDATE " + table;
     statement.append(QLatin1String(" SET ") + column + QLatin1String(" = '") + value);
     statement.append(QLatin1String("' WHERE "));
 
     switch (match) {
-    case sql::exactMatch:
+    case db::exactMatch:
         statement.append(checkColumn + " = '" + checkvalue + QLatin1Char('\''));
         break;
-    case sql::partialMatch:
+    case db::partialMatch:
         value.append(QLatin1Char('%'));
         value.prepend(QLatin1Char('%'));
         statement.append(checkColumn + " LIKE '" + checkvalue + QLatin1Char('\''));
@@ -386,50 +274,6 @@ bool db::singleUpdate(QString table, QString column, QString value, QString chec
         return true;
     }
 }
-
-/*!
- * \brief db::deleteRow Deletes a single row from the database.
- * Query format: DELETE FROM table WHERE column =/LIKE value
- * \param table - Name of the table
- * \param column - Name of the column
- * \param value - Identifier for WHERE statement
- * \param match - enum sql::exactMatch or sql::partialMatch
- * \return true on success, otherwise error messages in debug out
- */
-bool db::deleteRow(QString table, QString column, QString value, sql::matchType match)
-{
-    QString statement = "DELETE FROM " + table + " WHERE ";
-    statement.append(column);
-
-
-    switch (match) {
-    case sql::exactMatch:
-        statement += " = '" + value + QLatin1Char('\'');
-        break;
-    case sql::partialMatch:
-        value.append(QLatin1Char('%'));
-        value.prepend(QLatin1Char('%'));
-        statement.append(" LIKE '" + value + QLatin1Char('\''));
-        break;
-    }
-
-    DEB(statement);
-
-    QSqlQuery q(statement);
-    q.exec();
-    QString error = q.lastError().text();
-
-    if(error.length() > 1)
-    {
-        DEB("Errors have occured: " << error);
-        return false;
-    }else
-    {
-        DEB("Success!");
-        return true;
-    }
-}
-
 /*!
  * \brief db::customQuery Can be used to send a complex query to the database.
  * \param query - the full sql query statement
@@ -459,118 +303,3 @@ QVector<QString> db::customQuery(QString query, int returnValues)
         return result;
     }
 }
-
-/*!
- * \brief db::getColumnNames Looks up column names of a given table
- * \param table name of the table in the database
-
-QVector<QString> db::getColumnNames(QString table)
-{
-    QSqlDatabase db = QSqlDatabase::database("qt_sql_default_connection");
-    QVector<QString> columnNames;
-    QSqlRecord fields = db.record(table);
-
-    for(int i = 0; i < fields.count(); i++){
-        columnNames << fields.field(i).name();
-    }
-    return columnNames;
-}*/
-
-/*!
- * \brief db::update updates the database with the values contained in the object.
- * \return True on Success
- */
-bool db::update()
-{
-    //check prerequisites
-    if(row_id == 0){
-        DEB("Invalid Row ID: " << row_id);
-        return false;
-    }
-    if(data.isEmpty()){
-        DEB("Object Contains no data. Aborting.");
-        return false;
-    }
-    //create query
-    QString statement = "UPDATE " + table + " SET ";
-
-    QMap<QString,QString>::const_iterator i;
-    for (i = data.constBegin(); i != data.constEnd(); ++i){
-        if(i.value()!=QString()){
-            statement += i.key()+QLatin1String("='")+i.value()+QLatin1String("', ");
-        }else{DEB(i.key() << "is empty. skipping.");}
-    }
-    statement.chop(2); // Remove last comma
-    statement.append(QLatin1String(" WHERE _rowid_=")+QString::number(row_id));
-
-    //execute query
-    QSqlQuery q(statement);
-    q.exec();
-    //check result. Upon success, error should be " "
-    QString error = q.lastError().text();
-    if(error.length() < 2){
-        return true;
-    }else{
-        DEB("Query Error: " << q.lastError().text());
-        return false;
-    }
-}
-
-bool db::commit()
-{
-    //check prerequisites
-    if(row_id != 0){
-        DEB("Row ID already set. Unable to commit as new, try update() for existing entries: " << row_id);
-        return false;
-    }
-    if(data.isEmpty()){
-        DEB("Object Contains no data. Aborting.");
-        return false;
-    }
-    QString statement = "INSERT INTO " + table + 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);
-    QString error = q.lastError().text();
-    if(error.length() < 2){
-        DEB("Entry successfully committed.");
-        return true;
-    }else{
-        DEB("Unable to commit. Query Error: " << q.lastError().text());
-        return false;
-    }
-}
-
-
-//Debug
-void db::print()
-{
-    QString v = "Object status:\t\033[38;2;0;255;0;48;2;0;0;0m VALID \033[0m\n";
-    QString nv = "Object status:\t\033[38;2;255;0;0;48;2;0;0;0m INVALID \033[0m\n";
-    QTextStream cout(stdout, QIODevice::WriteOnly);
-
-    cout << "=========Database Object=========\n";
-    if(isValid){cout << v;}else{cout << nv;}
-    cout << "Record from table: " << table << ", row: " << row_id << "\n";
-    cout << "=================================\n";
-    QMap<QString,QString>::const_iterator i;
-    for (i = data.constBegin(); i != data.constEnd(); ++i){
-        cout << i.key() << ": " << i.value() << "\n";
-    }
-}
-
-QString db::debug()
-{
-    print();
-    return QString();
-}

+ 26 - 57
src/database/db.h

@@ -28,71 +28,40 @@
 #include <QDir>
 #include <QDebug>
 
-
-class sql
+/*!
+ * \brief The db class provides a basic API for accessing the database programatically.
+ * It is used to set up the initial connection and various basic queries can be
+ * executed using a set of static functions. When interfacing with the database
+ * for the purpose of adding, deleting or updating entries, the use of the entry class
+ * and its subclasses is recommended.
+ */
+class db
 {
 public:
-    enum tableName {flights, pilots, tails, aircraft, airports };
+    /*!
+     * \brief The editRole enum {createNew, editExisting} is used to differentiate
+     * between creating a new entry in the database vs editing an existing one
+     */
     enum editRole {createNew, editExisting};
+    /*!
+     * \brief The matchType enum {exactMatch, partialMatch} is used to determine the
+     * matching when using a WHERE sql statement. exactMatch results in a "=" operator,
+     * whereas partiasMatch results in a "LIKE" operator
+     */
     enum matchType {exactMatch, partialMatch};
-};
-
-
-class db
-{
-private:
-
-    bool retreiveData();
-
-public:
-
-    db();
-
-    db(sql::tableName, int row_ID);
-
-    db(sql::tableName, QMap<QString, QString> newData);
-
-    bool isValid = false;
-
-    QMap<QString, QString> data;
-
-    QString table = QString();
-
-    int row_id = 0;
-
-    void setData(const QMap<QString, QString> &value);
-
-    QMap<QString, QString> getData() const;
-
-    //Functions
-
-    bool update();
-
-    bool commit();
-
-    static void connect();
-
-    static QVector<QString> getColumnNames(QString table);
-
-    static bool exists(QString column, QString table, QString checkColumn, QString value, sql::matchType match);
-
-    static QString singleSelect(QString column, QString table, QString checkColumn, QString value, sql::matchType match);
-
-    static QVector<QString> multiSelect(QVector<QString> columns, QString table, QString checkColumn, QString value, sql::matchType match);
 
+    static void             connect();
+    static bool             exists(QString column, QString table, QString checkColumn,
+                                   QString value, db::matchType match);
+    static bool             singleUpdate(QString table, QString column, QString value,
+                                         QString checkColumn, QString checkvalue, db::matchType match);
+    static QString          singleSelect(QString column, QString table, QString checkColumn,
+                                         QString value, db::matchType match);
+    static QVector<QString> multiSelect(QVector<QString> columns, QString table,
+                                        QString checkColumn, QString value, db::matchType match);
     static QVector<QString> multiSelect(QVector<QString> columns, QString table);
-
-    static bool singleUpdate(QString table, QString column, QString value, QString checkColumn, QString checkvalue, sql::matchType match);
-
-    static bool deleteRow(QString table, QString column, QString value, sql::matchType match);
-
     static QVector<QString> customQuery(QString query, int returnValues);
 
-    // Debug functionality
-    void print();
-    QString debug();
-    operator QString() { return debug(); } //overload for compatibility with qDebug()
-
 };
 
 #endif // DB_H

+ 1 - 1
src/database/dbinfo.cpp

@@ -18,7 +18,7 @@
 #include "dbinfo.h"
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "dbInfo ::" << __func__ << "\t" << expr
+    qDebug() << "dbInfo ::" << __PRETTY_FUNCTION__ << "\t" << expr
 dbInfo::dbInfo()
 {
     QSqlDatabase db = QSqlDatabase::database("qt_sql_default_connection");

+ 233 - 0
src/database/entry.cpp

@@ -0,0 +1,233 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "entry.h"
+// Debug Makro
+#define DEB(expr) \
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
+
+entry::entry()
+{
+
+}
+
+entry::entry(QString table, int row)
+{
+    //retreive database layout
+    const auto dbContent = dbInfo();
+
+    if(dbContent.tables.contains(table)){
+        position.first = table;
+        columns = dbContent.format.value(table);
+    }else{
+        DEB(table << " not a table in database. Unable to create entry object.");
+        position.first = QString();}
+
+    //Check database for row id
+    QString statement = "SELECT COUNT(*) FROM " + table + " WHERE _rowid_="+QString::number(row);
+    QSqlQuery q(statement);
+    q.next();
+    int rows = q.value(0).toInt();
+    if(rows==0){
+        DEB("No entry found for row id: " << row );
+        position.second = 0;
+    }else{
+        DEB("Retreiving data for row id: " << row);
+        QString statement = "SELECT * FROM " + table + " WHERE _rowid_="+QString::number(row);
+        DEB("Executing SQL...");
+        DEB(statement);
+
+        QSqlQuery q(statement);
+        q.exec();
+        q.next();
+        for(int i=0; i < dbContent.format.value(table).length(); i++){
+            data.insert(dbContent.format.value(table)[i],q.value(i).toString());
+        }
+
+        QString error = q.lastError().text();
+        if(error.length() > 2){
+            DEB("Error: " << q.lastError().text());
+            position.second = 0;
+        }else{
+            position.second = row;
+        }
+    }
+}
+
+entry::entry(QString table, QMap<QString, QString> newData)
+{
+    //retreive database layout
+    const auto dbContent = dbInfo();
+
+    if(dbContent.tables.contains(table)){
+        position.first = table;
+        position.second = 0;
+        columns = dbContent.format.value(table);
+    }else{
+        DEB(table << " not a table in database. Unable to create entry object.");
+        position.first = QString();
+    }
+    //Check validity of newData
+    QVector<QString> badkeys;
+    QMap<QString,QString>::iterator i;
+    for (i = newData.begin(); i != newData.end(); ++i){
+        if(!columns.contains(i.key())){
+            DEB(i.key() << "Not in column list for table " << table <<". Discarding.");
+            badkeys << i.key();
+        }
+    }
+    for(const auto& var : badkeys){
+        newData.remove(var);
+    }
+    data = newData;
+}
+
+void entry::setData(const QMap<QString, QString> &value)
+{
+    data = value;
+}
+
+bool entry::commit()
+{
+    if(exists()){
+        return update();
+    }else{
+        return insert();
+    }
+}
+
+bool entry::remove()
+{
+    if(exists()){
+        QString statement = "DELETE FROM " + position.first +
+                           " WHERE _rowid_=" + QString::number(position.second);
+        QSqlQuery q(statement);
+        QString error = q.lastError().text();
+
+        if(error.length() > 1)
+        {
+            DEB("Errors have occured: " << error);
+            return false;
+        }else
+        {
+            DEB("Entry removed.");
+            return true;
+        }
+    }else{
+        return false;
+    }
+}
+
+bool entry::exists()
+{
+    //Check database for row id
+    QString statement = "SELECT COUNT(*) FROM " + position.first +
+                       " WHERE _rowid_="+QString::number(position.second);
+    QSqlQuery q(statement);
+    q.next();
+    int rows = q.value(0).toInt();
+    if(rows){
+        DEB("Entry exists. "<<rows);
+        return true;
+    }else{
+        DEB("Entry does not exist. "<<rows);
+        return false;
+    }
+}
+
+bool entry::insert()
+{
+    DEB("Inserting...");
+    //check prerequisites
+
+    if(data.isEmpty()){
+        DEB("Object Contains no data. Aborting.");
+        return false;
+    }
+    QString statement = "INSERT INTO " + 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);
+    QString error = q.lastError().text();
+    if(error.length() < 2){
+        DEB("Entry successfully committed.");
+        return true;
+    }else{
+        DEB("Unable to commit. Query Error: " << q.lastError().text());
+        return false;
+    }
+}
+
+bool entry::update()
+{
+    //create query
+    QString statement = "UPDATE " + position.first + " SET ";
+
+    QMap<QString,QString>::const_iterator i;
+    for (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));
+
+    //execute query
+    QSqlQuery q(statement);
+    //check result. Upon success, error should be " "
+    QString error = q.lastError().text();
+    if(error.length() < 2){
+        DEB("Object successfully updated.");
+        return true;
+    }else{
+        DEB("Query Error: " << q.lastError().text());
+        return false;
+    }
+}
+
+//Debug
+void entry::print()
+{
+    QString v = "Object status:\t\033[38;2;0;255;0;48;2;0;0;0m VALID \033[0m\n";
+    QString nv = "Object status:\t\033[38;2;255;0;0;48;2;0;0;0m INVALID \033[0m\n";
+    QTextStream cout(stdout, QIODevice::WriteOnly);
+
+    cout << "=========Database Entry=========\n";
+    //if(isValid){cout << v;}else{cout << nv;}
+    cout << "Record from table: " << position.first << ", row: " << position.second << "\n";
+    cout << "=================================\n";
+    QMap<QString,QString>::const_iterator i;
+    for (i = data.constBegin(); i != data.constEnd(); ++i){
+        cout << i.key() << ":\t" << i.value() << "\n";
+    }
+}
+
+QString entry::debug()
+{
+    print();
+    return QString();
+}

+ 57 - 0
src/database/entry.h

@@ -0,0 +1,57 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include <QCoreApplication>
+#include "src/database/db.h"
+#include "src/database/dbinfo.h"
+/*!
+ * \brief The entry class is the base class for database entries.
+ * It can be seen as a row in a table within the database.
+ *
+ */
+class entry
+{
+public:
+    entry();
+    entry(QString table, int row);
+    entry(QString table, QMap<QString, QString> newData);
+
+    QPair   <QString,int>       position = QPair<QString,int>();     // Position within the database, i.e. <table,row>
+    QVector <QString>           columns  = QVector<QString>();       // The columns within the table
+    QMap    <QString,QString>   data     = QMap<QString,QString>();  // Tha data to fill that table, <column,value>
+
+    void setData(const QMap<QString, QString> &value);
+
+    bool commit();
+    bool remove();
+    bool exists();
+
+    // Debug functionality
+    void print();
+    QString debug();
+    operator QString() { return debug(); } //overload for compatibility with qDebug()
+
+private:
+
+    bool insert();
+    bool update();
+};
+
+#endif // ENTRY_H

+ 105 - 0
src/gui/dialogues/newpilot.cpp

@@ -0,0 +1,105 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#include "newpilot.h"
+#include "ui_newpilot.h"
+// Debug Makro
+#define DEB(expr) \
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
+
+NewPilot::NewPilot(db::editRole edRole, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::NewPilot)
+{
+    role = edRole;
+    ui->setupUi(this);
+}
+
+NewPilot::NewPilot(db::editRole edRole, pilot existingEntry, QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::NewPilot)
+{
+    oldEntry = existingEntry;
+    role = edRole;
+    ui->setupUi(this);
+    formFiller();
+    ui->piclastnameLineEdit->setFocus();
+}
+
+NewPilot::~NewPilot()
+{
+    delete ui;
+}
+
+void NewPilot::on_buttonBox_accepted()
+{
+    DEB("aseontuh");
+    if(ui->piclastnameLineEdit->text().isEmpty()){
+        auto mb = new QMessageBox(this);
+        mb->setText("Last Name is required.");
+    }else{
+        submitForm();
+    }
+}
+
+void NewPilot::formFiller()
+{
+    DEB("Filling Form...");
+    DEB(oldEntry);
+    auto line_edits = parent()->findChildren<QLineEdit*>();
+
+    for (const auto& le : line_edits) {
+        QString key = le->objectName();
+        key.chop(8);//remove "LineEdit"
+        QString value = oldEntry.data.value(key);
+        if(!value.isEmpty()){
+            le->setText(value);
+        }
+    }
+}
+
+void NewPilot::submitForm()
+{
+    DEB("Creating Database Object...");
+    QMap<QString,QString> newData;
+
+    auto line_edits = parent()->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);
+        }
+    }
+    DEB("New Data: "<<newData);
+    DEB("Role: "<<role);
+    //create db object
+    switch (role) {
+    case db::createNew:{
+        auto newEntry = pilot("pilots",newData);;
+        DEB("New Object: ");
+        newEntry.commit();
+        break;}
+    case db::editExisting:
+        oldEntry.setData(newData);
+        DEB("updated entry: "<< oldEntry);
+        oldEntry.commit();
+        break;
+    }
+}

+ 53 - 0
src/gui/dialogues/newpilot.h

@@ -0,0 +1,53 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+#ifndef NEWPILOT_H
+#define NEWPILOT_H
+
+#include <QDialog>
+#include <QMessageBox>
+#include "src/classes/pilot.h"
+
+namespace Ui {
+class NewPilot;
+}
+
+class NewPilot : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit NewPilot(db::editRole, QWidget *parent = nullptr);
+    explicit NewPilot(db::editRole, pilot, QWidget *parent = nullptr);
+    ~NewPilot();
+
+private slots:
+    void on_buttonBox_accepted();
+
+private:
+    Ui::NewPilot *ui;
+
+    db::editRole role;
+
+    pilot oldEntry;
+
+    void formFiller();
+
+    void submitForm();
+};
+
+#endif // NEWPILOT_H

+ 112 - 0
src/gui/dialogues/newpilot.ui

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NewPilot</class>
+ <widget class="QDialog" name="NewPilot">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>640</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="4" column="1">
+    <widget class="QLineEdit" name="phoneLineEdit"/>
+   </item>
+   <item row="0" column="0">
+    <widget class="QLabel" name="picfirstnameLabel">
+     <property name="text">
+      <string>First Name</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="phoneLabel">
+     <property name="text">
+      <string>Phone</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1">
+    <widget class="QLineEdit" name="emailLineEdit"/>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="aliasLabel">
+     <property name="text">
+      <string>Alias</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0">
+    <widget class="QLabel" name="emailLabel">
+     <property name="text">
+      <string>eMail</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="employeeidLabel">
+     <property name="text">
+      <string>Employee ID</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="piclastnameLineEdit"/>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="picfirstnameLineEdit"/>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="piclastnameLabel">
+     <property name="text">
+      <string>Last Name</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QLineEdit" name="aliasLineEdit"/>
+   </item>
+   <item row="3" column="1">
+    <widget class="QLineEdit" name="employeeidLineEdit">
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>NewPilot</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>315</x>
+     <y>410</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

+ 23 - 123
src/gui/dialogues/newtail.cpp

@@ -20,21 +20,11 @@
 
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "NewTail ::" << __func__ << "\t" << expr
+    qDebug() << __PRETTY_FUNCTION__<< "\t" << expr
 
-/*Dialog to be used to edit existing tail
-NewTail::NewTail(aircraft acft, QWidget *parent) :
-    QDialog(parent),
-    ui(new Ui::NewTail)
-{
-    ui->setupUi(this);
-    ui->searchLabel->hide();
-    ui->searchLineEdit->hide();
-    formFiller(acft);
-}*/
 
 //Dialog to be used to create a new tail
-NewTail::NewTail(QString newreg, sql::editRole edRole, QWidget *parent) :
+NewTail::NewTail(QString newreg, db::editRole edRole, QWidget *parent) :
     QDialog(parent),
     ui(new Ui::NewTail)
 {
@@ -49,7 +39,7 @@ NewTail::NewTail(QString newreg, sql::editRole edRole, QWidget *parent) :
 }
 
 //Dialog to be used to edit an existing tail
-NewTail::NewTail(db dbentry, sql::editRole edRole, QWidget *parent) :
+NewTail::NewTail(aircraft dbentry, db::editRole edRole, QWidget *parent) :
     QDialog(parent),
     ui(new Ui::NewTail)
 {
@@ -72,7 +62,7 @@ NewTail::~NewTail()
  * information contained in an aircraft object.
  * \param db - entry retreived from database
  */
-void NewTail::formFiller(db entry)
+void NewTail::formFiller(aircraft entry)
 {
     DEB("Filling Form for a/c" << entry);
     //fill Line Edits
@@ -128,57 +118,6 @@ void NewTail::setupCompleter()
     completer->setFilterMode(Qt::MatchContains);
     ui->searchLineEdit->setCompleter(completer);
 }
-
-/*!
- * \brief NewTail::formFiller populates the Dialog with the
- * information contained in an aircraft object.
- * \param ac
- *
-void NewTail::formFiller(aircraft ac)
-{
-    DEB("Filling Form for a/c" << ac);
-    if(!ac.registration.isEmpty()){
-        ui->registrationLineEdit->setText(ac.registration);
-    }
-
-    ui->companyLineEdit->setText(ac.company);
-    ui->makeLineEdit->setText(ac.make);
-    ui->modelLineEdit->setText(ac.model);
-    ui->variantLineEdit->setText(ac.variant);
-
-    if(ac.singlepilot){
-        ui->operationComboBox->setCurrentIndex(1);
-    }else if(ac.multipilot){
-        ui->operationComboBox->setCurrentIndex(2);
-    }
-
-    if(ac.unpowered){
-        ui->ppTypeComboBox->setCurrentIndex(1);
-    }else if(ac.piston){
-        ui->ppTypeComboBox->setCurrentIndex(2);
-    }else if(ac.turboprop){
-        ui->ppTypeComboBox->setCurrentIndex(3);
-    }else if(ac.jet){
-        ui->ppTypeComboBox->setCurrentIndex(4);
-    }
-
-    if(ac.singleengine){
-        ui->ppNumberComboBox->setCurrentIndex(1);
-    }else if(ac.multiengine){
-        ui->ppNumberComboBox->setCurrentIndex(2);
-    }
-
-    if(ac.light){
-        ui->weightComboBox->setCurrentIndex(1);
-    }else if(ac.medium){
-        ui->weightComboBox->setCurrentIndex(2);
-    }else if(ac.heavy){
-        ui->weightComboBox->setCurrentIndex(3);
-    }else if (ac.super) {
-        ui->weightComboBox->setCurrentIndex(4);
-    }
-}*/
-
 /*!
  * \brief NewTail::verify A simple check for empty recommended fields in the form
  * \return true if all reconmmended fields are populated
@@ -221,7 +160,7 @@ bool NewTail::verify()
     }
 }
 
-void NewTail::submitForm(sql::editRole edRole)
+void NewTail::submitForm(db::editRole edRole)
 {
     DEB("Creating Database Object...");
     QMap<QString,QString> newData;
@@ -244,70 +183,31 @@ void NewTail::submitForm(sql::editRole edRole)
     QVector<QString> weight    = {"light","medium",
                                   "heavy","super"};
 
-    newData.insert(operation[ui->operationComboBox->currentIndex()-1],QLatin1String("1"));
-    newData.insert(ppNumber[ui->ppNumberComboBox->currentIndex()-1],QLatin1String("1"));
-    newData.insert(ppType[ui->ppTypeComboBox->currentIndex()-1],QLatin1String("1"));
-    newData.insert(weight[ui->weightComboBox->currentIndex()-1],QLatin1String("1"));
+    if(ui->operationComboBox->currentIndex()!=0){
+        newData.insert(operation[ui->operationComboBox->currentIndex()-1],QLatin1String("1"));
+    }
+    if(ui->ppNumberComboBox->currentIndex()!=0){
+        newData.insert(ppNumber[ui->ppNumberComboBox->currentIndex()-1],QLatin1String("1"));
+    }
+    if(ui->ppTypeComboBox->currentIndex()!=0){
+        newData.insert(ppType[ui->ppTypeComboBox->currentIndex()-1],QLatin1String("1"));
+    }
+    if(ui->weightComboBox->currentIndex()!=0){
+        newData.insert(weight[ui->weightComboBox->currentIndex()-1],QLatin1String("1"));
+    }
     //create db object
     switch (edRole) {
-    case sql::createNew:{
-        auto newEntry = db(sql::tails,newData);;
-        newEntry.commit();
+    case db::createNew:{
+        auto newEntry = new aircraft("tails",newData);;
+        newEntry->commit();
         break;}
-    case sql::editExisting:
+    case db::editExisting:
         oldEntry.setData(newData);
-        oldEntry.update();
+        oldEntry.commit();
         break;
     }
 }
 
-
-/*!
- * \brief NewTail::createAircraftFromSelection Creates an aircraft object
- * from the current ui selections
- * \return
- *
-aircraft NewTail::createAircraftFromSelection()
-{
-    auto newacft = aircraft();
-    newacft.registration = ui->registrationLineEdit->text();
-    newacft.company = ui->companyLineEdit->text();
-    newacft.make = ui->makeLineEdit->text();
-    newacft.model = ui->modelLineEdit->text();
-    newacft.variant = ui->variantLineEdit->text();
-
-    if(ui->operationComboBox->currentIndex() == 1){
-        newacft.singlepilot = true;
-    }else if(ui->operationComboBox->currentIndex() == 2){
-        newacft.multipilot = true;
-    }
-
-    if(ui->ppNumberComboBox->currentIndex() == 1){
-        newacft.singleengine = true;
-    }else if(ui->ppNumberComboBox->currentIndex() == 2){
-        newacft.multiengine = true;
-    }
-
-    if(ui->ppTypeComboBox->currentIndex() == 1){
-        newacft.unpowered = true;
-    }else if (ui->ppTypeComboBox->currentIndex() == 2) {
-        newacft.piston = true;
-    }else if (ui->ppTypeComboBox->currentIndex() == 3) {
-        newacft.turboprop = true;
-    }else if (ui->ppTypeComboBox->currentIndex() == 4) {
-        newacft.jet = true;
-    }
-
-    if(ui->weightComboBox->currentIndex() == 1){
-        newacft.light = true;
-    }else if (ui->weightComboBox->currentIndex() == 2) {
-        newacft.medium = true;
-    }else if (ui->weightComboBox->currentIndex() == 3) {
-        newacft.heavy = true;
-    }
-    return newacft;
-}*/
-
 /// Slots
 
 void NewTail::on_searchLineEdit_textChanged(const QString &arg1)
@@ -316,7 +216,7 @@ void NewTail::on_searchLineEdit_textChanged(const QString &arg1)
 
         DEB("Template Selected. aircraft_id is: " << idMap.value(arg1));
         //call autofiller for dialog
-        formFiller(db(sql::aircraft,idMap.value(arg1)));
+        formFiller(aircraft("aircraft",idMap.value(arg1)));
         ui->searchLineEdit->setStyleSheet("border: 1px solid green");
     }else{
         //for example, editing finished without selecting a result from Qcompleter

+ 7 - 7
src/gui/dialogues/newtail.h

@@ -41,11 +41,11 @@ class NewTail : public QDialog
 
 public:
 
-    explicit NewTail(aircraft acft, QWidget *parent = nullptr);
+    //explicit NewTail(aircraft acft, QWidget *parent = nullptr);
     //to create new tail from scratch
-    explicit NewTail(QString reg, sql::editRole edRole, QWidget *parent = nullptr);
+    explicit NewTail(QString reg, db::editRole edRole, QWidget *parent = nullptr);
     //to edit existing tail
-    explicit NewTail(db dbentry, sql::editRole edRole, QWidget *parent = nullptr);
+    explicit NewTail(aircraft dbentry, db::editRole edRole, QWidget *parent = nullptr);
 
     ~NewTail();
 
@@ -68,17 +68,17 @@ private:
 
     Ui::NewTail *ui;
 
-    sql::editRole role;
+    db::editRole role;
 
-    db oldEntry;
+    aircraft oldEntry;
 
-    void submitForm(sql::editRole edRole);
+    void submitForm(db::editRole edRole);
 
     void setupCompleter();
 
     //void formFiller(aircraft);
 
-    void formFiller(db);
+    void formFiller(aircraft);
 
     bool verify();
 

+ 24 - 5
src/gui/widgets/aircraftwidget.cpp

@@ -1,9 +1,26 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #include "aircraftwidget.h"
 #include "ui_aircraftwidget.h"
 
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "aircraftWidget ::" << __func__ << "\t" << expr
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
 
 aircraftWidget::aircraftWidget(QWidget *parent) :
     QWidget(parent),
@@ -64,8 +81,8 @@ void aircraftWidget::tableView_selectionChanged(const QItemSelection &index, con
     setSelectedAircraft(index.indexes()[0].data().toInt());
     DEB("Selected aircraft with ID#: " << selectedAircraft);
 
-    auto nt = new NewTail(db(sql::tails,selectedAircraft),sql::editExisting,this);
-    //auto nt = new NewTail(db(sql::tails,selectedAircraft),this);
+    auto nt = new NewTail(aircraft("tails",selectedAircraft),db::editExisting,this);
+    //auto nt = new NewTail(db(db::tails,selectedAircraft),this);
 
     nt->setWindowFlag(Qt::Widget);
     ui->stackedWidget->addWidget(nt);
@@ -76,7 +93,9 @@ void aircraftWidget::on_deleteButton_clicked()
 {
     if(selectedAircraft > 0){
 
-        db::deleteRow("tails","_rowid_",QString::number(selectedAircraft),sql::exactMatch);
+        auto ac = new aircraft("tails",selectedAircraft);
+        ac->remove();
+
 
         QSqlTableModel *model = new QSqlTableModel;
         model->setTable("viewTails");
@@ -93,6 +112,6 @@ void aircraftWidget::on_deleteButton_clicked()
 
 void aircraftWidget::on_newButton_clicked()
 {
-    auto nt = new NewTail(QString(), sql::createNew,this);
+    auto nt = new NewTail(QString(), db::createNew,this);
     nt->show();
 }

+ 17 - 0
src/gui/widgets/aircraftwidget.h

@@ -1,3 +1,20 @@
+/*
+ *openPilot Log - A FOSS Pilot Logbook Application
+ *Copyright (C) 2020  Felix Turowsky
+ *
+ *This program is free software: you can redistribute it and/or modify
+ *it under the terms of the GNU General Public License as published by
+ *the Free Software Foundation, either version 3 of the License, or
+ *(at your option) any later version.
+ *
+ *This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
 #ifndef AIRCRAFTWIDGET_H
 #define AIRCRAFTWIDGET_H
 

+ 7 - 8
src/gui/widgets/homewidget.cpp

@@ -20,7 +20,7 @@
 
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "homeWidget ::" << __func__ << "\t" << expr
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
 
 
 homeWidget::homeWidget(QWidget *parent) :
@@ -52,15 +52,14 @@ homeWidget::~homeWidget()
 
 void homeWidget::on_pushButton_clicked()
 {
-    //aircraft ac(203,aircraft::tail);
+    auto pl = new pilot("pilots",498);
+    auto np = new NewPilot(db::editExisting,*pl,this);
+    np->show();
 
+    //auto ob = db(db::pilots,34);
 
-    //aircraft ac2(114,aircraft::acft);
-    //aircraft ac3(0,aircraft::acft);
-
-    auto ob = db(sql::tails,1);
-    auto nt = new NewTail("DE-NEU", sql::createNew,this);
-    nt->show();
+    //auto np = new NewPilot(db::editExisting,ob,this);
+    //np->show();
 
 
 }

+ 1 - 0
src/gui/widgets/homewidget.h

@@ -25,6 +25,7 @@
 #include "src/classes/completionlist.h"
 #include "src/gui/dialogues/newtail.h"
 #include "src/classes/aircraft.h"
+#include "src/gui/dialogues/newpilot.h"
 
 namespace Ui {
 class homeWidget;

+ 5 - 3
src/gui/widgets/logbookwidget.cpp

@@ -20,13 +20,14 @@
 
 // Debug Makro
 #define DEB(expr) \
-    qDebug() << "logbookWidget ::" << __func__ << "\t" << expr
+    qDebug() << __PRETTY_FUNCTION__ << "\t" << expr
 
 logbookWidget::logbookWidget(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::logbookWidget)
 {
     ui->setupUi(this);
+    ui->filterDateEdit->setDate(QDate::currentDate());
     ui->filterDateEdit_2->setDate(QDate::currentDate());
 
     auto start = std::chrono::high_resolution_clock::now(); // timer for performance testing
@@ -108,7 +109,7 @@ void logbookWidget::on_deleteFlightPushButton_clicked()
         QVector<QString> columns = {
             "doft", "dept", "dest"
         };
-        QVector<QString> details = db::multiSelect(columns,"flights","id",QString::number(selectedFlight),sql::exactMatch);
+        QVector<QString> details = db::multiSelect(columns,"flights","id",QString::number(selectedFlight),db::exactMatch);
         QString detailsstring = "The following flight will be deleted:\n\n";
         for(const auto& item : details)
         {
@@ -123,7 +124,8 @@ void logbookWidget::on_deleteFlightPushButton_clicked()
         if (reply == QMessageBox::Yes)
         {
             DEB("Deleting flight with ID# " << selectedFlight);
-            db::deleteRow("flights","id",QString::number(selectedFlight),sql::exactMatch);
+            auto en = new flight("flights",selectedFlight);
+            en->remove();
 
             QSqlTableModel *ShowAllModel = new QSqlTableModel; //refresh view
             ShowAllModel->setTable("Logbook");

+ 1 - 0
src/gui/widgets/logbookwidget.h

@@ -26,6 +26,7 @@
 #include <QDebug>
 
 #include "src/database/db.h"
+#include "src/classes/flight.h"
 
 namespace Ui {
 class logbookWidget;