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: { \
@@ -2416,6 +2431,7 @@ StatementSync::~StatementSync() {
24162431void StatementSync::Finalize () {
24172432 sqlite3_finalize (statement_);
24182433 statement_ = nullptr ;
2434+ cached_column_names_.clear ();
24192435}
24202436
24212437inline bool StatementSync::IsFinalized () {
@@ -2599,7 +2615,40 @@ MaybeLocal<Name> StatementSync::ColumnNameToName(const int column) {
25992615 return MaybeLocal<Name>();
26002616 }
26012617
2602- return String::NewFromUtf8 (env ()->isolate (), col_name).As <Name>();
2618+ return String::NewFromUtf8 (
2619+ env ()->isolate (), col_name, NewStringType::kInternalized )
2620+ .As <Name>();
2621+ }
2622+
2623+ bool StatementSync::GetCachedColumnNames (LocalVector<Name>* keys) {
2624+ Isolate* isolate = env ()->isolate ();
2625+
2626+ int reprepare_count =
2627+ sqlite3_stmt_status (statement_, SQLITE_STMTSTATUS_REPREPARE, 0 );
2628+ if (reprepare_count != cached_column_names_reprepare_count_) {
2629+ cached_column_names_.clear ();
2630+ int num_cols = sqlite3_column_count (statement_);
2631+ if (num_cols == 0 ) {
2632+ cached_column_names_reprepare_count_ = reprepare_count;
2633+ return true ;
2634+ }
2635+ cached_column_names_.reserve (num_cols);
2636+ for (int i = 0 ; i < num_cols; ++i) {
2637+ Local<Name> key;
2638+ if (!ColumnNameToName (i).ToLocal (&key)) {
2639+ cached_column_names_.clear ();
2640+ return false ;
2641+ }
2642+ cached_column_names_.emplace_back (Global<Name>(isolate, key));
2643+ }
2644+ cached_column_names_reprepare_count_ = reprepare_count;
2645+ }
2646+
2647+ keys->reserve (cached_column_names_.size ());
2648+ for (const auto & name : cached_column_names_) {
2649+ keys->emplace_back (name.Get (isolate));
2650+ }
2651+ return true ;
26032652}
26042653
26052654MaybeLocal<Value> StatementExecutionHelper::ColumnToValue (Environment* env,
@@ -2621,7 +2670,9 @@ MaybeLocal<Name> StatementExecutionHelper::ColumnNameToName(Environment* env,
26212670 return MaybeLocal<Name>();
26222671 }
26232672
2624- return String::NewFromUtf8 (env->isolate (), col_name).As <Name>();
2673+ return String::NewFromUtf8 (
2674+ env->isolate (), col_name, NewStringType::kInternalized )
2675+ .As <Name>();
26252676}
26262677
26272678void StatementSync::MemoryInfo (MemoryTracker* tracker) const {}
@@ -3531,12 +3582,7 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
35313582 if (iter->stmt_ ->return_arrays_ ) {
35323583 row_value = Array::New (isolate, row_values.data (), row_values.size ());
35333584 } else {
3534- row_keys.reserve (num_cols);
3535- for (int i = 0 ; i < num_cols; ++i) {
3536- Local<Name> key;
3537- if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
3538- row_keys.emplace_back (key);
3539- }
3585+ if (!iter->stmt_ ->GetCachedColumnNames (&row_keys)) return ;
35403586
35413587 DCHECK_EQ (row_keys.size (), row_values.size ());
35423588 row_value = Object::New (
0 commit comments