简体   繁体   English

如何授予我的 MacOS 应用程序权限以创建“WAL”文件以使用 journal-mode=WAL 打开 SQLite 数据库?

[英]How do I give my MacOS app permission to create "WAL" file to open an SQLite DB with journal-mode=WAL?

I'm an experienced programmer, but this is my first MacOS app (on 10.15.2), which needs to read an sqlite db of the user's choice (potentially anywhere on the machine)我是一位经验丰富的程序员,但这是我的第一个 MacOS 应用程序(在 10.15.2 上),它需要读取用户选择的 sqlite 数据库(可能在机器上的任何位置)

At first it wouldn't open the DB 'name.sqlite' file itself;起初它不会打开数据库“name.sqlite”文件本身; but when I used NSOpenPanel to let the user select it, that worked.但是当我使用 NSOpenPanel 让用户选择它时,它起作用了。

But then the query failed because sqlite3 (via SQLite.swift) was trying to open 'name.sqlite-wal'但随后查询失败,因为 sqlite3(通过 SQLite.swift)试图打开“name.sqlite-wal”

os_unix.c:43353: (0) open(/path/to/dbname.lrcat-wal) - Undefined error: 0

If I open the db using the command-line client, and pragma journal-mode=off then the app works fine, but I can't restrict the app based on that - most of the dbs have WAL journalling如果我使用命令行客户端打开数据库,并且pragma journal-mode=off那么应用程序运行良好,但我不能基于此限制应用程序 - 大多数数据库都有 WAL 日志

I tried turning com.apple.security.app-sandbox false in app.entitlements, but that didn't help.我尝试在 app.entitlements 中将com.apple.security.app-sandbox设为 false,但这没有帮助。

I tried moving the db to the Pictures folder and turning com.apple.security.assets.pictures.read-write true, but that didn't help.我尝试将数据库移动到图片文件夹并将com.apple.security.assets.pictures.read-write设为 true,但这没有帮助。

The unix permissions for db and the containing folder (/tmp in my test) are both good. db 和包含文件夹(在我的测试中为 /tmp)的 unix 权限都很好。

Because allowing the user to select the db via the NSOpenPanel allowed me to open the db for reading, I assume there's a similar restriction on the creation of the '-wal' file for writing.因为允许用户通过 NSOpenPanel 选择数据库允许我打开数据库进行读取,所以我认为创建用于写入的“-wal”文件也有类似的限制。

How can I get permission (ideally without bothering the user with details of what a wal file is) to create the file next to the db?我怎样才能获得在 db 旁边创建文件的权限(理想情况下不会用 wal 文件的详细信息打扰用户)?


Edit: Following TheNextMan's suggestion about sidecar files, I searched again.编辑:按照 TheNextMan 关于 sidecar 文件的建议,我再次搜索。 The WWDC presentation he (guessing the pronoun) linked shows how to use CFBundleDocumentTypes to relate extra extensions with NSIsRelatedItemType for NSFilePresenter , but (as far as I know) I'm not going through that route.(猜测代词)链接的 WWDC 演示文稿展示了如何使用CFBundleDocumentTypes将额外的扩展与NSIsRelatedItemTypeNSFilePresenter ,但是(据我所知)我不会通过那条路线。 I've tried it but it hasn't helped我试过了,但没有帮助

I also, armed with the "sidecar" search term, found Access sidecar files in a Mac sandboxed app , which looked good but didn't help.我还配备了“sidecar”搜索词, 在 Mac 沙盒应用程序中找到了Access sidecar 文件,这看起来不错,但没有帮助。

Even better I found the four-year-old unanswered duplicate of my question (if I had enough rep I'd mark this as a duplicate) , SQLite and Sandboxed OSX apps , which includes a quote from Apple documentation App Sandbox Design Guide , saying更好的是,我发现了我的问题的四年前未回答的重复项(如果我有足够的代表,我会将其标记为重复项)SQLite 和 Sandboxed OSX 应用程序,其中包括来自 Apple 文档App Sandbox Design Guide的引述,说

Note: In the case of a SQLite journal file, beginning in 10.8.2, journal files, write-ahead logging files, and shared memory files are automatically added to the related items list if you open a SQLite database, so this step is unnecessary.注意:如果是SQLite日志文件,从10.8.2开始,如果打开SQLite数据库,日志文件、预写日志文件和共享内存文件会自动添加到相关项目列表中,所以这一步是不必要的.

So apparently it should Just Work™.所以显然它应该 Just Work™。 But it doesn't.但事实并非如此。

Thank you for this thorough question.感谢您提出这个详尽的问题。 I encountered today the same issue as you, fighting the macOS sandbox restrictions.我今天遇到了和你一样的问题,与 macOS 沙盒限制作斗争。 Similar to you, I've already copied the user selected ( NSOpenPanel ) database to my apps temporary folder ( FileManager.default.temporaryDirectory ).与您类似,我已经将用户选择 ( NSOpenPanel ) 数据库复制到我的应用程序临时文件夹 ( FileManager.default.temporaryDirectory )。
But still I was unable to query the database file: sqlite3_prepare_v2 always returned the os_unix.c:45340: (0) open(/var/folders/.../myDB.db-wal) - Undefined error: 0 message.但我仍然无法查询数据库文件: sqlite3_prepare_v2总是返回os_unix.c:45340: (0) open(/var/folders/.../myDB.db-wal) - Undefined error: 0消息。

As the database already is located in the temporary folder, which definitely is writable by our app (as we copied the database file!), we can simply create the myDB.db-wal file ourselves:由于数据库已经位于临时文件夹中,我们的应用程序绝对可以写入该文件夹(因为我们复制了数据库文件!),我们可以简单地自己创建myDB.db-wal文件:

let tmpLocation = /// URL of the SQLite *.db file in a writable directory
let walLocation = tmpLocation.deletingPathExtension().appendingPathExtension("db-wal")
try Data().write(to: walLocation)

Et voilà: opening the DB is working. Et voilà:打开数据库正在工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在RestKit Swift中关闭WAL文件模式 - Turn off the WAL file mode in RestKit Swift 应用程序沙箱阻止创建.sqlite-shm,.sqlite-wal文件(swift) - App Sandbox blocks creation of .sqlite-shm, .sqlite-wal files (swift) MacOS:如何/在我的应用程序文件夹中存储以编程方式创建的文件? - MacOS: How/where do I store a programmatically created file within my app folder? Xcode Swift 3.0 macOS(Sierra)应用无法创建文件,没有权限 - Xcode Swift 3.0 macOS (Sierra) app unable to create file, no permission 如何在 SwiftUI 2 上禁用核心数据的 shm 和 wal 选项? - How to disable shm and wal options for Core Data on SwiftUI 2? MacOS 上的 Swift:无法从我的应用程序打开文件 - Swift on MacOS: cannot open a file from my app 如何在我的 Swift 应用程序中打开外部文件(epub 文件) - How do I open an external file (epub file) in my Swift App 如何从我的 iOS 应用程序打开 Instagram 应用程序? - How do I open Instagram app from my iOS app? 如何从我的 html 文件移动到另一个 html 文件以创建 iOS 混合应用程序? - How do I move from my html file to another html file to create an iOS hybrid app? 如何允许用户将文件保存到特定目录并在 macOS 应用程序中指定文件名? - How do I allow users to save a file to a specific directory and specify a file name in a macOS app?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM