xref: /aosp_15_r20/external/perfetto/src/trace_processor/sqlite/bindings/sqlite_module.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in, software
11  * distributed under the License is distributed on an "AS IS",
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_MODULE_H_
18 #define SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_MODULE_H_
19 
20 #include <sqlite3.h>
21 
22 #include "perfetto/base/logging.h"
23 
24 namespace perfetto::trace_processor::sqlite {
25 
26 // Prototype for a virtual table (vtab) module which can be registered with
27 // SQLite.
28 //
29 // See https://www.sqlite.org/vtab.html for how to implement this class.
30 template <typename Impl>
31 struct Module {
32   // Specifies the type of module: implementations can override this field by
33   // declaring and defining it.
34   //
35   // Specifying this to kCreateOnly requires that the |Create| and |Destroy|
36   // functions are defined.
37   //
38   // See the SQLite documentation on what these types mean.
39   static constexpr enum { kEponymousOnly, kCreateOnly } kType = kCreateOnly;
40 
41   // Specifies whether this table is supports making changes to it:
42   // implementations can override this field by declaring and defining it.
43   //
44   // Setting this to true requires the |Update| function to be defined.
45   static constexpr bool kSupportsWrites = true;
46 
47   // Specifies whether this table supports overloading functions:
48   // implementations can override this field by declaring and defining it.
49   //
50   // Setting this to true requires that the |FindFunction| function is defined.
51   static constexpr bool kDoesOverloadFunctions = true;
52 
53   // Specifies the type of context for the module. Implementations should define
54   // this type to match the context type which is expected to be passed into
55   // |sqlite3_create_module|.
56   using Context = void;
57 
58   // Specifies the type for the vtab created by this module.
59   //
60   // Implementations should define this type to match the vtab type they use in
61   // |Create| and |Connect|.
62   using Vtab = sqlite3_vtab;
63 
64   // Specifies the type for the cursor created by this module.
65   //
66   // Implementations should define this type to match the cursor type they use
67   // in |Open| and |Close|.
68   using Cursor = sqlite3_vtab_cursor;
69 
70   // Creates a new instance of a virtual table and its backing storage.
71   //
72   // Implementations MUST define this function themselves if
73   // |kType| == |kCreateOnly|; this function is declared but *not* defined so
74   // linker errors will be thrown if not defined.
75   static int Create(sqlite3*,
76                     void*,
77                     int,
78                     const char* const*,
79                     sqlite3_vtab**,
80                     char**);
81 
82   // Destroys the virtual table and its backing storage.
83   //
84   // Implementations MUST define this function themselves if
85   // |kType| == |kCreateOnly|; this function is declared but *not* defined so
86   // linker errors will be thrown if not defined.
87   static int Destroy(sqlite3_vtab*);
88 
89   // Creates a new instance of the virtual table, connecting to existing
90   // backing storage.
91   //
92   // Implementations MUST define this function themselves; this function is
93   // declared but *not* defined so linker errors will be thrown if not defined.
94   static int Connect(sqlite3*,
95                      void*,
96                      int,
97                      const char* const*,
98                      sqlite3_vtab**,
99                      char**);
100 
101   // Destroys the virtual table but *not* its backing storage.
102   //
103   // Implementations MUST define this function themselves; this function is
104   // declared but *not* defined so linker errors will be thrown if not defined.
105   static int Disconnect(sqlite3_vtab*);
106 
107   // Specifies filtering and cost information for the query planner.
108   //
109   // Implementations MUST define this function themselves; this function is
110   // declared but *not* defined so linker errors will be thrown if not defined.
111   static int BestIndex(sqlite3_vtab*, sqlite3_index_info*);
112 
113   // Opens a cursor into the given vtab.
114   //
115   // Implementations MUST define this function themselves; this function is
116   // declared but *not* defined so linker errors will be thrown if not defined.
117   static int Open(sqlite3_vtab*, sqlite3_vtab_cursor**);
118 
119   // Closes the cursor.
120   //
121   // Implementations MUST define this function themselves; this function is
122   // declared but *not* defined so linker errors will be thrown if not defined.
123   static int Close(sqlite3_vtab_cursor*);
124 
125   // Resets this cursor to filter rows matching the provided set of filter
126   // constraints and order by clauses.
127   //
128   // Implementations MUST define this function themselves; this function is
129   // declared but *not* defined so linker errors will be thrown if not defined.
130   static int Filter(sqlite3_vtab_cursor*,
131                     int,
132                     const char*,
133                     int,
134                     sqlite3_value**);
135 
136   // Forwards the cursor to point to the next row.
137   //
138   // Implementations MUST define this function themselves; this function is
139   // declared but *not* defined so linker errors will be thrown if not defined.
140   static int Next(sqlite3_vtab_cursor*);
141 
142   // Returns 1 if the cursor has reached its end or 0 otherwise.
143   //
144   // Implementations MUST define this function themselves; this function is
145   // declared but *not* defined so linker errors will be thrown if not defined.
146   static int Eof(sqlite3_vtab_cursor*);
147 
148   // Returns the value column at the given index for the current row the cursor
149   // points to.
150   //
151   // Implementations MUST define this function themselves; this function is
152   // declared but *not* defined so linker errors will be thrown if not defined.
153   static int Column(sqlite3_vtab_cursor*, sqlite3_context*, int);
154 
155   // Returns the rowid for the current row.
156   //
157   // Implementations MUST define this function themselves; this function is
158   // declared but *not* defined so linker errors will be thrown if not defined.
159   static int Rowid(sqlite3_vtab_cursor*, sqlite_int64*);
160 
161   // Inserts/deletes/updates one row.
162   //
163   // Implementations MUST define this function themselves if
164   // |kSupportsWrites| == |true|; this function is declared but *not* defined so
165   // linker errors will be thrown if not defined.
166   static int Update(sqlite3_vtab*, int, sqlite3_value**, sqlite_int64*);
167 
168   // Overloads a function with the given name when executed with a vtab column
169   // as the first argument.
170   //
171   // Implementations MUST define this function themselves if
172   // |kDoesOverloadFunctions| == |true|; this function is declared but *not*
173   // defined so linker errors will be thrown if not defined.
174   using FindFunctionFn = void(sqlite3_context*, int, sqlite3_value**);
175   static int FindFunction(sqlite3_vtab*,
176                           int,
177                           const char*,
178                           FindFunctionFn**,
179                           void**);
180 
181   // Helper function to cast the module context pointer to the correct type.
GetContextModule182   static auto GetContext(void* ctx) {
183     return static_cast<typename Impl::Context*>(ctx);
184   }
185 
186   // Helper function to cast the vtab pointer to the correct type.
GetVtabModule187   static auto GetVtab(sqlite3_vtab* vtab) {
188     return static_cast<typename Impl::Vtab*>(vtab);
189   }
190 
191   // Helper function to cast the cursor pointer to the correct type.
GetCursorModule192   static auto GetCursor(sqlite3_vtab_cursor* cursor) {
193     return static_cast<typename Impl::Cursor*>(cursor);
194   }
195 
196   // Returns sqlite3_module object corresponding to the module. Used to pass
197   // information about this module to SQLite.
CreateModuleModule198   static constexpr sqlite3_module CreateModule() {
199     sqlite3_module module{};
200     module.xBestIndex = &Impl::BestIndex;
201     module.xOpen = &Impl::Open;
202     module.xClose = &Impl::Close;
203     module.xFilter = &Impl::Filter;
204     module.xNext = &Impl::Next;
205     module.xEof = &Impl::Eof;
206     module.xColumn = &Impl::Column;
207     module.xRowid = &Impl::Rowid;
208     if constexpr (Impl::kType == kCreateOnly) {
209       module.xCreate = &Impl::Create;
210       module.xDestroy = &Impl::Destroy;
211       module.xConnect = &Impl::Connect;
212       module.xDisconnect = &Impl::Disconnect;
213     } else {
214       module.xCreate = nullptr;
215       module.xDestroy = [](sqlite3_vtab*) -> int {
216         PERFETTO_FATAL("Should not be reachable");
217       };
218       module.xConnect = &Impl::Connect;
219       module.xDisconnect = &Impl::Disconnect;
220     }
221     if constexpr (Impl::kSupportsWrites) {
222       module.xUpdate = &Impl::Update;
223     }
224     if constexpr (Impl::kDoesOverloadFunctions) {
225       module.xFindFunction = &Impl::FindFunction;
226     }
227     return module;
228   }
229 };
230 
231 }  // namespace perfetto::trace_processor::sqlite
232 
233 #endif  // SRC_TRACE_PROCESSOR_SQLITE_BINDINGS_SQLITE_MODULE_H_
234