Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Transaction.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Database_SQL_Transaction_h_
5#define _Stroika_Foundation_Database_SQL_Transaction_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
13
14/**
15 * \file
16 *
17 * \note Code-Status: <a href="Code-Status.md#Alpha">Alpha</a>
18 */
19
20namespace Stroika::Foundation::Database::SQL {
21
22 using Characters::String;
23
24 /**
25 * \note Transactions are not required. This is for explicit transactions. If you omit
26 * using transactions, sqlite creates mini transactions automatically for each statement.
27 *
28 * \note Nested transactions not supported (for sqlite - add featre for detecting if engine supports)
29 *
30 * \par Example Usage
31 * \code
32 * T DB::AddOrMergeUpdate (ORM::TableConnection<T>* dbConnTable, const T& d)
33 * {
34 * SQL::Transaction t{dbConnTable->connection ()->mkTransaction ()};
35 * std::optional<T> result;
36 * if (auto dbObj = dbConnTable->Get (id)) {
37 * result = T::Merge (*dbObj, d);
38 * dbConnTable->Update (*result);
39 * }
40 * else {
41 * result = d;
42 * dbConnTable->AddNew (d);
43 * }
44 * t.Commit ();
45 * return Memory::ValueOf (result);
46 * }
47 * \endcode
48 */
49 class [[nodiscard]] Transaction {
50 public:
51 class IRep;
52
53 public:
54 /**
55 */
56 Transaction (Transaction&&) = default;
57 Transaction (const Transaction&) = delete;
58
59 protected:
60 Transaction (unique_ptr<IRep>&& rep);
61
62 public:
63 /**
64 * If Commit() has not already been called, this automatically calls Rollback() and suppresses any
65 * exceptions.
66 */
67 ~Transaction ();
68
69 public:
70 /**
71 */
72 nonvirtual Transaction& operator= (const Transaction&) = delete;
73
74 public:
75 /**
76 * Cause the transaction to end successfully, flushing to the database.
77 * It is (an assertion) error to call this multiple times. And calling OMITTING
78 * a call before the destructor causes the transaction to Rollback.
79 */
80 nonvirtual void Commit ();
81
82 public:
83 /**
84 * This cannot be called after a rollback or commit.
85 *
86 * This causes no data to be written for the commands already issued in the transaction.
87 *
88 * This is equivalent to just destroying this object, except that it can propagate
89 * exceptions if needed, whereas a destructor cannot.
90 */
91 nonvirtual void Rollback ();
92
93 public:
94 /**
95 * @see Characters::ToString ()
96 */
97 nonvirtual String ToString () const;
98
99 protected:
100 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex _fThisAssertExternallySynchronized;
101 unique_ptr<IRep> _fRep;
102 };
103
104 /**
105 * Transaction::IRep provides an (abstract) API for transactions, supported by each backend connection type.
106 *
107 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety-For-Envelope-But-Ambiguous-Thread-Safety-For-Letter">C++-Standard-Thread-Safety-For-Envelope-But-Ambiguous-Thread-Safety-For-Letter/a>
108 * But though each Statement can only be accessed from a single thread at a time, the underlying database may be
109 * threadsafe (even if accessed across processes).
110 */
112 public:
113 /**
114 */
115 virtual ~IRep () = default;
116
117 public:
118 /**
119 * Cause the transaction to end successfully, flushing to the database.
120 * It is (an assertion) error to call this multiple times. And calling OMITTING
121 * a call before the destructor causes the transaction to Rollback.
122 */
123 virtual void Commit () = 0;
124
125 public:
126 /**
127 * This cannot be called after a rollback or commit.
128 *
129 * This causes no data to be written for the commands already issued in the transaction.
130 *
131 * This is equivalent to just destroying this object, except that it can propagate
132 * exceptions if needed, whereas a destructor cannot.
133 */
134 virtual void Rollback () = 0;
135
136 public:
137 /**
138 * \note Common::DefaultNames<> supported
139 */
140 enum class Disposition {
141 eNone,
142 eRolledBack,
143 eCompleted,
144 eFailed,
145
146 Stroika_Define_Enum_Bounds (eNone, eFailed)
147 };
148
149 public:
150 /**
151 * Mostly this reports eNone or something else. But extra status could be useful for logging.
152 */
153 virtual Disposition GetDisposition () const = 0;
154
155 protected:
156 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex _fThisAssertExternallySynchronized;
157
158 private:
159 friend class Transaction;
160 };
161
162}
163
164/*
165 ********************************************************************************
166 ***************************** Implementation Details ***************************
167 ********************************************************************************
168 */
169#include "Transaction.inl"
170
171#endif /*_Stroika_Foundation_Database_SQL_Transaction_h_*/
#define Stroika_Define_Enum_Bounds(FIRST_ITEM, LAST_ITEM)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
NOT a real mutex - just a debugging infrastructure support tool so in debug builds can be assured thr...