/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_ |