/* *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 . */ #include "dbflight.h" #include "dbpilots.h" #include "dbaircraft.h" /*! * \brief dbFlight::verifyInput Checks the validity of the data in a * flight object against the database and sets its verified flag * accordingly. Information about partial validity can be obtained * by querying the flight objects invalidItems member. */ flight dbFlight::verifyInput(flight object) { if (object.doft.isValid()){ object.invalidItems.removeOne("doft"); qDebug() << "doft verified."; }else{ qWarning() << "Invalid entry: doft"; } if(dbAirport::checkICAOValid(object.dept)){ object.invalidItems.removeOne("dept"); qDebug() << "dept verified."; }else{ qWarning() << "Invalid entry: dept"; } if(dbAirport::checkICAOValid(object.dest)){ object.invalidItems.removeOne("dest"); qDebug() << "dest verified."; }else{ qWarning() << "Invalid entry: dest"; } if(object.tofb.isValid()){ object.invalidItems.removeOne("tofb"); qDebug() << "tofb verified."; }else{ qWarning() << "Invalid entry: tofb"; } if(object.tonb.isValid()){ object.invalidItems.removeOne("tonb"); qDebug() << "tonb verified."; }else{ qWarning() << "Invalid entry: tonb"; } if(dbPilots::verifyPilotExists(object.pic.split(QLatin1Char(',')))){ object.invalidItems.removeOne("pic"); qDebug() << "pic verified."; }else{ qWarning() << "Invalid entry: pic"; } //acft QTime tblkcheck = calc::blocktime(object.tofb, object.tonb); if(object.tblk.isValid() && !object.tblk.isNull() && tblkcheck == object.tblk){ object.invalidItems.removeOne("tblk"); qDebug() << "tblk verified."; }else{ qWarning() << "Invalid entry: tblk"; } if(!dbAircraft::retreiveTailId(object.acft).isEmpty()){ object.invalidItems.removeOne("acft"); qDebug() << "acft verified."; }else{ qWarning() << "Invalid entry: acft"; } if(object.invalidItems.isEmpty()){ object.isValid = true; qDebug() << "All checks passed. Object is now verified."; }else{ qDebug() << "Not all checks have been passed."; qDebug() << "Invalid items: " << object.invalidItems; } return object; /* To Do: Checks on internal logic, i.e. times <= tblk, * restrict what strings are allowed in remarks etc. 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];*/ } /*! * \brief dbFlight::retreiveFlight Runs a select statement on the database * for a given flight_id and returns a flight object containing the details * for the given ID. If no matching ID is found, an empty flight object is * returned * \param flight_id Primary Key of flight database */ flight dbFlight::retreiveFlight(QString flight_id) { QSqlQuery query; query.prepare("SELECT * FROM flights WHERE id = ?"); query.addBindValue(flight_id); query.exec(); if(query.first()); else { qWarning() << __func__ << "No Flight with this ID found"; return flight(); //return empty } flight object; object.id = query.value(0).toInt(); object.doft = QDate::fromString(query.value(1).toString(),Qt::ISODate); object.dept = query.value(2).toString(); object.dest = query.value(3).toString(); object.tofb = QTime::fromString( calc::minutes_to_string( query.value(4).toString()),"hh:mm"); object.tonb = QTime::fromString( calc::minutes_to_string( query.value(5).toString()),"hh:mm"); object.pic = dbPilots::retreivePilotNameFromID( query.value(6).toString()); object.acft = dbAircraft::retreiveRegistration( query.value(7).toString()); object.tblk = QTime::fromString( calc::minutes_to_string( query.value(8).toString()),"hh:mm"); object.tSPSE = QTime::fromString( calc::minutes_to_string( query.value(9).toString()),"hh:mm"); object.tSPME = QTime::fromString( calc::minutes_to_string( query.value(10).toString()),"hh:mm"); object.tMP = QTime::fromString( calc::minutes_to_string( query.value(11).toString()),"hh:mm"); object.tNIGHT = QTime::fromString( calc::minutes_to_string( query.value(12).toString()),"hh:mm"); object.tIFR = QTime::fromString( calc::minutes_to_string( query.value(13).toString()),"hh:mm"); object.tPIC = QTime::fromString( calc::minutes_to_string( query.value(14).toString()),"hh:mm"); object.tPICUS = QTime::fromString( calc::minutes_to_string( query.value(15).toString()),"hh:mm"); object.tSIC = QTime::fromString( calc::minutes_to_string( query.value(16).toString()),"hh:mm"); object.tDUAL = QTime::fromString( calc::minutes_to_string( query.value(17).toString()),"hh:mm"); object.tFI = QTime::fromString( calc::minutes_to_string( query.value(18).toString()),"hh:mm"); object.tSIM = QTime::fromString( calc::minutes_to_string( query.value(19).toString()),"hh:mm"); object.pilotFlying = query.value(20).toInt(); object.toDay = query.value(21).toInt(); object.toNight = query.value(22).toInt(); object.ldgDay = query.value(23).toInt(); object.ldgNight = query.value(24).toInt(); object.autoland = query.value(25).toInt(); object.secondPilot = query.value(26).toInt(); object.thirdPilot = query.value(27).toInt(); object.approachType = query.value(28).toString(); object.flightNumber = query.value(29).toString(); object.remarks = query.value(30).toString(); //Database entries are assumed to be valid object.isValid = true; object.invalidItems.clear(); return object; } bool dbFlight::commitFlight(flight object) { //To Do qDebug() << object; return false; } /*! * \brief SelectFlightById Retreives a single flight from the database. * \param flight_id Primary Key of flights database * \return Flight details of selected flight. */ QVector dbFlight::selectFlightById(QString flight_id) { QSqlQuery query; query.prepare("SELECT * FROM flights WHERE id = ?"); query.addBindValue(flight_id); query.exec(); if(query.first()); else { qDebug() << "db::SelectFlightById - No Flight with this ID found"; QVector flight; //return empty return flight; } QVector flight; flight.append(query.value(0).toString()); flight.append(query.value(1).toString()); flight.append(query.value(2).toString()); flight.append(query.value(3).toString()); flight.append(query.value(4).toString()); flight.append(query.value(5).toString()); flight.append(query.value(6).toString()); flight.append(query.value(7).toString()); flight.append(query.value(8).toString()); qDebug() << "db::SelectFlightById - retreived flight: " << flight; return flight; } /*! * \brief deleteFlightById Deletes a Flight from the database. * Entries in the basic flights table as well as in the extras table are deleted. * \param flight_id The primary key of the entry in the database * \return True if no errors, otherwise false */ bool dbFlight::deleteFlightById(QString flight_id) { QSqlQuery query; query.prepare("DELETE FROM flights WHERE id = ?"); query.addBindValue(flight_id); query.exec(); QString error = query.lastError().text(); QSqlQuery query2; query2.prepare("DELETE FROM extras WHERE extras_id = ?"); query2.addBindValue(flight_id); query2.exec(); QString error2 = query2.lastError().text(); qDebug() << "db::deleteFlightById: Removing flight with ID#: " << flight_id; if(error.length() > 0 || error2.length() > 0) { qWarning() << "db::deleteFlightsById: Errors have occured: " << error << " " << error2; return false; }else { return true; } } /*! * \brief CreateFlightVectorFromInput Converts input from NewFlight Window into database format * \param doft Date of flight * \param dept Place of Departure * \param tofb Time Off Blocks (UTC) * \param dest Place of Destination * \param tonb Time On Blocks (UTC) * \param tblk Total Block Time * \param pic Pilot in command * \param acft Aircraft * \return Vector of values ready for committing */ QVector dbFlight::createFlightVectorFromInput(QString doft, QString dept, QTime tofb, QString dest, QTime tonb, QTime tblk, QString pic, QString acft) { QVector flight; flight.insert(0, ""); // ID, created as primary key during commit flight.insert(1, doft); flight.insert(2, dept); flight.insert(3, QString::number(calc::time_to_minutes(tofb))); flight.insert(4, dest); flight.insert(5, QString::number(calc::time_to_minutes(tonb))); flight.insert(6, QString::number(calc::time_to_minutes(tblk))); flight.insert(7, pic); // lookup and matching tbd flight.insert(8, acft);// lookup and matching tbd //qDebug() << flight; return flight; } /*! * \brief CommitToScratchpad Commits the inputs of the NewFlight window to a scratchpad * to make them available for restoring entries when the input fields are being reloaded. * \param flight The input data, which was not accepted for commiting to the flights table. */ void dbFlight::commitToScratchpad(QVector flight)// to store input mask { //qDebug() << "Saving invalid flight to scratchpad"; QSqlQuery query; query.prepare("INSERT INTO scratchpad (doft, dept, tofb, dest, tonb, tblk, pic, acft) " "VALUES (:doft, :dept, :tofb, :dest, :tonb, :tblk, :pic, :acft)"); //flight[0] is primary key, not required for commit query.bindValue(":doft", flight[1]); //string query.bindValue(":dept", flight[2]); query.bindValue(":tofb", flight[3].toInt()); //int query.bindValue(":dest", flight[4]); query.bindValue(":tonb", flight[5].toInt()); query.bindValue(":tblk", flight[6].toInt()); query.bindValue(":pic", flight[7].toInt()); query.bindValue(":acft", flight[8].toInt()); query.exec(); qDebug() << query.lastError().text(); } /*! * \brief RetreiveScratchpad Selects data from scratchpad * \return Vector of data contained in scratchpad */ QVector dbFlight::retreiveScratchpad() { //qDebug() << "Retreiving invalid flight from scratchpad"; QSqlQuery query; query.prepare("SELECT * FROM scratchpad"); query.exec(); if(query.first()); else { //qDebug() << ("scratchpad empty"); QVector flight; //return empty return flight; } query.previous(); QVector flight; while (query.next()) { flight.append(query.value(0).toString()); flight.append(query.value(1).toString()); flight.append(query.value(2).toString()); flight.append(calc::minutes_to_string((query.value(3).toString()))); flight.append(query.value(4).toString()); flight.append(calc::minutes_to_string((query.value(5).toString()))); flight.append(calc::minutes_to_string((query.value(6).toString()))); flight.append(query.value(7).toString()); flight.append(query.value(8).toString()); } clearScratchpad(); return flight; } /*! * \brief CheckScratchpad Verifies if the scratchpad contains data * \return true if scratchpad contains data */ bool dbFlight::checkScratchpad() // see if scratchpad is empty { //qDebug() << "Checking if scratchpad contains data"; QSqlQuery query; query.prepare("SELECT * FROM scratchpad"); query.exec(); if(query.first()) { //qDebug() << "Scratchpad contains data"; return 1; } else { //qDebug() << ("Scratchpad contains NO data"); return 0; } } /*! * \brief ClearScratchpad Deletes data contained in the scratchpad */ void dbFlight::clearScratchpad() { qDebug() << "Deleting scratchpad"; QSqlQuery query; query.prepare("DELETE FROM scratchpad;"); query.exec(); }