From 449eb6e818660ae8cd3da4d8ca0aec57e522fad0 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Sat, 20 Jul 2013 11:07:03 +0100 Subject: [PATCH] Fixup Athlete/DBAccess/MainWindow dependency A bit of a mix of stuff, but basically the Athlete class has sql stuff in it, that DBAccess used but also referenced a session number in MainWindow. Removed the interdependency and moved all code to do with DB to DBAccess and out of MainWindow and Athlete. At the same time needed to clean up a bit of memory management and so introduced a MainWindow and Athlete destructor. We are now ready to do refactor part 4 to split MainWindow into a new View class (that will be in each tab). --- src/Athlete.cpp | 21 ++++++++++++ src/Athlete.h | 2 +- src/DBAccess.cpp | 67 ++++++++++++++++-------------------- src/DBAccess.h | 85 +++++++++++++++++++++++----------------------- src/MainWindow.cpp | 21 ++++++++++-- src/MainWindow.h | 4 +-- 6 files changed, 113 insertions(+), 87 deletions(-) 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