1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/*
* SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileName: Connection.h
* SPDX-FileContributor: Dmitry Vedenko
*/
#pragma once
#include <mutex>
#include <optional>
#include <string>
#include <vector>
#include "Blob.h"
#include "Function.h"
#include "Result.h"
#include "Statement.h"
#include "Transaction.h"
struct sqlite3;
namespace audacity::sqlite
{
//! The mode in which the database should be opened
enum class OpenMode
{
ReadWrite,
ReadOnly,
ReadWriteCreate,
Memory,
};
//! The mode in which the database should be accessed
/*!
* Connection is never thread-safe. This mode is used to specify how the
* multiple connections to the same database should be handled.
*/
enum class ThreadMode
{
MultiThread,
Serialized,
};
class Transaction;
//! A class representing a connection to a SQLite database
class SQLITE_HELPERS_API Connection final
{
public:
//! Opens a connection to a database
static Result<Connection> Open(
std::string_view path, OpenMode mode = OpenMode::ReadWriteCreate,
ThreadMode threadMode = ThreadMode::Serialized);
//! Wraps an existing connection. The connection will not be closed when the
//! object is destroyed.
static Result<Connection> Wrap(sqlite3* connection);
//! Opens a new connection to the same database as the existing connection
//! but with different parameters
static Result<Connection> Reopen(
const Connection& connection, OpenMode mode = OpenMode::ReadWriteCreate,
ThreadMode threadMode = ThreadMode::Serialized);
//! Opens a new connection to the same database as the existing connection
//! but with different parameters
static Result<Connection> Reopen(
sqlite3* connection, OpenMode mode = OpenMode::ReadWriteCreate,
ThreadMode threadMode = ThreadMode::Serialized);
Connection() = default;
Connection(const Connection&) = delete;
Connection(Connection&&) noexcept;
Connection& operator=(const Connection&) = delete;
Connection& operator=(Connection&&) noexcept;
~Connection();
//! Returns true if the connection is open
bool IsOpen() const noexcept;
//! Returns true if the table exists in the database
bool CheckTableExists(std::string_view tableName) const;
//! Executes the given SQL statement and returns the result
Error Execute(std::string_view sql) noexcept;
//! Starts a new transaction
Transaction BeginTransaction(std::string name);
//! Prepares the given SQL statement for execution
Result<Statement> CreateStatement(std::string_view sql) const;
//! Registers a scalar function with the given name
template<typename ScalarFunctionType>
ScalarFunction
CreateScalarFunction(std::string name, ScalarFunctionType function)
{
return ScalarFunction { mConnection, std::move(name),
std::move(function) };
}
//! Registers an aggregate function with the given name
template<typename StepFunctionType, typename FinalFunctionType>
AggregateFunction CreateAggregateFunction(
std::string name, StepFunctionType stepFunction,
FinalFunctionType finalFunction)
{
return AggregateFunction { mConnection, std::move(name),
std::move(stepFunction),
std::move(finalFunction) };
}
//! Opens a BLOB for reading or writing
Result<Blob> OpenBlob(
const std::string& tableName, const std::string& columnName,
int64_t rowId, bool readOnly,
const std::string& databaseName = "main") const;
//! Returns the underlying sqlite3* object
explicit operator sqlite3*() const noexcept;
//! Returns true if the connection is open
explicit operator bool() const noexcept;
//! Closes the connection
Error Close(bool force) noexcept;
//! Returns the path to the database
std::string_view GetPath(const char* dbName = {}) const noexcept;
private:
Connection(sqlite3* connection, bool owned) noexcept;
static Error TransactionHandler(
Connection& connection, Transaction::TransactionOperation operation,
Transaction& name);
sqlite3* mConnection {};
std::vector<Transaction*> mPendingTransactions {};
bool mInDestructor {};
bool mIsOwned {};
};
} // namespace audacity::sqlite
|