Skip to content

Commit 8499283

Browse files
committed
Attachment class
1 parent bc211bb commit 8499283

6 files changed

Lines changed: 521 additions & 3 deletions

File tree

src/lib/Attachment.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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 "Attachment.h"
26+
#include "Client.h"
27+
#include "Exception.h"
28+
29+
using namespace fbcpp;
30+
using namespace fbcpp::impl;
31+
32+
33+
Attachment::Attachment(Client& client, const std::string& uri, const AttachmentOptions& options)
34+
: client{client}
35+
{
36+
const auto master = client.getMaster();
37+
38+
const auto status = client.newStatus();
39+
StatusWrapper statusWrapper{client, status.get()};
40+
41+
auto dpbBuilder = fbUnique(master->getUtilInterface()->getXpbBuilder(&statusWrapper, fb::IXpbBuilder::DPB,
42+
reinterpret_cast<const std::uint8_t*>(options.getDpb().data()),
43+
static_cast<unsigned>(options.getDpb().size())));
44+
45+
if (const auto connectionCharSet = options.getConnectionCharSet())
46+
dpbBuilder->insertString(&statusWrapper, isc_dpb_lc_ctype, connectionCharSet->c_str());
47+
48+
if (const auto userName = options.getUserName())
49+
dpbBuilder->insertString(&statusWrapper, isc_dpb_user_name, userName->c_str());
50+
51+
if (const auto password = options.getPassword())
52+
dpbBuilder->insertString(&statusWrapper, isc_dpb_password, password->c_str());
53+
54+
if (const auto role = options.getRole())
55+
dpbBuilder->insertString(&statusWrapper, isc_dpb_sql_role_name, role->c_str());
56+
57+
auto dispatcher = fbRef(master->getDispatcher());
58+
const auto dpbBuffer = dpbBuilder->getBuffer(&statusWrapper);
59+
const auto dpbBufferLen = dpbBuilder->getBufferLength(&statusWrapper);
60+
61+
if (options.getCreateDatabase())
62+
handle.reset(dispatcher->createDatabase(&statusWrapper, uri.c_str(), dpbBufferLen, dpbBuffer));
63+
else
64+
handle.reset(dispatcher->attachDatabase(&statusWrapper, uri.c_str(), dpbBufferLen, dpbBuffer));
65+
}
66+
67+
void Attachment::disconnectOrDrop(bool drop)
68+
{
69+
assert(isValid());
70+
71+
const auto status = client.newStatus();
72+
StatusWrapper statusWrapper{client, status.get()};
73+
74+
if (drop)
75+
handle->dropDatabase(&statusWrapper);
76+
else
77+
handle->detach(&statusWrapper);
78+
79+
handle.reset();
80+
}
81+
82+
83+
void Attachment::disconnect()
84+
{
85+
disconnectOrDrop(false);
86+
}
87+
88+
void Attachment::dropDatabase()
89+
{
90+
disconnectOrDrop(true);
91+
}

src/lib/Attachment.h

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
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_ATTACHMENT_H
26+
#define FBCPP_ATTACHMENT_H
27+
28+
#include "fb-api.h"
29+
#include "SmartPtrs.h"
30+
#include <cstdint>
31+
#include <memory>
32+
#include <optional>
33+
#include <string>
34+
#include <vector>
35+
#include <cstddef>
36+
37+
38+
///
39+
/// fb-cpp namespace.
40+
///
41+
namespace fbcpp
42+
{
43+
class Client;
44+
45+
///
46+
/// Represents options used when creating an Attachment object.
47+
///
48+
class AttachmentOptions final
49+
{
50+
public:
51+
///
52+
/// Returns the character set which will be used for the connection.
53+
///
54+
const std::optional<std::string>& getConnectionCharSet() const
55+
{
56+
return connectionCharSet;
57+
}
58+
59+
///
60+
/// Sets the character set which will be used for the connection.
61+
///
62+
AttachmentOptions& setConnectionCharSet(const std::string& value)
63+
{
64+
connectionCharSet = value;
65+
return *this;
66+
}
67+
68+
///
69+
/// Returns the user name which will be used to connect to the database.
70+
///
71+
const std::optional<std::string>& getUserName() const
72+
{
73+
return userName;
74+
}
75+
76+
///
77+
/// Sets the user name which will be used to connect to the database.
78+
///
79+
AttachmentOptions& setUserName(const std::string& value)
80+
{
81+
userName = value;
82+
return *this;
83+
}
84+
85+
///
86+
/// Returns the password which will be used to connect to the database.
87+
///
88+
const std::optional<std::string>& getPassword() const
89+
{
90+
return password;
91+
}
92+
93+
///
94+
/// Sets the password which will be used to connect to the database.
95+
///
96+
AttachmentOptions& setPassword(const std::string& value)
97+
{
98+
password = value;
99+
return *this;
100+
}
101+
102+
///
103+
/// Returns the role which will be used to connect to the database.
104+
///
105+
const std::optional<std::string>& getRole() const
106+
{
107+
return role;
108+
}
109+
110+
///
111+
/// Sets the role which will be used to connect to the database.
112+
///
113+
AttachmentOptions& setRole(const std::string& value)
114+
{
115+
role = value;
116+
return *this;
117+
}
118+
119+
///
120+
/// Returns the DPB (Database Parameter Block) which will be used to connect to the database.
121+
///
122+
const std::vector<std::byte>& getDpb() const
123+
{
124+
return dpb;
125+
}
126+
127+
///
128+
/// Sets the DPB (Database Parameter Block) which will be used to connect to the database.
129+
///
130+
AttachmentOptions& setDpb(const std::vector<std::byte>& value)
131+
{
132+
dpb = value;
133+
return *this;
134+
}
135+
136+
///
137+
/// Sets the DPB (Database Parameter Block) which will be used to connect to the database.
138+
///
139+
AttachmentOptions& setDpb(std::vector<std::byte>&& value)
140+
{
141+
dpb = std::move(value);
142+
return *this;
143+
}
144+
145+
///
146+
/// Returns whether the database should be created instead of connected to.
147+
///
148+
bool getCreateDatabase() const
149+
{
150+
return createDatabase;
151+
}
152+
153+
///
154+
/// Sets whether the database should be created instead of connected to.
155+
///
156+
AttachmentOptions& setCreateDatabase(bool value)
157+
{
158+
createDatabase = value;
159+
return *this;
160+
}
161+
162+
private:
163+
std::optional<std::string> connectionCharSet;
164+
std::optional<std::string> userName;
165+
std::optional<std::string> password;
166+
std::optional<std::string> role;
167+
std::vector<std::byte> dpb;
168+
bool createDatabase = false;
169+
};
170+
171+
///
172+
/// Represents a connection to a Firebird database.
173+
/// The Attachment must exist and remain valid while there are other objects using it, such as Transaction and
174+
/// Statement.
175+
///
176+
class Attachment final
177+
{
178+
public:
179+
///
180+
/// Constructs an Attachment object that connects to (or creates) the database specified by the URI
181+
/// using the specified Client object and options.
182+
///
183+
explicit Attachment(Client& client, const std::string& uri, const AttachmentOptions& options = {});
184+
185+
///
186+
/// Move constructor.
187+
/// A moved Attachment object becomes invalid.
188+
///
189+
Attachment(Attachment&& o) noexcept
190+
: client{o.client},
191+
handle{std::move(o.handle)}
192+
{
193+
}
194+
195+
Attachment& operator=(Attachment&&) = delete;
196+
197+
Attachment(const Attachment&) = delete;
198+
Attachment& operator=(const Attachment&) = delete;
199+
200+
///
201+
/// Disconnects from the database.
202+
///
203+
~Attachment() noexcept
204+
{
205+
if (isValid())
206+
{
207+
try
208+
{
209+
disconnectOrDrop(false);
210+
}
211+
catch (...)
212+
{
213+
// swallow
214+
}
215+
}
216+
}
217+
218+
public:
219+
///
220+
/// Returns whether the Attachment object is valid.
221+
///
222+
bool isValid() noexcept
223+
{
224+
return handle != nullptr;
225+
}
226+
227+
///
228+
/// Returns the Client object reference used to create this Attachment object.
229+
///
230+
Client& getClient() noexcept
231+
{
232+
return client;
233+
}
234+
235+
///
236+
/// Returns the internal Firebird IAttachment handle.
237+
///
238+
FbRef<fb::IAttachment> getHandle() noexcept
239+
{
240+
return handle;
241+
}
242+
243+
///
244+
/// Disconnects from the database.
245+
///
246+
void disconnect();
247+
248+
///
249+
/// Drops the database.
250+
///
251+
void dropDatabase();
252+
253+
private:
254+
void disconnectOrDrop(bool drop);
255+
256+
private:
257+
Client& client;
258+
FbRef<fb::IAttachment> handle;
259+
};
260+
} // namespace fbcpp
261+
262+
263+
#endif // FBCPP_ATTACHMENT_H

src/lib/fb-cpp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@
2626
#define FBCPP_H
2727

2828
#include "Client.h"
29+
#include "Attachment.h"
2930

3031
#endif // FBCPP_H

0 commit comments

Comments
 (0)