Skip to content

gh-103489: Add get/set config methods to sqlite3.Connection #103506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 26, 2023

Conversation

erlend-aasland
Copy link
Contributor

@erlend-aasland erlend-aasland commented Apr 13, 2023

@erlend-aasland
Copy link
Contributor Author

cc. @simonw / @numist: proof of concept; feel free to test.

I deliberately did not add support for SQLITE_DBCONFIG_MAINDBNAME and SQLITE_DBCONFIG_LOOKASIDE.

@numist
Copy link

numist commented Apr 13, 2023

Good call on SQLITE_DBCONFIG_LOOKASIDE. Is the decision wrt SQLITE_DBCONFIG_MAINDBNAME due more to the risk of breaking existing code relying on the magic constant MAIN. or the memory lifetime requirements of its parameter?

I'm surprised to see SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER made the cut given it gates operation of fts3_tokenizer(), which takes a C struct of function pointers.

@erlend-aasland
Copy link
Contributor Author

Good call on SQLITE_DBCONFIG_LOOKASIDE. Is the decision wrt SQLITE_DBCONFIG_MAINDBNAME due more to the risk of breaking existing code relying on the magic constant MAIN. or the memory lifetime requirements of its parameter?

Well, those two are the only ones with non-standard arg spec, so by keeping them out we get a cleaner API. They are also pretty esoteric features IMO, so I'm not sure they're worth the added complexity.

I'm surprised to see SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER made the cut given it gates operation of fts3_tokenizer(), which takes a C struct of function pointers.

Thanks, you're quite correct; there's no reason to expose that constant.

@numist
Copy link

numist commented Apr 13, 2023

Well, those two are the only ones with non-standard arg spec, so by keeping them out we get a cleaner API.

Fair enough, though it seems like this runs a risk the SQLite project adds a desirable verb with non-int parameters in the future.

I don't see an API analogue for sqlite3_config in Python to act as precedent1; would it make sense/be more idiomatic for the verbs to be subproperties of a config property on the database object? Something like:

db.config.defensive = False

There's still a type risk here—SQLite has a history of adding third options to formerly boolean configurations (like PRAGMA auto_vacuum) but it's not nearly as rigid

Footnotes

  1. just as well, global configurations wreak havoc on unsuspecting code modules that expect default behaviours

@erlend-aasland
Copy link
Contributor Author

Fair enough, though it seems like this runs a risk the SQLite project adds a desirable verb with non-int parameters in the future.

Yep, that's a risk, but we can expand the scope of the new Python API later, so it's not too big of a risk. Another option is of course the namespace design you hinted at.

I don't see an API analogue for sqlite3_config in Python to act as precedent [...]

The problem with that SQLite C API, is that it must be called prior to SQLite initialisation. Currently, that happens during sqlite3 initialisation. We initialise SQLite explicitly with a call to sqlite3_initialize, and we kind of need it to stay like that, because the runtime library may have been compiled with SQLITE_OMIT_AUTOINIT. I see four possible paths:

  1. Expose sqlite3_config and initialize SQLite lazily (for example during sqlite3.connect / sqlite3.Connection.__init__); raise an exception if the user tries to alter the configuration post init.
  2. Expose sqlite3_config and require explicit SQLite init (backwards incompatible, so not a real alternative)
  3. Expose sqlite3_config and wrap it with a sqlite3_shutdown/sqlite3_initialize dance; fail if there are open connections.
  4. Don't expose sqlite3_config

Anyway, this discussion is off-topic for this PR :) If you want to follow this up, please create a topic on Discourse; we can continue there.

@erlend-aasland erlend-aasland linked an issue Apr 20, 2023 that may be closed by this pull request
@erlend-aasland
Copy link
Contributor Author

@numist:

[...] would it make sense/be more idiomatic for the verbs to be subproperties of a config property on the database object? Something like:

db.config.defensive = False

A namespace could of course be an option, but I think a simple get/set pair is a cleaner API for this feature (both programmatically and regarding to documentation). (Also, we've already got setlimit() and getlimit() for connection limits.)

@erlend-aasland erlend-aasland marked this pull request as ready for review April 24, 2023 12:14
@erlend-aasland
Copy link
Contributor Author

@AlexWaygood: The added docs are quite sparse, but I'm hesitant to explode this PR by documenting every single constant. I've added a link to the SQLite docs, maybe that is enough. What do you think?

@erlend-aasland erlend-aasland self-assigned this Apr 24, 2023
@AlexWaygood
Copy link
Member

@AlexWaygood: The added docs are quite sparse, but I'm hesitant to explode this PR by documenting every single constant. I've added a link to the SQLite docs, maybe that is enough. What do you think?

This looks like a reasonable solution to me, but I'm not an SQLite expert :)

Copy link
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

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

Docs approval!

@erlend-aasland
Copy link
Contributor Author

Thanks everybody! I'll land this later today.

@erlend-aasland erlend-aasland enabled auto-merge (squash) April 26, 2023 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Expose sqlite3_db_config and verbs (or equivalent)
4 participants