fb-cpp 0.0.1
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
Transaction.cpp
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Adriano dos Santos Fernandes
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "Transaction.h"
26#include "Attachment.h"
27#include "Client.h"
28#include "Exception.h"
29#include <cassert>
30
31using namespace fbcpp;
32using namespace fbcpp::impl;
33
34
36 : client{attachment.getClient()}
37{
38 assert(attachment.isValid());
39
40 const auto master = client.getMaster();
41
42 const auto status = client.newStatus();
43 StatusWrapper statusWrapper{client, status.get()};
44
45 auto tpbBuilder = fbUnique(master->getUtilInterface()->getXpbBuilder(&statusWrapper, fb::IXpbBuilder::TPB,
46 reinterpret_cast<const std::uint8_t*>(options.getTpb().data()),
47 static_cast<unsigned>(options.getTpb().size())));
48
49 if (const auto accessMode = options.getAccessMode())
50 {
51 switch (accessMode.value())
52 {
53 case TransactionAccessMode::READ_ONLY:
54 tpbBuilder->insertTag(&statusWrapper, isc_tpb_read);
55 break;
56
57 case TransactionAccessMode::READ_WRITE:
58 tpbBuilder->insertTag(&statusWrapper, isc_tpb_write);
59 break;
60
61 default:
62 assert(false);
63 break;
64 }
65 }
66
67 if (const auto waitMode = options.getWaitMode())
68 {
69 switch (waitMode.value())
70 {
71 case TransactionWaitMode::NO_WAIT:
72 tpbBuilder->insertTag(&statusWrapper, isc_tpb_nowait);
73 break;
74
75 case TransactionWaitMode::WAIT:
76 tpbBuilder->insertTag(&statusWrapper, isc_tpb_wait);
77 break;
78
79 default:
80 assert(false);
81 break;
82 }
83 }
84
85 if (const auto isolationLevel = options.getIsolationLevel())
86 {
87 switch (isolationLevel.value())
88 {
89 case TransactionIsolationLevel::CONSISTENCY:
90 tpbBuilder->insertTag(&statusWrapper, isc_tpb_consistency);
91 break;
92
93 case TransactionIsolationLevel::SNAPSHOT:
94 tpbBuilder->insertTag(&statusWrapper, isc_tpb_concurrency);
95 break;
96
97 case TransactionIsolationLevel::READ_COMMITTED:
98 tpbBuilder->insertTag(&statusWrapper, isc_tpb_read_committed);
99
100 if (const auto readCommittedMode = options.getReadCommittedMode())
101 {
102 switch (readCommittedMode.value())
103 {
104 case TransactionReadCommittedMode::NO_RECORD_VERSION:
105 tpbBuilder->insertTag(&statusWrapper, isc_tpb_no_rec_version);
106 break;
107
108 case TransactionReadCommittedMode::RECORD_VERSION:
109 tpbBuilder->insertTag(&statusWrapper, isc_tpb_rec_version);
110 break;
111
112 default:
113 assert(false);
114 break;
115 }
116 }
117
118 break;
119
120 default:
121 assert(false);
122 break;
123 }
124 }
125
126 if (options.getNoAutoUndo())
127 tpbBuilder->insertTag(&statusWrapper, isc_tpb_no_auto_undo);
128
129 if (options.getIgnoreLimbo())
130 tpbBuilder->insertTag(&statusWrapper, isc_tpb_ignore_limbo);
131
132 if (options.getRestartRequests())
133 tpbBuilder->insertTag(&statusWrapper, isc_tpb_restart_requests);
134
135 if (options.getAutoCommit())
136 tpbBuilder->insertTag(&statusWrapper, isc_tpb_autocommit);
137
138 const auto tpbBuffer = tpbBuilder->getBuffer(&statusWrapper);
139 const auto tpbBufferLen = tpbBuilder->getBufferLength(&statusWrapper);
140
141 handle.reset(attachment.getHandle()->startTransaction(&statusWrapper, tpbBufferLen, tpbBuffer));
142}
143
144Transaction::Transaction(Attachment& attachment, std::string_view setTransactionCmd)
145 : client{attachment.getClient()}
146{
147 assert(attachment.isValid());
148
149 const auto status = client.newStatus();
150 StatusWrapper statusWrapper{client, status.get()};
151
152 handle.reset(
153 attachment.getHandle()->execute(&statusWrapper, nullptr, static_cast<unsigned>(setTransactionCmd.length()),
154 setTransactionCmd.data(), SQL_DIALECT_V6, nullptr, nullptr, nullptr, nullptr));
155}
156
158{
159 assert(isValid());
160
161 const auto status = client.newStatus();
162 StatusWrapper statusWrapper{client, status.get()};
163
164 handle->rollback(&statusWrapper);
165 handle.reset();
166}
167
168
170{
171 assert(isValid());
172
173 const auto status = client.newStatus();
174 StatusWrapper statusWrapper{client, status.get()};
175
176 handle->commit(&statusWrapper);
177 handle.reset();
178}
179
181{
182 assert(isValid());
183
184 const auto status = client.newStatus();
185 StatusWrapper statusWrapper{client, status.get()};
186
187 handle->commitRetaining(&statusWrapper);
188}
189
191{
192 assert(isValid());
193
194 const auto status = client.newStatus();
195 StatusWrapper statusWrapper{client, status.get()};
196
197 handle->rollbackRetaining(&statusWrapper);
198}
Represents a connection to a Firebird database.
Definition Attachment.h:177
FbRef< fb::IAttachment > getHandle() noexcept
Returns the internal Firebird IAttachment handle.
Definition Attachment.h:238
bool isValid() noexcept
Returns whether the Attachment object is valid.
Definition Attachment.h:222
FbUniquePtr< fb::IStatus > newStatus()
Creates and returns a Firebird IStatus instance.
Definition Client.h:183
fb::IMaster * getMaster() noexcept
Returns the Firebird IMaster interface.
Definition Client.h:134
Represents options used when creating a Transaction object.
Definition Transaction.h:87
bool getAutoCommit() const
Returns whether the transaction will be automatically committed.
const std::vector< std::uint8_t > & getTpb() const
Returns the TPB (Transaction Parameter Block) which will be used to start the transaction.
Definition Transaction.h:93
bool getRestartRequests() const
Returns whether the transaction will restart requests.
const std::optional< TransactionAccessMode > getAccessMode() const
Returns the transaction access mode.
bool getNoAutoUndo() const
Returns whether the transaction will not automatically undo changes in case of a deadlock or update c...
bool getIgnoreLimbo() const
Returns whether the transaction will ignore limbo transactions.
const std::optional< TransactionIsolationLevel > getIsolationLevel() const
Returns the transaction isolation level.
const std::optional< TransactionReadCommittedMode > getReadCommittedMode() const
Returns the read committed mode.
const std::optional< TransactionWaitMode > getWaitMode() const
Returns the transaction wait mode.
void rollback()
Rolls back the transaction.
void commit()
Commits the transaction.
bool isValid() noexcept
Returns whether the Transaction object is valid.
void commitRetaining()
Commits the transaction while maintains it active.
void rollbackRetaining()
Rolls back the transaction while maintains it active.
Transaction(Attachment &attachment, const TransactionOptions &options={})
Constructs a Transaction object that starts a transaction in the specified Attachment using the speci...
fb-cpp namespace.
Definition Attachment.h:42