File: Connection.h

package info (click to toggle)
audacity 3.7.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 134,800 kB
  • sloc: cpp: 366,277; ansic: 198,323; lisp: 7,761; sh: 3,414; python: 1,501; xml: 1,385; perl: 854; makefile: 125
file content (149 lines) | stat: -rw-r--r-- 4,304 bytes parent folder | download | duplicates (2)
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