Skip to content

Conversation

@mertcanaltin
Copy link
Member

@mertcanaltin mertcanaltin commented Jan 6, 2026

Fixes: #61268

add limits property to databaseSync

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/sqlite

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jan 6, 2026
@mertcanaltin mertcanaltin requested a review from louwers January 6, 2026 20:46
Copy link
Contributor

@louwers louwers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add SQLITE_MAX_LENGTH etc. as constants? https://sqlite.org/limits.html

@mertcanaltin
Copy link
Member Author

Should we add SQLITE_MAX_LENGTH etc. as constants? https://sqlite.org/limits.html

SQLITE_MAX are compile-time preprocessor macros, so they can't be exported directly at runtime. however, the default values returned by db.limits are exactly these SQLITE_MAX values (assuming SQLite was compiled with default settings).

so db.limits.length returns 1000000000 which equals SQLITE_MAX_LENGTH.

if you want explicit constants, i could add SQLITE_LIMIT (the enum IDs used with sqlite3_limit()) to the constants object.
let me know what you think would be most useful.

mertcanaltin and others added 9 commits January 7, 2026 00:39
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
Co-authored-by: Anna Henningsen <[email protected]>
@mertcanaltin
Copy link
Member Author

@addaleax thanks for reviews, I tried solve

@louwers
Copy link
Contributor

louwers commented Jan 9, 2026

Would it be possible to interpret Infinity as a special value?

Having a setter that accepts different types from the corresponding getter feels wrong to me.

Also, I would except that 'resetting' a limit means it goes back to the value that was initially provided to the constructor. Not that it takes on the highest value (which is the same as the default value). Setting it to Infinity leaves little room for alternate interpretations.

@mertcanaltin
Copy link
Member Author

mertcanaltin commented Jan 11, 2026

+1 Of course! I used Infinity instead of Null and updated the test documents.

@mertcanaltin mertcanaltin requested a review from louwers January 11, 2026 10:46
@louwers
Copy link
Contributor

louwers commented Jan 11, 2026

Neat, is @Renegade334 on board with that too?

@Renegade334
Copy link
Member

Renegade334 commented Jan 11, 2026

SGTM!

The only alternative thought I'd have would be making -1 the magic number. It's perhaps less semantically on-the-button than Infinity, but the handling becomes a lot more straightforward.

@mertcanaltin
Copy link
Member Author

Hi, I think I need a review here. @Renegade334 @louwers

Isolate* isolate = info.GetIsolate();
LocalVector<Value> names(isolate);

for (size_t i = 0; i < kLimitMapping.size(); ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need "i" here, so I'm using the traditional for method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it needed?

Copy link
Contributor

@louwers louwers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments. But a collaborator will have to review this as well.

@mertcanaltin
Copy link
Member Author

Left some comments. But a collaborator will have to review this as well.

thanks for reviews 🙏

Co-authored-by: Bart Louwers <[email protected]>
LocalVector<Value> names(isolate);

for (size_t i = 0; i < kLimitMapping.size(); ++i) {
for (const auto& mapping : kLimitMapping) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a structured binding declaration.


// Apply initial limits
const auto& limits = open_config_.initial_limits();
for (size_t i = 0; i < limits.size(); ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that here a regular for-loop has to be used. Well, C++23 will allow std::views::enumerate. But we're not there yet

Nit: change i to limit_id to avoid a single letter variable, and make it more clear what it represents.

Copy link
Member Author

@mertcanaltin mertcanaltin Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for detail, I will edit

Co-authored-by: Bart Louwers <[email protected]>

Local<Object> limits_obj = limits_v.As<Object>();

// Iterate through known limit names and extract values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying suggested approach from other thread, since the comment got marked outdated:

      // Iterate through known limit names and extract values
      for (const auto& [js_name, sqlite_limit_id] : kLimitMapping) {
        Local<String> key;
        if (!String::NewFromUtf8(env->isolate(),
                                 js_name.data(),
                                 NewStringType::kNormal,
                                 js_name.size())
                 .ToLocal(&key)) {
          return;
        }

        Local<Value> val;
        if (!limits_obj->Get(env->context(), key).ToLocal(&val)) {
          return;
        }

        if (!val->IsUndefined()) {
          if (!val->IsInt32()) {
            std::string msg = "The \"options.limits." +
                              std::string(js_name) +
                              "\" argument must be an integer.";
            THROW_ERR_INVALID_ARG_TYPE(env->isolate(), msg);
            return;
          }

          int limit_val = val.As<Int32>()->Value();
          if (limit_val < 0) {
            std::string msg = "The \"options.limits." +
                              std::string(js_name) +
                              "\" argument must be non-negative.";
            THROW_ERR_OUT_OF_RANGE(env->isolate(), msg);
            return;
          }

          open_config.set_initial_limit(sqlite_limit_id, limit_val);
        }
      }

bool allow_bare_named_params_ = true;
bool allow_unknown_named_params_ = false;
bool defensive_ = false;
std::array<std::optional<int>, kNumSqliteLimits> initial_limits_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::array<std::optional<int>, kNumSqliteLimits> initial_limits_;
std::array<std::optional<int>, kLimitMapping.size()> initial_limits_;

Still need to be declared in the header it seems.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: oh I guess it needs to move to the header completely then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sqlite: allow setting limits on inputs

5 participants