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

Most upvoted comments

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.