From 55461be05f5420ce5e0338287fe38963aa7dcc3a Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Thu, 18 Jul 2024 16:41:49 -0400 Subject: [PATCH] src: refactor webstorage implementation PR-URL: https://github.com/nodejs/node/pull/53876 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_webstorage.cc | 69 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc index 798a07c5b7a5b6..6c3e19db1dbffc 100644 --- a/src/node_webstorage.cc +++ b/src/node_webstorage.cc @@ -29,7 +29,6 @@ using v8::Maybe; using v8::MaybeLocal; using v8::Name; using v8::NamedPropertyHandlerConfiguration; -using v8::Null; using v8::Object; using v8::PropertyAttribute; using v8::PropertyCallbackInfo; @@ -40,7 +39,7 @@ using v8::Uint32; using v8::Value; #define THROW_SQLITE_ERROR(env, r) \ - node::THROW_ERR_INVALID_STATE((env), sqlite3_errstr((r))) + THROW_ERR_INVALID_STATE((env), sqlite3_errstr((r))) #define CHECK_ERROR_OR_THROW(env, expr, expected, ret) \ do { \ @@ -80,7 +79,7 @@ static void ThrowQuotaExceededException(Local context) { Storage::Storage(Environment* env, Local object, Local location) : BaseObject(env, object) { MakeWeak(); - node::Utf8Value utf8_location(env->isolate(), location); + Utf8Value utf8_location(env->isolate(), location); symbols_.Reset(env->isolate(), Map::New(env->isolate())); db_ = nullptr; location_ = utf8_location.ToString(); @@ -97,9 +96,9 @@ void Storage::MemoryInfo(MemoryTracker* tracker) const { bool Storage::Open() { static const int kCurrentSchemaVersion = 1; - static const char get_schema_version_sql[] = + static constexpr std::string_view get_schema_version_sql = "SELECT schema_version FROM nodejs_webstorage_state"; - static const char init_sql_v0[] = + static constexpr std::string_view init_sql_v0 = "PRAGMA encoding = 'UTF-16le';" "PRAGMA busy_timeout = 3000;" "PRAGMA journal_mode = WAL;" @@ -165,13 +164,14 @@ bool Storage::Open() { int r = sqlite3_open(location_.c_str(), &db); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); - r = sqlite3_exec(db, init_sql_v0, 0, 0, nullptr); + r = sqlite3_exec(db, init_sql_v0.data(), 0, 0, nullptr); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); // Get the current schema version, used to determine schema migrations. sqlite3_stmt* s = nullptr; - r = sqlite3_prepare_v2(db, get_schema_version_sql, -1, &s, 0); - r = sqlite3_exec(db, init_sql_v0, 0, 0, nullptr); + r = sqlite3_prepare_v2( + db, get_schema_version_sql.data(), get_schema_version_sql.size(), &s, 0); + r = sqlite3_exec(db, init_sql_v0.data(), 0, 0, nullptr); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); auto stmt = stmt_unique_ptr(s); CHECK_ERROR_OR_THROW(env(), sqlite3_step(stmt.get()), SQLITE_ROW, false); @@ -180,7 +180,7 @@ bool Storage::Open() { stmt = nullptr; // Force finalization. if (schema_version > kCurrentSchemaVersion) { - node::THROW_ERR_INVALID_STATE( + THROW_ERR_INVALID_STATE( env(), "localStorage was created with a newer version of Node.js"); return false; } @@ -217,10 +217,13 @@ void Storage::Clear() { return; } - static const char sql[] = "DELETE FROM nodejs_webstorage"; + static constexpr std::string_view sql = "DELETE FROM nodejs_webstorage"; sqlite3_stmt* s = nullptr; CHECK_ERROR_OR_THROW( - env(), sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0), SQLITE_OK, void()); + env(), + sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0), + SQLITE_OK, + void()); auto stmt = stmt_unique_ptr(s); CHECK_ERROR_OR_THROW(env(), sqlite3_step(stmt.get()), SQLITE_DONE, void()); } @@ -230,9 +233,9 @@ Local Storage::Enumerate() { return Local(); } - static const char sql[] = "SELECT key FROM nodejs_webstorage"; + static constexpr std::string_view sql = "SELECT key FROM nodejs_webstorage"; sqlite3_stmt* s = nullptr; - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); auto stmt = stmt_unique_ptr(s); std::vector> values; @@ -253,12 +256,13 @@ Local Storage::Enumerate() { Local Storage::Length() { if (!Open()) { - return Local(); + return {}; } - static const char sql[] = "SELECT count(*) FROM nodejs_webstorage"; + static constexpr std::string_view sql = + "SELECT count(*) FROM nodejs_webstorage"; sqlite3_stmt* s = nullptr; - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); auto stmt = stmt_unique_ptr(s); CHECK_ERROR_OR_THROW( @@ -276,16 +280,16 @@ Local Storage::Load(Local key) { } if (!Open()) { - return Local(); + return {}; } - static const char sql[] = + static constexpr std::string_view sql = "SELECT value FROM nodejs_webstorage WHERE key = ? LIMIT 1"; sqlite3_stmt* s = nullptr; - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); auto stmt = stmt_unique_ptr(s); - node::TwoByteValue utf16key(env()->isolate(), key); + TwoByteValue utf16key(env()->isolate(), key); auto key_size = utf16key.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 1, utf16key.out(), key_size, SQLITE_STATIC); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); @@ -312,10 +316,10 @@ Local Storage::LoadKey(const int index) { return Local(); } - static const char sql[] = + static constexpr std::string_view sql = "SELECT key FROM nodejs_webstorage LIMIT 1 OFFSET ?"; sqlite3_stmt* s = nullptr; - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); auto stmt = stmt_unique_ptr(s); r = sqlite3_bind_int(stmt.get(), 1, index); @@ -350,12 +354,13 @@ bool Storage::Remove(Local key) { return false; } - static const char sql[] = "DELETE FROM nodejs_webstorage WHERE key = ?"; + static constexpr std::string_view sql = + "DELETE FROM nodejs_webstorage WHERE key = ?"; sqlite3_stmt* s = nullptr; - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); auto stmt = stmt_unique_ptr(s); - node::TwoByteValue utf16key(env()->isolate(), key); + TwoByteValue utf16key(env()->isolate(), key); auto key_size = utf16key.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 1, utf16key.out(), key_size, SQLITE_STATIC); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); @@ -379,14 +384,14 @@ bool Storage::Store(Local key, Local value) { return false; } - static const char sql[] = + static constexpr std::string_view sql = "INSERT INTO nodejs_webstorage (key, value) VALUES (?, ?)" " ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value" " WHERE EXCLUDED.key = key"; sqlite3_stmt* s = nullptr; - node::TwoByteValue utf16key(env()->isolate(), key); - node::TwoByteValue utf16val(env()->isolate(), val); - int r = sqlite3_prepare_v2(db_.get(), sql, -1, &s, 0); + TwoByteValue utf16key(env()->isolate(), key); + TwoByteValue utf16val(env()->isolate(), val); + int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); auto stmt = stmt_unique_ptr(s); auto key_size = utf16key.length() * sizeof(uint16_t); @@ -435,7 +440,7 @@ static void GetItem(const FunctionCallbackInfo& info) { Local result = storage->Load(prop); if (result.IsEmpty()) { - info.GetReturnValue().Set(Null(env->isolate())); + info.GetReturnValue().SetNull(); } else { info.GetReturnValue().Set(result); } @@ -457,13 +462,13 @@ static void Key(const FunctionCallbackInfo& info) { } if (index < 0) { - info.GetReturnValue().Set(Null(env->isolate())); + info.GetReturnValue().SetNull(); return; } Local result = storage->LoadKey(index); if (result.IsEmpty()) { - info.GetReturnValue().Set(Null(env->isolate())); + info.GetReturnValue().SetNull(); } else { info.GetReturnValue().Set(result); }