在我的项目中,我正在使用.db
从sqlite3_open
打开一个已经存在的数据库。该文件是使用命令行工具sqlite3
创建的。我正在更新表中的某些行,效果很好,但是这些更新仅在数据库的临时实例中进行。我如何还可以更新.db
文件,以供项目的将来运行以使用更新的数据?
有人问here如何在Swift中保存SQLite数据库。但是答案对我来说似乎有点令人不满意,因为该文件应以与sqlite3
创建的格式相同的格式写入,以便可以通过sqlite3_open
再次打开该文件。
SQLite可能甚至提供了一个功能吗?我找不到任何东西...
最佳答案
您不能修改捆绑软件的内容。因此,您需要将文件复制到可以修改的目录中。从历史上看,我们可能建议使用“文档”文件夹。但是如今,我们使用“应用程序支持目录”。参见iOS Storage Best Practices。
无论如何,基本思想是:
SQLITE_READWRITE
选项,但不使用SQLITE_CREATE
选项……如果没有找到,我们不希望它创建一个空白数据库);和因此,可能类似于:
var db: OpaquePointer?
enum DatabaseError: Error {
case bundleDatabaseNotFound
case sqliteError(Int32, String?)
}
func openDatabase() throws {
let fileURL = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("database.db")
// try opening database and just return if it succeeded
if sqlite3_open_v2(fileURL.path, &db, SQLITE_OPEN_READWRITE, nil) == SQLITE_OK {
return
}
// if it failed, clean up before trying again ...
sqlite3_close(db)
db = nil
// then copy database from bundle ...
guard let bundlePath = Bundle.main.url(forResource: "database", withExtension: "db") else {
throw DatabaseError.bundleDatabaseNotFound
}
try FileManager.default.copyItem(at: bundlePath, to: fileURL)
// and try again
let rc = sqlite3_open_v2(fileURL.path, &db, SQLITE_OPEN_READWRITE, nil)
if rc == SQLITE_OK { return }
// and if it still failed, again, clean up, and then throw error
let errorMessage = sqlite3_errmsg(db)
.flatMap { String(cString: $0) }
sqlite3_close(db)
db = nil
throw DatabaseError.sqliteError(rc, errorMessage)
}
关于ios - 使用SQLite将数据库更改保存到.db文件(Swift),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56416832/