Repository: nodejs/node
Pull request: sqlite: make `SQLTagStore.prototype.size` a getter

As implemented, `.db` and `.capacity` are getters, and `.size` is a callable method. There's no reason for this inconsistency, so change `.size` to a getter.

Drive-by changes while making alterations to the class template: the `FunctionCallbackInfo` parameter for SQLTagStore member functions was variably labelled `args` or `info`, and wasn't consistent with the header either. Use the canonical `args`.


Changed files:
filename: doc/api/sqlite.md
patch: @@ -1076,13 +1076,17 @@ Executes the given SQL query, which is expected to not return any rows (e.g., IN
 This function is intended to be used as a template literal tag, not to be
 called directly.
 
-### `sqlTagStore.size()`
+### `sqlTagStore.size`
 
 <!-- YAML
 added: v24.9.0
+changes:
+  - version: REPLACEME
+    pr-url: https://github.com/nodejs/node/pull/60246
+    description: Changed from a method to a getter.
 -->
 
-* Returns: {integer} The number of prepared statements currently in the cache.
+* Type: {integer}
 
 A read-only property that returns the number of prepared statements currently in the cache.
 

filename: src/node_sqlite.cc
patch: @@ -2700,11 +2700,13 @@ Local<FunctionTemplate> SQLTagStore::GetConstructorTemplate(Environment* env) {
   SetProtoMethod(isolate, tmpl, "iterate", Iterate);
   SetProtoMethod(isolate, tmpl, "run", Run);
   SetProtoMethod(isolate, tmpl, "clear", Clear);
-  SetProtoMethod(isolate, tmpl, "size", Size);
-  SetSideEffectFreeGetter(
-      isolate, tmpl, FIXED_ONE_BYTE_STRING(isolate, "capacity"), Capacity);
+  SetSideEffectFreeGetter(isolate,
+                          tmpl,
+                          FIXED_ONE_BYTE_STRING(isolate, "capacity"),
+                          CapacityGetter);
   SetSideEffectFreeGetter(
       isolate, tmpl, FIXED_ONE_BYTE_STRING(isolate, "db"), DatabaseGetter);
+  SetSideEffectFreeGetter(isolate, tmpl, env->size_string(), SizeGetter);
   return tmpl;
 }
 
@@ -2720,32 +2722,44 @@ BaseObjectPtr<SQLTagStore> SQLTagStore::Create(
   return MakeBaseObject<SQLTagStore>(env, obj, std::move(database), capacity);
 }
 
+void SQLTagStore::CapacityGetter(const FunctionCallbackInfo<Value>& args) {
+  SQLTagStore* store;
+  ASSIGN_OR_RETURN_UNWRAP(&store, args.This());
+  args.GetReturnValue().Set(static_cast<double>(store->sql_tags_.Capacity()));
+}
+
 void SQLTagStore::DatabaseGetter(const FunctionCallbackInfo<Value>& args) {
   SQLTagStore* store;
   ASSIGN_OR_RETURN_UNWRAP(&store, args.This());
   args.GetReturnValue().Set(store->database_->object());
 }
 
-void SQLTagStore::Run(const FunctionCallbackInfo<Value>& info) {
+void SQLTagStore::SizeGetter(const FunctionCallbackInfo<Value>& args) {
+  SQLTagStore* store;
+  ASSIGN_OR_RETURN_UNWRAP(&store, args.This());
+  args.GetReturnValue().Set(static_cast<double>(store->sql_tags_.Size()));
+}
+
+void SQLTagStore::Run(const FunctionCallbackInfo<Value>& args) {
   SQLTagStore* session;
-  ASSIGN_OR_RETURN_UNWRAP(&session, info.This());
-  Environment* env = Environment::GetCurrent(info);
+  ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
+  Environment* env = Environment::GetCurrent(args);
 
   THROW_AND_RETURN_ON_BAD_STATE(
       env, !session->database_->IsOpen(), "database is not open");
 
-  BaseObjectPtr<StatementSync> stmt = PrepareStatement(info);
+  BaseObjectPtr<StatementSync> stmt = PrepareStatement(args);
 
   if (!stmt) {
     return;
   }
 
-  uint32_t n_params = info.Length() - 1;
+  uint32_t n_params = args.Length() - 1;
   int r = sqlite3_reset(stmt->statement_);
   CHECK_ERROR_OR_THROW(env->isolate(), stmt->db_.get(), r, SQLITE_OK, void());
   int param_count = sqlite3_bind_parameter_count(stmt->statement_);
   for (int i = 0; i < static_cast<int>(n_params) && i < param_count; ++i) {
-    Local<Value> value = info[i + 1];
+    Local<Value> value = args[i + 1];
     if (!stmt->BindValue(value, i + 1)) {
       return;
     }
@@ -2755,7 +2769,7 @@ void SQLTagStore::Run(const FunctionCallbackInfo<Value>& info) {
   if (StatementExecutionHelper::Run(
           env, stmt->db_.get(), stmt->statement_, stmt->use_big_ints_)
           .ToLocal(&result)) {
-    info.GetReturnValue().Set(result);
+    args.GetReturnValue().Set(result);
   }
 }
 
@@ -2873,23 +2887,9 @@ void SQLTagStore::All(const FunctionCallbackInfo<Value>& args) {
   }
 }
 
-void SQLTagStore::Size(const FunctionCallbackInfo<Value>& info) {
+void SQLTagStore::Clear(const FunctionCallbackInfo<Value>& args) {
   SQLTagStore* store;
-  ASSIGN_OR_RETURN_UNWRAP(&store, info.This());
-  info.GetReturnValue().Set(
-      Integer::New(info.GetIsolate(), store->sql_tags_.Size()));
-}
-
-void SQLTagStore::Capacity(const FunctionCallbackInfo<Value>& info) {
-  SQLTagStore* store;
-  ASSIGN_OR_RETURN_UNWRAP(&store, info.This());
-  info.GetReturnValue().Set(
-      Integer::New(info.GetIsolate(), store->sql_tags_.Capacity()));
-}
-
-void SQLTagStore::Clear(const FunctionCallbackInfo<Value>& info) {
-  SQLTagStore* store;
-  ASSIGN_OR_RETURN_UNWRAP(&store, info.This());
+  ASSIGN_OR_RETURN_UNWRAP(&store, args.This());
   store->sql_tags_.Clear();
 }
 

filename: src/node_sqlite.h
patch: @@ -313,15 +313,14 @@ class SQLTagStore : public BaseObject {
       Environment* env, BaseObjectWeakPtr<DatabaseSync> database, int capacity);
   static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
       Environment* env);
-  static void All(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Get(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Iterate(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Run(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Size(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Capacity(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Reset(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void Clear(const v8::FunctionCallbackInfo<v8::Value>& info);
-  static void DatabaseGetter(const v8::FunctionCallbackInfo<v8::Value>& info);
+  static void All(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Get(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Iterate(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Run(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Clear(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void CapacityGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void DatabaseGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void SizeGetter(const v8::FunctionCallbackInfo<v8::Value>& args);
   void MemoryInfo(MemoryTracker* tracker) const override;
   SET_MEMORY_INFO_NAME(SQLTagStore)
   SET_SELF_SIZE(SQLTagStore)

filename: test/parallel/test-sqlite-template-tag.js
patch: @@ -77,23 +77,23 @@ test('queries with no results', () => {
 
 test('TagStore capacity, size, and clear', () => {
   assert.strictEqual(sql.capacity, 10);
-  assert.strictEqual(sql.size(), 0);
+  assert.strictEqual(sql.size, 0);
 
   assert.strictEqual(sql.run`INSERT INTO foo (text) VALUES (${'one'})`.changes, 1);
-  assert.strictEqual(sql.size(), 1);
+  assert.strictEqual(sql.size, 1);
 
   assert.ok(sql.get`SELECT * FROM foo WHERE text = ${'one'}`);
-  assert.strictEqual(sql.size(), 2);
+  assert.strictEqual(sql.size, 2);
 
   // Using the same template string shouldn't increase the size
   assert.strictEqual(sql.get`SELECT * FROM foo WHERE text = ${'two'}`, undefined);
-  assert.strictEqual(sql.size(), 2);
+  assert.strictEqual(sql.size, 2);
 
   assert.strictEqual(sql.all`SELECT * FROM foo`.length, 1);
-  assert.strictEqual(sql.size(), 3);
+  assert.strictEqual(sql.size, 3);
 
   sql.clear();
-  assert.strictEqual(sql.size(), 0);
+  assert.strictEqual(sql.size, 0);
   assert.strictEqual(sql.capacity, 10);
 });