dbman.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. /*
  2. *openPilot Log - A FOSS Pilot Logbook Application
  3. *Copyright (C) 2020 Felix Turowsky
  4. *
  5. *This program is free software: you can redistribute it and/or modify
  6. *it under the terms of the GNU General Public License as published by
  7. *the Free Software Foundation, either version 3 of the License, or
  8. *(at your option) any later version.
  9. *
  10. *This program is distributed in the hope that it will be useful,
  11. *but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. *GNU General Public License for more details.
  14. *
  15. *You should have received a copy of the GNU General Public License
  16. *along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. #include <QCoreApplication>
  19. #include <QDebug>
  20. #include <QSqlDatabase>
  21. #include <QSqlDriver>
  22. #include <QSqlError>
  23. #include <QSqlQuery>
  24. #include "calc.h"
  25. #include <chrono>
  26. #include <QRandomGenerator>
  27. #include <QStandardPaths>
  28. class db
  29. {
  30. public:
  31. static void connect()
  32. {
  33. const QString DRIVER("QSQLITE");
  34. if(QSqlDatabase::isDriverAvailable(DRIVER))
  35. {
  36. QSqlDatabase db = QSqlDatabase::addDatabase(DRIVER);
  37. //QString pathtodb = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
  38. //db.setDatabaseName(pathtodb+"/flog.db");
  39. //qDebug() << "Database: " << pathtodb+"/logbook.db";
  40. db.setDatabaseName("logbook.db");
  41. if(!db.open())
  42. qWarning() << "MainWindow::DatabaseConnect - ERROR: " << db.lastError().text();
  43. }
  44. else
  45. qWarning() << "MainWindow::DatabaseConnect - ERROR: no driver " << DRIVER << " available";
  46. }
  47. static void initexample()
  48. {
  49. QSqlQuery query("CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT)");
  50. if(!query.isActive())
  51. qWarning() << "MainWindow::DatabaseInit - ERROR: " << query.lastError().text();
  52. }
  53. static void queryexamplenamedbinding()
  54. {
  55. QSqlQuery query;
  56. //query.prepare("SELECT * FROM people");
  57. //query.prepare("SELECT * FROM people WHERE name LIKE 'Linus' OR id = :id");
  58. query.prepare("SELECT * from people WHERE name LIKE :name");
  59. query.bindValue(":name", "%Linus%");
  60. query.bindValue(":id",2);
  61. query.exec();
  62. /*
  63. * QSqlQuery provides access to the result set one record at a time. After the call to exec(),
  64. * QSqlQuery's internal pointer is located one position before the first record.
  65. * We must call QSqlQuery::next() once to advance to the first record, then next() again
  66. * repeatedly to access the other records, until it returns false. Here's a typical loop that
  67. * iterates over all the records in order:
  68. * After a SELECT query is executed we have to browse the records (result rows) returned to access
  69. * the data. In this case we try to retrieve the first record calling the function first which
  70. * returns true when the query has been successful and false otherwise.
  71. */
  72. if(query.first());
  73. else
  74. qDebug() << ("No entry found");
  75. query.previous();//To go back to index 0
  76. while (query.next()) {
  77. QString name = query.value(1).toString();
  78. int id = query.value(0).toInt();
  79. qDebug() << name << id;
  80. }
  81. /*
  82. *The QSqlQuery::value() function returns the value of a field in the current record. Fields are
  83. * specified as zero-based indexes. QSqlQuery::value() returns a QVariant, a type that can hold
  84. * various C++ and core Qt data types such as int, QString, and QByteArray. The different database
  85. * types are automatically mapped into the closest Qt equivalent. In the code snippet, we call
  86. * QVariant::toString() and QVariant::toInt() to convert variants to QString and int.
  87. */
  88. }
  89. /*
  90. *
  91. *
  92. * Flights Database Related Functions
  93. *
  94. *
  95. */
  96. static QVector<QString> SelectFlightDate(QString doft)
  97. {
  98. QSqlQuery query;
  99. if (doft == "ALL")
  100. {
  101. query.prepare("SELECT * FROM flights ORDER BY doft DESC, tofb ASC");
  102. qDebug() << "All flights selected";
  103. }else
  104. {
  105. query.prepare("SELECT * FROM flights WHERE doft = ? ORDER BY tofb ASC");
  106. query.addBindValue(doft);
  107. qDebug() << "Searching flights for " << doft;
  108. }
  109. //query.prepare("SELECT * FROM flights WHERE doft = ?");
  110. query.exec();
  111. if(query.first());
  112. else
  113. {
  114. qDebug() << ("No flight with this date found");
  115. QVector<QString> flight; //return empty
  116. return flight;
  117. }
  118. query.previous();// To go back to index 0
  119. query.last(); // this can be very slow, used to determine query size since .size is not supported by sqlite
  120. int numRows = query.at() + 1; // Number of rows (flights) in the query
  121. query.first();
  122. query.previous();// Go back to index 0
  123. QVector<QString> flight(numRows * 9); // Every flight has 9 fields in the database
  124. int index = 0; // counter for output vector
  125. while (query.next()) {
  126. QString id = query.value(0).toString();
  127. QString doft = query.value(1).toString();
  128. QString dept = query.value(2).toString();
  129. QString tofb = calc::minutes_to_string((query.value(3).toString()));
  130. QString dest = query.value(4).toString();
  131. QString tonb = calc::minutes_to_string((query.value(5).toString()));
  132. QString tblk = calc::minutes_to_string((query.value(6).toString()));
  133. QString pic = db::RetreivePilotNameFromID(query.value(7).toString());
  134. QString acft = db::RetreiveRegistration(query.value(8).toString());
  135. //qDebug() << id << doft << dept << tofb << dest << tonb << tblk << pic << acft << endl;
  136. flight[index] = id;
  137. ++index;
  138. flight[index] = doft;
  139. ++index;
  140. flight[index] = dept;
  141. ++index;
  142. flight[index] = tofb;
  143. ++index;
  144. flight[index] = dest;
  145. ++index;
  146. flight[index] = tonb;
  147. ++index;
  148. flight[index] = tblk;
  149. ++index;
  150. flight[index] = pic;
  151. ++index;
  152. flight[index] = acft;
  153. ++index;
  154. }
  155. //QString minutes = calc::minutes_to_string(flight[3]);
  156. //flight.replace(3, minutes);
  157. //qDebug() << "Length of flight vector " << flight.size();
  158. return flight;
  159. }
  160. static QVector<QString> SelectFlightById(QString flight_id)
  161. {
  162. QSqlQuery query;
  163. query.prepare("SELECT * FROM flights WHERE id = ?");
  164. query.addBindValue(flight_id);
  165. query.exec();
  166. if(query.first());
  167. else
  168. {
  169. qDebug() << "db::SelectFlightById - No Flight with this ID found";
  170. QVector<QString> flight; //return empty
  171. return flight;
  172. }
  173. QVector<QString> flight;
  174. flight.append(query.value(0).toString());
  175. flight.append(query.value(1).toString());
  176. flight.append(query.value(2).toString());
  177. flight.append(query.value(3).toString());
  178. flight.append(query.value(4).toString());
  179. flight.append(query.value(5).toString());
  180. flight.append(query.value(6).toString());
  181. flight.append(query.value(7).toString());
  182. flight.append(query.value(8).toString());
  183. /*
  184. flight.append(calc::minutes_to_string((query.value(3).toString())));
  185. flight.append(query.value(4).toString());
  186. flight.append(calc::minutes_to_string((query.value(5).toString())));
  187. flight.append(calc::minutes_to_string((query.value(6).toString())));
  188. flight.append(db::RetreivePilotNameFromID(query.value(7).toString()));
  189. flight.append(db::RetreiveRegistration(query.value(8).toString()));
  190. */
  191. qDebug() << "db::SelectFlightById - retreived flight: " << flight;
  192. return flight;
  193. }
  194. static QVector<QString> CreateFlightVectorFromInput(QString doft, QString dept, QTime tofb, QString dest, QTime tonb, QTime tblk, QString pic, QString acft)
  195. {
  196. QVector<QString> flight;
  197. flight.insert(0, ""); // ID, created as primary key during commit
  198. flight.insert(1, doft);
  199. flight.insert(2, dept);
  200. flight.insert(3, QString::number(calc::time_to_minutes(tofb)));
  201. flight.insert(4, dest);
  202. flight.insert(5, QString::number(calc::time_to_minutes(tonb)));
  203. flight.insert(6, QString::number(calc::time_to_minutes(tblk)));
  204. flight.insert(7, pic); // lookup and matching tbd
  205. flight.insert(8, acft);// lookup and matching tbd
  206. //qDebug() << flight;
  207. return flight;
  208. }
  209. static int CommitFlight(QVector<QString> flight)// flight vector shall always have length 9
  210. {
  211. QSqlQuery query;
  212. query.prepare("INSERT INTO flights (doft, dept, tofb, dest, tonb, tblk, pic, acft) "
  213. "VALUES (:doft, :dept, :tofb, :dest, :tonb, :tblk, :pic, :acft)");
  214. //flight[0] is primary key, not required for commit
  215. query.bindValue(":doft", flight[1]); //string
  216. query.bindValue(":dept", flight[2]);
  217. query.bindValue(":tofb", flight[3].toInt()); //int
  218. query.bindValue(":dest", flight[4]);
  219. query.bindValue(":tonb", flight[5].toInt());
  220. query.bindValue(":tblk", flight[6].toInt());
  221. query.bindValue(":pic", flight[7].toInt());
  222. query.bindValue(":acft", flight[8].toInt());
  223. query.exec();
  224. qDebug() << "Error message for commiting flight: " << query.lastError().text();
  225. QSqlQuery query2;
  226. query2.prepare("INSERT INTO extras DEFAULT VALUES");
  227. query2.exec();
  228. qDebug() << "Creating extras entry" << query2.lastError().text();
  229. return 0;
  230. }
  231. static int CommitToScratchpad(QVector<QString> flight)// to store input mask
  232. {
  233. //qDebug() << "Saving invalid flight to scratchpad";
  234. QSqlQuery query;
  235. query.prepare("INSERT INTO scratchpad (doft, dept, tofb, dest, tonb, tblk, pic, acft) "
  236. "VALUES (:doft, :dept, :tofb, :dest, :tonb, :tblk, :pic, :acft)");
  237. //flight[0] is primary key, not required for commit
  238. query.bindValue(":doft", flight[1]); //string
  239. query.bindValue(":dept", flight[2]);
  240. query.bindValue(":tofb", flight[3].toInt()); //int
  241. query.bindValue(":dest", flight[4]);
  242. query.bindValue(":tonb", flight[5].toInt());
  243. query.bindValue(":tblk", flight[6].toInt());
  244. query.bindValue(":pic", flight[7].toInt());
  245. query.bindValue(":acft", flight[8].toInt());
  246. query.exec();
  247. qDebug() << query.lastError().text();
  248. return 0;
  249. }
  250. static bool CheckScratchpad() // see if scratchpad is empty
  251. {
  252. //qDebug() << "Checking if scratchpad contains data";
  253. QSqlQuery query;
  254. query.prepare("SELECT * FROM scratchpad");
  255. query.exec();
  256. if(query.first())
  257. {
  258. //qDebug() << "Scratchpad contains data";
  259. return 1;
  260. }
  261. else
  262. {
  263. //qDebug() << ("Scratchpad contains NO data");
  264. return 0;
  265. }
  266. }
  267. static QVector<QString> RetreiveScratchpad()
  268. {
  269. //qDebug() << "Retreiving invalid flight from scratchpad";
  270. QSqlQuery query;
  271. query.prepare("SELECT * FROM scratchpad");
  272. query.exec();
  273. if(query.first());
  274. else
  275. {
  276. //qDebug() << ("scratchpad empty");
  277. QVector<QString> flight; //return empty
  278. return flight;
  279. }
  280. query.previous();// To go back to index 0
  281. //query.last(); // this can be very slow, used to determine query size since .size is not supported by sqlite
  282. //int numRows = query.at() + 1; // Number of rows (flights) in the query
  283. //query.first();
  284. //query.previous();// Go back to index 0
  285. //QVector<QString> flight(numRows * 9); // Every flight has 9 fields in the database
  286. QVector<QString> flight(9);
  287. int index = 0; // counter for output vector
  288. while (query.next()) {
  289. QString id = query.value(0).toString();
  290. QString doft = query.value(1).toString();
  291. QString dept = query.value(2).toString();
  292. QString tofb = calc::minutes_to_string((query.value(3).toString()));
  293. QString dest = query.value(4).toString();
  294. QString tonb = calc::minutes_to_string((query.value(5).toString()));
  295. QString tblk = calc::minutes_to_string((query.value(6).toString()));
  296. QString pic = query.value(7).toString();
  297. QString acft = query.value(8).toString();
  298. //qDebug() << id << doft << dept << tofb << dest << tonb << tblk << pic << acft << endl;
  299. flight[index] = id;
  300. ++index;
  301. flight[index] = doft;
  302. ++index;
  303. flight[index] = dept;
  304. ++index;
  305. flight[index] = tofb;
  306. ++index;
  307. flight[index] = dest;
  308. ++index;
  309. flight[index] = tonb;
  310. ++index;
  311. flight[index] = tblk;
  312. ++index;
  313. flight[index] = pic;
  314. ++index;
  315. flight[index] = acft;
  316. ++index;
  317. }
  318. ClearScratchpad();
  319. return flight;
  320. }
  321. static void ClearScratchpad()
  322. {
  323. qDebug() << "Deleting scratchpad";
  324. QSqlQuery query;
  325. query.prepare("DELETE FROM scratchpad;");
  326. query.exec();
  327. }
  328. static bool DeleteFlightById(QString flight_id)
  329. {
  330. QSqlQuery query;
  331. query.prepare("DELETE FROM flights WHERE id = ?");
  332. query.addBindValue(flight_id);
  333. query.exec();
  334. QString error = query.lastError().text();
  335. qDebug() << "db::DeleteFlightById: Removing flight with ID#: " << flight_id << "Query Error: " << error;
  336. if(error.length() > 0)
  337. {
  338. return false;
  339. }else
  340. {
  341. return true;
  342. }
  343. }
  344. /*
  345. *
  346. *
  347. * Pilots Database Related Functions
  348. *
  349. *
  350. */
  351. static QString RetreivePilotNameFromID(QString pilotID)
  352. /* Looks up the pilot ID in the Database and returns the name as a string
  353. * unless the pilot in command is the logbook owner.
  354. */
  355. {
  356. QString pilotName("");
  357. if (pilotID == "1")
  358. {
  359. pilotName = "self";
  360. return pilotName;
  361. }
  362. QSqlQuery query;
  363. query.prepare("SELECT piclastname, picfirstname, alias FROM pilots WHERE pilot_id == ?");
  364. query.addBindValue(pilotID.toInt());
  365. query.exec();
  366. //if(query.first());
  367. //else
  368. // qDebug() << ("No Pilot with this ID found");
  369. //query.previous();//To go back to index 0
  370. while (query.next()) {
  371. pilotName.append(query.value(0).toString());
  372. pilotName.append(", ");
  373. pilotName.append(query.value(1).toString());//.left(1));
  374. //pilotName.append(".");
  375. }
  376. if(pilotName.length() == 0)
  377. {
  378. qDebug() << ("No Pilot with this ID found");
  379. }
  380. return pilotName;
  381. }
  382. static QString RetreivePilotIdFromString(QString lastname, QString firstname)
  383. {
  384. QSqlQuery query;
  385. query.prepare("SELECT pilot_id from pilots "
  386. "WHERE piclastname = ? AND picfirstname LIKE ?");
  387. query.addBindValue(lastname);
  388. firstname.prepend("%"); firstname.append("%");
  389. query.addBindValue(firstname);
  390. query.exec();
  391. QString id;
  392. if(query.first()){id.append(query.value(0).toString());}
  393. return id;
  394. }
  395. static QStringList RetreivePilotNameFromString(QString searchstring)
  396. /* Searches the pilot Name in the Database and returns the name as a vector of results
  397. * unless the pilot in command is the logbook owner.
  398. */
  399. {
  400. QString firstname = searchstring; //To Do: Two control paths, one for single word, query as before with only searchstring
  401. QString lastname = searchstring; // second control path with comma, lastname like AND firstname like
  402. if(searchstring.contains(QLatin1Char(',')))
  403. {
  404. QStringList namelist = searchstring.split(QLatin1Char(','));
  405. QString lastname = namelist[0].trimmed();
  406. lastname = lastname.toLower();
  407. lastname[0] = lastname[0].toUpper();
  408. lastname.prepend("%"), lastname.append("%");
  409. QString firstname = namelist[1].trimmed();
  410. if(firstname.length()>1)
  411. {
  412. firstname = firstname.toLower();
  413. firstname[0] = firstname[0].toUpper();
  414. firstname.prepend("%"), firstname.append("%");
  415. }
  416. qDebug() << "db::RetreivePilotNameFromString: first last after comma";
  417. qDebug() << firstname << lastname;
  418. }
  419. QSqlQuery query;
  420. query.prepare("SELECT piclastname, picfirstname, alias "
  421. "FROM pilots WHERE "
  422. "picfirstname LIKE ? OR piclastname LIKE ? OR alias LIKE ?");
  423. searchstring.prepend("%");
  424. searchstring.append("%");
  425. query.addBindValue(firstname);
  426. query.addBindValue(lastname);
  427. query.addBindValue(searchstring);
  428. query.exec();
  429. QStringList result;
  430. while (query.next()) {
  431. QString piclastname = query.value(0).toString();
  432. QString picfirstname = query.value(1).toString();
  433. QString alias = query.value(2).toString();
  434. QString name = piclastname + ", " + picfirstname;
  435. result.append(name);
  436. }
  437. qDebug() << "db::RetreivePilotNameFromString Result: " << result;
  438. //qDebug() << query.lastError();
  439. if(result.size() == 0)
  440. {
  441. qDebug() << ("db::RetreivePilotNameFromString: No Pilot found");
  442. return result;
  443. }
  444. return result;
  445. }
  446. static QStringList newPicGetString(QString searchstring)
  447. /*
  448. * This function is returning a QStringList for the QCompleter in the NewFlight::newPic line edit.
  449. * A regular expression limits the input possibilities to only characters, followed by an optional ',' and 1 whitespace, e.g.:
  450. * Miller, Jim ->valid / Miller, Jim -> invalid / Miller,, Jim -> invalid
  451. * Miller Jim -> valid / Miller Jim ->invalid
  452. * Jim Miller-> valid
  453. */
  454. {
  455. QStringList result;
  456. QStringList searchlist;
  457. if(searchstring == "self")
  458. {
  459. result.append("self");
  460. qDebug() << "Pilot is self";
  461. return result;
  462. }
  463. //Fall 1) Nachname, Vorname
  464. if(searchstring.contains(QLatin1Char(',')))
  465. {
  466. QStringList namelist = searchstring.split(QLatin1Char(','));
  467. QString name1 = namelist[0].trimmed();
  468. name1 = name1.toLower();
  469. name1[0] = name1[0].toUpper();
  470. searchlist.append(name1);
  471. if(namelist[1].length() > 1)
  472. {
  473. QString name2 = namelist[1].trimmed();
  474. name2 = name2.toLower();
  475. name2[0] = name2[0].toUpper();
  476. searchlist.append(name2);
  477. }
  478. }
  479. //Fall 2) Vorname Nachname
  480. if(searchstring.contains(" ") && !searchstring.contains(QLatin1Char(',')))
  481. {
  482. QStringList namelist = searchstring.split(" ");
  483. QString name1 = namelist[0].trimmed();
  484. name1 = name1.toLower();
  485. name1[0] = name1[0].toUpper();
  486. searchlist.append(name1);
  487. if(namelist[1].length() > 1) //To avoid index out of range if the searchstring is one word followed by only one whitespace
  488. {
  489. QString name2 = namelist[1].trimmed();
  490. name2 = name2.toLower();
  491. name2[0] = name2[0].toUpper();
  492. searchlist.append(name2);
  493. }
  494. }
  495. //Fall 3) Name
  496. if(!searchstring.contains(" ") && !searchstring.contains(QLatin1Char(',')))
  497. {
  498. QString name1 = searchstring.toLower();
  499. name1[0] = name1[0].toUpper();
  500. searchlist.append(name1);
  501. }
  502. if(searchlist.length() == 1)
  503. {
  504. QSqlQuery query;
  505. query.prepare("SELECT piclastname, picfirstname FROM pilots "
  506. "WHERE piclastname LIKE ?");
  507. query.addBindValue(searchlist[0] + '%');
  508. query.exec();
  509. while(query.next())
  510. {
  511. result.append(query.value(0).toString() + ", " + query.value(1).toString());
  512. }
  513. QSqlQuery query2;
  514. query2.prepare("SELECT piclastname, picfirstname FROM pilots "
  515. "WHERE picfirstname LIKE ?");
  516. query2.addBindValue(searchlist[0] + '%');
  517. query2.exec();
  518. while(query2.next())
  519. {
  520. result.append(query2.value(0).toString() + ", " + query2.value(1).toString());
  521. }
  522. }else
  523. {
  524. QSqlQuery query;
  525. query.prepare("SELECT piclastname, picfirstname FROM pilots "
  526. "WHERE piclastname LIKE ? AND picfirstname LIKE ?");
  527. query.addBindValue(searchlist[0] + '%');
  528. query.addBindValue(searchlist[1] + '%');
  529. query.exec();
  530. while(query.next())
  531. {
  532. result.append(query.value(0).toString() + ", " + query.value(1).toString());
  533. }
  534. QSqlQuery query2;
  535. query2.prepare("SELECT piclastname, picfirstname FROM pilots "
  536. "WHERE picfirstname LIKE ? AND piclastname LIKE ?");
  537. query2.addBindValue(searchlist[0] + '%');
  538. query2.addBindValue(searchlist[1] + '%');
  539. query2.exec();
  540. while(query2.next())
  541. {
  542. result.append(query2.value(0).toString() + ", " + query2.value(1).toString());
  543. }
  544. }
  545. qDebug() << "db::newPic Result" << result.length() << result;
  546. if(result.length() == 0)
  547. {
  548. //try first name search
  549. qDebug() << "No Pilot with this last name found. trying first name search.";
  550. return result;
  551. }else
  552. {
  553. return result;
  554. }
  555. }
  556. static QString newPicGetId(QString name)
  557. {
  558. QString result;
  559. QStringList nameparts = name.split(QLatin1Char(','));
  560. QString lastname = nameparts[0].trimmed();
  561. lastname = lastname.toLower(); lastname[0] = lastname[0].toUpper();
  562. QString firstname = nameparts[1].trimmed();
  563. firstname = firstname.toLower(); firstname[0] = firstname[0].toUpper();
  564. firstname.prepend("%"); firstname.append("%");
  565. QSqlQuery query;
  566. query.prepare("SELECT pilot_id FROM pilots "
  567. "WHERE piclastname = ? AND picfirstname LIKE ?");
  568. query.addBindValue(lastname);
  569. query.addBindValue(firstname);
  570. query.exec();
  571. while (query.next())
  572. {
  573. result.append(query.value(0).toString());
  574. }
  575. qDebug() << "newPicGetId: result = " << result;
  576. return result;
  577. }
  578. /*
  579. *
  580. *
  581. * Airport Database Related Functions
  582. *
  583. *
  584. */
  585. static QString RetreiveAirportNameFromIcaoOrIata(QString identifier)
  586. /*
  587. * 'EDDF' gets looked up and 'Frankfurt International Airport' returned
  588. *
  589. */
  590. {
  591. QString result = "";
  592. QSqlQuery query;
  593. query.prepare("SELECT name "
  594. "FROM airports WHERE icao LIKE ? OR iata LIKE ?");
  595. identifier.append("%");
  596. identifier.prepend("%");
  597. query.addBindValue(identifier);
  598. query.addBindValue(identifier);
  599. query.exec();
  600. if(query.first())
  601. {
  602. result.append(query.value(0).toString());
  603. return result;
  604. }else
  605. {
  606. result = result.left(result.length()-1);
  607. result.append("No matching airport found.");
  608. return result;
  609. }
  610. }
  611. static QString RetreiveAirportIdFromIcao(QString identifier)
  612. {
  613. QString result;
  614. QSqlQuery query;
  615. query.prepare("SELECT airport_id FROM airports WHERE icao = ?");
  616. query.addBindValue(identifier);
  617. query.exec();
  618. while(query.next())
  619. {
  620. result.append(query.value(0).toString());
  621. //qDebug() << "db::RetreiveAirportIdFromIcao says Airport found! #" << result;
  622. }
  623. return result;
  624. }
  625. static QStringList CompleteIcaoOrIata(QString icaoStub)
  626. {
  627. QStringList result;
  628. QSqlQuery query;
  629. query.prepare("SELECT icao FROM airports WHERE icao LIKE ? OR iata LIKE ?");
  630. icaoStub.prepend("%"); icaoStub.append("%");
  631. query.addBindValue(icaoStub);
  632. query.addBindValue(icaoStub);
  633. query.exec();
  634. while(query.next())
  635. {
  636. result.append(query.value(0).toString());
  637. qDebug() << "db::CompleteIcaoOrIata says... Result:" << result;
  638. }
  639. return result;
  640. }
  641. static bool CheckICAOValid(QString identifier)
  642. // Verifies if a user input airport exists in the database
  643. {
  644. if(identifier.length() == 4)
  645. {
  646. QString check = RetreiveAirportIdFromIcao(identifier);
  647. if(check.length() > 0)
  648. {
  649. //qDebug() << "db::CheckICAOValid says: Check passed!";
  650. return 1;
  651. }else
  652. {
  653. //qDebug() << "db::CheckICAOValid says: Check NOT passed! Lookup unsuccessful";
  654. return 0;
  655. }
  656. }else
  657. {
  658. //qDebug() << "db::CheckICAOValid says: Check NOT passed! Empty String NOT epico!";
  659. return 0;
  660. }
  661. }
  662. static QVector<double> retreiveIcaoCoordinates(QString icao)
  663. {
  664. QSqlQuery query;
  665. query.prepare("SELECT lat, long "
  666. "FROM airports "
  667. "WHERE icao = ?");
  668. query.addBindValue(icao);
  669. query.exec();
  670. QVector<double> result;
  671. while(query.next()) {
  672. result.append(query.value(0).toDouble());
  673. result.append(query.value(1).toDouble());
  674. }
  675. return result;
  676. }
  677. /*
  678. *
  679. *
  680. * Aircraft Database Related Functions
  681. *
  682. *
  683. */
  684. static QString RetreiveRegistration(QString tail_ID)
  685. /* Looks up the Aircraft Registration in the Database and returns it as a string
  686. *
  687. */
  688. {
  689. QString acftRegistration("");
  690. QSqlQuery query;
  691. query.prepare("SELECT registration FROM tails WHERE tail_id == ?");
  692. query.addBindValue(tail_ID.toInt());
  693. query.exec();
  694. if(query.first());
  695. else
  696. qDebug() << ("No Aircraft with this ID found");
  697. query.previous();//To go back to index 0
  698. while (query.next()) {
  699. acftRegistration.append(query.value(0).toString());
  700. }
  701. return acftRegistration;
  702. }
  703. static QStringList newAcftGetString(QString searchstring)
  704. {
  705. QStringList result;
  706. if(searchstring.length()<2){return result;}
  707. QSqlQuery query;
  708. query.prepare("SELECT registration, make, model, variant "
  709. "FROM aircraft "
  710. "INNER JOIN tails on tails.aircraft_ID = aircraft.aircraft_id "
  711. "WHERE tails.registration LIKE ?");
  712. searchstring.append("%"); searchstring.prepend("%");
  713. query.addBindValue(searchstring);
  714. query.exec();
  715. while(query.next())
  716. {
  717. result.append(query.value(0).toString() + " (" + query.value(1).toString() + "-" + query.value(2).toString() + "-" + query.value(3).toString() + ")");
  718. }
  719. qDebug() << "newAcftGetString: " << result.length() << result;
  720. return result;
  721. }
  722. static QString newAcftGetId(QString registration)
  723. {
  724. QString result;
  725. QSqlQuery query;
  726. query.prepare("SELECT tail_id "
  727. "FROM tails "
  728. "WHERE registration LIKE ?");
  729. registration.prepend("%"); registration.append("%");
  730. query.addBindValue(registration);
  731. query.exec();
  732. while(query.next())
  733. {
  734. result.append(query.value(0).toString());
  735. }
  736. qDebug() << "newAcftGetId: " << result;
  737. return result;
  738. }
  739. static QVector<QString> RetreiveAircraftTypeFromReg(QString searchstring)
  740. /*
  741. * Searches the tails Database and returns the aircraft Type.
  742. */
  743. {
  744. QSqlQuery query;
  745. query.prepare("SELECT Name, iata, registration, tail_id " //"SELECT Registration, Name, icao, iata "
  746. "FROM aircraft "
  747. "INNER JOIN tails on tails.aircraft_ID = aircraft.aircraft_id "
  748. "WHERE tails.registration LIKE ?");
  749. // Returns Registration/Name/icao/iata
  750. searchstring.prepend("%");
  751. searchstring.append("%");
  752. query.addBindValue(searchstring);
  753. query.exec();
  754. //qDebug() << "SQL Error: " << query.lastError().text();
  755. //qDebug() << "Query result: " << query.first();
  756. //qDebug() << query.value(2);
  757. QVector<QString> result;
  758. if(query.first())
  759. {
  760. QString acType = query.value(0).toString();
  761. QString iataCode = query.value(1).toString();
  762. QString registration = query.value(2).toString();
  763. QString tail_id = query.value(3).toString();
  764. //QString formatted = acType + " [ " + registration + " | " + iataCode + " ]";
  765. //qDebug() << formatted;
  766. result.append(registration); result.append(acType);
  767. result.append(iataCode); result.append(tail_id);
  768. return result;
  769. }else
  770. {
  771. return result; // empty vector
  772. }
  773. }
  774. static QStringList RetreiveAircraftMake(QString searchstring)
  775. {
  776. QStringList result;
  777. QSqlQuery query;
  778. query.prepare("SELECT make from aircraft WHERE make LIKE ?");
  779. searchstring.prepend("%"); searchstring.append("%");
  780. query.addBindValue(searchstring);
  781. query.exec();
  782. while(query.next())
  783. {
  784. result.append(query.value(0).toString());
  785. }
  786. qDebug() << "db::RetreiveAircraftMake says... Result:" << result;
  787. return result;
  788. }
  789. static QStringList RetreiveAircraftModel(QString make, QString searchstring)
  790. {
  791. QStringList result;
  792. QSqlQuery query;
  793. query.prepare("SELECT model FROM aircraft WHERE make = ? AND model LIKE ?");
  794. query.addBindValue(make);
  795. searchstring.prepend("%"); searchstring.append("%");
  796. query.addBindValue(searchstring);
  797. query.exec();
  798. while(query.next())
  799. {
  800. result.append(query.value(0).toString());
  801. qDebug() << "db::RetreiveAircraftModel says... Result:" << result;
  802. }
  803. return result;
  804. }
  805. static QStringList RetreiveAircraftVariant(QString make, QString model, QString searchstring)
  806. {
  807. QStringList result;
  808. QSqlQuery query;
  809. query.prepare("SELECT variant from aircraft WHERE make = ? AND model = ? AND variant LIKE ?");
  810. query.addBindValue(make);
  811. query.addBindValue(model);
  812. searchstring.prepend("%"); searchstring.append("%");
  813. query.addBindValue(searchstring);
  814. query.exec();
  815. while(query.next())
  816. {
  817. result.append(query.value(0).toString());
  818. qDebug() << "db::RetreiveAircraftVariant says... Result:" << result;
  819. }
  820. return result;
  821. }
  822. static QString RetreiveAircraftIdFromMakeModelVariant(QString make, QString model, QString variant)
  823. {
  824. QString result;
  825. QSqlQuery query;
  826. query.prepare("SELECT aircraft_id FROM aircraft WHERE make = ? AND model = ? AND variant = ?");
  827. query.addBindValue(make);
  828. query.addBindValue(model);
  829. query.addBindValue(variant);
  830. query.exec();
  831. if(query.first())
  832. {
  833. result.append(query.value(0).toString());
  834. qDebug() << "db::RetreiveAircraftIdFromMakeModelVariant: Aircraft found! ID# " << result;
  835. return result;
  836. }else
  837. {
  838. result = result.left(result.length()-1);
  839. result.append("0");
  840. qDebug() << "db::RetreiveAircraftIdFromMakeModelVariant: ERROR - no AircraftId found.";
  841. return result;
  842. }
  843. }
  844. static bool CommitTailToDb(QString registration, QString aircraft_id, QString company)
  845. {
  846. QSqlQuery commit;
  847. commit.prepare("INSERT INTO tails (registration, aircraft_id, company) VALUES (?,?,?)");
  848. commit.addBindValue(registration);
  849. commit.addBindValue(aircraft_id);
  850. commit.addBindValue(company);
  851. commit.exec();
  852. QString error = commit.lastError().text();
  853. if(error.length() < 0)
  854. {
  855. qDebug() << "db::CommitAircraftToDb:: SQL error:" << error;
  856. return false;
  857. }else
  858. {
  859. return true;
  860. }
  861. }
  862. /*
  863. *
  864. *
  865. * Aircraft Database Related Functions
  866. *
  867. *
  868. */
  869. static QVector<QString> retreiveSetting(QString setting_id)
  870. {
  871. QSqlQuery query;
  872. query.prepare("SELECT * FROM settings WHERE setting_id = ?");
  873. query.addBindValue(setting_id);
  874. query.exec();
  875. QVector<QString> setting;
  876. while(query.next()){
  877. setting.append(query.value(0).toString());
  878. setting.append(query.value(1).toString());
  879. setting.append(query.value(2).toString());
  880. }
  881. return setting;
  882. }
  883. static void storesetting(int setting_id, QString setting_value)
  884. {
  885. QSqlQuery query;
  886. query.prepare("UPDATE settings "
  887. "SET setting = ? "
  888. "WHERE setting_id = ?");
  889. query.addBindValue(setting_value);
  890. query.addBindValue(setting_id);
  891. query.exec();
  892. }
  893. };