Lightweight 0.20260617.0
Loading...
Searching...
No Matches
SqlLogger.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "Api.hpp"
6#include "SqlDataBinder.hpp"
7#include "SqlError.hpp"
8
9#include <functional>
10#include <source_location>
11#include <string_view>
12
13namespace Lightweight
14{
15
16class SqlConnection;
17
18struct SqlVariant;
19
20/// Represents a logger for SQL operations.
22{
23 public:
24 /// Mandates the support for logging bind operations.
25 enum class SupportBindLogging : uint8_t
26 {
27 No,
28 Yes
29 };
30
31 LIGHTWEIGHT_API SqlLogger();
32 /// Default copy constructor.
33 LIGHTWEIGHT_API SqlLogger(SqlLogger const& /*other*/) = default;
34 /// Default move constructor.
35 LIGHTWEIGHT_API SqlLogger(SqlLogger&& /*other*/) = default;
36 /// Default copy assignment operator.
37 LIGHTWEIGHT_API SqlLogger& operator=(SqlLogger const& /*other*/) = default;
38 /// Default move assignment operator.
39 LIGHTWEIGHT_API SqlLogger& operator=(SqlLogger&& /*other*/) = default;
40 LIGHTWEIGHT_API virtual ~SqlLogger() = default;
41
42 /// Type definition for a function that writes messages.
43 using MessageWriter = std::function<void(std::string /*message*/)>;
44
45 /// Constructs a new logger.
46 ///
47 /// @param supportBindLogging Indicates if the logger should support bind logging.
48 /// @param writer Optional message writer function for log output.
49 LIGHTWEIGHT_API explicit SqlLogger(SupportBindLogging supportBindLogging, MessageWriter writer = {});
50
51 /// Sets the logging sink for the logger.
52 ///
53 /// @param writer A function that takes a message string and writes it to the desired output.
54 LIGHTWEIGHT_API void SetLoggingSink(MessageWriter writer = {});
55
56 /// Invoked on a warning.
57 virtual void OnWarning(std::string_view const& message) = 0;
58
59 /// Invoked on ODBC SQL error occurred.
60 virtual void OnError(SqlError errorCode, std::source_location sourceLocation = std::source_location::current()) = 0;
61
62 /// Invoked an ODBC SQL error occurred, with extended error information.
63 virtual void OnError(SqlErrorInfo const& errorInfo,
64 std::source_location sourceLocation = std::source_location::current()) = 0;
65
66 /// Invoked when a scoped code region needs to be timed and logged. The region starts with this call.
67 virtual void OnScopedTimerStart(std::string const& tag) = 0;
68
69 /// Invoked when a scoped code region needs to be timed and logged. The region ends with this call.
70 virtual void OnScopedTimerStop(std::string const& tag) = 0;
71
72 /// Invoked when a connection is opened.
73 virtual void OnConnectionOpened(SqlConnection const& connection) = 0;
74
75 /// Invoked when a connection is closed.
76 virtual void OnConnectionClosed(SqlConnection const& connection) = 0;
77
78 /// Invoked when a connection is idle.
79 virtual void OnConnectionIdle(SqlConnection const& connection) = 0;
80
81 /// Invoked when a connection is reused.
82 virtual void OnConnectionReuse(SqlConnection const& connection) = 0;
83
84 /// Invoked when a direct query is executed.
85 virtual void OnExecuteDirect(std::string_view const& query) = 0;
86
87 /// Invoked when a query is prepared.
88 virtual void OnPrepare(std::string_view const& query) = 0;
89
90 /// Invoked when an input parameter is bound.
91 template <typename T>
92 void OnBindInputParameter(std::string_view const& name, T&& value)
93 {
94 if (_supportsBindLogging)
95 {
96 using value_type = std::remove_cvref_t<T>;
97 if constexpr (SqlDataBinderSupportsInspect<value_type>)
98 {
99 OnBind(name, std::string(SqlDataBinder<value_type>::Inspect(std::forward<T>(value))));
100 }
101 }
102 }
103
104 /// Invoked when an input parameter is bound, by name.
105 virtual void OnBind(std::string_view const& name, std::string value) = 0;
106
107 /// Invoked when a prepared query is executed.
108 virtual void OnExecute(std::string_view const& query) = 0;
109
110 /// Invoked when a batch of queries is executed
111 virtual void OnExecuteBatch() = 0;
112
113 /// Invoked when a row is fetched.
114 virtual void OnFetchRow() = 0;
115
116 /// @brief Invoked once per block-prefetch round-trip (one @c SQLFetchScroll that materialized a
117 /// whole row block on the transparent prefetch path), with the number of rows the block yielded.
118 ///
119 /// Non-pure with an empty default so existing loggers need no change; override to observe how many
120 /// network round-trips a query actually cost (N rows at depth D collapse to @c ceil(N/D) blocks).
121 /// The argument is the number of rows materialized by this block fetch (0 at end of result set).
122 virtual void OnFetchBlock(std::size_t /*rowsInBlock*/) {}
123
124 /// Invoked when fetching is done.
125 virtual void OnFetchEnd() = 0;
126
127 class Null;
128
129 /// Retrieves a null logger that does nothing.
130 LIGHTWEIGHT_API static Null& NullLogger() noexcept;
131
132 /// Retrieves a logger that logs to standard output.
133 LIGHTWEIGHT_API static SqlLogger& StandardLogger();
134
135 /// Retrieves a logger that logs to the trace logger.
136 LIGHTWEIGHT_API static SqlLogger& TraceLogger();
137
138 /// Retrieves the currently configured logger.
139 LIGHTWEIGHT_API static SqlLogger& GetLogger();
140
141 /// Sets the current logger.
142 ///
143 /// The ownership of the logger is not transferred and remains with the caller.
144 LIGHTWEIGHT_API static void SetLogger(SqlLogger& logger);
145
146 protected:
147 /// The function used to write log messages.
148 MessageWriter _messageWriter; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
149
150 private:
151 bool _supportsBindLogging = false;
152};
153
154class SqlLogger::Null: public SqlLogger
155{
156 public:
157 void OnWarning(std::string_view const& /*message*/) override {}
158 void OnError(SqlError /*errorCode*/, std::source_location /*sourceLocation*/) override {}
159 void OnError(SqlErrorInfo const& /*errorInfo*/, std::source_location /*sourceLocation*/) override {}
160 void OnScopedTimerStart(std::string const& /*tag*/) override {}
161 void OnScopedTimerStop(std::string const& /*tag*/) override {}
162 void OnConnectionOpened(SqlConnection const& /*connection*/) override {}
163 void OnConnectionClosed(SqlConnection const& /*connection*/) override {}
164 void OnConnectionIdle(SqlConnection const& /*connection*/) override {}
165 void OnConnectionReuse(SqlConnection const& /*connection*/) override {}
166 void OnExecuteDirect(std::string_view const& /*query*/) override {}
167 void OnPrepare(std::string_view const& /*qurey*/) override {}
168 void OnBind(std::string_view const& /*name*/, std::string /*value*/) override {}
169 void OnExecute(std::string_view const& /*query*/) override {}
170 void OnExecuteBatch() override {}
171 void OnFetchRow() override {}
172 void OnFetchEnd() override {}
173};
174
175/// A scoped timer for logging.
176///
177/// This class is used to measure the time spent in a code region and log it.
178/// This is typically useful for performance analysis, to identify bottlenecks.
179///
180/// @see SqlLogger
182{
183 public:
184 /// Default copy constructor.
187 /// Default copy assignment operator.
189 SqlScopedTimeLogger& operator=(SqlScopedTimeLogger&&) = delete;
190 /// Constructs a scoped time logger with the given tag.
191 explicit SqlScopedTimeLogger(std::string tag):
192 _tag { std::move(tag) }
193 {
194 SqlLogger::GetLogger().OnScopedTimerStart(_tag);
195 }
196
198 {
199 SqlLogger::GetLogger().OnScopedTimerStop(_tag);
200 }
201
202 private:
203 std::string _tag;
204};
205
206} // namespace Lightweight
Represents a connection to a SQL database.
Represents a logger for SQL operations.
Definition SqlLogger.hpp:22
MessageWriter _messageWriter
The function used to write log messages.
virtual void OnExecuteDirect(std::string_view const &query)=0
Invoked when a direct query is executed.
virtual void OnExecute(std::string_view const &query)=0
Invoked when a prepared query is executed.
virtual void OnError(SqlError errorCode, std::source_location sourceLocation=std::source_location::current())=0
Invoked on ODBC SQL error occurred.
static LIGHTWEIGHT_API Null & NullLogger() noexcept
Retrieves a null logger that does nothing.
static LIGHTWEIGHT_API SqlLogger & GetLogger()
Retrieves the currently configured logger.
LIGHTWEIGHT_API SqlLogger(SqlLogger const &)=default
Default copy constructor.
virtual void OnFetchEnd()=0
Invoked when fetching is done.
LIGHTWEIGHT_API SqlLogger & operator=(SqlLogger &&)=default
Default move assignment operator.
static LIGHTWEIGHT_API SqlLogger & TraceLogger()
Retrieves a logger that logs to the trace logger.
static LIGHTWEIGHT_API void SetLogger(SqlLogger &logger)
virtual void OnError(SqlErrorInfo const &errorInfo, std::source_location sourceLocation=std::source_location::current())=0
Invoked an ODBC SQL error occurred, with extended error information.
LIGHTWEIGHT_API void SetLoggingSink(MessageWriter writer={})
virtual void OnBind(std::string_view const &name, std::string value)=0
Invoked when an input parameter is bound, by name.
virtual void OnConnectionReuse(SqlConnection const &connection)=0
Invoked when a connection is reused.
static LIGHTWEIGHT_API SqlLogger & StandardLogger()
Retrieves a logger that logs to standard output.
virtual void OnPrepare(std::string_view const &query)=0
Invoked when a query is prepared.
virtual void OnExecuteBatch()=0
Invoked when a batch of queries is executed.
void OnBindInputParameter(std::string_view const &name, T &&value)
Invoked when an input parameter is bound.
Definition SqlLogger.hpp:92
LIGHTWEIGHT_API SqlLogger(SqlLogger &&)=default
Default move constructor.
std::function< void(std::string)> MessageWriter
Type definition for a function that writes messages.
Definition SqlLogger.hpp:43
virtual void OnConnectionClosed(SqlConnection const &connection)=0
Invoked when a connection is closed.
virtual void OnFetchBlock(std::size_t)
Invoked once per block-prefetch round-trip (one SQLFetchScroll that materialized a whole row block on...
SupportBindLogging
Mandates the support for logging bind operations.
Definition SqlLogger.hpp:26
virtual void OnScopedTimerStart(std::string const &tag)=0
Invoked when a scoped code region needs to be timed and logged. The region starts with this call.
virtual void OnConnectionIdle(SqlConnection const &connection)=0
Invoked when a connection is idle.
virtual void OnScopedTimerStop(std::string const &tag)=0
Invoked when a scoped code region needs to be timed and logged. The region ends with this call.
virtual void OnWarning(std::string_view const &message)=0
Invoked on a warning.
LIGHTWEIGHT_API SqlLogger & operator=(SqlLogger const &)=default
Default copy assignment operator.
virtual void OnFetchRow()=0
Invoked when a row is fetched.
virtual void OnConnectionOpened(SqlConnection const &connection)=0
Invoked when a connection is opened.
LIGHTWEIGHT_API SqlLogger(SupportBindLogging supportBindLogging, MessageWriter writer={})
SqlScopedTimeLogger & operator=(SqlScopedTimeLogger const &)=default
Default copy assignment operator.
SqlScopedTimeLogger(std::string tag)
Constructs a scoped time logger with the given tag.
SqlScopedTimeLogger(SqlScopedTimeLogger const &)=default
Default copy constructor.
Represents an ODBC SQL error.
Definition SqlError.hpp:33