[11.x] Support named in-memory SQLite connections #53635
+7
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
SQLite supports named in-memory databases. The benefit of named connections is that you can essentially "reconnect" to the same memory region even without passing a PDO instance around. Only the DSN needs to be the same.
Here's an example:
It shows how you can connect to the same database, without passing the PDO instance directly, as long as the DSN string is identical.
foo()
will logfoo
whilebar()
will logfoo
andbar
. The only condition here is that the connection is kept alive somehow.If you swap the
$dsn
definitions, bothfoo()
andbar()
will create their own database when the PDO connection is created (and free it once$conn
goes out of scope). Additionally, if you remove the$_ =
, the memory of the database will be freed as there's no longer any open connection, so it'll behave identically to:memory:
.Practical use case
This lets me support
:memory:
in my tenancy package for testing tenant databases, providing a nice speedup. During the tenant creation process there's a lot of logic that essentially keeps connecting to and disconnecting from the tenant DB. Users may also switch to the central context usingtenancy()->end()
ortenancy()->central(closure)
which closes the tenant connection.With named databases, I only need to keep a connection to the tenant DB alive somewhere (literally just
register_shutdown_function(fn () => $conn)
works) and then the package can seamlessly connect to and disconnect from tenant databases that live entirely in process memory and don't need any special cleanup.Code style
I could just check for
mode=memory
but that could in theory be part of a real filename. Don't think it'd make anything vulnerable if therealpath()
check got skipped, but I went with?mode
||&mode
just in case since it's a little more restrictive.The DSN syntax for named in-memory databases is just
mode=memory
in URI format typically paired withcache=shared
. The order being arbitrary.I also tried to respect the 3 char rule in the comment but couldn't think of anything that'd fit here better, so the last line is an extra character shorter.