@@ -25,6 +25,10 @@ using v8::FunctionTemplate;
2525using v8::Integer;
2626using v8::Isolate;
2727using v8::Local;
28+ using v8::LocalVector;
29+ using v8::MaybeLocal;
30+ using v8::Name;
31+ using v8::Null;
2832using v8::Number;
2933using v8::Object;
3034using v8::String;
@@ -405,7 +409,7 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
405409 return true ;
406410}
407411
408- Local <Value> StatementSync::ColumnToValue (const int column) {
412+ MaybeLocal <Value> StatementSync::ColumnToValue (const int column) {
409413 switch (sqlite3_column_type (statement_, column)) {
410414 case SQLITE_INTEGER: {
411415 sqlite3_int64 value = sqlite3_column_int64 (statement_, column);
@@ -419,7 +423,7 @@ Local<Value> StatementSync::ColumnToValue(const int column) {
419423 " represented as a JavaScript number: %" PRId64,
420424 column,
421425 value);
422- return Local <Value>();
426+ return MaybeLocal <Value>();
423427 }
424428 }
425429 case SQLITE_FLOAT:
@@ -428,14 +432,10 @@ Local<Value> StatementSync::ColumnToValue(const int column) {
428432 case SQLITE_TEXT: {
429433 const char * value = reinterpret_cast <const char *>(
430434 sqlite3_column_text (statement_, column));
431- Local<Value> val;
432- if (!String::NewFromUtf8 (env ()->isolate (), value).ToLocal (&val)) {
433- return Local<Value>();
434- }
435- return val;
435+ return String::NewFromUtf8 (env ()->isolate (), value).As <Value>();
436436 }
437437 case SQLITE_NULL:
438- return v8:: Null (env ()->isolate ());
438+ return Null (env ()->isolate ());
439439 case SQLITE_BLOB: {
440440 size_t size =
441441 static_cast <size_t >(sqlite3_column_bytes (statement_, column));
@@ -451,19 +451,15 @@ Local<Value> StatementSync::ColumnToValue(const int column) {
451451 }
452452}
453453
454- Local<Value > StatementSync::ColumnNameToValue (const int column) {
454+ MaybeLocal<Name > StatementSync::ColumnNameToName (const int column) {
455455 const char * col_name = sqlite3_column_name (statement_, column);
456456 if (col_name == nullptr ) {
457457 node::THROW_ERR_INVALID_STATE (
458458 env (), " Cannot get name of column %d" , column);
459- return Local<Value >();
459+ return MaybeLocal<Name >();
460460 }
461461
462- Local<String> key;
463- if (!String::NewFromUtf8 (env ()->isolate (), col_name).ToLocal (&key)) {
464- return Local<Value>();
465- }
466- return key;
462+ return String::NewFromUtf8 (env ()->isolate (), col_name).As <Name>();
467463}
468464
469465void StatementSync::MemoryInfo (MemoryTracker* tracker) const {}
@@ -474,38 +470,40 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
474470 Environment* env = Environment::GetCurrent (args);
475471 THROW_AND_RETURN_ON_BAD_STATE (
476472 env, stmt->IsFinalized (), " statement has been finalized" );
473+ Isolate* isolate = env->isolate ();
477474 int r = sqlite3_reset (stmt->statement_ );
478- CHECK_ERROR_OR_THROW (
479- env->isolate (), stmt->db_ ->Connection (), r, SQLITE_OK, void ());
475+ CHECK_ERROR_OR_THROW (isolate, stmt->db_ ->Connection (), r, SQLITE_OK, void ());
480476
481477 if (!stmt->BindParams (args)) {
482478 return ;
483479 }
484480
485481 auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
486482 int num_cols = sqlite3_column_count (stmt->statement_ );
487- std::vector<Local< Value>> rows;
483+ LocalVector< Value> rows (isolate) ;
488484 while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
489- Local<Object> row = Object::New (env->isolate ());
485+ LocalVector<Name> row_keys (isolate);
486+ row_keys.reserve (num_cols);
487+ LocalVector<Value> row_values (isolate);
488+ row_values.reserve (num_cols);
490489
491490 for (int i = 0 ; i < num_cols; ++i) {
492- Local<Value> key = stmt->ColumnNameToValue (i);
493- if (key.IsEmpty ()) return ;
494- Local<Value> val = stmt->ColumnToValue (i);
495- if (val.IsEmpty ()) return ;
496-
497- if (row->Set (env->context (), key, val).IsNothing ()) {
498- return ;
499- }
491+ Local<Name> key;
492+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
493+ Local<Value> val;
494+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
495+ row_keys.emplace_back (key);
496+ row_values.emplace_back (val);
500497 }
501498
499+ Local<Object> row = Object::New (
500+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
502501 rows.emplace_back (row);
503502 }
504503
505504 CHECK_ERROR_OR_THROW (
506- env->isolate (), stmt->db_ ->Connection (), r, SQLITE_DONE, void ());
507- args.GetReturnValue ().Set (
508- Array::New (env->isolate (), rows.data (), rows.size ()));
505+ isolate, stmt->db_ ->Connection (), r, SQLITE_DONE, void ());
506+ args.GetReturnValue ().Set (Array::New (isolate, rows.data (), rows.size ()));
509507}
510508
511509void StatementSync::Get (const FunctionCallbackInfo<Value>& args) {
@@ -514,9 +512,9 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
514512 Environment* env = Environment::GetCurrent (args);
515513 THROW_AND_RETURN_ON_BAD_STATE (
516514 env, stmt->IsFinalized (), " statement has been finalized" );
515+ Isolate* isolate = env->isolate ();
517516 int r = sqlite3_reset (stmt->statement_ );
518- CHECK_ERROR_OR_THROW (
519- env->isolate (), stmt->db_ ->Connection (), r, SQLITE_OK, void ());
517+ CHECK_ERROR_OR_THROW (isolate, stmt->db_ ->Connection (), r, SQLITE_OK, void ());
520518
521519 if (!stmt->BindParams (args)) {
522520 return ;
@@ -526,7 +524,7 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
526524 r = sqlite3_step (stmt->statement_ );
527525 if (r == SQLITE_DONE) return ;
528526 if (r != SQLITE_ROW) {
529- THROW_ERR_SQLITE_ERROR (env-> isolate () , stmt->db_ ->Connection ());
527+ THROW_ERR_SQLITE_ERROR (isolate, stmt->db_ ->Connection ());
530528 return ;
531529 }
532530
@@ -535,19 +533,23 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
535533 return ;
536534 }
537535
538- Local<Object> result = Object::New (env->isolate ());
536+ LocalVector<Name> keys (isolate);
537+ keys.reserve (num_cols);
538+ LocalVector<Value> values (isolate);
539+ values.reserve (num_cols);
539540
540541 for (int i = 0 ; i < num_cols; ++i) {
541- Local<Value> key = stmt->ColumnNameToValue (i);
542- if (key.IsEmpty ()) return ;
543- Local<Value> val = stmt->ColumnToValue (i);
544- if (val.IsEmpty ()) return ;
545-
546- if (result->Set (env->context (), key, val).IsNothing ()) {
547- return ;
548- }
542+ Local<Name> key;
543+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
544+ Local<Value> val;
545+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
546+ keys.emplace_back (key);
547+ values.emplace_back (val);
549548 }
550549
550+ Local<Object> result =
551+ Object::New (isolate, Null (isolate), keys.data (), values.data (), num_cols);
552+
551553 args.GetReturnValue ().Set (result);
552554}
553555
@@ -676,7 +678,7 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
676678 if (tmpl.IsEmpty ()) {
677679 Isolate* isolate = env->isolate ();
678680 tmpl = NewFunctionTemplate (isolate, IllegalConstructor);
679- tmpl->SetClassName (FIXED_ONE_BYTE_STRING (env-> isolate () , " StatementSync" ));
681+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " StatementSync" ));
680682 tmpl->InstanceTemplate ()->SetInternalFieldCount (
681683 StatementSync::kInternalFieldCount );
682684 SetProtoMethod (isolate, tmpl, " all" , StatementSync::All);
0 commit comments