Audacity 3.2.0
Function.h
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-or-later
3 * SPDX-FileName: Function.h
4 * SPDX-FileContributor: Dmitry Vedenko
5 */
6
7#pragma once
8
9#include <functional>
10#include <string>
11#include <string_view>
12#include <tuple>
13#include <type_traits>
14
15struct sqlite3;
16struct sqlite3_value;
17struct sqlite3_context;
18
19namespace audacity::sqlite
20{
21namespace details
22{
24 std::function<void(sqlite3_context*, int, sqlite3_value**)>;
25
26using SQLiteFunctor= std::function<void(sqlite3_context*)>;
27
28SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, bool& result);
29SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, int& result);
30SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, unsigned int& result);
31SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, long& result);
32SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, unsigned long& result);
33SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, long long& result);
34SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, unsigned long long& result);
35SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, double& result);
36SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, float& result);
37SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, std::string& result);
38SQLITE_HELPERS_API void FromSQLiteValue(sqlite3_value& value, std::string_view& result);
39
40SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, bool value);
41SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, int value);
42SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, unsigned int value);
43SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, long value);
44SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, unsigned long value);
45SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, long long value);
46SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, unsigned long long value);
47SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, double value);
48SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, float value);
49SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, const std::string& value);
50SQLITE_HELPERS_API void SetSQLiteFunctionResult(sqlite3_context* context, const std::string_view& value);
51
52SQLITE_HELPERS_API void
53SetSQLiteFunctionError(sqlite3_context* context, const std::string_view& error);
54
55template<typename T>
56std::decay_t<T> FromSQLiteValue(sqlite3_value& value)
57{
58 std::decay_t<T> result;
59 FromSQLiteValue(value, result);
60 return result;
61}
62
63template<typename... Args, std::size_t... Is>
64auto SQLiteValuesToTuple(sqlite3_value** values, std::index_sequence<Is...>)
65{
66 return std::make_tuple(FromSQLiteValue<Args>(*values[Is])...);
67}
68
69template <typename CallbackType>
71
72template<typename R, typename... Args>
73struct SQLiteFunction<std::function<R(Args...)>>
74{
75 static constexpr std::size_t Arity = sizeof...(Args);
76
77 static SQLiteFunctorWithArgs ToSQLiteFunctorWithArgs(std::function<R(Args...)> callback)
78 {
79 return [function = std::move(callback)](
80 sqlite3_context* context, int argc, sqlite3_value** argv)
81 {
82 if (argc != sizeof...(Args))
83 {
84 SetSQLiteFunctionError(context, "Invalid number of arguments");
85 return;
86 }
87
88 if constexpr (std::is_same_v<R, void>)
89 {
90 std::apply(
91 function, SQLiteValuesToTuple<Args...>(
92 argv, std::make_index_sequence<sizeof...(Args)>()));
93 }
94 else
95 {
97 context,
98 std::apply(
99 function,
100 SQLiteValuesToTuple<Args...>(
101 argv, std::make_index_sequence<sizeof...(Args)>())));
102 }
103 };
104 }
105};
106
107template <typename R> struct SQLiteFunction<std::function<R()>>
108{
109 static SQLiteFunctor ToSQLiteFunctor(std::function<R()> callback)
110 {
111 return [function = std::move(callback)](sqlite3_context* context)
112 {
113 if constexpr (std::is_same_v<R, void>)
114 function();
115 else
116 SetSQLiteFunctionResult(context, function());
117 };
118 }
119};
120
121template<typename CallbackType>
122auto MakeSQLiteFunctorWithArgs(CallbackType callback)
123{
124 using FunctionType = decltype(std::function { callback });
126 std::move(callback));
127}
128
129template<typename CallbackType>
130constexpr std::size_t GetFunctionArity()
131{
132 using FunctionType = decltype(std::function { std::declval<CallbackType>() });
134}
135
136template <typename CallbackType>
137auto MakeSQLiteFunctor(CallbackType callback)
138{
139 using FunctionType = decltype(std::function { callback });
141 std::move(callback));
142}
143
144} // namespace details
145
147class SQLITE_HELPERS_API ScalarFunction final
148{
149 template<typename ScalarFunctionType>
151 sqlite3* connection, std::string name, ScalarFunctionType function)
152 : mConnection { connection }
153 , mName { std::move(name) }
154 , mFunctor { details::MakeSQLiteFunctorWithArgs(std::move(function)) }
155 {
156 Register(details::GetFunctionArity<ScalarFunctionType>());
157 }
158
159public:
160 ScalarFunction() = default;
162 ScalarFunction(ScalarFunction&&) noexcept;
163 ScalarFunction& operator=(const ScalarFunction&) = delete;
164 ScalarFunction& operator=(ScalarFunction&&) noexcept;
165
167
168private:
169 void Register(std::size_t arity);
170
171 static void CallFunction(sqlite3_context* context, int argc, sqlite3_value** argv);
172
173 sqlite3* mConnection { nullptr };
174 std::string mName;
176 friend class Connection;
177};
178
180class SQLITE_HELPERS_API AggregateFunction final
181{
182 template<typename StepFunctionType, typename FinalFunctionType>
184 sqlite3* connection, std::string name, StepFunctionType stepFunction,
185 FinalFunctionType finalFunction)
186 : mConnection { connection }
187 , mName { std::move(name) }
188 , mStepFunctor { details::MakeSQLiteFunctorWithArgs(
189 std::move(stepFunction)) }
190 , mFinalFunctor { details::MakeSQLiteFunctor(std::move(finalFunction)) }
191 {
192 Register(details::GetFunctionArity<StepFunctionType>());
193 }
194
195public:
196
197 AggregateFunction() = default;
200 AggregateFunction& operator=(const AggregateFunction&) = delete;
201 AggregateFunction& operator=(AggregateFunction&&) noexcept;
202
204
205private:
206 void Register(std::size_t arity);
207
208 static void CallStepFunction (
209 sqlite3_context* context, int argc, sqlite3_value** argv);
210
211 static void CallFinalFunction(sqlite3_context* context);
212
213 sqlite3* mConnection { nullptr };
214 std::string mName;
217 friend class Connection;
218};
219
220} // namespace audacity::sqlite
const wxChar * values
wxString name
Definition: TagsEditor.cpp:166
A class representing an aggregate function in a SQLite database.
Definition: Function.h:181
details::SQLiteFunctor mFinalFunctor
Definition: Function.h:216
details::SQLiteFunctorWithArgs mStepFunctor
Definition: Function.h:215
AggregateFunction(const AggregateFunction &)=delete
AggregateFunction(sqlite3 *connection, std::string name, StepFunctionType stepFunction, FinalFunctionType finalFunction)
Definition: Function.h:183
A class representing a connection to a SQLite database.
Definition: Connection.h:48
A class representing a scalar function in a SQLite database.
Definition: Function.h:148
details::SQLiteFunctorWithArgs mFunctor
Definition: Function.h:175
ScalarFunction(sqlite3 *connection, std::string name, ScalarFunctionType function)
Definition: Function.h:150
ScalarFunction(const ScalarFunction &)=delete
UTILITY_API const char *const * argv
A copy of argv; responsibility of application startup to assign it.
UTILITY_API int argc
A copy of argc; responsibility of application startup to assign it.
Call< Predicate, T > Is
Apply a metapredicate to a type.
Definition: TypeList.h:391
void FromSQLiteValue(sqlite3_value &value, bool &result)
Definition: Function.cpp:17
auto MakeSQLiteFunctor(CallbackType callback)
Definition: Function.h:137
std::function< void(sqlite3_context *)> SQLiteFunctor
Definition: Function.h:26
void SetSQLiteFunctionError(sqlite3_context *context, const std::string_view &error)
Definition: Function.cpp:146
constexpr std::size_t GetFunctionArity()
Definition: Function.h:130
std::function< void(sqlite3_context *, int, sqlite3_value **)> SQLiteFunctorWithArgs
Definition: Function.h:24
auto MakeSQLiteFunctorWithArgs(CallbackType callback)
Definition: Function.h:122
void SetSQLiteFunctionResult(sqlite3_context *context, bool value)
Definition: Function.cpp:84
auto SQLiteValuesToTuple(sqlite3_value **values, std::index_sequence< Is... >)
Definition: Function.h:64
STL namespace.
static SQLiteFunctor ToSQLiteFunctor(std::function< R()> callback)
Definition: Function.h:109
static SQLiteFunctorWithArgs ToSQLiteFunctorWithArgs(std::function< R(Args...)> callback)
Definition: Function.h:77