adatabase.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. #ifndef ADATABASE_H
  19. #define ADATABASE_H
  20. #include <QPair>
  21. #include <QMap>
  22. #include <QString>
  23. #include <QDir>
  24. #include <QSqlDatabase>
  25. #include <QSqlDriver>
  26. #include <QSqlQuery>
  27. #include <QSqlError>
  28. #include <QSqlTableModel>
  29. #include <QSqlQuery>
  30. #include <QSqlRecord>
  31. #include <QSqlField>
  32. #include "src/database/declarations.h"
  33. #include "src/classes/aentry.h"
  34. #include "src/classes/apilotentry.h"
  35. #include "src/classes/atailentry.h"
  36. #include "src/classes/aaircraftentry.h"
  37. #include "src/classes/aflightentry.h"
  38. /*!
  39. * \brief The DBTarget enum lists database items that are
  40. * used by completers, for content matching or need to be accessed programatically.
  41. */
  42. enum class ADatabaseTarget
  43. {
  44. aircraft,
  45. airport_identifier_icao,
  46. airport_identifier_iata,
  47. airport_identifier_all,
  48. airport_names,
  49. pilots,
  50. registrations,
  51. companies,
  52. tails
  53. };
  54. // [G]: This is how we should handle custom "events" in the program.
  55. // In this case a custom error doesnt need to be built from scratch.
  56. // Find the type of error you want and extend it with a few tweaks.
  57. /*!
  58. * \brief Custom Database Error derived from QSqlError.
  59. * Extends text() adding "Database Error: " before the text.
  60. */
  61. class ADatabaseError : public QSqlError {
  62. public:
  63. ADatabaseError() = default;
  64. ADatabaseError(QString msg);
  65. QString text() const;
  66. };
  67. /*!
  68. * \brief The DB class encapsulates the SQL database by providing fast access
  69. * to hot database data.
  70. */
  71. class ADatabase : public QObject {
  72. Q_OBJECT
  73. private:
  74. TableNames tableNames;
  75. TableColumns tableColumns;
  76. static ADatabase* instance;
  77. ADatabase() = default;
  78. public:
  79. // Ensure DB is not copiable or assignable
  80. ADatabase(const ADatabase&) = delete;
  81. void operator=(const ADatabase&) = delete;
  82. static ADatabase* getInstance();
  83. TableNames getTableNames() const;
  84. TableColumns getTableColumns() const;
  85. const QString sqliteVersion();
  86. ADatabaseError lastError;
  87. /*!
  88. * \brief Connect to the database and populate database information.
  89. */
  90. bool connect();
  91. /*!
  92. * \brief closes the database connection.
  93. */
  94. void disconnect();
  95. /*!
  96. * \brief Can be used to access the database connection.
  97. * \return The QSqlDatabase object pertaining to the connection.
  98. */
  99. static QSqlDatabase database();
  100. /*!
  101. * \brief Can be used to send a complex query to the database.
  102. * \param query - the full sql query statement
  103. * \param returnValues - the number of return values
  104. */
  105. QVector<QString> customQuery(QString statement, int return_values);
  106. /*!
  107. * \brief Checks if an entry exists in the database, based on position data
  108. */
  109. bool exists(AEntry entry);
  110. bool exists(DataPosition data_position);
  111. /*!
  112. * \brief commits an entry to the database, calls either insert or update,
  113. * based on position data
  114. */
  115. bool commit(AEntry entry);
  116. /*!
  117. * \brief Create new entry in the databse based on UserInput
  118. */
  119. bool insert(AEntry new_entry);
  120. /*!
  121. * \brief Updates entry in database from existing entry tweaked by the user.
  122. */
  123. bool update(AEntry updated_entry);
  124. /*!
  125. * \brief deletes an entry from the database.
  126. */
  127. bool remove(AEntry entry);
  128. /*!
  129. * \brief deletes a list of entries from the database. Optimised for speed when
  130. * deleting many entries.
  131. */
  132. bool removeMany(QList<DataPosition>);
  133. /*!
  134. * \brief retreive entry data from the database to create an entry object
  135. */
  136. RowData getEntryData(DataPosition data_position);
  137. /*!
  138. * \brief retreive an Entry from the database.
  139. */
  140. AEntry getEntry(DataPosition data_position);
  141. /*!
  142. * \brief retreives a PilotEntry from the database.
  143. *
  144. * This function is a wrapper for DataBase::getEntry(DataPosition),
  145. * where the table is already set and which returns a PilotEntry
  146. * instead of an Entry. It allows for easy access to a pilot entry
  147. * with only the RowId required as input.
  148. */
  149. APilotEntry getPilotEntry(RowId row_id);
  150. /*!
  151. * \brief retreives a TailEntry from the database.
  152. *
  153. * This function is a wrapper for DataBase::getEntry(DataPosition),
  154. * where the table is already set and which returns a TailEntry
  155. * instead of an Entry. It allows for easy access to a tail entry
  156. * with only the RowId required as input.
  157. */
  158. ATailEntry getTailEntry(RowId row_id);
  159. /*!
  160. * \brief retreives a TailEntry from the database.
  161. *
  162. * This function is a wrapper for DataBase::getEntry(DataPosition),
  163. * where the table is already set and which returns an AAircraftEntry
  164. * instead of an AEntry. It allows for easy access to an aircraft entry
  165. * with only the RowId required as input.
  166. */
  167. AAircraftEntry getAircraftEntry(RowId row_id);
  168. /*!
  169. * \brief retreives a flight entry from the database.
  170. *
  171. * This function is a wrapper for DataBase::getEntry(DataPosition),
  172. * where the table is already set and which returns an AFlightEntry
  173. * instead of an AEntry. It allows for easy access to a flight entry
  174. * with only the RowId required as input.
  175. */
  176. AFlightEntry getFlightEntry(RowId row_id);
  177. /*!
  178. * \brief getCompletionList returns a QStringList of values for a
  179. * QCompleter based on database values
  180. */
  181. const QStringList getCompletionList(ADatabaseTarget);
  182. /*!
  183. * \brief returns a QMap<QString, int> of a human-readable database value and
  184. * its row id. Used in the Dialogs to map user input to unique database entries.
  185. */
  186. const QMap<QString, int> getIdMap(ADatabaseTarget);
  187. /*!
  188. * \brief returns the ROWID for the newest entry in the respective database.
  189. */
  190. int getLastEntry(ADatabaseTarget);
  191. /*!
  192. * \brief returns a list of ROWID's in the flights table for which foreign key constraints
  193. * exist.
  194. */
  195. QList<int> getForeignKeyConstraints(int foreign_row_id, ADatabaseTarget target);
  196. /*!
  197. * \brief Resolves the foreign key in a flight entry
  198. * \return The Pilot Entry referencted by the foreign key.
  199. */
  200. APilotEntry resolveForeignPilot(int foreign_key);
  201. /*!
  202. * \brief Resolves the foreign key in a flight entry
  203. * \return The Tail Entry referencted by the foreign key.
  204. */
  205. ATailEntry resolveForeignTail(int foreign_key);
  206. signals:
  207. /*!
  208. * \brief updated is emitted whenever the database contents have been updated.
  209. * This can be either a commit, update or remove. This signal should be used to
  210. * trigger an update to the models of the views displaying database contents in
  211. * the user interface so that a user is always presented with up-to-date information.
  212. */
  213. void dataBaseUpdated();
  214. };
  215. /*!
  216. * \brief Convinience function that returns instance of DataBase.
  217. * Instead of this:
  218. * DataBase::getInstance().commit(...)
  219. * Write this:
  220. * aDB()->commit(...)
  221. */
  222. ADatabase* aDB();
  223. #endif // ADATABASE_H