1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-23 17:30:17 +01:00

Dependency cleanup (#627)

* DBConnection doesn't use ProjectFileIO or need friendship...

... Instead, it is given its own weak_ptr to the project

* Demote the bypass flag into DBConnection...

... So SqliteSampleBlock needs ProjectFileIO only to get the DBConnection

* Accessor functions for the connection objects for SqliteSampleBlock

* Another level of indirection to get to the DBConnection object...

... The document holds the unique_ptr to DBConnection in an attached object;
later we want the SqliteSampleBlockFactory to locate the same pointer without
using ProjectFileIO

* SqliteSampleBlock and its factory don't use class ProjectFileIO...

... Instead they share a pointer to the pointer to the current DBConnection.

This means they no longer know how to invoke the lazy opening of that
connection.

So just require that this be done before any operations on blocks happen.  If
it hasn't, throw and let the application recover.

* ProjectFileIO no longer needs weak_ptr to Project for safety...

... so eliminate much ugliness from 127696879d

* Move DBConnection to new files...

... And SqliteSampleBlock does not depend on ProjectFileIO.

* SampleBlock.h doesn't need ClientData.h

* Function ProjectFileIO::Conn() isn't needed
This commit is contained in:
Paul Licameli
2020-07-23 02:04:46 -04:00
committed by GitHub
parent 38e830edf0
commit a3fcd611b5
9 changed files with 535 additions and 441 deletions

View File

@@ -11,8 +11,8 @@ Paul Licameli -- split from SampleBlock.cpp and SampleBlock.h
#include <float.h>
#include <sqlite3.h>
#include "DBConnection.h"
#include "SampleFormat.h"
#include "ProjectFileIO.h"
#include "xml/XMLTagHandler.h"
#include "SampleBlock.h" // to inherit
@@ -22,7 +22,8 @@ class SqliteSampleBlock final : public SampleBlock
{
public:
explicit SqliteSampleBlock(ProjectFileIO &io);
explicit SqliteSampleBlock(
const std::shared_ptr<ConnectionPtr> &ppConnection);
~SqliteSampleBlock() override;
void CloseLock() override;
@@ -75,9 +76,25 @@ private:
void CalcSummary();
private:
DBConnection *Conn() const
{
auto &pConnection = mppConnection->mpConnection;
if (!pConnection) {
throw SimpleMessageBoxException
{
XO("Failed to open the project's database")
};
}
return pConnection.get();
}
sqlite3 *DB() const
{
return Conn()->DB();
}
friend SqliteSampleBlockFactory;
ProjectFileIO & mIO;
const std::shared_ptr<ConnectionPtr> mppConnection;
bool mValid;
bool mDirty;
bool mSilent;
@@ -126,11 +143,11 @@ public:
const wxChar **attrs) override;
private:
std::shared_ptr<ProjectFileIO> mpIO;
const std::shared_ptr<ConnectionPtr> mppConnection;
};
SqliteSampleBlockFactory::SqliteSampleBlockFactory( AudacityProject &project )
: mpIO{ ProjectFileIO::Get(project).shared_from_this() }
: mppConnection{ ConnectionPtr::Get(project).shared_from_this() }
{
}
@@ -140,7 +157,7 @@ SqliteSampleBlockFactory::~SqliteSampleBlockFactory() = default;
SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
samplePtr src, size_t numsamples, sampleFormat srcformat )
{
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
auto sb = std::make_shared<SqliteSampleBlock>(mppConnection);
sb->SetSamples(src, numsamples, srcformat);
return sb;
}
@@ -148,7 +165,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreate(
SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
size_t numsamples, sampleFormat srcformat )
{
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
auto sb = std::make_shared<SqliteSampleBlock>(mppConnection);
sb->SetSilent(numsamples, srcformat);
return sb;
}
@@ -157,7 +174,7 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateSilent(
SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
sampleFormat srcformat, const wxChar **attrs )
{
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
auto sb = std::make_shared<SqliteSampleBlock>(mppConnection);
sb->mSampleFormat = srcformat;
int found = 0;
@@ -223,13 +240,14 @@ SampleBlockPtr SqliteSampleBlockFactory::DoCreateFromXML(
SampleBlockPtr SqliteSampleBlockFactory::DoGet( SampleBlockID sbid )
{
auto sb = std::make_shared<SqliteSampleBlock>(*mpIO);
auto sb = std::make_shared<SqliteSampleBlock>(mppConnection);
sb->Load(sbid);
return sb;
}
SqliteSampleBlock::SqliteSampleBlock(ProjectFileIO &io)
: mIO(io)
SqliteSampleBlock::SqliteSampleBlock(
const std::shared_ptr<ConnectionPtr> &ppConnection)
: mppConnection(ppConnection)
{
mValid = false;
mSilent = false;
@@ -250,7 +268,7 @@ SqliteSampleBlock::SqliteSampleBlock(ProjectFileIO &io)
SqliteSampleBlock::~SqliteSampleBlock()
{
// See ProjectFileIO::Bypass() for a description of mIO.mBypass
if (!mLocked && !mIO.ShouldBypass())
if (!mLocked && !Conn()->ShouldBypass())
{
// In case Delete throws, don't let an exception escape a destructor,
// but we can still enqueue the delayed handler so that an error message
@@ -287,7 +305,7 @@ size_t SqliteSampleBlock::DoGetSamples(samplePtr dest,
size_t numsamples)
{
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::GetSamples,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::GetSamples,
"SELECT samples FROM sampleblocks WHERE blockid = ?1;");
return GetBlob(dest,
@@ -334,7 +352,7 @@ bool SqliteSampleBlock::GetSummary256(float *dest,
size_t numframes)
{
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::GetSummary256,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::GetSummary256,
"SELECT summary256 FROM sampleblocks WHERE blockid = ?1;");
return GetSummary(dest, frameoffset, numframes, stmt, mSummary256Bytes);
@@ -345,7 +363,7 @@ bool SqliteSampleBlock::GetSummary64k(float *dest,
size_t numframes)
{
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::GetSummary64k,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::GetSummary64k,
"SELECT summary64k FROM sampleblocks WHERE blockid = ?1;");
return GetSummary(dest, frameoffset, numframes, stmt, mSummary256Bytes);
@@ -447,7 +465,7 @@ size_t SqliteSampleBlock::GetBlob(void *dest,
size_t srcoffset,
size_t srcbytes)
{
auto db = mIO.DB();
auto db = DB();
wxASSERT(mBlockID > 0);
@@ -516,7 +534,7 @@ size_t SqliteSampleBlock::GetBlob(void *dest,
void SqliteSampleBlock::Load(SampleBlockID sbid)
{
auto db = mIO.DB();
auto db = DB();
int rc;
wxASSERT(sbid > 0);
@@ -531,7 +549,7 @@ void SqliteSampleBlock::Load(SampleBlockID sbid)
mSumMin = 0.0;
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::LoadSampleBlock,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::LoadSampleBlock,
"SELECT sampleformat, summin, summax, sumrms,"
" length('summary256'), length('summary64k'), length('samples')"
" FROM sampleblocks WHERE blockid = ?1;");
@@ -579,11 +597,11 @@ void SqliteSampleBlock::Load(SampleBlockID sbid)
void SqliteSampleBlock::Commit()
{
auto db = mIO.DB();
auto db = DB();
int rc;
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::InsertSampleBlock,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::InsertSampleBlock,
"INSERT INTO sampleblocks (sampleformat, summin, summax, sumrms,"
" summary256, summary64k, samples)"
" VALUES(?1,?2,?3,?4,?5,?6,?7);");
@@ -634,13 +652,13 @@ void SqliteSampleBlock::Commit()
void SqliteSampleBlock::Delete()
{
auto db = mIO.DB();
auto db = DB();
int rc;
wxASSERT(mBlockID > 0);
// Prepare and cache statement...automatically finalized at DB close
sqlite3_stmt *stmt = mIO.Conn()->Prepare(DBConnection::DeleteSampleBlock,
sqlite3_stmt *stmt = Conn()->Prepare(DBConnection::DeleteSampleBlock,
"DELETE FROM sampleblocks WHERE blockid = ?1;");
// Bind statement paraemters