diff --git a/src/Athlete.cpp b/src/Athlete.cpp index b71b94e5c..b9ecb3998 100644 --- a/src/Athlete.cpp +++ b/src/Athlete.cpp @@ -194,6 +194,27 @@ Athlete::close() appsettings->setCValue(context->athlete->home.dirName(), GC_SAFEEXIT, true); } +Athlete::~Athlete() +{ + delete withingsDownload; + delete zeoDownload; + delete calendarDownload; + +#ifdef GC_HAVE_ICAL + delete rideCalendar; + delete davCalendar; +#endif + delete treeWidget; + + // close the db connection (but clear models first!) + delete sqlModel; + delete metricDB; + + delete seasons; + delete zones_; + delete hrzones_; +} + void Athlete::selectRideFile(QString fileName) { for (int i = 0; i < allRides->childCount(); i++) diff --git a/src/Athlete.h b/src/Athlete.h index 839dcf80c..cc9739968 100644 --- a/src/Athlete.h +++ b/src/Athlete.h @@ -54,6 +54,7 @@ class Athlete : public QObject public: Athlete(Context *context, const QDir &home); + ~Athlete(); void close(); // basic athlete info @@ -66,7 +67,6 @@ class Athlete : public QObject HrZones *hrzones_; void setCriticalPower(int cp); bool isclean; - QSqlDatabase db; MetricAggregator *metricDB; QSqlTableModel *sqlModel; RideMetadata *rideMetadata_; diff --git a/src/DBAccess.cpp b/src/DBAccess.cpp index 53ddad24a..c4fdd1efa 100644 --- a/src/DBAccess.cpp +++ b/src/DBAccess.cpp @@ -70,21 +70,20 @@ int DBSchemaVersion = 48; -DBAccess::DBAccess(Context* context) : context(context) +DBAccess::DBAccess(Context* context) : context(context), db(NULL) { // check we have one and use built in if not there RideMetadata::readXML(":/xml/measures.xml", mkeywordDefinitions, mfieldDefinitions, mcolorfield); initDatabase(context->athlete->home); } -void DBAccess::closeConnection() -{ - dbconn.close(); -} - DBAccess::~DBAccess() { - closeConnection(); + if (db) { + db->close(); + delete db; + QSqlDatabase::removeDatabase(sessionid); + } } void @@ -92,25 +91,17 @@ DBAccess::initDatabase(QDir home) { - if(dbconn.isOpen()) return; + if(db && db->database(sessionid).isOpen()) return; QString cyclist = QFileInfo(home.path()).baseName(); - sessionid = QString("%1%2").arg(cyclist).arg(context->mainWindow->session++); + sessionid = QString("%1").arg(context->athlete->cyclist); - if (context->mainWindow->session == 1) { - // use different name for v3 metricDB to avoid constant rebuilding - // when switching between v2 stable and v3 development builds - context->athlete->db = QSqlDatabase::addDatabase("QSQLITE", sessionid); - context->athlete->db.setDatabaseName(home.absolutePath() + "/metricDBv3"); - //dbconn = db.database(QString("GC")); - dbconn = context->athlete->db.database(sessionid); - } else { - // clone the first one! - dbconn = QSqlDatabase::cloneDatabase(context->athlete->db, sessionid); - dbconn.open(); - } + // use different name for v3 metricDB to avoid constant rebuilding + // when switching between v2 stable and v3 development builds + db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", sessionid)); + db->setDatabaseName(home.absolutePath() + "/metricDBv3"); - if (!dbconn.isOpen()) { + if (!db->database(sessionid).isOpen()) { QMessageBox::critical(0, qApp->translate("DBAccess","Cannot open database"), qApp->translate("DBAccess","Unable to establish a database connection.\n" "This feature requires SQLite support. Please read " @@ -146,7 +137,7 @@ computeFileCRC(QString filename) bool DBAccess::createMetricsTable() { - QSqlQuery query(dbconn); + QSqlQuery query(db->database(sessionid)); bool rc; bool createTables = true; @@ -214,14 +205,14 @@ bool DBAccess::createMetricsTable() bool DBAccess::dropMetricTable() { - QSqlQuery query("DROP TABLE metrics", dbconn); + QSqlQuery query("DROP TABLE metrics", db->database(sessionid)); bool rc = query.exec(); return rc; } bool DBAccess::createMeasuresTable() { - QSqlQuery query(dbconn); + QSqlQuery query(db->database(sessionid)); bool rc; bool createTables = true; @@ -278,7 +269,7 @@ bool DBAccess::createMeasuresTable() bool DBAccess::dropMeasuresTable() { - QSqlQuery query("DROP TABLE measures", dbconn); + QSqlQuery query("DROP TABLE measures", db->database(sessionid)); bool rc = query.exec(); return rc; } @@ -308,7 +299,7 @@ void DBAccess::checkDBVersion() int measurescrcnow = 0; //computeFileCRC(measuresXML);// we don't allow user to edit // can we get a version number? - QSqlQuery query("SELECT table_name, schema_version, creation_date, metadata_crc from version;", dbconn); + QSqlQuery query("SELECT table_name, schema_version, creation_date, metadata_crc from version;", db->database(sessionid)); bool rc = query.exec(); @@ -316,11 +307,11 @@ void DBAccess::checkDBVersion() // we couldn't read the version table properly // it must be out of date!! - QSqlQuery dropM("DROP TABLE version", dbconn); + QSqlQuery dropM("DROP TABLE version", db->database(sessionid)); dropM.exec(); // recreate version table and add one entry - QSqlQuery version("CREATE TABLE version ( table_name varchar primary key, schema_version integer, creation_date date, metadata_crc integer );", dbconn); + QSqlQuery version("CREATE TABLE version ( table_name varchar primary key, schema_version integer, creation_date date, metadata_crc integer );", db->database(sessionid)); version.exec(); // wipe away whatever (if anything is there) @@ -373,7 +364,7 @@ int DBAccess::getDBVersion() { int schema_version = -1; // can we get a version number? - QSqlQuery query("SELECT schema_version from version;", dbconn); + QSqlQuery query("SELECT schema_version from version;", db->database(sessionid)); bool rc = query.exec(); @@ -392,7 +383,7 @@ int DBAccess::getDBVersion() *----------------------------------------------------------------------*/ bool DBAccess::importRide(SummaryMetrics *summaryMetrics, RideFile *ride, QColor color, unsigned long fingerprint, bool modify) { - QSqlQuery query(dbconn); + QSqlQuery query(db->database(sessionid)); QDateTime timestamp = QDateTime::currentDateTime(); if (modify) { @@ -475,7 +466,7 @@ bool DBAccess::importRide(SummaryMetrics *summaryMetrics, RideFile *ride, QColor bool DBAccess::deleteRide(QString name) { - QSqlQuery query(dbconn); + QSqlQuery query(db->database(sessionid)); query.prepare("DELETE FROM metrics WHERE filename = ?;"); query.addBindValue(name); @@ -484,7 +475,7 @@ DBAccess::deleteRide(QString name) QList DBAccess::getAllDates() { - QSqlQuery query("SELECT ride_date from metrics ORDER BY ride_date;", dbconn); + QSqlQuery query("SELECT ride_date from metrics ORDER BY ride_date;", db->database(sessionid)); QList dates; query.exec(); @@ -515,7 +506,7 @@ DBAccess::getRide(QString filename, SummaryMetrics &summaryMetrics, QColor&color selectStatement += " FROM metrics where filename = :name;"; // execute the select statement - QSqlQuery query(selectStatement, dbconn); + QSqlQuery query(selectStatement, db->database(sessionid)); query.bindValue(":start", filename); query.exec(); @@ -572,7 +563,7 @@ QList DBAccess::getAllMetricsFor(QDateTime start, QDateTime end) " ORDER BY ride_date;"; // execute the select statement - QSqlQuery query(selectStatement, dbconn); + QSqlQuery query(selectStatement, db->database(sessionid)); query.bindValue(":start", start.date()); query.bindValue(":end", end.date()); query.exec(); @@ -621,7 +612,7 @@ SummaryMetrics DBAccess::getRideMetrics(QString filename) selectStatement += " FROM metrics where filename == :filename ;"; // execute the select statement - QSqlQuery query(selectStatement, dbconn); + QSqlQuery query(selectStatement, db->database(sessionid)); query.bindValue(":filename", filename); query.exec(); while(query.next()) @@ -653,7 +644,7 @@ SummaryMetrics DBAccess::getRideMetrics(QString filename) *----------------------------------------------------------------------*/ bool DBAccess::importMeasure(SummaryMetrics *summaryMetrics) { - QSqlQuery query(dbconn); + QSqlQuery query(db->database(sessionid)); // construct an insert statement QString insertStatement = "insert into measures (timestamp, measure_date"; @@ -726,7 +717,7 @@ QList DBAccess::getAllMeasuresFor(QDateTime start, QDateTime end " ORDER BY measure_date;"; // execute the select statement - QSqlQuery query(selectStatement, dbconn); + QSqlQuery query(selectStatement, db->database(sessionid)); query.bindValue(":start", start.date()); query.bindValue(":end", end.date()); query.exec(); diff --git a/src/DBAccess.h b/src/DBAccess.h index 0885a6e8d..58ed6dcdc 100644 --- a/src/DBAccess.h +++ b/src/DBAccess.h @@ -42,61 +42,62 @@ class DBAccess public: - // get connection name - QSqlDatabase connection() { return dbconn; } + // get connection name + QSqlDatabase connection() { return db->database(sessionid); } - // check the db structure is up to date - void checkDBVersion(); + // check the db structure is up to date + void checkDBVersion(); - // get schema version - int getDBVersion(); + // get schema version + int getDBVersion(); - // create and drop connections - DBAccess(Context *context); - ~DBAccess(); + // create and drop connections + DBAccess(Context *context); + ~DBAccess(); - // Create/Delete Metrics - bool importRide(SummaryMetrics *summaryMetrics, RideFile *ride, QColor color, unsigned long, bool); - bool deleteRide(QString); + // Create/Delete Metrics + bool importRide(SummaryMetrics *summaryMetrics, RideFile *ride, QColor color, unsigned long, bool); + bool deleteRide(QString); - // Create/Delete Measures - bool importMeasure(SummaryMetrics *summaryMetrics); + // Create/Delete Measures + bool importMeasure(SummaryMetrics *summaryMetrics); - // Query Records - QList getAllMetricsFor(QDateTime start, QDateTime end); - QList getAllMetricsFor(DateRange dr) { - return getAllMetricsFor(QDateTime(dr.from,QTime(0,0,0)), QDateTime(dr.to, QTime(23,59,59))); - } + // Query Records + QList getAllMetricsFor(QDateTime start, QDateTime end); + QList getAllMetricsFor(DateRange dr) { + return getAllMetricsFor(QDateTime(dr.from,QTime(0,0,0)), QDateTime(dr.to, QTime(23,59,59))); + } - bool getRide(QString filename, SummaryMetrics &metrics, QColor&color); - QList getAllMeasuresFor(QDateTime start, QDateTime end); - QList getAllMeasuresFor(DateRange dr) { - return getAllMeasuresFor(QDateTime(dr.from,QTime(0,0,0)), QDateTime(dr.to, QTime(23,59,59))); - } + bool getRide(QString filename, SummaryMetrics &metrics, QColor&color); + QList getAllMeasuresFor(QDateTime start, QDateTime end); + QList getAllMeasuresFor(DateRange dr) { + return getAllMeasuresFor(QDateTime(dr.from,QTime(0,0,0)), QDateTime(dr.to, QTime(23,59,59))); + } - SummaryMetrics getRideMetrics(QString filename); // for a filename + SummaryMetrics getRideMetrics(QString filename); // for a filename - QList getAllDates(); - QList getAllSeasons(); + QList getAllDates(); + QList getAllSeasons(); private: - Context *context; - QSqlDatabase dbconn; - QString sessionid; - SpecialFields msp; - QList mfieldDefinitions; - QList mkeywordDefinitions; //NOTE: not used in measures.xml - QString mcolorfield; + Context *context; + QSqlDatabase *db; + QSqlDatabase dbconn; + QString sessionid; - typedef QHash MetricMap; + SpecialFields msp; + QList mfieldDefinitions; + QList mkeywordDefinitions; //NOTE: not used in measures.xml + QString mcolorfield; - bool createDatabase(); - void closeConnection(); - bool createMetricsTable(); - bool dropMetricTable(); - bool createMeasuresTable(); - bool dropMeasuresTable(); - void initDatabase(QDir home); + typedef QHash MetricMap; + + bool createDatabase(); + bool createMetricsTable(); + bool dropMetricTable(); + bool createMeasuresTable(); + bool dropMeasuresTable(); + void initDatabase(QDir home); }; #endif diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 8c9e69e24..c453ba671 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -99,6 +99,7 @@ #include "WFApi.h" #endif +#include "GcUpgrade.h" // handy spacer class Spacer : public QWidget @@ -114,8 +115,7 @@ public: QList mainwindows; // keep track of all the MainWindows we have open QDesktopWidget *desktop = NULL; -MainWindow::MainWindow(const QDir &home) : - session(0), isfiltered(false) +MainWindow::MainWindow(const QDir &home) : isfiltered(false) { setAttribute(Qt::WA_DeleteOnClose); @@ -1060,7 +1060,7 @@ MainWindow::closeEvent(QCloseEvent* event) appsettings->setCValue(context->athlete->cyclist, GC_BLANK_HOME, blankStateHomePage->dontShow->isChecked()); appsettings->setCValue(context->athlete->cyclist, GC_BLANK_TRAIN, blankStateTrainPage->dontShow->isChecked()); - // clear down athlete + // close athlete context->athlete->close(); // now remove from the list @@ -1070,6 +1070,21 @@ MainWindow::closeEvent(QCloseEvent* event) } } +MainWindow::~MainWindow() +{ + delete analysisSidebar; + delete ltmSidebar; + delete diarySidebar; + delete trainSidebar; + + delete analWindow; + delete homeWindow; + delete trainWindow; + delete diaryWindow; + + delete context->athlete; +} + // global search/data filter void MainWindow::searchResults(QStringList f) diff --git a/src/MainWindow.h b/src/MainWindow.h index b71b6c84a..55ee34f71 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -66,9 +66,7 @@ class MainWindow : public QMainWindow public: MainWindow(const QDir &home); - - // state data - int session; // by DBAccess + ~MainWindow(); // temp to zap db - will move to tab // // global filters bool isfiltered; // used by lots of charts