summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Klotz <uwe_klotz@web.de>2017-06-20 23:53:19 +0200
committerUwe Klotz <uwe_klotz@web.de>2017-06-20 23:54:30 +0200
commit337533855f09237b8a1e3551b32baa4a87a317b4 (patch)
treed84c6c237c4f6e4ede992c0ad4044de364e40eee
parentc0b7a50815706df9a1d382a4464d902044816bae (diff)
Fix saving of waveform analysis in database
The initialization of the AnalysisDao with the thread-local database connection was missing. The restricted design of the analyzer API required to move the AnalysisDao from AnalyzeWaveform to AnalyzerQueue.
-rw-r--r--src/analyzer/analyzerqueue.cpp33
-rw-r--r--src/analyzer/analyzerqueue.h3
-rw-r--r--src/analyzer/analyzerwaveform.cpp13
-rw-r--r--src/analyzer/analyzerwaveform.h6
-rw-r--r--src/test/analyserwaveformtest.cpp4
5 files changed, 42 insertions, 17 deletions
diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp
index ba579fff32..6f25bbd195 100644
--- a/src/analyzer/analyzerqueue.cpp
+++ b/src/analyzer/analyzerqueue.cpp
@@ -7,11 +7,13 @@
#include "analyzer/analyzergain.h"
#include "analyzer/analyzerebur128.h"
#include "analyzer/analyzerwaveform.h"
+#include "library/dao/analysisdao.h"
#include "mixer/playerinfo.h"
#include "sources/soundsourceproxy.h"
#include "track/track.h"
#include "util/compatibility.h"
#include "util/db/dbconnectionpooler.h"
+#include "util/db/dbconnectionpooled.h"
#include "util/event.h"
#include "util/timer.h"
#include "util/trace.h"
@@ -51,7 +53,8 @@ AnalyzerQueue::AnalyzerQueue(
m_queue_size(0) {
if (mode != Mode::WithoutWaveform) {
- m_pAnalyzers.push_back(std::make_unique<AnalyzerWaveform>(pConfig));
+ m_pAnalysisDao = std::make_unique<AnalysisDao>(pConfig);
+ m_pAnalyzers.push_back(std::make_unique<AnalyzerWaveform>(m_pAnalysisDao.get()));
}
m_pAnalyzers.push_back(std::make_unique<AnalyzerGain>(pConfig));
m_pAnalyzers.push_back(std::make_unique<AnalyzerEbur128>(pConfig));
@@ -299,12 +302,21 @@ void AnalyzerQueue::run() {
}
void AnalyzerQueue::execThread() {
- const mixxx::DbConnectionPooler dbConnection(m_pDbConnectionPool);
- if (!dbConnection) {
- kLogger.warning()
- << "Failed to open database connection for analyzer queue";
- kLogger.debug() << "Exiting thread";
- return;
+ mixxx::DbConnectionPooler dbConnectionPooler;
+ if (m_pAnalysisDao) {
+ // Only create/open a new database connection for when needed
+ // for storing waveform analyses
+ dbConnectionPooler = mixxx::DbConnectionPooler(m_pDbConnectionPool);
+ if (!dbConnectionPooler) {
+ kLogger.warning()
+ << "Failed to open database connection for analyzer queue thread";
+ return;
+ }
+ // Use the newly created database connection for this thread
+ m_pAnalysisDao->initialize(mixxx::DbConnectionPooled(m_pDbConnectionPool));
+ // The database connection is valid until dbConnectionPooler is destroyed
+ // when exiting the enclosing function scope. The pooler as the owner of
+ // the connection must not be destroyed now!
}
m_progressInfo.current_track.reset();
@@ -380,6 +392,13 @@ void AnalyzerQueue::execThread() {
}
emptyCheck();
}
+
+ if (m_pAnalysisDao) {
+ // Invalidate reference to the thread-local database connection
+ // that will be closed soon. Not necessary, just in case ;)
+ m_pAnalysisDao->initialize(QSqlDatabase());
+ }
+
emit(queueEmpty()); // emit in case of exit;
}
diff --git a/src/analyzer/analyzerqueue.h b/src/analyzer/analyzerqueue.h
index b37341a61d..c6c62e97cf 100644
--- a/src/analyzer/analyzerqueue.h
+++ b/src/analyzer/analyzerqueue.h
@@ -16,6 +16,7 @@
#include "util/memory.h"
class Analyzer;
+class AnalysisDao;
class AnalyzerQueue : public QThread {
Q_OBJECT
@@ -60,6 +61,8 @@ class AnalyzerQueue : public QThread {
mixxx::DbConnectionPoolPtr m_pDbConnectionPool;
+ std::unique_ptr<AnalysisDao> m_pAnalysisDao;
+
typedef std::unique_ptr<Analyzer> AnalyzerPtr;
std::vector<AnalyzerPtr> m_pAnalyzers;
diff --git a/src/analyzer/analyzerwaveform.cpp b/src/analyzer/analyzerwaveform.cpp
index 19fb2a8663..eb90ba1627 100644
--- a/src/analyzer/analyzerwaveform.cpp
+++ b/src/analyzer/analyzerwaveform.cpp
@@ -16,14 +16,15 @@ mixxx::Logger kLogger("AnalyzerWaveform");
} // anonymous
AnalyzerWaveform::AnalyzerWaveform(
- const UserSettingsPointer& pConfig) :
- m_analysisDao(pConfig),
+ AnalysisDao* pAnalysisDao) :
+ m_pAnalysisDao(pAnalysisDao),
m_skipProcessing(false),
m_waveformData(nullptr),
m_waveformSummaryData(nullptr),
m_stride(0, 0),
m_currentStride(0),
m_currentSummaryStride(0) {
+ DEBUG_ASSERT(m_pAnalysisDao); // mandatory
m_filter[0] = 0;
m_filter[1] = 0;
m_filter[2] = 0;
@@ -102,7 +103,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const {
if (trackId.isValid() && (missingWaveform || missingWavesummary)) {
QList<AnalysisDao::AnalysisInfo> analyses =
- m_analysisDao.getAnalysesForTrack(trackId);
+ m_pAnalysisDao->getAnalysesForTrack(trackId);
QListIterator<AnalysisDao::AnalysisInfo> it(analyses);
while (it.hasNext()) {
@@ -117,7 +118,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const {
missingWaveform = false;
} else if (vc != WaveformFactory::VC_KEEP) {
// remove all other Analysis except that one we should keep
- m_analysisDao.deleteAnalysis(analysis.analysisId);
+ m_pAnalysisDao->deleteAnalysis(analysis.analysisId);
}
} if (analysis.type == AnalysisDao::TYPE_WAVESUMMARY) {
vc = WaveformFactory::waveformSummaryVersionToVersionClass(analysis.version);
@@ -127,7 +128,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const {
missingWavesummary = false;
} else if (vc != WaveformFactory::VC_KEEP) {
// remove all other Analysis except that one we should keep
- m_analysisDao.deleteAnalysis(analysis.analysisId);
+ m_pAnalysisDao->deleteAnalysis(analysis.analysisId);
}
}
}
@@ -309,7 +310,7 @@ void AnalyzerWaveform::finalize(TrackPointer tio) {
// waveforms (i.e. if the config setting was disabled in a previous scan)
// and then it is not called. The other analyzers have signals which control
// the update of their data.
- m_analysisDao.saveTrackAnalyses(*tio);
+ m_pAnalysisDao->saveTrackAnalyses(*tio);
kLogger.debug() << "Waveform generation for track" << tio->getId() << "done"
<< m_timer.elapsed().debugSecondsWithUnit();
diff --git a/src/analyzer/analyzerwaveform.h b/src/analyzer/analyzerwaveform.h
index ccc4bdf778..085194707d 100644
--- a/src/analyzer/analyzerwaveform.h
+++ b/src/analyzer/analyzerwaveform.h
@@ -7,7 +7,6 @@
#include "analyzer/analyzer.h"
#include "waveform/waveform.h"
-#include "library/dao/analysisdao.h"
#include "util/math.h"
#include "util/performancetimer.h"
@@ -15,6 +14,7 @@
//#define TEST_HEAT_MAP
class EngineFilterIIRBase;
+class AnalysisDao;
inline CSAMPLE scaleSignal(CSAMPLE invalue, FilterIndex index = FilterCount) {
if (invalue == 0.0) {
@@ -137,7 +137,7 @@ struct WaveformStride {
class AnalyzerWaveform : public Analyzer {
public:
explicit AnalyzerWaveform(
- const UserSettingsPointer& pConfig);
+ AnalysisDao* pAnalysisDao);
~AnalyzerWaveform() override;
bool initialize(TrackPointer tio, int sampleRate, int totalSamples) override;
@@ -154,7 +154,7 @@ class AnalyzerWaveform : public Analyzer {
void destroyFilters();
void storeIfGreater(float* pDest, float source);
- mutable AnalysisDao m_analysisDao;
+ AnalysisDao* m_pAnalysisDao;
bool m_skipProcessing;
diff --git a/src/test/analyserwaveformtest.cpp b/src/test/analyserwaveformtest.cpp
index ad619b842f..8e40121dbb 100644
--- a/src/test/analyserwaveformtest.cpp
+++ b/src/test/analyserwaveformtest.cpp
@@ -18,7 +18,8 @@ namespace {
class AnalyzerWaveformTest: public MixxxTest {
protected:
AnalyzerWaveformTest()
- : aw(config()),
+ : analysisDao(config()),
+ aw(&analysisDao),
bigbuf(nullptr),
canaryBigBuf(nullptr) {
}
@@ -49,6 +50,7 @@ class AnalyzerWaveformTest: public MixxxTest {
}
protected:
+ AnalysisDao analysisDao;
AnalyzerWaveform aw;
TrackPointer tio;
CSAMPLE* bigbuf;