Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
audacity::sqlite::Connection Class Referencefinal

A class representing a connection to a SQLite database. More...

#include <Connection.h>

Collaboration diagram for audacity::sqlite::Connection:
[legend]

Public Member Functions

 Connection ()=default
 
 Connection (const Connection &)=delete
 
 Connection (Connection &&) noexcept
 
Connectionoperator= (const Connection &)=delete
 
Connectionoperator= (Connection &&) noexcept
 
 ~Connection ()
 
bool IsOpen () const noexcept
 Returns true if the connection is open. More...
 
bool CheckTableExists (std::string_view tableName) const
 Returns true if the table exists in the database. More...
 
Error Execute (std::string_view sql) noexcept
 Executes the given SQL statement and returns the result. More...
 
Transaction BeginTransaction (std::string name)
 Starts a new transaction. More...
 
Result< StatementCreateStatement (std::string_view sql) const
 Prepares the given SQL statement for execution. More...
 
template<typename ScalarFunctionType >
ScalarFunction CreateScalarFunction (std::string name, ScalarFunctionType function)
 Registers a scalar function with the given name. More...
 
template<typename StepFunctionType , typename FinalFunctionType >
AggregateFunction CreateAggregateFunction (std::string name, StepFunctionType stepFunction, FinalFunctionType finalFunction)
 Registers an aggregate function with the given name. More...
 
Result< BlobOpenBlob (const std::string &tableName, const std::string &columnName, int64_t rowId, bool readOnly, const std::string &databaseName="main") const
 Opens a BLOB for reading or writing. More...
 
 operator sqlite3 * () const noexcept
 Returns the underlying sqlite3* object. More...
 
 operator bool () const noexcept
 Returns true if the connection is open. More...
 
Error Close (bool force) noexcept
 Closes the connection. More...
 
std::string_view GetPath (const char *dbName={}) const noexcept
 Returns the path to the database. More...
 

Static Public Member Functions

static Result< ConnectionOpen (std::string_view path, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized)
 Opens a connection to a database. More...
 
static Result< ConnectionWrap (sqlite3 *connection)
 
static Result< ConnectionReopen (const Connection &connection, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized)
 
static Result< ConnectionReopen (sqlite3 *connection, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized)
 

Private Member Functions

 Connection (sqlite3 *connection, bool owned) noexcept
 

Static Private Member Functions

static Error TransactionHandler (Connection &connection, Transaction::TransactionOperation operation, Transaction &name)
 

Private Attributes

sqlite3 * mConnection {}
 
std::vector< Transaction * > mPendingTransactions {}
 
bool mInDestructor {}
 
bool mIsOwned {}
 

Detailed Description

A class representing a connection to a SQLite database.

Definition at line 47 of file Connection.h.

Constructor & Destructor Documentation

◆ Connection() [1/4]

audacity::sqlite::Connection::Connection ( )
default

Referenced by Open(), and Wrap().

Here is the caller graph for this function:

◆ Connection() [2/4]

audacity::sqlite::Connection::Connection ( const Connection )
delete

◆ Connection() [3/4]

audacity::sqlite::Connection::Connection ( Connection &&  rhs)
noexcept

Definition at line 114 of file Connection.cpp.

115{
116 *this = std::move(rhs);
117}

◆ ~Connection()

audacity::sqlite::Connection::~Connection ( )

Definition at line 129 of file Connection.cpp.

130{
131 mInDestructor = true;
132 auto error = Close(true);
133 assert(!error.IsError());
134}
Error Close(bool force) noexcept
Closes the connection.
Definition: Connection.cpp:298

References Close(), and mInDestructor.

Here is the call graph for this function:

◆ Connection() [4/4]

audacity::sqlite::Connection::Connection ( sqlite3 *  connection,
bool  owned 
)
privatenoexcept

Definition at line 108 of file Connection.cpp.

109 : mConnection { connection }
110 , mIsOwned { owned }
111{
112}

Member Function Documentation

◆ BeginTransaction()

Transaction audacity::sqlite::Connection::BeginTransaction ( std::string  name)

Starts a new transaction.

Definition at line 200 of file Connection.cpp.

201{
202 return Transaction(*this, TransactionHandler, std::move(name));
203}
const TranslatableString name
Definition: Distortion.cpp:76
static Error TransactionHandler(Connection &connection, Transaction::TransactionOperation operation, Transaction &name)
Definition: Connection.cpp:205

References name, and TransactionHandler().

Here is the call graph for this function:

◆ CheckTableExists()

bool audacity::sqlite::Connection::CheckTableExists ( std::string_view  tableName) const

Returns true if the table exists in the database.

Definition at line 141 of file Connection.cpp.

142{
143 auto stmt = CreateStatement(
144 "SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?)");
145
146 if (!stmt)
147 return false;
148
149 auto result = stmt->Prepare(tableName).Run();
150
151 if (!result.HasRows())
152 return false;
153
154 for (auto row : result)
155 return row.GetOr(0, false);
156
157 return false;
158}
Result< Statement > CreateStatement(std::string_view sql) const
Prepares the given SQL statement for execution.
Definition: Connection.cpp:253

References CreateStatement().

Here is the call graph for this function:

◆ Close()

Error audacity::sqlite::Connection::Close ( bool  force)
noexcept

Closes the connection.

Definition at line 298 of file Connection.cpp.

299{
300 // If there is a transaction in progress,
301 // rollback it.
302 std::vector<Transaction*> pendingTransactions;
303
304 for (auto* transaction : pendingTransactions)
305 if (auto err = transaction->Abort(); !force && err.IsError())
306 return err;
307
308 if (mConnection != nullptr && mIsOwned)
309 if(auto err = Error(sqlite3_close(mConnection)); err.IsError())
310 return err;
311
312 mConnection = nullptr;
313
314 return {};
315}

References audacity::sqlite::Error::IsError().

Referenced by ~Connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateAggregateFunction()

template<typename StepFunctionType , typename FinalFunctionType >
AggregateFunction audacity::sqlite::Connection::CreateAggregateFunction ( std::string  name,
StepFunctionType  stepFunction,
FinalFunctionType  finalFunction 
)
inline

Registers an aggregate function with the given name.

Definition at line 107 of file Connection.h.

110 {
111 return AggregateFunction { mConnection, std::move(name),
112 std::move(stepFunction),
113 std::move(finalFunction) };
114 }

References name.

◆ CreateScalarFunction()

template<typename ScalarFunctionType >
ScalarFunction audacity::sqlite::Connection::CreateScalarFunction ( std::string  name,
ScalarFunctionType  function 
)
inline

Registers a scalar function with the given name.

Definition at line 99 of file Connection.h.

100 {
101 return ScalarFunction { mConnection, std::move(name),
102 std::move(function) };
103 }

References name.

◆ CreateStatement()

Result< Statement > audacity::sqlite::Connection::CreateStatement ( std::string_view  sql) const

Prepares the given SQL statement for execution.

Definition at line 253 of file Connection.cpp.

254{
255 if (mInDestructor || mConnection == nullptr)
256 return Error(SQLITE_MISUSE);
257
258 sqlite3_stmt* statement = nullptr;
259
260 auto error = Error(sqlite3_prepare_v2(
261 mConnection, sql.data(), sql.size(), &statement, nullptr));
262
263 if (error.IsError())
264 return error;
265
266 return Result<Statement>(Statement(statement));
267}

References mConnection, and mInDestructor.

Referenced by audacity::cloud::audiocom::sync::RemoteProjectSnapshot::AttachOriginalDB(), CheckTableExists(), audacity::cloud::audiocom::sync::CloudProjectsDatabase::DeleteProject(), audacity::cloud::audiocom::sync::anonymous_namespace{RemoteProjectSnapshot.cpp}::ListAttachedDatabases(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::RemoteProjectSnapshot(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::SetupBlocksCopy(), and audacity::cloud::audiocom::sync::RemoteProjectSnapshot::~RemoteProjectSnapshot().

Here is the caller graph for this function:

◆ Execute()

Error audacity::sqlite::Connection::Execute ( std::string_view  sql)
noexcept

Executes the given SQL statement and returns the result.

Definition at line 160 of file Connection.cpp.

161{
162 if (mInDestructor || mConnection == nullptr)
163 return Error(SQLITE_MISUSE);
164
165 auto tx = BeginTransaction("Connection_Execute");
166
167 auto first = sql.data();
168 auto last = first + sql.size();
169
170 while (first != last)
171 {
172 const char* next = nullptr;
173 sqlite3_stmt* statement = nullptr;
174
175 int result = sqlite3_prepare_v2 (
176 mConnection, first, last - first, &statement, &next);
177
178 if (result != SQLITE_OK)
179 return Error(result);
180
181 first = next;
182
183 if (statement == nullptr)
184 continue;
185
186 auto finalizer = finally([statement] { sqlite3_finalize(statement); });
187
188 result = sqlite3_step(statement);
189
190 if (result != SQLITE_OK && result != SQLITE_DONE && result != SQLITE_ROW)
191 return Error(result);
192
193 while (result == SQLITE_ROW)
194 result = sqlite3_step(statement);
195 }
196
197 return tx.Commit();
198}
Transaction BeginTransaction(std::string name)
Starts a new transaction.
Definition: Connection.cpp:200

◆ GetPath()

std::string_view audacity::sqlite::Connection::GetPath ( const char *  dbName = {}) const
noexcept

Returns the path to the database.

Definition at line 317 of file Connection.cpp.

318{
319 auto path = sqlite3_db_filename(mConnection, dbName);
320
321 if (path == nullptr)
322 return {};
323
324 return path;
325}

Referenced by Reopen().

Here is the caller graph for this function:

◆ IsOpen()

bool audacity::sqlite::Connection::IsOpen ( ) const
noexcept

Returns true if the connection is open.

Definition at line 136 of file Connection.cpp.

137{
138 return mConnection != nullptr;
139}

References mConnection.

Referenced by Reopen().

Here is the caller graph for this function:

◆ Open()

Result< Connection > audacity::sqlite::Connection::Open ( std::string_view  path,
OpenMode  mode = OpenMode::ReadWriteCreate,
ThreadMode  threadMode = ThreadMode::Serialized 
)
static

Opens a connection to a database.

Definition at line 21 of file Connection.cpp.

22{
23 auto error = Initialize();
24
25 if (error.IsError())
26 return error;
27
28 int flags = 0;
29
30 switch (mode)
31 {
33 flags = SQLITE_OPEN_READWRITE;
34 break;
36 flags = SQLITE_OPEN_READONLY;
37 break;
39 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
40 break;
42 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
43 break;
44 }
45
46 switch (threadMode)
47 {
49 flags |= SQLITE_OPEN_NOMUTEX;
50 break;
52 flags |= SQLITE_OPEN_FULLMUTEX;
53 break;
54 }
55
56 sqlite3* connection = nullptr;
57
58 // If the path is not null-terminated, copy it to a temporary string.
59 std::string temp;
60 if (*(path.data() + path.size()) != '\0')
61 {
62 temp = std::string(path);
63 path = temp;
64 }
65
66 error = Error(sqlite3_open_v2(path.data(), &connection, flags, nullptr));
67
68 if (error.IsError())
69 return error;
70
71 return Connection(connection, true);
72}
Error Initialize() noexcept
Definition: SQLiteUtils.cpp:92

References Connection(), audacity::sqlite::Initialize(), audacity::sqlite::Memory, audacity::sqlite::MultiThread, audacity::sqlite::ReadOnly, audacity::sqlite::ReadWrite, audacity::sqlite::ReadWriteCreate, and audacity::sqlite::Serialized.

Referenced by audacity::sqlite::SafeConnection::Open(), and Reopen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OpenBlob()

Result< Blob > audacity::sqlite::Connection::OpenBlob ( const std::string &  tableName,
const std::string &  columnName,
int64_t  rowId,
bool  readOnly,
const std::string &  databaseName = "main" 
) const

Opens a BLOB for reading or writing.

Definition at line 269 of file Connection.cpp.

272{
273 if (mInDestructor || mConnection == nullptr)
274 return Error(SQLITE_MISUSE);
275
276 sqlite3_blob* blob = nullptr;
277
278 auto error = Error(sqlite3_blob_open(
279 mConnection, databaseName.c_str(), tableName.c_str(), columnName.c_str(),
280 rowId, readOnly ? 0 : 1, &blob));
281
282 if (error.IsError())
283 return error;
284
285 return Blob { blob };
286}

References mConnection, and mInDestructor.

◆ operator bool()

audacity::sqlite::Connection::operator bool ( ) const
explicitnoexcept

Returns true if the connection is open.

Definition at line 293 of file Connection.cpp.

294{
295 return IsOpen();
296}
bool IsOpen() const noexcept
Returns true if the connection is open.
Definition: Connection.cpp:136

◆ operator sqlite3 *()

audacity::sqlite::Connection::operator sqlite3 * ( ) const
explicitnoexcept

Returns the underlying sqlite3* object.

Definition at line 288 of file Connection.cpp.

289{
290 return mConnection;
291}

◆ operator=() [1/2]

Connection & audacity::sqlite::Connection::operator= ( Connection &&  rhs)
noexcept

Definition at line 119 of file Connection.cpp.

120{
121 std::swap(mConnection, rhs.mConnection);
122 std::swap(mIsOwned, rhs.mIsOwned);
123 std::swap(mInDestructor, rhs.mInDestructor);
124 std::swap(mPendingTransactions, rhs.mPendingTransactions);
125
126 return *this;
127}
std::vector< Transaction * > mPendingTransactions
Definition: Connection.h:143
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:628

References anonymous_namespace{NoteTrack.cpp}::swap().

Here is the call graph for this function:

◆ operator=() [2/2]

Connection & audacity::sqlite::Connection::operator= ( const Connection )
delete

◆ Reopen() [1/2]

Result< Connection > audacity::sqlite::Connection::Reopen ( const Connection connection,
OpenMode  mode = OpenMode::ReadWriteCreate,
ThreadMode  threadMode = ThreadMode::Serialized 
)
static

Opens a new connection to the same database as the existing connection but with different parameters

Definition at line 82 of file Connection.cpp.

84{
85 if (!connection.IsOpen())
86 return Error(SQLITE_MISUSE);
87
88 auto path = connection.GetPath();
89
90 // For memory and temporary databases, the path is empty.
91 if (path.empty())
92 return Error(SQLITE_MISUSE);
93
94 return Open(path, mode, threadMode);
95}
static Result< Connection > Open(std::string_view path, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized)
Opens a connection to a database.
Definition: Connection.cpp:21

References GetPath(), IsOpen(), and Open().

Referenced by audacity::sqlite::SafeConnection::Reopen(), and Reopen().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Reopen() [2/2]

Result< Connection > audacity::sqlite::Connection::Reopen ( sqlite3 *  connection,
OpenMode  mode = OpenMode::ReadWriteCreate,
ThreadMode  threadMode = ThreadMode::Serialized 
)
static

Opens a new connection to the same database as the existing connection but with different parameters

Definition at line 98 of file Connection.cpp.

99{
100 auto result = Wrap(connection);
101
102 if (!result)
103 return result;
104
105 return Reopen(*result, mode, threadMode);
106}
static Result< Connection > Reopen(const Connection &connection, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized)
Definition: Connection.cpp:82
static Result< Connection > Wrap(sqlite3 *connection)
Definition: Connection.cpp:74

References Reopen(), and Wrap().

Here is the call graph for this function:

◆ TransactionHandler()

Error audacity::sqlite::Connection::TransactionHandler ( Connection connection,
Transaction::TransactionOperation  operation,
Transaction name 
)
staticprivate

Definition at line 205 of file Connection.cpp.

208{
209 std::string sql;
210
211 const auto& name = transaction.mName;
212
213 switch (operation)
214 {
216 sql = std::string("SAVEPOINT ") + name;
217 break;
219 sql = std::string("RELEASE SAVEPOINT ") + name;
220 break;
222 sql = std::string("ROLLBACK TO SAVEPOINT ") + name +
223 std::string("; RELEASE SAVEPOINT ") + name;
224 break;
225 }
226
227 auto error = Error(sqlite3_exec(
228 connection.mConnection, sql.c_str(), nullptr, nullptr, nullptr));
229
231 {
232 transaction.mCommitted = true;
233
234 connection.mPendingTransactions.erase(
235 std::remove_if(
236 connection.mPendingTransactions.begin(),
237 connection.mPendingTransactions.end(),
238 [tx = &transaction](auto lhs) { return lhs == tx; }),
239 connection.mPendingTransactions.end());
240 }
241
242 if (error.IsError())
243 return error;
244
246 {
247 connection.mPendingTransactions.push_back(&transaction);
248 }
249
250 return {};
251}

References audacity::sqlite::Transaction::BeginOp, audacity::sqlite::Transaction::CommitOp, audacity::sqlite::Transaction::mCommitted, mConnection, audacity::sqlite::Transaction::mName, mPendingTransactions, name, and audacity::sqlite::Transaction::RollbackOp.

Referenced by BeginTransaction().

Here is the caller graph for this function:

◆ Wrap()

Result< Connection > audacity::sqlite::Connection::Wrap ( sqlite3 *  connection)
static

Wraps an existing connection. The connection will not be closed when the object is destroyed.

Definition at line 74 of file Connection.cpp.

75{
76 if (connection == nullptr)
77 return Error(SQLITE_MISUSE);
78
79 return Connection(connection, false);
80}

References Connection().

Referenced by Reopen().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mConnection

sqlite3* audacity::sqlite::Connection::mConnection {}
private

◆ mInDestructor

bool audacity::sqlite::Connection::mInDestructor {}
private

Definition at line 145 of file Connection.h.

Referenced by CreateStatement(), OpenBlob(), and ~Connection().

◆ mIsOwned

bool audacity::sqlite::Connection::mIsOwned {}
private

Definition at line 146 of file Connection.h.

◆ mPendingTransactions

std::vector<Transaction*> audacity::sqlite::Connection::mPendingTransactions {}
private

Definition at line 143 of file Connection.h.

Referenced by TransactionHandler().


The documentation for this class was generated from the following files: