@@ -24,6 +24,7 @@ using v8::BigInt;
2424using  v8::Boolean;
2525using  v8::ConstructorBehavior;
2626using  v8::Context;
27+ using  v8::DictionaryTemplate;
2728using  v8::DontDelete;
2829using  v8::Exception;
2930using  v8::Function;
@@ -119,6 +120,18 @@ using v8::Value;
119120    }                                                                          \
120121  } while  (0 )
121122
123+ namespace  {
124+ Local<DictionaryTemplate> getLazyIterTemplate (Environment* env) {
125+   auto  iter_template = env->iter_template ();
126+   if  (iter_template.IsEmpty ()) {
127+     static  constexpr  std::string_view iter_keys[] = {" done"  , " value"  };
128+     iter_template = DictionaryTemplate::New (env->isolate (), iter_keys);
129+     env->set_iter_template (iter_template);
130+   }
131+   return  iter_template;
132+ }
133+ }  //  namespace
134+ 
122135inline  MaybeLocal<Object> CreateSQLiteError (Isolate* isolate,
123136                                            const  char * message) {
124137  Local<String> js_msg;
@@ -2231,58 +2244,35 @@ void StatementSync::Columns(const FunctionCallbackInfo<Value>& args) {
22312244  int  num_cols = sqlite3_column_count (stmt->statement_ );
22322245  Isolate* isolate = env->isolate ();
22332246  LocalVector<Value> cols (isolate);
2234-   LocalVector<Name>  col_keys (isolate, 
2235-                              {env-> column_string (), 
2236-                               env-> database_string (), 
2237-                               env-> name_string (), 
2238-                               env-> table_string (), 
2239-                                env->type_string ()} );
2240-   Local<Value> value; 
2247+   auto  sqlite_column_template = env-> sqlite_column_template (); 
2248+   if  (sqlite_column_template. IsEmpty ()) { 
2249+     static   constexpr  std::string_view col_keys[] = { 
2250+         " column " ,  " database " ,  " name " ,  " table " ,  " type " }; 
2251+     sqlite_column_template =  DictionaryTemplate::New (isolate, col_keys); 
2252+     env->set_sqlite_column_template (sqlite_column_template );
2253+   } 
22412254
22422255  cols.reserve (num_cols);
22432256  for  (int  i = 0 ; i < num_cols; ++i) {
2244-     LocalVector<Value> col_values (isolate);
2245-     col_values.reserve (col_keys.size ());
2246- 
2247-     if  (!NullableSQLiteStringToValue (
2248-              isolate, sqlite3_column_origin_name (stmt->statement_ , i))
2249-              .ToLocal (&value)) {
2250-       return ;
2251-     }
2252-     col_values.emplace_back (value);
2253- 
2254-     if  (!NullableSQLiteStringToValue (
2255-              isolate, sqlite3_column_database_name (stmt->statement_ , i))
2256-              .ToLocal (&value)) {
2257-       return ;
2258-     }
2259-     col_values.emplace_back (value);
2260- 
2261-     if  (!stmt->ColumnNameToName (i).ToLocal (&value)) {
2262-       return ;
2263-     }
2264-     col_values.emplace_back (value);
2265- 
2266-     if  (!NullableSQLiteStringToValue (
2267-              isolate, sqlite3_column_table_name (stmt->statement_ , i))
2268-              .ToLocal (&value)) {
2269-       return ;
2270-     }
2271-     col_values.emplace_back (value);
2272- 
2273-     if  (!NullableSQLiteStringToValue (
2274-              isolate, sqlite3_column_decltype (stmt->statement_ , i))
2275-              .ToLocal (&value)) {
2257+     MaybeLocal<Value> values[] = {
2258+         NullableSQLiteStringToValue (
2259+             isolate, sqlite3_column_origin_name (stmt->statement_ , i)),
2260+         NullableSQLiteStringToValue (
2261+             isolate, sqlite3_column_database_name (stmt->statement_ , i)),
2262+         stmt->ColumnNameToName (i),
2263+         NullableSQLiteStringToValue (
2264+             isolate, sqlite3_column_table_name (stmt->statement_ , i)),
2265+         NullableSQLiteStringToValue (
2266+             isolate, sqlite3_column_decltype (stmt->statement_ , i)),
2267+     };
2268+ 
2269+     Local<Object> col;
2270+     if  (!NewDictionaryInstanceNullProto (
2271+              env->context (), sqlite_column_template, values)
2272+              .ToLocal (&col)) {
22762273      return ;
22772274    }
2278-     col_values.emplace_back (value);
2279- 
2280-     Local<Object> column = Object::New (isolate,
2281-                                        Null (isolate),
2282-                                        col_keys.data (),
2283-                                        col_values.data (),
2284-                                        col_keys.size ());
2285-     cols.emplace_back (column);
2275+     cols.emplace_back (col);
22862276  }
22872277
22882278  args.GetReturnValue ().Set (Array::New (isolate, cols.data (), cols.size ()));
@@ -2514,15 +2504,19 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
25142504  THROW_AND_RETURN_ON_BAD_STATE (
25152505      env, iter->stmt_ ->IsFinalized (), " statement has been finalized"  );
25162506  Isolate* isolate = env->isolate ();
2517-   LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2507+ 
2508+   auto  iter_template = getLazyIterTemplate (env);
25182509
25192510  if  (iter->done_ ) {
2520-     LocalVector<Value> values (isolate,
2521-                               {Boolean::New (isolate, true ), Null (isolate)});
2522-     DCHECK_EQ (values.size (), keys.size ());
2523-     Local<Object> result = Object::New (
2524-         isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2525-     args.GetReturnValue ().Set (result);
2511+     MaybeLocal<Value> values[]{
2512+         Boolean::New (isolate, true ),
2513+         Null (isolate),
2514+     };
2515+     Local<Object> result;
2516+     if  (NewDictionaryInstanceNullProto (env->context (), iter_template, values)
2517+             .ToLocal (&result)) {
2518+       args.GetReturnValue ().Set (result);
2519+     }
25262520    return ;
25272521  }
25282522
@@ -2531,12 +2525,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
25312525    CHECK_ERROR_OR_THROW (
25322526        env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE, void ());
25332527    sqlite3_reset (iter->stmt_ ->statement_ );
2534-     LocalVector <Value> values (isolate,
2535-                               { Boolean::New (isolate,  true ),  Null (isolate)}) ;
2536-     DCHECK_EQ (values. size ( ), keys. size ()); 
2537-     Local<Object> result =  Object::New ( 
2538-         isolate,  Null (isolate), keys. data (), values. data (), keys. size () );
2539-     args. GetReturnValue (). Set (result); 
2528+     MaybeLocal <Value> values[] = { Boolean::New (isolate,  true ),  Null (isolate)}; 
2529+     Local<Object> result ;
2530+     if  ( NewDictionaryInstanceNullProto (env-> context ( ), iter_template, values) 
2531+             . ToLocal (&result)) { 
2532+       args. GetReturnValue (). Set (result );
2533+     } 
25402534    return ;
25412535  }
25422536
@@ -2564,11 +2558,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
25642558        isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
25652559  }
25662560
2567-   LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row_value});
2568-   DCHECK_EQ (keys.size (), values.size ());
2569-   Local<Object> result = Object::New (
2570-       isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2571-   args.GetReturnValue ().Set (result);
2561+   MaybeLocal<Value> values[] = {Boolean::New (isolate, false ), row_value};
2562+   Local<Object> result;
2563+   if  (NewDictionaryInstanceNullProto (env->context (), iter_template, values)
2564+           .ToLocal (&result)) {
2565+     args.GetReturnValue ().Set (result);
2566+   }
25722567}
25732568
25742569void  StatementSyncIterator::Return (const  FunctionCallbackInfo<Value>& args) {
@@ -2581,14 +2576,15 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
25812576
25822577  sqlite3_reset (iter->stmt_ ->statement_ );
25832578  iter->done_  = true ;
2584-   LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2585-   LocalVector<Value> values (isolate,
2586-                             {Boolean::New (isolate, true ), Null (isolate)});
25872579
2588-   DCHECK_EQ (keys.size (), values.size ());
2589-   Local<Object> result = Object::New (
2590-       isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2591-   args.GetReturnValue ().Set (result);
2580+   auto  iter_template = getLazyIterTemplate (env);
2581+   MaybeLocal<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
2582+ 
2583+   Local<Object> result;
2584+   if  (NewDictionaryInstanceNullProto (env->context (), iter_template, values)
2585+           .ToLocal (&result)) {
2586+     args.GetReturnValue ().Set (result);
2587+   }
25922588}
25932589
25942590Session::Session (Environment* env,
0 commit comments