Coverage Report

Created: 2026-01-21 08:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/src/node_sqlite.h
Line
Count
Source
1
#ifndef SRC_NODE_SQLITE_H_
2
#define SRC_NODE_SQLITE_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "base_object.h"
7
#include "lru_cache-inl.h"
8
#include "node_mem.h"
9
#include "sqlite3.h"
10
#include "util.h"
11
12
#include <list>
13
#include <map>
14
#include <unordered_set>
15
16
namespace node {
17
namespace sqlite {
18
19
class DatabaseOpenConfiguration {
20
 public:
21
  explicit DatabaseOpenConfiguration(std::string&& location)
22
0
      : location_(std::move(location)) {}
23
24
0
  inline const std::string& location() const { return location_; }
25
26
0
  inline bool get_read_only() const { return read_only_; }
27
28
0
  inline void set_read_only(bool flag) { read_only_ = flag; }
29
30
0
  inline bool get_enable_foreign_keys() const { return enable_foreign_keys_; }
31
32
0
  inline void set_enable_foreign_keys(bool flag) {
33
0
    enable_foreign_keys_ = flag;
34
0
  }
35
36
0
  inline bool get_enable_dqs() const { return enable_dqs_; }
37
38
0
  inline void set_enable_dqs(bool flag) { enable_dqs_ = flag; }
39
40
0
  inline void set_timeout(int timeout) { timeout_ = timeout; }
41
42
0
  inline int get_timeout() { return timeout_; }
43
44
0
  inline void set_use_big_ints(bool flag) { use_big_ints_ = flag; }
45
46
0
  inline bool get_use_big_ints() const { return use_big_ints_; }
47
48
0
  inline void set_return_arrays(bool flag) { return_arrays_ = flag; }
49
50
0
  inline bool get_return_arrays() const { return return_arrays_; }
51
52
0
  inline void set_allow_bare_named_params(bool flag) {
53
0
    allow_bare_named_params_ = flag;
54
0
  }
55
56
0
  inline bool get_allow_bare_named_params() const {
57
0
    return allow_bare_named_params_;
58
0
  }
59
60
0
  inline void set_allow_unknown_named_params(bool flag) {
61
0
    allow_unknown_named_params_ = flag;
62
0
  }
63
64
0
  inline bool get_allow_unknown_named_params() const {
65
0
    return allow_unknown_named_params_;
66
0
  }
67
68
0
  inline void set_enable_defensive(bool flag) { defensive_ = flag; }
69
70
0
  inline bool get_enable_defensive() const { return defensive_; }
71
72
 private:
73
  std::string location_;
74
  bool read_only_ = false;
75
  bool enable_foreign_keys_ = true;
76
  bool enable_dqs_ = false;
77
  int timeout_ = 0;
78
  bool use_big_ints_ = false;
79
  bool return_arrays_ = false;
80
  bool allow_bare_named_params_ = true;
81
  bool allow_unknown_named_params_ = false;
82
  bool defensive_ = true;
83
};
84
85
class DatabaseSync;
86
class StatementSyncIterator;
87
class StatementSync;
88
class BackupJob;
89
90
class StatementExecutionHelper {
91
 public:
92
  static v8::MaybeLocal<v8::Value> All(Environment* env,
93
                                       DatabaseSync* db,
94
                                       sqlite3_stmt* stmt,
95
                                       bool return_arrays,
96
                                       bool use_big_ints);
97
  static v8::MaybeLocal<v8::Object> Run(Environment* env,
98
                                        DatabaseSync* db,
99
                                        sqlite3_stmt* stmt,
100
                                        bool use_big_ints);
101
  static BaseObjectPtr<StatementSyncIterator> Iterate(
102
      Environment* env, BaseObjectPtr<StatementSync> stmt);
103
  static v8::MaybeLocal<v8::Value> ColumnToValue(Environment* env,
104
                                                 sqlite3_stmt* stmt,
105
                                                 const int column,
106
                                                 bool use_big_ints);
107
  static v8::MaybeLocal<v8::Name> ColumnNameToName(Environment* env,
108
                                                   sqlite3_stmt* stmt,
109
                                                   const int column);
110
  static v8::MaybeLocal<v8::Value> Get(Environment* env,
111
                                       DatabaseSync* db,
112
                                       sqlite3_stmt* stmt,
113
                                       bool return_arrays,
114
                                       bool use_big_ints);
115
};
116
117
class DatabaseSync : public BaseObject {
118
 public:
119
  enum InternalFields {
120
    kAuthorizerCallback = BaseObject::kInternalFieldCount,
121
    kInternalFieldCount
122
  };
123
124
  DatabaseSync(Environment* env,
125
               v8::Local<v8::Object> object,
126
               DatabaseOpenConfiguration&& open_config,
127
               bool open,
128
               bool allow_load_extension);
129
  void MemoryInfo(MemoryTracker* tracker) const override;
130
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
131
  static void Open(const v8::FunctionCallbackInfo<v8::Value>& args);
132
  static void IsOpenGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
133
  static void IsTransactionGetter(
134
      const v8::FunctionCallbackInfo<v8::Value>& args);
135
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
136
  static void Dispose(const v8::FunctionCallbackInfo<v8::Value>& args);
137
  static void Prepare(const v8::FunctionCallbackInfo<v8::Value>& args);
138
  static void Exec(const v8::FunctionCallbackInfo<v8::Value>& args);
139
  static void CreateTagStore(const v8::FunctionCallbackInfo<v8::Value>& args);
140
  static void Location(const v8::FunctionCallbackInfo<v8::Value>& args);
141
  static void CustomFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
142
  static void AggregateFunction(
143
      const v8::FunctionCallbackInfo<v8::Value>& args);
144
  static void CreateSession(const v8::FunctionCallbackInfo<v8::Value>& args);
145
  static void ApplyChangeset(const v8::FunctionCallbackInfo<v8::Value>& args);
146
  static void EnableLoadExtension(
147
      const v8::FunctionCallbackInfo<v8::Value>& args);
148
  static void EnableDefensive(const v8::FunctionCallbackInfo<v8::Value>& args);
149
  static void LoadExtension(const v8::FunctionCallbackInfo<v8::Value>& args);
150
  static void SetAuthorizer(const v8::FunctionCallbackInfo<v8::Value>& args);
151
  static int AuthorizerCallback(void* user_data,
152
                                int action_code,
153
                                const char* param1,
154
                                const char* param2,
155
                                const char* param3,
156
                                const char* param4);
157
  void FinalizeStatements();
158
  void RemoveBackup(BackupJob* backup);
159
  void AddBackup(BackupJob* backup);
160
  void FinalizeBackups();
161
  void UntrackStatement(StatementSync* statement);
162
  bool IsOpen();
163
0
  bool use_big_ints() const { return open_config_.get_use_big_ints(); }
164
0
  bool return_arrays() const { return open_config_.get_return_arrays(); }
165
0
  bool allow_bare_named_params() const {
166
0
    return open_config_.get_allow_bare_named_params();
167
0
  }
168
0
  bool allow_unknown_named_params() const {
169
0
    return open_config_.get_allow_unknown_named_params();
170
0
  }
171
  sqlite3* Connection();
172
173
  // In some situations, such as when using custom functions, it is possible
174
  // that SQLite reports an error while JavaScript already has a pending
175
  // exception. In this case, the SQLite error should be ignored. These methods
176
  // enable that use case.
177
  void SetIgnoreNextSQLiteError(bool ignore);
178
  bool ShouldIgnoreSQLiteError();
179
180
  SET_MEMORY_INFO_NAME(DatabaseSync)
181
  SET_SELF_SIZE(DatabaseSync)
182
183
 private:
184
  bool Open();
185
  void DeleteSessions();
186
187
  ~DatabaseSync() override;
188
  DatabaseOpenConfiguration open_config_;
189
  bool allow_load_extension_;
190
  bool enable_load_extension_;
191
  sqlite3* connection_;
192
  bool ignore_next_sqlite_error_;
193
194
  std::set<BackupJob*> backups_;
195
  std::set<sqlite3_session*> sessions_;
196
  std::unordered_set<StatementSync*> statements_;
197
198
  friend class Session;
199
  friend class SQLTagStore;
200
  friend class StatementExecutionHelper;
201
};
202
203
class StatementSync : public BaseObject {
204
 public:
205
  StatementSync(Environment* env,
206
                v8::Local<v8::Object> object,
207
                BaseObjectPtr<DatabaseSync> db,
208
                sqlite3_stmt* stmt);
209
  void MemoryInfo(MemoryTracker* tracker) const override;
210
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
211
      Environment* env);
212
  static BaseObjectPtr<StatementSync> Create(Environment* env,
213
                                             BaseObjectPtr<DatabaseSync> db,
214
                                             sqlite3_stmt* stmt);
215
  static void All(const v8::FunctionCallbackInfo<v8::Value>& args);
216
  static void Iterate(const v8::FunctionCallbackInfo<v8::Value>& args);
217
  static void Get(const v8::FunctionCallbackInfo<v8::Value>& args);
218
  static void Run(const v8::FunctionCallbackInfo<v8::Value>& args);
219
  static void Columns(const v8::FunctionCallbackInfo<v8::Value>& args);
220
  static void SourceSQLGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
221
  static void ExpandedSQLGetter(
222
      const v8::FunctionCallbackInfo<v8::Value>& args);
223
  static void SetAllowBareNamedParameters(
224
      const v8::FunctionCallbackInfo<v8::Value>& args);
225
  static void SetAllowUnknownNamedParameters(
226
      const v8::FunctionCallbackInfo<v8::Value>& args);
227
  static void SetReadBigInts(const v8::FunctionCallbackInfo<v8::Value>& args);
228
  static void SetReturnArrays(const v8::FunctionCallbackInfo<v8::Value>& args);
229
  v8::MaybeLocal<v8::Value> ColumnToValue(const int column);
230
  v8::MaybeLocal<v8::Name> ColumnNameToName(const int column);
231
  void Finalize();
232
  bool IsFinalized();
233
234
  SET_MEMORY_INFO_NAME(StatementSync)
235
  SET_SELF_SIZE(StatementSync)
236
237
 private:
238
  ~StatementSync() override;
239
  BaseObjectPtr<DatabaseSync> db_;
240
  sqlite3_stmt* statement_;
241
  bool return_arrays_ = false;
242
  bool use_big_ints_;
243
  bool allow_bare_named_params_;
244
  bool allow_unknown_named_params_;
245
  std::optional<std::map<std::string, std::string>> bare_named_params_;
246
  bool BindParams(const v8::FunctionCallbackInfo<v8::Value>& args);
247
  bool BindValue(const v8::Local<v8::Value>& value, const int index);
248
249
  friend class DatabaseSync;
250
  friend class StatementSyncIterator;
251
  friend class SQLTagStore;
252
  friend class StatementExecutionHelper;
253
};
254
255
class StatementSyncIterator : public BaseObject {
256
 public:
257
  StatementSyncIterator(Environment* env,
258
                        v8::Local<v8::Object> object,
259
                        BaseObjectPtr<StatementSync> stmt);
260
  void MemoryInfo(MemoryTracker* tracker) const override;
261
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
262
      Environment* env);
263
  static BaseObjectPtr<StatementSyncIterator> Create(
264
      Environment* env, BaseObjectPtr<StatementSync> stmt);
265
  static void Next(const v8::FunctionCallbackInfo<v8::Value>& args);
266
  static void Return(const v8::FunctionCallbackInfo<v8::Value>& args);
267
268
  SET_MEMORY_INFO_NAME(StatementSyncIterator)
269
  SET_SELF_SIZE(StatementSyncIterator)
270
271
 private:
272
  ~StatementSyncIterator() override;
273
  BaseObjectPtr<StatementSync> stmt_;
274
  bool done_;
275
};
276
277
using Sqlite3ChangesetGenFunc = int (*)(sqlite3_session*, int*, void**);
278
279
class Session : public BaseObject {
280
 public:
281
  Session(Environment* env,
282
          v8::Local<v8::Object> object,
283
          BaseObjectWeakPtr<DatabaseSync> database,
284
          sqlite3_session* session);
285
  ~Session() override;
286
  template <Sqlite3ChangesetGenFunc sqliteChangesetFunc>
287
  static void Changeset(const v8::FunctionCallbackInfo<v8::Value>& args);
288
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
289
  static void Dispose(const v8::FunctionCallbackInfo<v8::Value>& args);
290
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
291
      Environment* env);
292
  static BaseObjectPtr<Session> Create(Environment* env,
293
                                       BaseObjectWeakPtr<DatabaseSync> database,
294
                                       sqlite3_session* session);
295
296
  void MemoryInfo(MemoryTracker* tracker) const override;
297
  SET_MEMORY_INFO_NAME(Session)
298
  SET_SELF_SIZE(Session)
299
300
 private:
301
  void Delete();
302
  sqlite3_session* session_;
303
  BaseObjectWeakPtr<DatabaseSync> database_;  // The Parent Database
304
};
305
306
class SQLTagStore : public BaseObject {
307
 public:
308
  SQLTagStore(Environment* env,
309
              v8::Local<v8::Object> object,
310
              BaseObjectWeakPtr<DatabaseSync> database,
311
              int capacity);
312
  ~SQLTagStore() override;
313
  static BaseObjectPtr<SQLTagStore> Create(
314
      Environment* env, BaseObjectWeakPtr<DatabaseSync> database, int capacity);
315
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
316
      Environment* env);
317
  static void All(const v8::FunctionCallbackInfo<v8::Value>& args);
318
  static void Get(const v8::FunctionCallbackInfo<v8::Value>& args);
319
  static void Iterate(const v8::FunctionCallbackInfo<v8::Value>& args);
320
  static void Run(const v8::FunctionCallbackInfo<v8::Value>& args);
321
  static void Clear(const v8::FunctionCallbackInfo<v8::Value>& args);
322
  static void CapacityGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
323
  static void DatabaseGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
324
  static void SizeGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
325
  void MemoryInfo(MemoryTracker* tracker) const override;
326
  SET_MEMORY_INFO_NAME(SQLTagStore)
327
  SET_SELF_SIZE(SQLTagStore)
328
329
 private:
330
  static BaseObjectPtr<StatementSync> PrepareStatement(
331
      const v8::FunctionCallbackInfo<v8::Value>& args);
332
  BaseObjectWeakPtr<DatabaseSync> database_;
333
  LRUCache<std::string, BaseObjectPtr<StatementSync>> sql_tags_;
334
  friend class StatementExecutionHelper;
335
};
336
337
class UserDefinedFunction {
338
 public:
339
  UserDefinedFunction(Environment* env,
340
                      v8::Local<v8::Function> fn,
341
                      DatabaseSync* db,
342
                      bool use_bigint_args);
343
  ~UserDefinedFunction();
344
  static void xFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
345
  static void xDestroy(void* self);
346
347
 private:
348
  Environment* env_;
349
  v8::Global<v8::Function> fn_;
350
  DatabaseSync* db_;
351
  bool use_bigint_args_;
352
};
353
354
}  // namespace sqlite
355
}  // namespace node
356
357
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
358
#endif  // SRC_NODE_SQLITE_H_