@@ -24,19 +24,24 @@ using v8::IndexedPropertyHandlerConfiguration;
24
24
using v8::Integer;
25
25
using v8::Intercepted;
26
26
using v8::Isolate;
27
+ using v8::JustVoid;
27
28
using v8::Local;
28
29
using v8::Map;
29
30
using v8::Maybe;
30
31
using v8::MaybeLocal;
31
32
using v8::Name;
32
33
using v8::NamedPropertyHandlerConfiguration;
34
+ using v8::NewStringType;
35
+ using v8::Nothing;
36
+ using v8::Null;
33
37
using v8::Object;
34
38
using v8::PropertyAttribute;
35
39
using v8::PropertyCallbackInfo;
36
40
using v8::PropertyDescriptor;
37
41
using v8::PropertyHandlerFlags;
38
42
using v8::String;
39
43
using v8::Uint32;
44
+ using v8::Undefined;
40
45
using v8::Value;
41
46
42
47
#define THROW_SQLITE_ERROR (env, r ) \
@@ -96,7 +101,7 @@ void Storage::MemoryInfo(MemoryTracker* tracker) const {
96
101
tracker->TrackField (" location" , location_);
97
102
}
98
103
99
- bool Storage::Open () {
104
+ Maybe< void > Storage::Open () {
100
105
static const int kCurrentSchemaVersion = 1 ;
101
106
static constexpr std::string_view get_schema_version_sql =
102
107
" SELECT schema_version FROM nodejs_webstorage_state" ;
@@ -161,30 +166,31 @@ bool Storage::Open() {
161
166
162
167
sqlite3* db = db_.get ();
163
168
if (db != nullptr ) {
164
- return true ;
169
+ return JustVoid () ;
165
170
}
166
171
167
172
int r = sqlite3_open (location_.c_str (), &db);
168
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
173
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
169
174
r = sqlite3_exec (db, init_sql_v0.data (), 0 , 0 , nullptr );
170
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
175
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
171
176
172
177
// Get the current schema version, used to determine schema migrations.
173
178
sqlite3_stmt* s = nullptr ;
174
179
r = sqlite3_prepare_v2 (
175
180
db, get_schema_version_sql.data (), get_schema_version_sql.size (), &s, 0 );
176
181
r = sqlite3_exec (db, init_sql_v0.data (), 0 , 0 , nullptr );
177
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
182
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
178
183
auto stmt = stmt_unique_ptr (s);
179
- CHECK_ERROR_OR_THROW (env (), sqlite3_step (stmt.get ()), SQLITE_ROW, false );
184
+ CHECK_ERROR_OR_THROW (
185
+ env (), sqlite3_step (stmt.get ()), SQLITE_ROW, Nothing<void >());
180
186
CHECK (sqlite3_column_type (stmt.get (), 0 ) == SQLITE_INTEGER);
181
187
int schema_version = sqlite3_column_int (stmt.get (), 0 );
182
188
stmt = nullptr ; // Force finalization.
183
189
184
190
if (schema_version > kCurrentSchemaVersion ) {
185
191
THROW_ERR_INVALID_STATE (
186
192
env (), " localStorage was created with a newer version of Node.js" );
187
- return false ;
193
+ return Nothing< void >() ;
188
194
}
189
195
190
196
if (schema_version < kCurrentSchemaVersion ) {
@@ -193,11 +199,11 @@ bool Storage::Open() {
193
199
" UPDATE nodejs_webstorage_state SET schema_version = " +
194
200
std::to_string (kCurrentSchemaVersion ) + " ;" ;
195
201
r = sqlite3_exec (db, set_user_version_sql.c_str (), 0 , 0 , nullptr );
196
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
202
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
197
203
}
198
204
199
205
db_ = conn_unique_ptr (db);
200
- return true ;
206
+ return JustVoid () ;
201
207
}
202
208
203
209
void Storage::New (const FunctionCallbackInfo<Value>& args) {
@@ -222,9 +228,9 @@ void Storage::New(const FunctionCallbackInfo<Value>& args) {
222
228
new Storage (env, args.This (), location.ToStringView ());
223
229
}
224
230
225
- void Storage::Clear () {
226
- if (!Open ()) {
227
- return ;
231
+ Maybe< void > Storage::Clear () {
232
+ if (!Open (). IsJust () ) {
233
+ return Nothing< void >() ;
228
234
}
229
235
230
236
static constexpr std::string_view sql = " DELETE FROM nodejs_webstorage" ;
@@ -233,13 +239,15 @@ void Storage::Clear() {
233
239
env (),
234
240
sqlite3_prepare_v2 (db_.get (), sql.data (), sql.size (), &s, 0 ),
235
241
SQLITE_OK,
236
- void ());
242
+ Nothing< void > ());
237
243
auto stmt = stmt_unique_ptr (s);
238
- CHECK_ERROR_OR_THROW (env (), sqlite3_step (stmt.get ()), SQLITE_DONE, void ());
244
+ CHECK_ERROR_OR_THROW (
245
+ env (), sqlite3_step (stmt.get ()), SQLITE_DONE, Nothing<void >());
246
+ return JustVoid ();
239
247
}
240
248
241
- Local <Array> Storage::Enumerate () {
242
- if (!Open ()) {
249
+ MaybeLocal <Array> Storage::Enumerate () {
250
+ if (!Open (). IsJust () ) {
243
251
return Local<Array>();
244
252
}
245
253
@@ -256,7 +264,7 @@ Local<Array> Storage::Enumerate() {
256
264
if (!String::NewFromTwoByte (env ()->isolate (),
257
265
reinterpret_cast <const uint16_t *>(
258
266
sqlite3_column_blob (stmt.get (), 0 )),
259
- v8:: NewStringType::kNormal ,
267
+ NewStringType::kNormal ,
260
268
size)
261
269
.ToLocal (&value)) {
262
270
return Local<Array>();
@@ -267,8 +275,8 @@ Local<Array> Storage::Enumerate() {
267
275
return Array::New (env ()->isolate (), values.data (), values.size ());
268
276
}
269
277
270
- Local <Value> Storage::Length () {
271
- if (!Open ()) {
278
+ MaybeLocal <Value> Storage::Length () {
279
+ if (!Open (). IsJust () ) {
272
280
return {};
273
281
}
274
282
@@ -285,14 +293,13 @@ Local<Value> Storage::Length() {
285
293
return Integer::New (env ()->isolate (), result);
286
294
}
287
295
288
- Local <Value> Storage::Load (Local<Name> key) {
296
+ MaybeLocal <Value> Storage::Load (Local<Name> key) {
289
297
if (key->IsSymbol ()) {
290
298
auto symbol_map = symbols_.Get (env ()->isolate ());
291
- MaybeLocal<Value> result = symbol_map->Get (env ()->context (), key);
292
- return result.FromMaybe (Local<Value>());
299
+ return symbol_map->Get (env ()->context (), key);
293
300
}
294
301
295
- if (!Open ()) {
302
+ if (!Open (). IsJust () ) {
296
303
return {};
297
304
}
298
305
@@ -306,28 +313,26 @@ Local<Value> Storage::Load(Local<Name> key) {
306
313
auto key_size = utf16key.length () * sizeof (uint16_t );
307
314
r = sqlite3_bind_blob (stmt.get (), 1 , utf16key.out (), key_size, SQLITE_STATIC);
308
315
CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Local<Value>());
309
- auto value = Local<Value>();
310
316
r = sqlite3_step (stmt.get ());
311
317
if (r == SQLITE_ROW) {
312
318
CHECK (sqlite3_column_type (stmt.get (), 0 ) == SQLITE_BLOB);
313
319
auto size = sqlite3_column_bytes (stmt.get (), 0 ) / sizeof (uint16_t );
314
- if (!String::NewFromTwoByte (env ()->isolate (),
315
- reinterpret_cast <const uint16_t *>(
316
- sqlite3_column_blob (stmt.get (), 0 )),
317
- v8::NewStringType::kNormal ,
318
- size)
319
- .ToLocal (&value)) {
320
- return {};
321
- }
320
+ return String::NewFromTwoByte (env ()->isolate (),
321
+ reinterpret_cast <const uint16_t *>(
322
+ sqlite3_column_blob (stmt.get (), 0 )),
323
+ NewStringType::kNormal ,
324
+ size)
325
+ .As <Value>();
322
326
} else if (r != SQLITE_DONE) {
323
327
THROW_SQLITE_ERROR (env (), r);
328
+ return {};
329
+ } else {
330
+ return Null (env ()->isolate ());
324
331
}
325
-
326
- return value;
327
332
}
328
333
329
- Local <Value> Storage::LoadKey (const int index) {
330
- if (!Open ()) {
334
+ MaybeLocal <Value> Storage::LoadKey (const int index) {
335
+ if (!Open (). IsJust () ) {
331
336
return {};
332
337
}
333
338
@@ -340,65 +345,64 @@ Local<Value> Storage::LoadKey(const int index) {
340
345
r = sqlite3_bind_int (stmt.get (), 1 , index );
341
346
CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Local<Value>());
342
347
343
- auto value = Local<Value>();
344
348
r = sqlite3_step (stmt.get ());
345
349
if (r == SQLITE_ROW) {
346
350
CHECK (sqlite3_column_type (stmt.get (), 0 ) == SQLITE_BLOB);
347
351
auto size = sqlite3_column_bytes (stmt.get (), 0 ) / sizeof (uint16_t );
348
- if (!String::NewFromTwoByte (env ()->isolate (),
349
- reinterpret_cast <const uint16_t *>(
350
- sqlite3_column_blob (stmt.get (), 0 )),
351
- v8::NewStringType::kNormal ,
352
- size)
353
- .ToLocal (&value)) {
354
- return {};
355
- }
352
+ return String::NewFromTwoByte (env ()->isolate (),
353
+ reinterpret_cast <const uint16_t *>(
354
+ sqlite3_column_blob (stmt.get (), 0 )),
355
+ NewStringType::kNormal ,
356
+ size)
357
+ .As <Value>();
356
358
} else if (r != SQLITE_DONE) {
357
359
THROW_SQLITE_ERROR (env (), r);
360
+ return {};
361
+ } else {
362
+ return Null (env ()->isolate ());
358
363
}
359
-
360
- return value;
361
364
}
362
365
363
- bool Storage::Remove (Local<Name> key) {
366
+ Maybe< void > Storage::Remove (Local<Name> key) {
364
367
if (key->IsSymbol ()) {
365
368
auto symbol_map = symbols_.Get (env ()->isolate ());
366
369
Maybe<bool > result = symbol_map->Delete (env ()->context (), key);
367
- return ! result.IsNothing ();
370
+ return result.IsNothing () ? Nothing< void >() : JustVoid ();
368
371
}
369
372
370
- if (!Open ()) {
371
- return false ;
373
+ if (!Open (). IsJust () ) {
374
+ return Nothing< void >() ;
372
375
}
373
376
374
377
static constexpr std::string_view sql =
375
378
" DELETE FROM nodejs_webstorage WHERE key = ?" ;
376
379
sqlite3_stmt* s = nullptr ;
377
380
int r = sqlite3_prepare_v2 (db_.get (), sql.data (), sql.size (), &s, 0 );
378
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
381
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
379
382
auto stmt = stmt_unique_ptr (s);
380
383
TwoByteValue utf16key (env ()->isolate (), key);
381
384
auto key_size = utf16key.length () * sizeof (uint16_t );
382
385
r = sqlite3_bind_blob (stmt.get (), 1 , utf16key.out (), key_size, SQLITE_STATIC);
383
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
384
- CHECK_ERROR_OR_THROW (env (), sqlite3_step (stmt.get ()), SQLITE_DONE, false );
385
- return true ;
386
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing<void >());
387
+ CHECK_ERROR_OR_THROW (
388
+ env (), sqlite3_step (stmt.get ()), SQLITE_DONE, Nothing<void >());
389
+ return JustVoid ();
386
390
}
387
391
388
- bool Storage::Store (Local<Name> key, Local<Value> value) {
392
+ Maybe< void > Storage::Store (Local<Name> key, Local<Value> value) {
389
393
if (key->IsSymbol ()) {
390
394
auto symbol_map = symbols_.Get (env ()->isolate ());
391
395
MaybeLocal<Map> result = symbol_map->Set (env ()->context (), key, value);
392
- return ! result.IsEmpty ();
396
+ return result.IsEmpty () ? Nothing< void >() : JustVoid ();
393
397
}
394
398
395
399
Local<String> val;
396
400
if (!value->ToString (env ()->context ()).ToLocal (&val)) {
397
- return false ;
401
+ return Nothing< void >() ;
398
402
}
399
403
400
- if (!Open ()) {
401
- return false ;
404
+ if (!Open (). IsJust () ) {
405
+ return Nothing< void >() ;
402
406
}
403
407
404
408
static constexpr std::string_view sql =
@@ -409,23 +413,23 @@ bool Storage::Store(Local<Name> key, Local<Value> value) {
409
413
TwoByteValue utf16key (env ()->isolate (), key);
410
414
TwoByteValue utf16val (env ()->isolate (), val);
411
415
int r = sqlite3_prepare_v2 (db_.get (), sql.data (), sql.size (), &s, 0 );
412
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
416
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
413
417
auto stmt = stmt_unique_ptr (s);
414
418
auto key_size = utf16key.length () * sizeof (uint16_t );
415
419
r = sqlite3_bind_blob (stmt.get (), 1 , utf16key.out (), key_size, SQLITE_STATIC);
416
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
420
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
417
421
auto val_size = utf16val.length () * sizeof (uint16_t );
418
422
r = sqlite3_bind_blob (stmt.get (), 2 , utf16val.out (), val_size, SQLITE_STATIC);
419
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, false );
423
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_OK, Nothing< void >() );
420
424
421
425
r = sqlite3_step (stmt.get ());
422
426
if (r == SQLITE_CONSTRAINT) {
423
427
ThrowQuotaExceededException (env ()->context ());
424
- return false ;
428
+ return Nothing< void >() ;
425
429
}
426
430
427
- CHECK_ERROR_OR_THROW (env (), r, SQLITE_DONE, false );
428
- return true ;
431
+ CHECK_ERROR_OR_THROW (env (), r, SQLITE_DONE, Nothing< void >() );
432
+ return JustVoid () ;
429
433
}
430
434
431
435
static MaybeLocal<String> Uint32ToName (Local<Context> context, uint32_t index) {
@@ -453,12 +457,11 @@ static void GetItem(const FunctionCallbackInfo<Value>& info) {
453
457
return ;
454
458
}
455
459
456
- Local<Value> result = storage->Load (prop);
457
- if (result.IsEmpty ()) {
458
- info.GetReturnValue ().SetNull ();
459
- } else {
460
- info.GetReturnValue ().Set (result);
460
+ Local<Value> result;
461
+ if (!storage->Load (prop).ToLocal (&result)) {
462
+ return ;
461
463
}
464
+ info.GetReturnValue ().Set (result);
462
465
}
463
466
464
467
static void Key (const FunctionCallbackInfo<Value>& info) {
@@ -481,10 +484,8 @@ static void Key(const FunctionCallbackInfo<Value>& info) {
481
484
return ;
482
485
}
483
486
484
- Local<Value> result = storage->LoadKey (index );
485
- if (result.IsEmpty ()) {
486
- info.GetReturnValue ().SetNull ();
487
- } else {
487
+ Local<Value> result;
488
+ if (storage->LoadKey (index ).ToLocal (&result)) {
488
489
info.GetReturnValue ().Set (result);
489
490
}
490
491
}
@@ -555,12 +556,12 @@ static Intercepted StorageGetter(Local<Name> property,
555
556
556
557
Storage* storage;
557
558
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This (), Intercepted::kNo );
558
- Local<Value> result = storage-> Load (property) ;
559
+ Local<Value> result;
559
560
560
- if (result.IsEmpty ()) {
561
- info.GetReturnValue ().SetUndefined ();
562
- } else {
561
+ if (storage->Load (property).ToLocal (&result) && !result->IsNull ()) {
563
562
info.GetReturnValue ().Set (result);
563
+ } else {
564
+ info.GetReturnValue ().Set (Undefined (info.GetIsolate ()));
564
565
}
565
566
566
567
return Intercepted::kYes ;
@@ -572,7 +573,7 @@ static Intercepted StorageSetter(Local<Name> property,
572
573
Storage* storage;
573
574
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This (), Intercepted::kNo );
574
575
575
- if (storage->Store (property, value)) {
576
+ if (storage->Store (property, value). IsJust () ) {
576
577
info.GetReturnValue ().Set (value);
577
578
}
578
579
@@ -587,8 +588,8 @@ static Intercepted StorageQuery(Local<Name> property,
587
588
588
589
Storage* storage;
589
590
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This (), Intercepted::kNo );
590
- Local<Value> result = storage-> Load (property) ;
591
- if (result. IsEmpty ()) {
591
+ Local<Value> result;
592
+ if (!storage-> Load (property). ToLocal (&result) || result-> IsNull ()) {
592
593
return Intercepted::kNo ;
593
594
}
594
595
@@ -601,17 +602,19 @@ static Intercepted StorageDeleter(Local<Name> property,
601
602
Storage* storage;
602
603
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This (), Intercepted::kNo );
603
604
604
- if (storage->Remove (property)) {
605
- info.GetReturnValue ().Set (true );
606
- }
605
+ info.GetReturnValue ().Set (storage->Remove (property).IsJust ());
607
606
608
607
return Intercepted::kYes ;
609
608
}
610
609
611
610
static void StorageEnumerator (const PropertyCallbackInfo<Array>& info) {
612
611
Storage* storage;
613
612
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This ());
614
- info.GetReturnValue ().Set (storage->Enumerate ());
613
+ Local<Array> result;
614
+ if (!storage->Enumerate ().ToLocal (&result)) {
615
+ return ;
616
+ }
617
+ info.GetReturnValue ().Set (result);
615
618
}
616
619
617
620
static Intercepted StorageDefiner (Local<Name> property,
@@ -697,7 +700,11 @@ static Intercepted IndexedDefiner(uint32_t index,
697
700
static void StorageLengthGetter (const FunctionCallbackInfo<Value>& info) {
698
701
Storage* storage;
699
702
ASSIGN_OR_RETURN_UNWRAP (&storage, info.This ());
700
- info.GetReturnValue ().Set (storage->Length ());
703
+ Local<Value> result;
704
+ if (!storage->Length ().ToLocal (&result)) {
705
+ return ;
706
+ }
707
+ info.GetReturnValue ().Set (result);
701
708
}
702
709
703
710
static void Initialize (Local<Object> target,
0 commit comments