88#include " node_errors.h"
99#include " node_mem-inl.h"
1010#include " node_url.h"
11+ #include " simdutf.h"
1112#include " sqlite3.h"
1213#include " threadpoolwork-inl.h"
1314#include " util-inl.h"
@@ -63,6 +64,19 @@ using v8::TryCatch;
6364using v8::Uint8Array;
6465using v8::Value;
6566
67+ inline MaybeLocal<String> Utf8StringMaybeOneByte (Isolate* isolate,
68+ const char * data,
69+ size_t length) {
70+ int len = static_cast <int >(length);
71+ if (simdutf::validate_ascii (data, length)) {
72+ return String::NewFromOneByte (isolate,
73+ reinterpret_cast <const uint8_t *>(data),
74+ NewStringType::kNormal ,
75+ len);
76+ }
77+ return String::NewFromUtf8 (isolate, data, NewStringType::kNormal , len);
78+ }
79+
6680#define CHECK_ERROR_OR_THROW (isolate, db, expr, expected, ret ) \
6781 do { \
6882 int r_ = (expr); \
@@ -105,7 +119,8 @@ using v8::Value;
105119 case SQLITE_TEXT: { \
106120 const char * v = \
107121 reinterpret_cast <const char *>(sqlite3_##from##_text (__VA_ARGS__)); \
108- (result) = String::NewFromUtf8 ((isolate), v).As <Value>(); \
122+ int v_len = sqlite3_##from##_bytes (__VA_ARGS__); \
123+ (result) = Utf8StringMaybeOneByte ((isolate), v, v_len).As <Value>(); \
109124 break ; \
110125 } \
111126 case SQLITE_NULL: { \
@@ -2415,6 +2430,7 @@ StatementSync::~StatementSync() {
24152430void StatementSync::Finalize () {
24162431 sqlite3_finalize (statement_);
24172432 statement_ = nullptr ;
2433+ cached_column_names_.clear ();
24182434}
24192435
24202436inline bool StatementSync::IsFinalized () {
@@ -2598,7 +2614,40 @@ MaybeLocal<Name> StatementSync::ColumnNameToName(const int column) {
25982614 return MaybeLocal<Name>();
25992615 }
26002616
2601- return String::NewFromUtf8 (env ()->isolate (), col_name).As <Name>();
2617+ return String::NewFromUtf8 (
2618+ env ()->isolate (), col_name, NewStringType::kInternalized )
2619+ .As <Name>();
2620+ }
2621+
2622+ bool StatementSync::GetCachedColumnNames (LocalVector<Name>* keys) {
2623+ Isolate* isolate = env ()->isolate ();
2624+
2625+ int reprepare_count =
2626+ sqlite3_stmt_status (statement_, SQLITE_STMTSTATUS_REPREPARE, 0 );
2627+ if (reprepare_count != cached_column_names_reprepare_count_) {
2628+ cached_column_names_.clear ();
2629+ int num_cols = sqlite3_column_count (statement_);
2630+ if (num_cols == 0 ) {
2631+ cached_column_names_reprepare_count_ = reprepare_count;
2632+ return true ;
2633+ }
2634+ cached_column_names_.reserve (num_cols);
2635+ for (int i = 0 ; i < num_cols; ++i) {
2636+ Local<Name> key;
2637+ if (!ColumnNameToName (i).ToLocal (&key)) {
2638+ cached_column_names_.clear ();
2639+ return false ;
2640+ }
2641+ cached_column_names_.emplace_back (Global<Name>(isolate, key));
2642+ }
2643+ cached_column_names_reprepare_count_ = reprepare_count;
2644+ }
2645+
2646+ keys->reserve (cached_column_names_.size ());
2647+ for (const auto & name : cached_column_names_) {
2648+ keys->emplace_back (name.Get (isolate));
2649+ }
2650+ return true ;
26022651}
26032652
26042653MaybeLocal<Value> StatementExecutionHelper::ColumnToValue (Environment* env,
@@ -2620,7 +2669,9 @@ MaybeLocal<Name> StatementExecutionHelper::ColumnNameToName(Environment* env,
26202669 return MaybeLocal<Name>();
26212670 }
26222671
2623- return String::NewFromUtf8 (env->isolate (), col_name).As <Name>();
2672+ return String::NewFromUtf8 (
2673+ env->isolate (), col_name, NewStringType::kInternalized )
2674+ .As <Name>();
26242675}
26252676
26262677void StatementSync::MemoryInfo (MemoryTracker* tracker) const {}
@@ -3530,12 +3581,7 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
35303581 if (iter->stmt_ ->return_arrays_ ) {
35313582 row_value = Array::New (isolate, row_values.data (), row_values.size ());
35323583 } else {
3533- row_keys.reserve (num_cols);
3534- for (int i = 0 ; i < num_cols; ++i) {
3535- Local<Name> key;
3536- if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
3537- row_keys.emplace_back (key);
3538- }
3584+ if (!iter->stmt_ ->GetCachedColumnNames (&row_keys)) return ;
35393585
35403586 DCHECK_EQ (row_keys.size (), row_values.size ());
35413587 row_value = Object::New (
0 commit comments