fb-cpp 0.0.1
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
Exception.h
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#ifndef FBCPP_EXCEPTION_H
26#define FBCPP_EXCEPTION_H
27
28#include "fb-api.h"
29#include <stdexcept>
30#include <string>
31#include <cstdint>
32
33
37namespace fbcpp
38{
39 class Client;
40}
41
42namespace fbcpp::impl
43{
44 class StatusWrapper : public fb::IStatusImpl<StatusWrapper, StatusWrapper>
45 {
46 public:
47 explicit StatusWrapper(Client& client, IStatus* status)
48 : client{client},
49 status{status}
50 {
51 }
52
53 public:
54 static void checkException(StatusWrapper* status);
55
56 static void catchException(IStatus* status) noexcept;
57
58 static void clearException(StatusWrapper* status) noexcept
59 {
60 status->clearException();
61 }
62
63 void clearException()
64 {
65 if (dirty)
66 {
67 dirty = false;
68 status->init();
69 }
70 }
71
72 bool isDirty() const noexcept
73 {
74 return dirty;
75 }
76
77 bool hasData() const noexcept
78 {
79 return getState() & IStatus::STATE_ERRORS;
80 }
81
82 bool isEmpty() const noexcept
83 {
84 return !hasData();
85 }
86
87 static void setVersionError(
88 IStatus* status, const char* interfaceName, uintptr_t currentVersion, uintptr_t expectedVersion) noexcept
89 {
90 // clang-format off
91 const intptr_t codes[] = {
92 isc_arg_gds, isc_interface_version_too_old,
93 isc_arg_number, (intptr_t) expectedVersion,
94 isc_arg_number, (intptr_t) currentVersion,
95 isc_arg_string, (intptr_t) interfaceName,
96 isc_arg_end,
97 };
98 // clang-format on
99
100 status->setErrors(codes);
101 }
102
103 public:
104 void dispose() noexcept override
105 {
106 // Disposes only the delegated status. Let the user destroy this instance.
107 status->dispose();
108 status = nullptr;
109 }
110
111 void init() noexcept override
112 {
113 clearException();
114 }
115
116 unsigned getState() const noexcept override
117 {
118 return dirty ? status->getState() : 0;
119 }
120
121 void setErrors2(unsigned length, const intptr_t* value) noexcept override
122 {
123 dirty = true;
124 status->setErrors2(length, value);
125 }
126
127 void setWarnings2(unsigned length, const intptr_t* value) noexcept override
128 {
129 dirty = true;
130 status->setWarnings2(length, value);
131 }
132
133 void setErrors(const intptr_t* value) noexcept override
134 {
135 dirty = true;
136 status->setErrors(value);
137 }
138
139 void setWarnings(const intptr_t* value) noexcept override
140 {
141 dirty = true;
142 status->setWarnings(value);
143 }
144
145 const intptr_t* getErrors() const noexcept override
146 {
147 return dirty ? status->getErrors() : cleanStatus();
148 }
149
150 const intptr_t* getWarnings() const noexcept override
151 {
152 return dirty ? status->getWarnings() : cleanStatus();
153 }
154
155 IStatus* clone() const noexcept override
156 {
157 return status->clone();
158 }
159
160 protected:
161 Client& client;
162 IStatus* status;
163 bool dirty = false;
164
165 static const intptr_t* cleanStatus() noexcept
166 {
167 static intptr_t clean[3] = {1, 0, 0};
168 return clean;
169 }
170 };
171} // namespace fbcpp::impl
172
173
177namespace fbcpp
178{
179 class FbCppException : public std::runtime_error
180 {
181 public:
182 using std::runtime_error::runtime_error;
183
184 explicit FbCppException(const std::string& message)
185 : std::runtime_error{message}
186 {
187 }
188 };
189
191 {
192 public:
193 using FbCppException::FbCppException;
194
195 explicit DatabaseException(Client& client, const std::intptr_t* status)
196 : FbCppException{buildMessage(client, status)}
197 {
198 }
199
200 private:
201 static std::string buildMessage(Client& client, const std::intptr_t* status);
202 };
203} // namespace fbcpp
204
205
206#endif // FBCPP_EXCEPTION_H
Represents a Firebird client library instance.
Definition Client.h:53
fb-cpp namespace.
Definition Attachment.h:42