feat(ios): add option to store databases in Library/Application Support - #323
Open
NicolasBonet wants to merge 1 commit into
Open
feat(ios): add option to store databases in Library/Application Support#323NicolasBonet wants to merge 1 commit into
NicolasBonet wants to merge 1 commit into
Conversation
The Documents directory becomes user-visible in the Files app when an app enables file sharing, exposing raw databases and their -wal/-shm journals to accidental sharing, modification, or deletion. Setting RNNitroSQLite_DatabaseLocation to "ApplicationSupport" in Info.plist stores databases in Library/Application Support instead (persistent, backed up, never user-visible). Databases created by older app versions are moved out of Documents when they are opened: the database and its journals are copied as a set before the originals are deleted, and if anything fails the database keeps being opened from Documents and the migration retries on the next open. Fixes margelo#289 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
|
Looking into this! Thanks 🙌🏼 |
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
Fixes #289.
On iOS (without an App Group), databases are stored in the app's Documents directory. When an app enables file sharing (
UIFileSharingEnabled+LSSupportsOpeningDocumentsInPlace), Documents becomes visible to users in the Files app — including the raw SQLite database and its-wal/-shmjournals, which can then be shared, modified, or deleted from outside the app. Apple's File System Programming Guide recommendsLibrary/Application Supportfor app-internal data files: it is persistent, backed up, and never user-visible.We hit this in production at Expensify and have been shipping this behavior as a
patch-packagepatch since Expensify/App#96531; this PR upstreams it in a generalized, opt-in form.What this does
Adds a new
Info.plistkey, following the existingRNNitroSQLite_AppGroupconvention:Documents(default, current behavior) andApplicationSupport. Making this opt-in avoids a breaking change for apps that rely on Files-app access to their databases — though I'd be happy to flip the default in a future major if you prefer, since the migration makes that safe data-wise.ApplicationSupport,OnLoad.mmpointsdocPathatLibrary/Application Support(creating it if needed) and records the old Documents path in a newHybridNitroSQLite::migrationDocPath.HybridNitroSQLite::open(), where the database name is known — so the migration is fully generic. It also honors thelocationoption (migratesDocuments/<location>→Application Support/<location>).RNNitroSQLite_AppGroupis set (app group databases live in the shared container).migrationDocPathstays empty in those cases, making theopen()change a no-op.Migration safety
Committed-but-uncheckpointed writes live in the
-walfile, and SQLite only replays a-walthat sits next to its database, so the database and its journals must never be separated. The migration therefore:-walfrom one database generation is never replayed into a database from another.db,-wal,-shm) before deleting anything. If any copy fails, the intact originals in Documents keep being used —open()falls back to opening the database from Documents — and the migration retries on the next open.-walmust stay next to it.This exact strategy has been running in the Expensify app in production.
Notes
open()only.attach()/drop()on a never-opened database would still look in the new location; I kept the scope minimal, but happy to extend it to those paths if you'd like.std::filesystem, available on all deployment targets Nitro supports.Testing
Library/Application Support.Library/Application Support, uncheckpointed WAL content preserved.Documents) → behavior unchanged.🤖 Generated with Claude Code