fb-cpp 0.0.2
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
Attachment.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 "Attachment.h"
26#include "Client.h"
27#include "Exception.h"
28#include "RowSet.h"
29#include "Statement.h"
30#include "Transaction.h"
31
32using namespace fbcpp;
33using namespace fbcpp::impl;
34
35
36Attachment::Attachment(Client& client, const std::string& uri, const AttachmentOptions& options)
37 : client{&client}
38{
39 const auto master = client.getMaster();
40
41 StatusWrapper statusWrapper{client};
42
43 auto dpbBuilder = fbUnique(client.getUtil()->getXpbBuilder(&statusWrapper, fb::IXpbBuilder::DPB,
44 reinterpret_cast<const std::uint8_t*>(options.getDpb().data()),
45 static_cast<unsigned>(options.getDpb().size())));
46
47 if (const auto connectionCharSet = options.getConnectionCharSet())
48 dpbBuilder->insertString(&statusWrapper, isc_dpb_lc_ctype, connectionCharSet->c_str());
49
50 if (const auto userName = options.getUserName())
51 dpbBuilder->insertString(&statusWrapper, isc_dpb_user_name, userName->c_str());
52
53 if (const auto password = options.getPassword())
54 dpbBuilder->insertString(&statusWrapper, isc_dpb_password, password->c_str());
55
56 if (const auto role = options.getRole())
57 dpbBuilder->insertString(&statusWrapper, isc_dpb_sql_role_name, role->c_str());
58
59 if (const auto sqlDialect = options.getSqlDialect())
60 dpbBuilder->insertInt(&statusWrapper, isc_dpb_sql_dialect, static_cast<int>(*sqlDialect));
61
62 if (const auto forcedWrites = options.getForcedWrites())
63 dpbBuilder->insertInt(&statusWrapper, isc_dpb_force_write, *forcedWrites ? 1 : 0);
64
65 auto dispatcher = fbRef(master->getDispatcher());
66 const auto dpbBuffer = dpbBuilder->getBuffer(&statusWrapper);
67 const auto dpbBufferLen = dpbBuilder->getBufferLength(&statusWrapper);
68
69 if (options.getCreateDatabase())
70 handle.reset(dispatcher->createDatabase(&statusWrapper, uri.c_str(), dpbBufferLen, dpbBuffer));
71 else
72 handle.reset(dispatcher->attachDatabase(&statusWrapper, uri.c_str(), dpbBufferLen, dpbBuffer));
73}
74
75void Attachment::disconnectOrDrop(bool drop)
76{
77 assert(isValid());
78
79 StatusWrapper statusWrapper{*client};
80
81 if (drop)
82 handle->dropDatabase(&statusWrapper);
83 else
84 handle->detach(&statusWrapper);
85
86 handle.reset();
87}
88
89
91{
92 disconnectOrDrop(false);
93}
94
96{
97 disconnectOrDrop(true);
98}
99
101{
102 assert(isValid());
103
104 StatusWrapper statusWrapper{*client};
105
106 handle->ping(&statusWrapper);
107}
108
110{
111 assert(isValid());
112
113 StatusWrapper statusWrapper{*client};
114
115 handle->execute(
116 &statusWrapper, nullptr, 0, "alter session reset", SQL_DIALECT_V6, nullptr, nullptr, nullptr, nullptr);
117}
118
119bool Attachment::execute(Transaction& transaction, std::string_view sql, const StatementOptions& options)
120{
121 Statement statement{*this, transaction, sql, options};
122 return statement.execute(transaction);
123}
124
126 Transaction& transaction, std::string_view sql, unsigned maxRows, const StatementOptions& options)
127{
128 Statement statement{*this, transaction, sql, options};
129 return queryPreparedRowSet(statement, transaction, maxRows);
130}
131
132RowSet Attachment::queryPreparedRowSet(Statement& statement, Transaction& transaction, unsigned maxRows)
133{
134 switch (statement.getType())
135 {
138 break;
139
141 if (!statement.getOutputDescriptors().empty())
142 break;
143
144 throw FbCppException("Cannot use procedure without output columns with Attachment::queryRowSet");
145
146 default:
147 throw FbCppException("Cannot use non-query SQL with Attachment::queryRowSet");
148 }
149
150 const auto hasRow = statement.execute(transaction);
151 const auto effectiveMaxRows = statement.getType() == StatementType::EXEC_PROCEDURE ? 1u : maxRows;
152 return RowSet{statement, hasRow ? effectiveMaxRows : 0u, hasRow};
153}
Represents options used when creating an Attachment object.
Definition Attachment.h:54
const std::optional< std::string > & getPassword() const
Returns the password which will be used to connect to the database.
Definition Attachment.h:93
const std::optional< std::string > & getRole() const
Returns the role which will be used to connect to the database.
Definition Attachment.h:110
const std::vector< std::uint8_t > & getDpb() const
Returns the DPB (Database Parameter Block) which will be used to connect to the database.
Definition Attachment.h:144
const std::optional< std::string > & getUserName() const
Returns the user name which will be used to connect to the database.
Definition Attachment.h:76
bool getCreateDatabase() const
Returns whether the database should be created instead of connected to.
Definition Attachment.h:170
const std::optional< std::string > & getConnectionCharSet() const
Returns the character set which will be used for the connection.
Definition Attachment.h:59
const std::optional< bool > & getForcedWrites() const
Returns whether forced writes should be enabled when creating the database.
Definition Attachment.h:187
const std::optional< std::uint32_t > & getSqlDialect() const
Returns the SQL dialect which will be used to connect to the database.
Definition Attachment.h:127
Attachment(Client &client, const std::string &uri, const AttachmentOptions &options={})
Constructs an Attachment object that connects to (or creates) the database specified by the URI using...
bool execute(Transaction &transaction, std::string_view sql, const StatementOptions &options={})
Prepares and executes an SQL statement using the supplied transaction.
void disconnect()
Disconnects from the database.
void ping()
Checks if the connection to the database is alive.
bool isValid() noexcept
Returns whether the Attachment object is valid.
Definition Attachment.h:278
void dropDatabase()
Drops the database.
void resetSession()
Resets the session state.
RowSet queryRowSet(Transaction &transaction, std::string_view sql, unsigned maxRows, const StatementOptions &options={})
Prepares and executes a query using the supplied transaction and returns up to maxRows rows.
Represents a Firebird client library instance.
Definition Client.h:53
fb::IUtil * getUtil()
Returns a Firebird IUtil interface.
Definition Client.h:144
fb::IMaster * getMaster() noexcept
Returns the Firebird IMaster interface.
Definition Client.h:136
Base exception class for all fb-cpp exceptions.
Definition Exception.h:230
A disconnected buffer of rows fetched from a Statement's result set.
Definition RowSet.h:56
Represents options used when preparing a Statement.
Prepares, executes, and fetches SQL statements against a Firebird attachment.
Definition Statement.h:138
const std::vector< Descriptor > & getOutputDescriptors() noexcept
Provides cached descriptors for each output column.
Definition Statement.h:286
StatementType getType() noexcept
Returns the type classification reported by the server.
Definition Statement.h:260
bool execute(Transaction &transaction)
Executes a prepared statement using the supplied transaction.
Represents a transaction in one or more Firebird databases.
fb-cpp namespace.
Definition Attachment.h:45
FbRef< T > fbRef(T *arg) noexcept
Creates a reference-counted smart pointer for a Firebird object.
Definition SmartPtrs.h:229
@ EXEC_PROCEDURE
Statement executes a stored procedure.
@ SELECT
Server classified the statement as a SELECT.
@ SELECT_FOR_UPDATE
Cursor-based SELECT that allows updates.
FbUniquePtr< T > fbUnique(T *obj) noexcept
Creates a unique pointer for a Firebird disposable object.
Definition SmartPtrs.h:59