fb-cpp 0.0.1
A modern C++ wrapper for the Firebird database API
Loading...
Searching...
No Matches
EventListener.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 do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef FBCPP_EVENT_LISTENER_H
25#define FBCPP_EVENT_LISTENER_H
26
27#include "Attachment.h"
28#include "Client.h"
29#include "Exception.h"
30#include "SmartPtrs.h"
31#include "fb-api.h"
32#include <condition_variable>
33#include <cstdint>
34#include <deque>
35#include <functional>
36#include <mutex>
37#include <string>
38#include <thread>
39#include <vector>
40
41
45namespace fbcpp
46{
50 struct EventCount final
51 {
55 std::string name;
56
60 unsigned count;
61 };
62
66 class EventListener final
67 {
68 public:
72 using Callback = std::function<void(const std::vector<EventCount>& counts)>;
73
74 private:
75 class FirebirdCallback final : public fb::IEventCallbackImpl<FirebirdCallback, impl::StatusWrapper>
76 {
77 public:
78 explicit FirebirdCallback(EventListener& owner) noexcept
79 : owner{&owner}
80 {
81 }
82
83 void eventCallbackFunction(unsigned length, const std::uint8_t* events) override
84 {
85 if (owner)
86 owner->handleEvent(length, events);
87 }
88
89 void addRef() override
90 {
91 // The listener owns this callback for its whole lifetime.
92 }
93
94 int release() override
95 {
96 // Prevent Firebird from attempting to destroy the stack-allocated callback.
97 return 1;
98 }
99
100 void detach() noexcept
101 {
102 owner = nullptr;
103 }
104
105 private:
106 EventListener* owner;
107 };
108
109 public:
113 explicit EventListener(Attachment& attachment, const std::vector<std::string>& eventNames, Callback callback);
114
118 ~EventListener() noexcept
119 {
120 try
121 {
122 stop();
123 }
124 catch (...)
125 {
126 // swallow
127 }
128 }
129
130 EventListener(const EventListener&) = delete;
131 EventListener& operator=(const EventListener&) = delete;
132
133 EventListener(EventListener&&) = delete;
134 EventListener& operator=(EventListener&&) = delete;
135
136 public:
140 bool isListening() noexcept;
141
145 void stop();
146
147 private:
148 void handleEvent(unsigned length, const std::uint8_t* events);
149 void dispatchLoop();
150 void cancelEventsHandle();
151 void decodeEventCounts();
152
153 private:
154 Attachment& attachment;
155 Client& client;
156 std::vector<std::string> eventNames;
157 Callback callback;
158 FbRef<fb::IEvents> eventsHandle;
159 FirebirdCallback firebirdCallback;
160 std::vector<std::uint8_t> eventBuffer;
161 std::vector<std::uint8_t> resultBuffer;
162 std::vector<std::uint32_t> rawCounts;
163 std::vector<unsigned> countOffsets;
164 std::deque<std::vector<EventCount>> pendingNotifications;
165 std::thread dispatcher;
166 std::mutex mutex;
167 std::condition_variable condition;
168 bool listening = false;
169 bool running = false;
170 bool first = false;
171 };
172} // namespace fbcpp
173
174
175#endif // FBCPP_EVENT_LISTENER_H
Represents a connection to a Firebird database.
Definition Attachment.h:177
Represents a Firebird client library instance.
Definition Client.h:53
Observes Firebird events and forwards aggregated counts to a callback on a background thread.
bool isListening() noexcept
Returns true if the listener is currently registered for event notifications.
~EventListener() noexcept
Stops the listener and waits for any background work to finish.
void stop()
Cancels event notifications and releases related resources.
std::function< void(const std::vector< EventCount > &counts)> Callback
Function invoked when new event counts are available.
fb-cpp namespace.
Definition Attachment.h:42
Represents the number of occurrences for a registered event delivered by Firebird.
std::string name
Name of the event reported by the database.
unsigned count
Number of times the event fired since the last notification.