Jelajahi Sumber

New Table for Previous Experience

Added a new table 'previousExperience' in the database to hold this data.
The old implementation used the same table as the regular flight data but this turned out to be messy. Separating these data and keeping the flights table clean seems the better way forward.
Felix Turowsky 1 tahun lalu
induk
melakukan
2c2d8fd127

+ 207 - 187
assets/database/database_schema.sql

@@ -3,11 +3,11 @@ CREATE TABLE IF NOT EXISTS 'pilots' (
 	'pilot_id'	INTEGER NOT NULL,
 	'lastname'	TEXT NOT NULL,
 	'firstname'	TEXT,
-	'alias'	TEXT,
+        'alias'		TEXT,
 	'company'	TEXT,
 	'employeeid'	TEXT,
-	'phone'	TEXT,
-	'email'	TEXT,
+        'phone'		TEXT,
+        'email'		TEXT,
 	PRIMARY KEY('pilot_id' AUTOINCREMENT)
 );
 DROP TABLE IF EXISTS 'tails';
@@ -15,8 +15,8 @@ CREATE TABLE IF NOT EXISTS 'tails' (
 	'tail_id'	INTEGER NOT NULL,
 	'registration'	TEXT NOT NULL,
 	'company'	TEXT,
-	'make'	TEXT,
-	'model'	TEXT,
+        'make'		TEXT,
+        'model'		TEXT,
 	'variant'	TEXT,
 	'multipilot'	INTEGER,
 	'multiengine'	INTEGER,
@@ -27,27 +27,27 @@ CREATE TABLE IF NOT EXISTS 'tails' (
 DROP TABLE IF EXISTS 'flights';
 CREATE TABLE IF NOT EXISTS 'flights' (
 	'flight_id'	INTEGER NOT NULL,
-	'doft'	NUMERIC NOT NULL,
-	'dept'	TEXT NOT NULL,
-	'dest'	TEXT NOT NULL,
-	'tofb'	INTEGER NOT NULL,
-	'tonb'	INTEGER NOT NULL,
-	'pic'	INTEGER NOT NULL,
-	'acft'	INTEGER NOT NULL,
-	'tblk'	INTEGER NOT NULL,
-	'tSPSE'	INTEGER,
-	'tSPME'	INTEGER,
-	'tMP'	INTEGER,
+        'doft'		NUMERIC NOT NULL,
+        'dept'		TEXT NOT NULL,
+        'dest'		TEXT NOT NULL,
+        'tofb'		INTEGER NOT NULL,
+        'tonb'		INTEGER NOT NULL,
+        'pic'		INTEGER NOT NULL,
+        'acft'		INTEGER NOT NULL,
+        'tblk'		INTEGER NOT NULL,
+        'tSPSE'		INTEGER,
+        'tSPME'		INTEGER,
+        'tMP'		INTEGER,
 	'tNIGHT'	INTEGER,
-	'tIFR'	INTEGER,
-	'tPIC'	INTEGER,
+        'tIFR'		INTEGER,
+        'tPIC'		INTEGER,
 	'tPICUS'	INTEGER,
-	'tSIC'	INTEGER,
-	'tDUAL'	INTEGER,
-	'tFI'	INTEGER,
-	'tSIM'	INTEGER,
+        'tSIC'		INTEGER,
+        'tDUAL'		INTEGER,
+        'tFI'		INTEGER,
+        'tSIM'		INTEGER,
 	'pilotFlying'	INTEGER,
-	'toDay'	INTEGER,
+        'toDay'		INTEGER,
 	'toNight'	INTEGER,
 	'ldgDay'	INTEGER,
 	'ldgNight'	INTEGER,
@@ -64,12 +64,12 @@ CREATE TABLE IF NOT EXISTS 'flights' (
 DROP TABLE IF EXISTS 'aircraft';
 CREATE TABLE IF NOT EXISTS 'aircraft' (
 	'aircraft_id'	INTEGER NOT NULL,
-	'make'	TEXT,
-	'model'	TEXT,
+        'make'		TEXT,
+        'model'		TEXT,
 	'variant'	TEXT,
-	'name'	TEXT,
-	'iata'	TEXT,
-	'icao'	TEXT,
+        'name'		TEXT,
+        'iata'		TEXT,
+        'icao'		TEXT,
 	'multipilot'	INTEGER,
 	'multiengine'	INTEGER,
 	'engineType'	INTEGER,
@@ -79,11 +79,11 @@ CREATE TABLE IF NOT EXISTS 'aircraft' (
 DROP TABLE IF EXISTS 'airports';
 CREATE TABLE IF NOT EXISTS 'airports' (
 	'airport_id'	INTEGER NOT NULL,
-	'icao'	TEXT NOT NULL,
-	'iata'	TEXT,
-	'name'	TEXT,
-	'lat'	REAL,
-	'long'	REAL,
+        'icao'		TEXT NOT NULL,
+        'iata'		TEXT,
+        'name'		TEXT,
+        'lat'		REAL,
+        'long'		REAL,
 	'country'	TEXT,
 	'tzolson'	TEXT,
 	PRIMARY KEY('airport_id' AUTOINCREMENT)
@@ -99,13 +99,13 @@ DROP TABLE IF EXISTS 'changelog';
 CREATE TABLE IF NOT EXISTS 'changelog' (
 	'revision'	INTEGER NOT NULL,
 	'comment'	TEXT,
-	'date'	NUMERIC,
+        'date'		NUMERIC,
 	PRIMARY KEY('revision' AUTOINCREMENT)
 );
 DROP TABLE IF EXISTS 'simulators';
 CREATE TABLE IF NOT EXISTS 'simulators' (
 	'session_id'	INTEGER NOT NULL,
-	'date'	NUMERIC NOT NULL,
+        'date'		NUMERIC NOT NULL,
 	'totalTime'	INTEGER NOT NULL,
 	'deviceType'	TEXT NOT NULL,
 	'aircraftType'	TEXT,
@@ -113,219 +113,239 @@ CREATE TABLE IF NOT EXISTS 'simulators' (
 	'remarks'	TEXT,
 	PRIMARY KEY('session_id' AUTOINCREMENT)
 );
+DROP TABLE IF EXISTS 'previousExperience';
+CREATE TABLE 'previousExperience' (
+        'tblk'		INTEGER,
+        'tSPSE'		INTEGER,
+        'tSPME'		INTEGER,
+        'tMP'		INTEGER,
+        'tNIGHT'	INTEGER,
+        'tIFR'		INTEGER,
+        'tPIC'		INTEGER,
+        'tPICUS'	INTEGER,
+        'tSIC'		INTEGER,
+        'tDUAL'		INTEGER,
+        'tFI'		INTEGER,
+        'tSIM'		INTEGER,
+        'toDay'		INTEGER,
+        'toNight'	INTEGER,
+        'ldgDay'	INTEGER,
+        'ldgNight'	INTEGER,
+        'autoland'	INTEGER
+)
 
 DROP VIEW IF EXISTS 'viewDefault';
 CREATE VIEW viewDefault AS  
-SELECT flight_id, 
-doft as 'Date',  
-dept AS 'Dept',  
-printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',  
-dest AS 'Dest', printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',  
-printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',  
-CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',  
-CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',  
-registration AS 'Registration',  
-FlightNumber AS 'Flight #',  
-remarks AS 'Remarks' 
+SELECT 	flight_id,
+        doft as 'Date',
+        dept AS 'Dept',
+        printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',
+        dest AS 'Dest', printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',
+        printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
+        CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
+        CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
+        registration AS 'Registration',
+        FlightNumber AS 'Flight #',
+        remarks AS 'Remarks'
 FROM flights  
-INNER JOIN pilots on flights.pic = pilots.pilot_id  
-INNER JOIN tails on flights.acft = tails.tail_id  
+INNER JOIN pilots on flights.pic = pilots.pilot_id
+INNER JOIN tails on flights.acft = tails.tail_id
 ORDER BY date DESC;
 
 DROP VIEW IF EXISTS 'viewDefaultSim';
 CREATE VIEW viewDefaultSim AS 
-SELECT flight_id AS 'rowid',   
-doft as 'Date',   
-dept AS 'Dept',   
-printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',   
-dest AS 'Dest', printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',   
-printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',   
-CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',   
-CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',   
-registration AS 'Registration',    
-null AS 'Sim Type', 
-null AS 'Time of Session', 
-remarks AS 'Remarks' 
+SELECT 	flight_id AS 'rowid',
+        doft as 'Date',
+        dept AS 'Dept',
+        printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',
+        dest AS 'Dest', printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',
+        printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
+        CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
+        CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
+        registration AS 'Registration',
+        null AS 'Sim Type',
+        null AS 'Time of Session',
+        remarks AS 'Remarks'
 FROM flights   
 INNER JOIN pilots on flights.pic = pilots.pilot_id  
 INNER JOIN tails on flights.acft = tails.tail_id   
 UNION 
-SELECT (session_id * -1), 
-date, 
-null, null, null, null, 
-'SIM', 
-null, 
-aircraftType, 
-registration, 
-deviceType, 
-printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)), 
-remarks 
+        SELECT (session_id * -1),
+        date,
+        null, null, null, null,
+        'SIM',
+        null,
+        aircraftType,
+        registration,
+        deviceType,
+        printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)),
+        remarks
 FROM simulators 
 ORDER BY date DESC;
 
 DROP VIEW IF EXISTS 'viewEasa';
 CREATE VIEW viewEasa AS  SELECT  flight_id, 
-doft as 'Date',  
-dept AS 'Dept',  
-printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',  
-dest AS 'Dest', 
-printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',  
-CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',  
-registration AS 'Registration',  
-(SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE',  
-(SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',  
-(SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',  
-printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',  
-CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',  
-ldgDay AS 'L/D',  
-ldgNight AS 'L/N',  
-(SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',  
-(SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',  
-(SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',  
-(SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',  
-(SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',  
-(SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',  
-remarks AS 'Remarks'  
+        doft as 'Date',
+        dept AS 'Dept',
+        printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',
+        dest AS 'Dest',
+        printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',
+        CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
+        registration AS 'Registration',
+        (SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE',
+        (SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',
+        (SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',
+        printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
+        CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
+        ldgDay AS 'L/D',
+        ldgNight AS 'L/N',
+        (SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',
+        (SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',
+        (SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',
+        (SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',
+        (SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',
+        (SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',
+        remarks AS 'Remarks'
 FROM flights  
 INNER JOIN pilots on flights.pic = pilots.pilot_id  
 INNER JOIN tails on flights.acft = tails.tail_id  ORDER BY date DESC;
 
 DROP VIEW IF EXISTS 'viewEasaSim';
 CREATE VIEW viewEasaSim AS  SELECT  flight_id, 
-doft as 'Date',    
-dept AS 'Dept',  
-printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',    
-dest AS 'Dest', 
-printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',    
-CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',    
-registration AS 'Registration',    
-(SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE', 
-(SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',    
-(SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',    
-printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',    
-CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',    
-ldgDay AS 'L/D',    
-ldgNight AS 'L/N',    
-(SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',    
-(SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',    
-(SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',    
-(SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',    
-(SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',    
-(SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',  
-null AS 'Sim Type',  
-null AS 'Time of Session',  
-remarks AS 'Remarks'    
+        doft as 'Date',
+        dept AS 'Dept',
+        printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time',
+        dest AS 'Dest',
+        printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time ',
+        CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
+        registration AS 'Registration',
+        (SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE',
+        (SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',
+        (SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',
+        printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
+        CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
+        ldgDay AS 'L/D',
+        ldgNight AS 'L/N',
+        (SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',
+        (SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',
+        (SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',
+        (SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',
+        (SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',
+        (SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',
+        null AS 'Sim Type',
+        null AS 'Time of Session',
+        remarks AS 'Remarks'
 FROM flights    
 INNER JOIN pilots on flights.pic = pilots.pilot_id    
 INNER JOIN tails on flights.acft = tails.tail_id    
 UNION  
 SELECT (session_id * -1),  
-date,  
-null,  null,  null,  null,  
-aircraftType,  
-registration,  
-null,  null,  null,  
-'SIM',  
-null,  null,  null,  null,  null,  null,  null,  null,  null,  
-deviceType,  printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)),  
-remarks  
+        date,
+        null,  null,  null,  null,
+        aircraftType,
+        registration,
+        null,  null,  null,
+        'SIM',
+        null,  null,  null,  null,  null,  null,  null,  null,  null,
+        deviceType,  printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)),
+        remarks
 FROM simulators  
 ORDER BY date DESC;
 
 DROP VIEW IF EXISTS 'viewSimulators';
 CREATE VIEW viewSimulators AS SELECT (session_id * -1),  
-date as 'Date',  
-registration AS 'Registration',   
-aircraftType AS 'Aircraft Type',   
-deviceType 'Sim Type',  
-printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)) AS 'Time of Session',  
-remarks AS 'Remarks'  
+        date as 'Date',
+        registration AS 'Registration',
+        aircraftType AS 'Aircraft Type',
+        deviceType 'Sim Type',
+        printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)) AS 'Time of Session',
+        remarks AS 'Remarks'
 FROM simulators  
 ORDER BY date DESC;
 
 DROP VIEW IF EXISTS 'viewTails';
 CREATE VIEW viewTails AS  
 SELECT  tail_id AS 'ID',  
-registration AS 'Registration',  
-make||' '||model AS 'Type',  
-company AS 'Company'  
+        registration AS 'Registration',
+        make||' '||model AS 'Type',
+        company AS 'Company'
 FROM tails WHERE model IS NOT NULL AND variant IS NULL  
 UNION  
 SELECT  tail_id AS 'ID',  
-registration AS 'Registration',  
-make||' '||model||'-'||variant AS 'Type',  
-company AS 'Company'  
+        registration AS 'Registration',
+        make||' '||model||'-'||variant AS 'Type',
+        company AS 'Company'
 FROM tails WHERE variant IS NOT NULL;
 
 DROP VIEW IF EXISTS 'viewPilots';
 CREATE VIEW viewPilots AS  
 SELECT  pilot_id AS 'ID',  
-lastname AS 'Last Name',  
-firstname AS 'First Name',  
-company AS 'Company'  
+        lastname AS 'Last Name',
+        firstname AS 'First Name',
+        company AS 'Company'
 FROM pilots;
 
 DROP VIEW IF EXISTS 'viewTotals';
 CREATE VIEW viewTotals AS  
 SELECT  printf('%02d',CAST(SUM(tblk) AS INT)/60)||':'||printf('%02d',CAST(SUM(tblk) AS INT)%60) AS 'TOTAL',  
-printf('%02d',CAST(SUM(tSPSE) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPSE) AS INT)%60) AS 'SP SE',  
-printf('%02d',CAST(SUM(tSPME) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPME) AS INT)%60) AS 'SP ME',  
-printf('%02d',CAST(SUM(tNIGHT) AS INT)/60)||':'||printf('%02d',CAST(SUM(tNIGHT) AS INT)%60) AS 'NIGHT',  
-printf('%02d',CAST(SUM(tIFR) AS INT)/60)||':'||printf('%02d',CAST(SUM(tIFR) AS INT)%60) AS 'IFR',  
-printf('%02d',CAST(SUM(tPIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPIC) AS INT)%60) AS 'PIC',  
-printf('%02d',CAST(SUM(tPICUS) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPICUS) AS INT)%60) AS 'PICUS',  
-printf('%02d',CAST(SUM(tSIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIC) AS INT)%60) AS 'SIC',  
-printf('%02d',CAST(SUM(tDual) AS INT)/60)||':'||printf('%02d',CAST(SUM(tDual) AS INT)%60) AS 'DUAL',  
-printf('%02d',CAST(SUM(tFI) AS INT)/60)||':'||printf('%02d',CAST(SUM(tFI) AS INT)%60) AS 'INSTRUCTOR',  
-printf('%02d',CAST(SUM(tSIM) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIM) AS INT)%60) AS 'SIMULATOR',  
-printf('%02d',CAST(SUM(tMP) AS INT)/60)||':'||printf('%02d',CAST(SUM(tMP) AS INT)%60) AS 'MultPilot',  
-CAST(SUM(toDay) AS INT) AS 'TO Day', 
-CAST(SUM(toNight) AS INT) AS 'TO Night',  
-CAST(SUM(ldgDay) AS INT) AS 'LDG Day', 
-CAST(SUM(ldgNight) AS INT) AS 'LDG Night'  
+        printf('%02d',CAST(SUM(tSPSE) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPSE) AS INT)%60) AS 'SP SE',
+        printf('%02d',CAST(SUM(tSPME) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSPME) AS INT)%60) AS 'SP ME',
+        printf('%02d',CAST(SUM(tNIGHT) AS INT)/60)||':'||printf('%02d',CAST(SUM(tNIGHT) AS INT)%60) AS 'NIGHT',
+        printf('%02d',CAST(SUM(tIFR) AS INT)/60)||':'||printf('%02d',CAST(SUM(tIFR) AS INT)%60) AS 'IFR',
+        printf('%02d',CAST(SUM(tPIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPIC) AS INT)%60) AS 'PIC',
+        printf('%02d',CAST(SUM(tPICUS) AS INT)/60)||':'||printf('%02d',CAST(SUM(tPICUS) AS INT)%60) AS 'PICUS',
+        printf('%02d',CAST(SUM(tSIC) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIC) AS INT)%60) AS 'SIC',
+        printf('%02d',CAST(SUM(tDual) AS INT)/60)||':'||printf('%02d',CAST(SUM(tDual) AS INT)%60) AS 'DUAL',
+        printf('%02d',CAST(SUM(tFI) AS INT)/60)||':'||printf('%02d',CAST(SUM(tFI) AS INT)%60) AS 'INSTRUCTOR',
+        printf('%02d',CAST(SUM(tSIM) AS INT)/60)||':'||printf('%02d',CAST(SUM(tSIM) AS INT)%60) AS 'SIMULATOR',
+        printf('%02d',CAST(SUM(tMP) AS INT)/60)||':'||printf('%02d',CAST(SUM(tMP) AS INT)%60) AS 'MultPilot',
+        CAST(SUM(toDay) AS INT) AS 'TO Day',
+        CAST(SUM(toNight) AS INT) AS 'TO Night',
+        CAST(SUM(ldgDay) AS INT) AS 'LDG Day',
+        CAST(SUM(ldgNight) AS INT) AS 'LDG Night'
 FROM flights;
 
 DROP VIEW IF EXISTS 'viewExport';
 CREATE VIEW viewExport AS
 SELECT  flight_id,
-doft as 'Date',
-dept AS 'Dept',
-printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time Out',
-dest AS 'Dest',
-printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time In ',
-CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
-registration AS 'Registration',
-(SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE',
-(SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',
-(SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',
-printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
-CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
-toDay AS 'Take-Off Day',
-ldgDay AS 'Landings Day',
-toNight AS 'Take-Off Night',
-ldgNight AS 'Landings Night',
-(SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',
-(SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',
-(SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',
-(SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',
-(SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',
-(SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',
-null AS 'Sim Type',
-null AS 'Time of Session',
-remarks AS 'Remarks'
+        doft as 'Date',
+        dept AS 'Dept',
+        printf('%02d',(tofb/60))||':'||printf('%02d',(tofb%60)) AS 'Time Out',
+        dest AS 'Dest',
+        printf('%02d',(tonb/60))||':'||printf('%02d',(tonb%60)) AS 'Time In ',
+        CASE  WHEN variant IS NOT NULL THEN make||' '||model||'-'||variant  ELSE make||' '||model  END  AS 'Type',
+        registration AS 'Registration',
+        (SELECT printf('%02d',(tSPSE/60))||':'||printf('%02d',(tSPSE%60)) WHERE tSPSE IS NOT NULL) AS 'SP SE',
+        (SELECT printf('%02d',(tSPME/60))||':'||printf('%02d',(tSPME%60)) WHERE tSPME IS NOT NULL) AS 'SP ME',
+        (SELECT printf('%02d',(tMP/60))||':'||printf('%02d',(tMP%60)) WHERE tMP IS NOT NULL) AS 'MP',
+        printf('%02d',(tblk/60))||':'||printf('%02d',(tblk%60)) AS 'Total',
+        CASE  WHEN pilot_id = 1 THEN alias  ELSE lastname||', '||substr(firstname, 1, 1)||'.'  END  AS 'Name PIC',
+        toDay AS 'Take-Off Day',
+        ldgDay AS 'Landings Day',
+        toNight AS 'Take-Off Night',
+        ldgNight AS 'Landings Night',
+        (SELECT printf('%02d',(tNight/60))||':'||printf('%02d',(tNight%60)) WHERE tNight IS NOT NULL)  AS 'Night',
+        (SELECT printf('%02d',(tIFR/60))||':'||printf('%02d',(tIFR%60)) WHERE tIFR IS NOT NULL)  AS 'IFR',
+        (SELECT printf('%02d',(tPIC/60))||':'||printf('%02d',(tPIC%60)) WHERE tPIC IS NOT NULL)  AS 'PIC',
+        (SELECT printf('%02d',(tSIC/60))||':'||printf('%02d',(tSIC%60)) WHERE tSIC IS NOT NULL)  AS 'SIC',
+        (SELECT printf('%02d',(tDual/60))||':'||printf('%02d',(tDual%60)) WHERE tDual IS NOT NULL)  AS 'Dual',
+        (SELECT printf('%02d',(tFI/60))||':'||printf('%02d',(tFI%60)) WHERE tFI IS NOT NULL)  AS 'FI',
+        null AS 'Sim Type',
+        null AS 'Time of Session',
+        remarks AS 'Remarks'
 FROM flights
 INNER JOIN pilots on flights.pic = pilots.pilot_id
 INNER JOIN tails on flights.acft = tails.tail_id
 UNION
 SELECT (session_id * -1),
-date,
-null,  null,  null,  null,
-aircraftType,
-registration,
-null,  null,  null,
-'SIM',
-null,  null,  null,  null,  null,  null,  null,  null,  null,  null, null,
-deviceType,  printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)),
-remarks
+        date,
+        null,  null,  null,  null,
+        aircraftType,
+        registration,
+        null,  null,  null,
+        'SIM',
+        null,  null,  null,  null,  null,  null,  null,  null,  null,  null, null,
+        deviceType,  printf('%02d',(totalTime/60))||':'||printf('%02d',(totalTime%60)),
+        remarks
 FROM simulators
 ORDER BY date DESC;

+ 6 - 6
mainwindow.cpp

@@ -26,15 +26,15 @@
 #include "src/gui/dialogues/newflightdialog.h"
 #include "src/database/databasecache.h"
 // Quick and dirty Debug area
-#include "src/testing/randomgenerator.h"
 void MainWindow::doDebugStuff()
 {
-    auto generator = OPL::RandomGenerator();
-    OPL::FlightEntry entry = generator.randomFlight();
-    DB->commit(entry);
+    OPL::RowData_T xp = DB->getTotals(false);
+    LOG << "Totals without previous:";
+    LOG << xp;
 
-    auto nfd = NewFlightDialog(DB->getLastEntry(OPL::DbTable::Flights));
-    nfd.exec();
+    xp = DB->getTotals(true);
+    LOG << "Totals with previous:";
+    LOG << xp;
 }
 
 MainWindow::MainWindow(QWidget *parent)

+ 57 - 3
src/database/database.cpp

@@ -470,9 +470,9 @@ int Database::getLastEntry(OPL::DbTable table)
     }
 }
 
-const RowData_T Database::getTotals()
+const RowData_T Database::getTotals(bool includePreviousExperience)
 {
-    const QString statement = "SELECT"
+    QString statement = "SELECT"
         " SUM(tblk) AS tblk,"
         " SUM(tSPSE) AS tSPSE,"
         " SUM(tSPME) AS tSPME,"
@@ -490,6 +490,7 @@ const RowData_T Database::getTotals()
         " SUM(ldgDay) AS ldgDay,"
         " SUM(ldgNight) AS ldgNight"
         " FROM flights";
+
     QSqlQuery query;
     query.prepare(statement);
     if (!query.exec()) {
@@ -512,7 +513,60 @@ const RowData_T Database::getTotals()
         }
     }
 
-    return entry_data;
+    if(!includePreviousExperience) {
+        return entry_data;
+    }
+
+    statement = "SELECT"
+                " SUM(tblk) AS tblk,"
+                " SUM(tSPSE) AS tSPSE,"
+                " SUM(tSPME) AS tSPME,"
+                " SUM(tMP) AS tMP,"
+                " SUM(tPIC) AS tPIC,"
+                " SUM(tSIC) AS tSIC,"
+                " SUM(tDUAL) AS tDUAL,"
+                " SUM(tFI) AS tFI,"
+                " SUM(tPICUS) AS tPICUS,"
+                " SUM(tNIGHT) AS tNIGHT,"
+                " SUM(tIFR) AS tIFR,"
+                " SUM(tSIM) AS tSIM,"
+                " SUM(toDay) AS toDay,"
+                " SUM(toNight) AS toNight,"
+                " SUM(ldgDay) AS ldgDay,"
+                " SUM(ldgNight) AS ldgNight"
+                " FROM previousExperience";
+    query.prepare(statement);
+
+    if (!query.exec()) {
+        DEB << "SQL error: " << query.lastError().text();
+        DEB << "Statement: " << query.lastQuery();
+        lastError = query.lastError();
+        return {}; // return invalid Row
+    }
+
+    RowData_T prev_exp_data;
+    if(query.next()) {
+        auto r = query.record(); // retreive record
+        if (r.count() == 0)  // row is empty
+            return {};
+
+        for (int i = 0; i < r.count(); i++){ // iterate through fields to get key:value map
+            if(!r.value(i).isNull()) {
+                prev_exp_data.insert(r.fieldName(i), r.value(i));
+            }
+        }
+    }
+
+    // add up the two query results
+    for(auto it = prev_exp_data.begin(); it != prev_exp_data.end(); it++) {
+        int prevXpValue = it.value().toInt();
+        int entryValue = entry_data.value(it.key()).toInt();
+
+        const QVariant sum = prevXpValue + entryValue;
+        it.value() = sum;
+    }
+
+    return prev_exp_data;
 }
 
 QList<int> Database::getForeignKeyConstraints(int foreign_row_id, OPL::DbTable table)

+ 5 - 3
src/database/database.h

@@ -328,10 +328,12 @@ public:
 
 
     /*!
-     * \brief Retreive the total time of all flight entries in the databasRe
-     * \return The sum of all entries in the flights table
+     * @brief Retreive the total time of all flight entries in the databas
+     * @param includePreviousExperience determines whether experience from previous logbooks
+     * is included.
+     * @return The sum of all entries in the flights table
      */
-    const RowData_T getTotals();
+    const RowData_T getTotals(bool includePreviousExperience);
 signals:
     /*!
      * \brief updated is emitted whenever the database contents have been updated.

+ 12 - 0
src/database/row.cpp

@@ -208,4 +208,16 @@ AirportEntry::AirportEntry(int row_id, const RowData_T &row_data)
     : Row(DbTable::Airports, row_id, row_data)
 {}
 
+PreviousExperienceEntry::PreviousExperienceEntry()
+    : Row(DbTable::PreviousExperience, 0)
+{}
+
+PreviousExperienceEntry::PreviousExperienceEntry(const RowData_T &row_data)
+    : Row(DbTable::PreviousExperience, 0, row_data)
+{}
+
+PreviousExperienceEntry::PreviousExperienceEntry(int row_id, const RowData_T &row_data)
+    : Row(DbTable::PreviousExperience, row_id, row_data)
+{}
+
 } // namespace OPL

+ 11 - 0
src/database/row.h

@@ -165,5 +165,16 @@ public:
     const QString icao() const { return getData().value(OPL::Db::AIRPORTS_ICAO).toString(); }
 };
 
+/*!
+ * \brief A Row representing an Airport entry. See Row class for details.
+ */
+class PreviousExperienceEntry : public Row
+{
+public:
+    PreviousExperienceEntry();
+    PreviousExperienceEntry(const RowData_T &row_data);
+    PreviousExperienceEntry(int row_id, const RowData_T &row_data);
+};
+
 } // namespace OPL
 #endif // ROW_H

+ 1 - 1
src/gui/dialogues/newflightdialog.cpp

@@ -273,7 +273,7 @@ void NewFlightDialog::onGoodInputReceived(QLineEdit *line_edit)
 void NewFlightDialog::onBadInputReceived(QLineEdit *line_edit)
 {
     DEB << line_edit->objectName() << " - Bad input received - " << line_edit->text();
-    line_edit->setStyleSheet(OPL::Styles::RED_BORDER);
+    line_edit->setStyleSheet(OPL::CssStyles::RED_BORDER);
     line_edit->setText(QString());
 
     if (mandatoryLineEdits->contains(line_edit))

+ 4 - 4
src/gui/dialogues/newsimdialog.cpp

@@ -80,7 +80,7 @@ void NewSimDialog::on_dateLineEdit_editingFinished()
         return;
     } else {
         ui->dateLineEdit->setText(QString());
-        ui->dateLineEdit->setStyleSheet(OPL::Styles::RED_BORDER);
+        ui->dateLineEdit->setStyleSheet(OPL::CssStyles::RED_BORDER);
     }
 }
 
@@ -94,7 +94,7 @@ void NewSimDialog::on_totalTimeLineEdit_editingFinished()
         QString fixed = input.fixup();
         if(fixed == QString()) {
             ui->totalTimeLineEdit->setText(QString());
-            ui->totalTimeLineEdit->setStyleSheet(OPL::Styles::RED_BORDER);
+            ui->totalTimeLineEdit->setStyleSheet(OPL::CssStyles::RED_BORDER);
         } else {
             ui->totalTimeLineEdit->setText(fixed);
             ui->totalTimeLineEdit->setStyleSheet(QString());
@@ -127,7 +127,7 @@ bool NewSimDialog::verifyInput(QString& error_msg)
     const auto date = OPL::DateTime::parseInput(text, date_format);
 
     if (!date.isValid()) {
-        ui->dateLineEdit->setStyleSheet(OPL::Styles::RED_BORDER);
+        ui->dateLineEdit->setStyleSheet(OPL::CssStyles::RED_BORDER);
         ui->dateLineEdit->setText(QString());
         error_msg = tr("Invalid Date");
         return false;
@@ -139,7 +139,7 @@ bool NewSimDialog::verifyInput(QString& error_msg)
     const OPL::Time time = OPL::Time::fromString(ui->totalTimeLineEdit->text());
 
     if (!time.isValidTimeOfDay()) {
-        ui->totalTimeLineEdit->setStyleSheet(OPL::Styles::RED_BORDER);
+        ui->totalTimeLineEdit->setStyleSheet(OPL::CssStyles::RED_BORDER);
         ui->totalTimeLineEdit->setText(QString());
         error_msg = tr("Invalid time");
         return false;

+ 11 - 34
src/gui/widgets/totalswidget.cpp

@@ -48,11 +48,7 @@ void TotalsWidget::setup(const WidgetType widgetType)
             }
         }
         // initialise m_rowData
-        m_rowData = DB->getRowData(OPL::DbTable::Flights, TOTALS_DATA_ROW_ID);
-        // DB returns empty object if no entry exists. Crate a stub to prepare for user data
-        if(m_rowData == OPL::RowData_T()) {
-            fillStubData();
-        }
+        m_rowData = DB->getRowData(OPL::DbTable::PreviousExperience, ROW_ID);
 
         // populate the UI
         fillTotals(widgetType);
@@ -64,8 +60,7 @@ void TotalsWidget::setup(const WidgetType widgetType)
 }
 
 /*!
- * \brief HomeWidget::fillTotals Retreives a Database Summary of Total Flight Time via the OPL::Statistics::totals
- * function and parses the return to fill out the QLineEdits.
+ * \brief HomeWidget::fillTotals Retreives a Database Summary of Total Flight Time and fills the UI.
  */
 void TotalsWidget::fillTotals(const WidgetType widgetType)
 {
@@ -74,10 +69,12 @@ void TotalsWidget::fillTotals(const WidgetType widgetType)
     // retreive times from database
     switch (widgetType) {
     case TotalTimeWidget:
-        time_data = DB->getTotals();
+        time_data = DB->getTotals(true);
         break;
     case PreviousExperienceWidget:
-        time_data = DB->getRowData(OPL::DbTable::Flights, TOTALS_DATA_ROW_ID);
+        time_data = DB->getRowData(OPL::DbTable::PreviousExperience, ROW_ID);
+        LOG << "Previous row data:";
+        LOG << time_data;
     }
 
     // fill the line edits with the data obtained
@@ -91,6 +88,7 @@ void TotalsWidget::fillTotals(const WidgetType widgetType)
             const QString &le_name = line_edit->objectName();
             if(le_name.contains("to") || le_name.contains("ldg")) {
                 // line edits for take offs and landings
+                DEB << "Setting to/ldg: " << le_name << " -> " + field.toString();
                 line_edit->setText(field.toString());
             } else {
                 // line edits for total time
@@ -102,27 +100,6 @@ void TotalsWidget::fillTotals(const WidgetType widgetType)
     }
 }
 
-/**
- * \brief TotalsWidget::fillStubData Fills the row entry object with stub data if it is empty.
- * \details The Widget retreives previous experience from the database. If the user has not entered
- * any previous experience this database entry does not exist. The database returns an empty
- * row object in this case. In order for the user to be able to fill in the previous experience,
- * a stub entry has to be created to fulfill the databases NOT NULL constrains.
- */
-void TotalsWidget::fillStubData()
-{
-    m_rowData.insert(OPL::Db::FLIGHTS_ROWID, OPL::STUB_ROW_ID);
-    m_rowData.insert(OPL::Db::FLIGHTS_DOFT, OPL::STUB_ISO_DATE);
-    m_rowData.insert(OPL::Db::FLIGHTS_TOFB, 0);
-    m_rowData.insert(OPL::Db::FLIGHTS_TONB, 0);
-    m_rowData.insert(OPL::Db::FLIGHTS_TBLK, 0);
-    m_rowData.insert(OPL::Db::FLIGHTS_DEPT, OPL::STUB_AIRPORT_CODE);
-    m_rowData.insert(OPL::Db::FLIGHTS_DEST, OPL::STUB_AIRPORT_CODE);
-    m_rowData.insert(OPL::Db::FLIGHTS_PIC, OPL::STUB_ROW_ID);
-    m_rowData.insert(OPL::Db::FLIGHTS_ACFT, OPL::STUB_ROW_ID);
-    DEB << m_rowData;
-}
-
 /*!
  * \brief TotalsWidget::connectSignalsAndSlots If the widget is editable, connects the signals and slots
  */
@@ -185,11 +162,11 @@ void TotalsWidget::timeLineEditEditingFinished()
     m_rowData.insert(db_field, value);
     LOG << "Added row data: " + db_field + ": " + value.toString();
 
-    const auto previous_experience = OPL::FlightEntry(TOTALS_DATA_ROW_ID, m_rowData);
+    const auto previous_experience = OPL::PreviousExperienceEntry(ROW_ID, m_rowData);
     DB->commit(previous_experience);
 
     // Read back the value and set the line edit to confirm input is correct and provide user feedback
-    m_rowData = DB->getRowData(OPL::DbTable::Flights, TOTALS_DATA_ROW_ID);
+    m_rowData = DB->getRowData(OPL::DbTable::PreviousExperience, ROW_ID);
     OPL::Time new_time = OPL::Time(m_rowData.value(db_field).toInt());
     line_edit->setText(new_time.toString());
 }
@@ -206,11 +183,11 @@ void TotalsWidget::movementLineEditEditingFinished()
 
     m_rowData.insert(db_field, value);
 
-    const auto previous_experience = OPL::FlightEntry(TOTALS_DATA_ROW_ID, m_rowData);
+    const auto previous_experience = OPL::PreviousExperienceEntry(ROW_ID, m_rowData);
     DB->commit(previous_experience);
 
     // read back the value and set the line edit to the retreived value to give user feedback
-    m_rowData = DB->getRowData(OPL::DbTable::Flights, TOTALS_DATA_ROW_ID);
+    m_rowData = DB->getRowData(OPL::DbTable::PreviousExperience, ROW_ID);
     const QString new_value = QString::number(m_rowData.value(db_field).toInt());
     line_edit->setText(new_value);
 }

+ 4 - 3
src/gui/widgets/totalswidget.h

@@ -28,10 +28,11 @@ private:
      * \brief m_rowData holds the data displayed in the line edits
      */
     OPL::RowData_T m_rowData;
-    const static int TOTALS_DATA_ROW_ID = OPL::STUB_ROW_ID;
-
+    /*!
+     * \brief ROW_ID the row ID for previous experience entries (0)
+     */
+    const static int ROW_ID = 1;
     void fillTotals(const WidgetType widgetType);
-    void fillStubData();
     void setup(const WidgetType widgetType);
     void connectSignalsAndSlots();
     bool verifyUserTimeInput(QLineEdit *line_edit, const TimeInput &input);

+ 30 - 14
src/opl.h

@@ -81,11 +81,6 @@ const static char* STUB_AIRPORT_CODE = "XXXX";
  */
 const static char* STUB_AIRCRAFT_REG = "XX-XXX";
 
-/**
- * @brief Defines a dummy date in the ISO date format: "1900-01-01"
- */
-const static char* STUB_ISO_DATE = "1900-01-01";
-
 /*!
  * \brief The ANotificationHandler class handles displaying of user-directed messages. It displays
  * information to the user in a QMessageBox and forwards the displayed message to ALog so it is written
@@ -157,7 +152,7 @@ enum class SimulatorType {FNPTI = 0, FNPTII = 1, FSTD = 2};
 /*!
  * \brief Enumerates the tables in the database
  */
-enum class DbTable {Any, Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog};
+enum class DbTable {Any, Flights, Simulators, Pilots, Tails, Aircraft, Airports, Currencies, Changelog, PreviousExperience};
 
 /*!
  * \brief Enumerates the currency names
@@ -234,6 +229,7 @@ private:
         {DbTable::Airports,     QStringLiteral("airports")},
         {DbTable::Currencies,   QStringLiteral("currencies")},
         {DbTable::Changelog,    QStringLiteral("changelog")},
+        {DbTable::PreviousExperience,    QStringLiteral("previousExperience")},
     };
 #else
     const static inline QMap<Translation, QString> L10N_FilePaths {
@@ -281,6 +277,7 @@ private:
         {DbTable::Airports,     QStringLiteral("airports")},
         {DbTable::Currencies,   QStringLiteral("currencies")},
         {DbTable::Changelog,    QStringLiteral("changelog")},
+        {DbTable::PreviousExperience,    QStringLiteral("previousExperience")},
     };
 #endif
 
@@ -331,13 +328,14 @@ namespace Db {
 
 
 // Table names
-const inline auto TABLE_FLIGHTS          = QStringLiteral("flights");
-const inline auto TABLE_PILOTS           = QStringLiteral("pilots");
-const inline auto TABLE_TAILS            = QStringLiteral("tails");
-const inline auto TABLE_AIRCRAFT         = QStringLiteral("aircraft");
-const inline auto TABLE_AIRPORTS         = QStringLiteral("airports");
-const inline auto TABLE_CURRENCIES       = QStringLiteral("currencies");
-const inline auto TABLE_SIMULATORS       = QStringLiteral("simulators");
+const inline auto TABLE_FLIGHTS         = QStringLiteral("flights");
+const inline auto TABLE_PILOTS          = QStringLiteral("pilots");
+const inline auto TABLE_TAILS           = QStringLiteral("tails");
+const inline auto TABLE_AIRCRAFT        = QStringLiteral("aircraft");
+const inline auto TABLE_AIRPORTS        = QStringLiteral("airports");
+const inline auto TABLE_CURRENCIES  	= QStringLiteral("currencies");
+const inline auto TABLE_SIMULATORS      = QStringLiteral("simulators");
+const inline auto TABLE_PREVIOUS_EXP	= QStringLiteral("previousExperience");
 
 // Flights table columns
 const inline auto FLIGHTS_ROWID          = QStringLiteral("flight_id");
@@ -420,6 +418,24 @@ const inline auto AIRPORTS_ALTITIDUE      = QStringLiteral("alt");
 const inline auto AIRPORTS_UTC_OFFSET     = QStringLiteral("utcoffset");
 const inline auto AIRPORTS_TZ_OLSON       = QStringLiteral("tzolson");
 
+// Previous Experience table
+const inline auto PREVXP_TBLK           = &FLIGHTS_TBLK;
+const inline auto PREVXP_TSPSE          = &FLIGHTS_TSPSE;
+const inline auto PREVXP_TSPME          = &FLIGHTS_TSPME;
+const inline auto PREVXP_TMP            = &FLIGHTS_TMP;
+const inline auto PREVXP_TNIGHT         = &FLIGHTS_TNIGHT;
+const inline auto PREVXP_TIFR           = &FLIGHTS_TIFR;
+const inline auto PREVXP_TPIC           = &FLIGHTS_TPIC;
+const inline auto PREVXP_TPICUS         = &FLIGHTS_TPICUS;
+const inline auto PREVXP_TSIC           = &FLIGHTS_TSIC;
+const inline auto PREVXP_TDUAL          = &FLIGHTS_TDUAL;
+const inline auto PREVXP_TFI            = &FLIGHTS_TFI;
+const inline auto PREVXP_TSIM           = &FLIGHTS_TSIM;
+const inline auto PREVXP_TODAY          = &FLIGHTS_TODAY;
+const inline auto PREVXP_TONIGHT        = &FLIGHTS_TONIGHT;
+const inline auto PREVXP_LDGDAY         = &FLIGHTS_LDGDAY;
+const inline auto PREVXP_LDGNIGHT       = &FLIGHTS_LDGNIGHT;
+
 // all tables
 const inline auto  ROWID                  = QStringLiteral("rowid");
 const inline auto  NULL_TIME_hhmm         = QStringLiteral("00:00");
@@ -462,7 +478,7 @@ const inline auto  ICON_TOOLBAR_BACKUP_DARK      = QStringLiteral(":/icons/opl-i
 
 }
 
-namespace Styles {
+namespace CssStyles {
 
 const inline auto  RED_BORDER = QStringLiteral("border: 1px solid red");
 } // namespace Styles