Repository: nodejs/node
File: src/node_sqlite.h (C/C++)

Code before:
              v8::Local<v8::Object> object,
              BaseObjectPtr<DatabaseSync> database,
              int capacity);
  ~SQLTagStore() override;
  static BaseObjectPtr<SQLTagStore> Create(Environment* env,
                                           BaseObjectPtr<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);
  void MemoryInfo(MemoryTracker* tracker) const override;
  SET_MEMORY_INFO_NAME(SQLTagStore)
  SET_SELF_SIZE(SQLTagStore)

 private:
  static BaseObjectPtr<StatementSync> PrepareStatement(
      const v8::FunctionCallbackInfo<v8::Value>& args);
  BaseObjectPtr<DatabaseSync> database_;
  LRUCache<std::string, BaseObjectPtr<StatementSync>> sql_tags_;
  int capacity_;
  friend class StatementExecutionHelper;
};

class UserDefinedFunction {
 public:
  UserDefinedFunction(Environment* env,
                      v8::Local<v8::Function> fn,
                      DatabaseSync* db,
                      bool use_bigint_args);
  ~UserDefinedFunction();
  static void xFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
  static void xDestroy(void* self);

 private:
  Environment* env_;
  v8::Global<v8::Function> fn_;
  DatabaseSync* db_;
  bool use_bigint_args_;
};

}  // namespace sqlite
}  // namespace node


Review comment (performance):
If the `DatabaseSync` object somehow refers back to the `SQLTagStore` object, this creates a memory leak.

Would it make sense to keep storing a `BaseObjectWeakPtr` but to keep it alive by also storing the associated JS object in an internal field of `SQLTagStore`?

Code after:
    kDatabaseObject = BaseObject::kInternalFieldCount,
    kInternalFieldCount
  };

  SQLTagStore(Environment* env,
              v8::Local<v8::Object> object,
              BaseObjectWeakPtr<DatabaseSync> database,
              int capacity);
  ~SQLTagStore() override;
  static BaseObjectPtr<SQLTagStore> Create(
      Environment* env, BaseObjectWeakPtr<DatabaseSync> database, int capacity);
  static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
      Environment* env);
  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)

 private:
  static BaseObjectPtr<StatementSync> PrepareStatement(
      const v8::FunctionCallbackInfo<v8::Value>& args);
  BaseObjectWeakPtr<DatabaseSync> database_;
  LRUCache<std::string, BaseObjectPtr<StatementSync>> sql_tags_;
  friend class StatementExecutionHelper;
};

class UserDefinedFunction {
 public:
  UserDefinedFunction(Environment* env,
                      v8::Local<v8::Function> fn,
                      DatabaseSync* db,
                      bool use_bigint_args);
  ~UserDefinedFunction();
  static void xFunc(sqlite3_context* ctx, int argc, sqlite3_value** argv);
  static void xDestroy(void* self);

 private:
  Environment* env_;
  v8::Global<v8::Function> fn_;
  DatabaseSync* db_;
  bool use_bigint_args_;
};

}  // namespace sqlite