openPilotLog
database.h
1 /*
2  *openPilotLog - A FOSS Pilot Logbook Application
3  *Copyright (C) 2020-2021 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 DATABASE_H
19 #define DATABASE_H
20 
21 #include <QPair>
22 #include <QHash>
23 #include <QString>
24 #include <QDir>
25 #include <QSqlDatabase>
26 #include <QSqlDriver>
27 #include <QSqlQuery>
28 #include <QSqlError>
29 #include <QSqlTableModel>
30 #include <QSqlQuery>
31 #include <QSqlRecord>
32 #include <QSqlField>
33 
34 #include "src/opl.h"
35 #include "src/database/row.h"
36 #include "src/classes/astandardpaths.h"
37 
38 using RowData_T = QHash<QString, QVariant>;
39 
40 namespace OPL {
41 
49 #define DB OPL::Database::instance()
50 
57 struct UserDataState {
58 
59  UserDataState(){numTails = 0; numPilots = 0;}
60  UserDataState(int numTails_, int numPilots_)
61  : numTails(numTails_), numPilots(numPilots_){}
62 
63  bool operator==(const UserDataState& other)
64  {
65  return numTails == other.numTails && numPilots == other.numPilots;
66  }
67  bool operator!=(const UserDataState& other)
68  {
69  return numTails != other.numTails || numPilots != other.numPilots;
70  }
71 
72  int numTails;
73  int numPilots;
74 };
75 
76 
77 
82 class Database : public QObject {
83 
84 private:
85  Q_OBJECT
86  Database()
87  : databaseFile(QFileInfo(AStandardPaths::directory(AStandardPaths::Database).
88  absoluteFilePath(QStringLiteral("logbook.db"))))
89  {}
90  static Database* self;
91  const QFileInfo databaseFile;
92  QStringList tableNames;
93  QHash<QString, QStringList> tableColumns;
94 
95  inline const static QString SQLITE_DRIVER = QStringLiteral("QSQLITE");
96  inline const static QList<OPL::DbTable> USER_TABLES = {
97  OPL::DbTable::Flights,
98  OPL::DbTable::Pilots,
99  OPL::DbTable::Tails
100  };
101  inline const static QList<OPL::DbTable> TEMPLATE_TABLES = {
102  OPL::DbTable::Aircraft,
103  OPL::DbTable::Airports,
104  OPL::DbTable::Currencies,
105  OPL::DbTable::Changelog
106  };
107 
108 
109 public:
110  Database(const Database&) = delete;
111  void operator=(const Database&) = delete;
112  static Database* instance();
113 
122  QSqlError lastError;
123 
127  bool connect();
128 
132  void disconnect();
133 
138  void updateLayout();
139 
143  const QString version() const;
144 
149  const QString sqliteVersion() const;
150 
154  const QStringList getTableNames() const;
155 
159  const QStringList getTableColumns(OPL::DbTable table_name) const;
160 
165  static QSqlDatabase database();
166 
172  QVector<QVariant> customQuery(QString statement, int return_values);
173 
177  bool exists(const OPL::Row &row);
178 
183  bool clear();
184 
189  bool commit(const OPL::Row &row);
190 
196  bool commit(const QJsonArray &json_arr, const OPL::DbTable table);
197 
201  bool insert(const OPL::Row &new_row);
202 
206  bool update(const OPL::Row &updated_row);
207 
211  bool remove(const OPL::Row &row);
212 
217  bool removeMany(OPL::DbTable table, const QList<int> &row_id_list);
218 
222  OPL::Row getRow(const OPL::DbTable table, const int row_id);
223 
227  RowData_T getRowData(const OPL::DbTable table, const int row_id);
228 
232  inline OPL::PilotEntry getPilotEntry(int row_id)
233  {
234  const auto data = getRowData(OPL::DbTable::Pilots, row_id);
235  return OPL::PilotEntry(row_id, data);
236  }
237 
241  inline OPL::TailEntry getTailEntry(int row_id)
242  {
243  const auto data = getRowData(OPL::DbTable::Tails, row_id);
244  return OPL::TailEntry(row_id, data);
245  }
246 
251  {
252  const auto data = getRowData(OPL::DbTable::Aircraft, row_id);
253  return OPL::AircraftEntry(row_id, data);
254  }
255 
259  inline OPL::FlightEntry getFlightEntry(int row_id)
260  {
261  const auto data = getRowData(OPL::DbTable::Flights, row_id);
262  return OPL::FlightEntry(row_id, data);
263  }
264 
268  inline OPL::SimulatorEntry getSimEntry(int row_id)
269  {
270  const auto data = getRowData(OPL::DbTable::Simulators, row_id);
271  return OPL::SimulatorEntry(row_id, data);
272  }
273 
278  {
279  const auto data = getRowData(OPL::DbTable::Currencies, row_id);
280  return OPL::CurrencyEntry(row_id, data);
281  }
282 
286  int getLastEntry(OPL::DbTable table);
287 
292  QList<int> getForeignKeyConstraints(int foreign_row_id, OPL::DbTable table);
293 
298  QVector<RowData_T> getTable(OPL::DbTable table);
299 
304  const QList<OPL::DbTable> &getUserTables() const;
305 
310  const QList<OPL::DbTable> &getTemplateTables() const;
311 
317  const UserDataState getUserDataState() const;
318 
319  // Maintenance and setup
320 
326  bool createSchema();
335  bool importTemplateData(bool use_local_ressources);
336 
340  bool resetUserData();
341 
346  bool createBackup(const QString& dest_file);
347 
352  bool restoreBackup(const QString& backup_file);
353 
354 
355 
356 signals:
369 };
370 
371 } // namespace OPL
372 
373 #endif // DATABASE_H
static const QDir & directory(Directories location)
Returns the QDir for the standard directory referenced by the Directories enum 'loc'.
Definition: astandardpaths.cpp:43
Definition: row.h:45
Definition: row.h:89
The DB class encapsulates the SQL database by providing fast access to hot database data.
Definition: database.h:82
const QString sqliteVersion() const
Database::sqliteVersion returns the database sqlite version. See also dbRevision()
Definition: database.cpp:132
const UserDataState getUserDataState() const
getUserDataState returns a struct containing the current amount of entries in the tails and pilots ta...
Definition: database.cpp:81
bool connect()
Connect to the database and populate database information.
Definition: database.cpp:29
static QSqlDatabase database()
Can be used to access the database connection.
Definition: database.cpp:141
OPL::PilotEntry getPilotEntry(int row_id)
retreives a PilotEntry from the database. See row class for details.
Definition: database.h:232
bool remove(const OPL::Row &row)
deletes an entry from the database.
Definition: database.cpp:204
RowData_T getRowData(const OPL::DbTable table, const int row_id)
retreive a Map of <column name, column content> for a specific row in the database.
Definition: database.cpp:430
bool createBackup(const QString &dest_file)
Database::createBackup copies the currently used database to an external backup location provided by ...
Definition: database.cpp:585
bool update(const OPL::Row &updated_row)
Updates entry in database from existing entry tweaked by the user.
Definition: database.cpp:319
bool importTemplateData(bool use_local_ressources)
importTemplateData fills an empty database with the template data (Aircraft, Airports,...
Definition: database.cpp:669
QList< int > getForeignKeyConstraints(int foreign_row_id, OPL::DbTable table)
returns a list of ROWID's in the flights table for which foreign key constraints exist.
Definition: database.cpp:475
void updateLayout()
Updates the member variables tableNames and tableColumns with up-to-date layout information if the da...
Definition: database.cpp:107
OPL::FlightEntry getFlightEntry(int row_id)
retreives a flight entry from the database. See row class for details.
Definition: database.h:259
bool resetUserData()
Delete all rows from the user data tables (flights, pliots, tails)
Definition: database.cpp:706
bool exists(const OPL::Row &row)
Checks if an entry exists in the database, based on position data.
Definition: database.cpp:275
bool removeMany(OPL::DbTable table, const QList< int > &row_id_list)
deletes a batch of entries from the database. Optimised for speed when deleting many entries....
Definition: database.cpp:233
const QString version() const
Return the database revision number (not the sqlite version number).
Definition: database.cpp:64
bool restoreBackup(const QString &backup_file)
Database::restoreBackup restores the database from a given backup file and replaces the currently act...
Definition: database.cpp:603
QVector< RowData_T > getTable(OPL::DbTable table)
getTable returns all contents of a given table from the database
Definition: database.cpp:540
OPL::AircraftEntry getAircraftEntry(int row_id)
retreives a TailEntry from the database. See row class for details.
Definition: database.h:250
bool createSchema()
Create or restore the database to its ready-to-use but empty state.
Definition: database.cpp:634
OPL::TailEntry getTailEntry(int row_id)
retreives a TailEntry from the database. See row class for details.
Definition: database.h:241
const QStringList getTableNames() const
Return the names of all tables in the database.
Definition: database.cpp:102
OPL::SimulatorEntry getSimEntry(int row_id)
retreives a Simulator entry from the database. See row class for details.
Definition: database.h:268
bool clear()
clear resets the database, i.e. deletes all content in the tables containing userdata (pilots,...
Definition: database.cpp:304
bool insert(const OPL::Row &new_row)
Create new entry in the databse based on UserInput.
Definition: database.cpp:355
QSqlError lastError
Holds information about the last error that ocurred during a SQL operation. If the error type is QSql...
Definition: database.h:122
void dataBaseUpdated()
updated is emitted whenever the database contents have been updated. This can be either a commit,...
QVector< QVariant > customQuery(QString statement, int return_values)
Can be used to send a complex query to the database.
Definition: database.cpp:512
const QList< OPL::DbTable > & getUserTables() const
getUserTables returns a list of the of the tables that contain user-created data (flights,...
Definition: database.cpp:76
const QStringList getTableColumns(OPL::DbTable table_name) const
Return the names of a given table in the database.
Definition: database.cpp:97
void connectionReset()
connectionReset is emitted whenever the database connection is reset, for example when creating or re...
void disconnect()
closes the database connection.
Definition: database.cpp:56
const QList< OPL::DbTable > & getTemplateTables() const
getTemplateTables returns a list of the tables that contain template data (aiports,...
Definition: database.cpp:71
bool commit(const OPL::Row &row)
commits an entry to the database, calls either insert or update, based on position data
Definition: database.cpp:155
OPL::Row getRow(const OPL::DbTable table, const int row_id)
retreive a Row from the database
Definition: database.cpp:398
int getLastEntry(OPL::DbTable table)
returns the ROWID for the newest entry in the respective table.
Definition: database.cpp:462
OPL::CurrencyEntry getCurrencyEntry(int row_id)
Retreives a currency entry from the database. See row class for details.
Definition: database.h:277
Definition: row.h:81
Definition: row.h:64
The Row class provides an interface for retreiving and submitting entries from the database....
Definition: row.h:13
Definition: row.h:73
Definition: row.h:53
A namespace to collect constants and enums used throughout the application.
Definition: database.cpp:25
DbTable
Enumerates the tables in the database.
Definition: opl.h:122
The UserDateState struct caches the current number of entries in relevant database tables for fast ac...
Definition: database.h:57