@@ -24,6 +24,7 @@ using v8::BigInt;
24
24
using v8::Boolean;
25
25
using v8::ConstructorBehavior;
26
26
using v8::Context;
27
+ using v8::DictionaryTemplate;
27
28
using v8::DontDelete;
28
29
using v8::Exception;
29
30
using v8::Function;
@@ -119,6 +120,18 @@ using v8::Value;
119
120
} \
120
121
} while (0 )
121
122
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
+
122
135
inline MaybeLocal<Object> CreateSQLiteError (Isolate* isolate,
123
136
const char * message) {
124
137
Local<String> js_msg;
@@ -2231,58 +2244,35 @@ void StatementSync::Columns(const FunctionCallbackInfo<Value>& args) {
2231
2244
int num_cols = sqlite3_column_count (stmt->statement_ );
2232
2245
Isolate* isolate = env->isolate ();
2233
2246
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
+ }
2241
2254
2242
2255
cols.reserve (num_cols);
2243
2256
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)) {
2276
2273
return ;
2277
2274
}
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);
2286
2276
}
2287
2277
2288
2278
args.GetReturnValue ().Set (Array::New (isolate, cols.data (), cols.size ()));
@@ -2514,15 +2504,19 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
2514
2504
THROW_AND_RETURN_ON_BAD_STATE (
2515
2505
env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
2516
2506
Isolate* isolate = env->isolate ();
2517
- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2507
+
2508
+ auto iter_template = getLazyIterTemplate (env);
2518
2509
2519
2510
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
+ }
2526
2520
return ;
2527
2521
}
2528
2522
@@ -2531,12 +2525,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
2531
2525
CHECK_ERROR_OR_THROW (
2532
2526
env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE, void ());
2533
2527
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
+ }
2540
2534
return ;
2541
2535
}
2542
2536
@@ -2564,11 +2558,12 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
2564
2558
isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
2565
2559
}
2566
2560
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
+ }
2572
2567
}
2573
2568
2574
2569
void StatementSyncIterator::Return (const FunctionCallbackInfo<Value>& args) {
@@ -2581,14 +2576,15 @@ void StatementSyncIterator::Return(const FunctionCallbackInfo<Value>& args) {
2581
2576
2582
2577
sqlite3_reset (iter->stmt_ ->statement_ );
2583
2578
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)});
2587
2579
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
+ }
2592
2588
}
2593
2589
2594
2590
Session::Session (Environment* env,
0 commit comments