GRDB.swift: DatabasePool can't read from existing non-WAL database
I ran into the same issue as #40 and did a little digging. I appears that a DatabasePool connection fails if no SerializedDatabase exists for the connection yet. I wrote a sample which illustrates this below.
` import UIKit import GRDB
class ViewController: UIViewController {
internal static var connectionPool = [String:DatabasePool]()
override func viewDidLoad() {
super.viewDidLoad()
doStuff()
}
func doStuff()
{
//a call to this db creates the .db-shm and .db-wal files
createTable("WillNotFail")
getAllTables("WillNotFail")
//this call does not and throws an exception
getAllTables("WillFail")
}
internal func getPooledConnection(name:String) -> DatabasePool?
{
do
{
if ViewController.connectionPool[name] == nil
{
let rootLibDirectory = NSSearchPathForDirectoriesInDomains( .LibraryDirectory, .UserDomainMask, true ).first as String!
print(rootLibDirectory)
ViewController.connectionPool[name] = try DatabasePool( path: "\(rootLibDirectory)/\(name).db" )
}
}
catch
{
print("\(error)")
return nil
}
return ViewController.connectionPool[name]
}
internal func createTable(name: String)
{
guard let pool = getPooledConnection(name)
else
{
return
}
do
{
try pool.write
{ db in
try db.execute("CREATE TABLE IF NOT EXISTS SampleTable (col1 varchar)")
}
}
catch
{
print(error)
}
return
}
internal func getAllTables(name: String)
{
guard let pool = getPooledConnection(name)
else
{
return
}
pool.read
{ db in
let results = Row.fetchAll( db, "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name")
for result in results
{
print( result.value(atIndex: 0) )
}
}
return
}
}
`
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 19 (9 by maintainers)
Commits related to this issue
- Add failing test for #102 (DatabasePool can't open a non-WAL database and then read, with error 14) — committed to groue/GRDB.swift by groue 8 years ago
- DatabasePool setup: handle #102 in a savepoint — committed to groue/GRDB.swift by groue 5 years ago
Hello @blkbam. If this is the same trouble than #40, then the answer is the same: don’t create several instances of DatabasePool that connect to a given database file.
Review your application architecture. Don’t create DatabasePool in temporary objects like UIViewController, since this implies that you can’t guarantee that there is never more than one DatabasePool connected to a single database file.