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"
@@ -55,6 +56,19 @@ using v8::TryCatch;
5556using v8::Uint8Array;
5657using v8::Value;
5758
59+ inline MaybeLocal<String> Utf8StringMaybeOneByte (Isolate* isolate,
60+ const char * data,
61+ size_t length) {
62+ int len = static_cast <int >(length);
63+ if (simdutf::validate_ascii (data, length)) {
64+ return String::NewFromOneByte (isolate,
65+ reinterpret_cast <const uint8_t *>(data),
66+ NewStringType::kNormal ,
67+ len);
68+ }
69+ return String::NewFromUtf8 (isolate, data, NewStringType::kNormal , len);
70+ }
71+
5872#define CHECK_ERROR_OR_THROW (isolate, db, expr, expected, ret ) \
5973 do { \
6074 int r_ = (expr); \
@@ -97,7 +111,8 @@ using v8::Value;
97111 case SQLITE_TEXT: { \
98112 const char * v = \
99113 reinterpret_cast <const char *>(sqlite3_##from##_text (__VA_ARGS__)); \
100- (result) = String::NewFromUtf8 ((isolate), v).As <Value>(); \
114+ int v_len = sqlite3_##from##_bytes (__VA_ARGS__); \
115+ (result) = Utf8StringMaybeOneByte ((isolate), v, v_len).As <Value>(); \
101116 break ; \
102117 } \
103118 case SQLITE_NULL: { \
@@ -2147,6 +2162,7 @@ StatementSync::~StatementSync() {
21472162void StatementSync::Finalize () {
21482163 sqlite3_finalize (statement_);
21492164 statement_ = nullptr ;
2165+ cached_column_names_.clear ();
21502166}
21512167
21522168inline bool StatementSync::IsFinalized () {
@@ -2325,7 +2341,40 @@ MaybeLocal<Name> StatementSync::ColumnNameToName(const int column) {
23252341 return MaybeLocal<Name>();
23262342 }
23272343
2328- return String::NewFromUtf8 (env ()->isolate (), col_name).As <Name>();
2344+ return String::NewFromUtf8 (
2345+ env ()->isolate (), col_name, NewStringType::kInternalized )
2346+ .As <Name>();
2347+ }
2348+
2349+ bool StatementSync::GetCachedColumnNames (LocalVector<Name>* keys) {
2350+ Isolate* isolate = env ()->isolate ();
2351+
2352+ int reprepare_count =
2353+ sqlite3_stmt_status (statement_, SQLITE_STMTSTATUS_REPREPARE, 0 );
2354+ if (reprepare_count != cached_column_names_reprepare_count_) {
2355+ cached_column_names_.clear ();
2356+ int num_cols = sqlite3_column_count (statement_);
2357+ if (num_cols == 0 ) {
2358+ cached_column_names_reprepare_count_ = reprepare_count;
2359+ return true ;
2360+ }
2361+ cached_column_names_.reserve (num_cols);
2362+ for (int i = 0 ; i < num_cols; ++i) {
2363+ Local<Name> key;
2364+ if (!ColumnNameToName (i).ToLocal (&key)) {
2365+ cached_column_names_.clear ();
2366+ return false ;
2367+ }
2368+ cached_column_names_.emplace_back (Global<Name>(isolate, key));
2369+ }
2370+ cached_column_names_reprepare_count_ = reprepare_count;
2371+ }
2372+
2373+ keys->reserve (cached_column_names_.size ());
2374+ for (const auto & name : cached_column_names_) {
2375+ keys->emplace_back (name.Get (isolate));
2376+ }
2377+ return true ;
23292378}
23302379
23312380MaybeLocal<Value> StatementExecutionHelper::ColumnToValue (Environment* env,
@@ -2347,7 +2396,9 @@ MaybeLocal<Name> StatementExecutionHelper::ColumnNameToName(Environment* env,
23472396 return MaybeLocal<Name>();
23482397 }
23492398
2350- return String::NewFromUtf8 (env->isolate (), col_name).As <Name>();
2399+ return String::NewFromUtf8 (
2400+ env->isolate (), col_name, NewStringType::kInternalized )
2401+ .As <Name>();
23512402}
23522403
23532404void StatementSync::MemoryInfo (MemoryTracker* tracker) const {}
@@ -3251,12 +3302,7 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
32513302 if (iter->stmt_ ->return_arrays_ ) {
32523303 row_value = Array::New (isolate, row_values.data (), row_values.size ());
32533304 } else {
3254- row_keys.reserve (num_cols);
3255- for (int i = 0 ; i < num_cols; ++i) {
3256- Local<Name> key;
3257- if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
3258- row_keys.emplace_back (key);
3259- }
3305+ if (!iter->stmt_ ->GetCachedColumnNames (&row_keys)) return ;
32603306
32613307 DCHECK_EQ (row_keys.size (), row_values.size ());
32623308 row_value = Object::New (
0 commit comments