Fix in-memory metadatabase creation in defaultMetadatabase#508
Open
lukaskubanek wants to merge 1 commit into
Open
Fix in-memory metadatabase creation in defaultMetadatabase#508lukaskubanek wants to merge 1 commit into
defaultMetadatabase#508lukaskubanek wants to merge 1 commit into
Conversation
This was referenced Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
The metadatabase is meant to live in the same world as the user database. When the user database is on disk, the metadatabase is created as a file next to it. When the user database is in-memory (useful for tests), the metadatabase is meant to be in-memory as well, so the whole setup stays ephemeral and isolated. For that case,
URL.metadatabase(…)builds the corresponding SQLite address (file:sqlitedata_icloud?mode=memory&cache=shared).However,
defaultMetadatabase(…)converts that URL to a plain path before opening it, which cannot represent an in-memory address. The dedicatedDatabaseQueuepath for in-memory URLs was removed in #367 (see this discussion). The effect of this change depends on the OS version:url.path(percentEncoded: false)returns an empty string, soDatabasePool(path: "")crashes when activating WAL mode."sqlitedata_icloud", which SQLite receives as an ordinary filename. Instead of a throwaway in-memory database, a real file namedsqlitedata_icloudis silently created in the current working directory of the process (verified on macOS 27).As most tests in the test suite use temporary on-disk databases, the issue doesn’t surface much. The few tests exercising in-memory user databases (in
SyncEngineTestsandSyncEngineValidationTests) don't observe where the metadatabase writer lands, though they do leave a straysqlitedata_icloudfile behind in the working directory.There is another side effect when the metadatabase is attached to the user database connection via
attachMetadatabase(…)inprepareDatabase. That code path handles the in-memory URL correctly, so the sync engine ends up with two different metadatabases at once. The triggers installed on the user’s tables write metadata into the attached in-memory store, while the sync engine's own writer reads and writes the on-disk file, each seeing only part of the picture. I verified this briefly on macOS 27.Implementation
This PR restores the
DatabaseQueuepath for in-memory URLs indefaultMetadatabase(…)that was removed in #367, matching howattachMetadatabase(…)already handles them. The on-disk case is unchanged and continues to useDatabasePoolwith a regular file path.It also adds a regression test that derives the in-memory URL via
URL.metadatabase(…), exactly asSyncEngine.initdoes, and asserts the resulting metadatabase is actually in-memory.The test lives in a standalone suite rather than being nested in
BaseCloudKitTests, since it doesn't use any of that infrastructure, similar toUserlandTests.Supersedes #410, which contained the same fix framed as a macOS 15 issue only.
Disclaimer: AI assistance (Claude Code with Fable model) was used to investigate this issue and prepare this PR. All changes and verifications were reviewed by me.