英文:
In Swift how do I run a checkpoint on SQLite database
问题
I have a program that adds data from CSV files to core data. Once I have saved the managed object context to the persistent store I want to run a checkpoint to flush the contents of the WAL file into the SQLite file. I have added code to my class in an attempt to do so but am unable to determine on the line "sqlite3_wal_checkpoint( ...)" what to put in the unsafe pointer
class UpdateCoreDataTest: ObservableObject {
@Published var isLoading: Bool = true
var moc: NSManagedObjectContext
init(moc: NSManagedObjectContext) {
self.moc = moc
Task {
await IsDataStoreEmpty(moc: self.moc)
let fund1 = CSVtoCoreData(fundName: "Fund1", fileName: "Fund1.csv")
let fund2 = CSVtoCoreData(fundName: "Fund2", fileName: "Fund2.csv")
let fund3 = CSVtoCoreData(fundName: "Fund3", fileName: "Fund3.csv")
await fund1.CSVtoCoreDataG(moc: self.moc)
await fund2.CSVtoCoreDataG(moc: self.moc)
await fund3.CSVtoCoreDataG(moc: self.moc)
do {
try moc.save()
} catch {
print("Error saving. \(error)")
}
//--- start of added code
let fileURL = URL(fileURLWithPath: "/Users/Chris/Downloads/Persistent Store 2/Funds.sqlite")
var dataBase: OpaquePointer?
if sqlite3_open(fileURL.path, &dataBase) != SQLITE_OK {
print("Unable to open sqlite file")
} else {
print("Successfully opened sqlite file")
}
// sqlite3_wal_checkpoint(dataBase, ??????? )
sqlite3_close(dataBase)
//--- end of added code
DispatchQueue.main.async {
self.isLoading = false
}
}
} // end init
}
(Note: I left the "???????" in your code as it is, as I'm not providing an actual value for that parameter.)
英文:
I have a program that adds data from CSV files to core data. Once I have saved the managed object context to the persistent store I want to run a checkpoint to flush the contents of the WAL file into the SQLite file. I have added code to my class in an attempt to do so but am unable to determine on the line "sqlite3_wal_checkpoint( ...)" what to put in the unsafe pointer <cchar> parameter (denoted with ??????? in the code). Of course if there is a better way, please let me know.
class UpdateCoreDataTest: ObservableObject {
@Published var isLoading: Bool = true
var moc: NSManagedObjectContext
init(moc: NSManagedObjectContext) {
self.moc = moc
Task {
await IsDataStoreEmpty(moc: self.moc)
let fund1 = CSVtoCoreData(fundName: "Fund1", fileName: "Fund1.csv")
let fund2 = CSVtoCoreData(fundName: "Fund2", fileName: "Fund2.csv")
let fund3 = CSVtoCoreData(fundName: "Fund3", fileName: "Fund3.csv")
await fund1.CSVtoCoreDataG(moc: self.moc)
await fund2.CSVtoCoreDataG(moc: self.moc)
await fund3.CSVtoCoreDataG(moc: self.moc)
do {
try moc.save()
} catch {
print("Error saving. \(error)")
}
//--- start of added code
let fileURL = URL(fileURLWithPath: "/Users/Chris/Downloads/Persistent Store 2/Funds.sqlite")
var dataBase: OpaquePointer?
if sqlite3_open(fileURL.path, &dataBase) != SQLITE_OK {
print("Unable to open sqlite file")
} else {
print("Succesfully opened sqlite file")
}
// sqlite3_wal_checkpoint(dataBase, ??????? )
sqlite3_close(dataBase)
//--- end of added code
DispatchQueue.main.async {
self.isLoading = false
}
}
} // end init
}
答案1
得分: 1
以下是翻译好的部分:
从文档中:
> 第二个参数是附加数据库的名称(或NULL)。如果参数为NULL或指向零长度字符串,则将尝试在连接到数据库连接db的所有WAL数据库上执行指定的操作。
然而,当数据库文件上的最后一个数据库连接关闭并删除WAL文件时,SQLite将自动进行检查点。因此,如果您需要打开数据库来执行检查点,那么可能根本没有什么可做的。
英文:
From the docs:
> The second parameter is the Name of attached database (or NULL). If
> parameter is NULL or points to a zero length string, then the
> specified operation is attempted on all WAL databases attached to
> database connection db.
However, SQLite will automatically checkpoint when the last database connection on a database file closes and WAL file will be deleted. So if you need to open the database to do the checkpoint, then there is probably nothing at all to do.
答案2
得分: 0
I thought more about your statement regarding SQLite automatically running a checkpoint when the last database connection on a database file closes. So I removed the code between "start of added code" and "end of added code" above. In its place I put the code below. Removing the persistent store from the coordinator appears to close the connection between core data and the disk file. Once this bit of code is executed, a checkpoint is run automatically as you stated. Perfect.
英文:
I thought more about your statement regarding SQLite automatically running a checkpoint when the last database connection on a database file closes. So I removed the code between "start of added code" and "end of added code" above. In its place I put the code below. Removing the persistent store from the coordinator appears to close the connection between core data and the disk file . Once this bit of code is executed, a checkpoint is run automatically as you stated. Perfect.
let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.first
do {
try coreDataContainer.persistentStoreCoordinator.remove(persistentStore!)
} catch {
print("Unable to remove store -> \(error)")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论