1

I can not make a simple select on a SQLite database, via GRDB.swift Here is my code:

    override func viewDidLoad()
{
    super.viewDidLoad()

    do
    {
        let dbQueue = try DatabaseQueue(path: "games.sqlite")

        try dbQueue.inDatabase
        {
            db in try db.execute("SELECT * FROM games")
        }
    }
    catch
    {
        print("Erreur !")
    }
}

I do not find in the documentation a simple way to perform a simple select, the doc speaks of model, and I desire just for the moment to make direct queries. The documentation speaks only for error on my part of model.

Thank you all for your help.

My environment : Xcode8.2.1 swift3 cocoapods 1.2.0.rc.1

Fattie
  • 27,874
  • 70
  • 431
  • 719

1 Answers1

2

The GRDB documentation says:

Once granted with a database connection, the execute method executes the SQL statements that do not return any database row, such as CREATE TABLE, INSERT, DELETE, ALTER, etc.

So if you want to fetch rows, you picked the wrong method.

To fetch rows, you use a fetching method (which starts with fetch), as documented in the Row Queries documentation chapter, that I encourage you to read.

For example:

let rows = try dbQueue.inDatabase { db in
    try Row.fetchAll(db, "SELECT * FROM games")
}
// Now we're back to the main thread: use rows:
for row in rows {
    let name: String = row.value(named: "name")
    let year: Int = row.value(named: "year")
    print(name)
    print(year)
}

That's what it gives "without going through models".

Yet models are still handy:

let games = try dbQueue.inDatabase { db -> [Game] in
    let rows = try Row.fetchAll(db, "SELECT * FROM games")
    return rows.map { row in
        Game(
            name: row.value(named: "name"),
            year: row.value(named: "year"))
    }
}
// Now we're back to the main thread: use games
for game in games {
    print(game.name)
    print(game.year)
}

If you have your Game type (struct or class) adopt the RowConvertible protocol, you can even write:

let games = try dbQueue.inDatabase { db in
    try Game.fetchAll(db, "SELECT * FROM games")
}

And if Game also adopts TableMapping protocol, you get:

let games = try dbQueue.inDatabase { try Game.fetchAll($0) }

See Record for the documentation of those protocols.

Gwendal Roué
  • 3,949
  • 15
  • 34
  • Hello, I thank you very much for taking the time to explain. In fact, I also had a problem connecting to my database (I do not know a class for automated this: relative path and / or absolute), I did not give the right way! Your explanation, my whole time enormously served to apprehend the framework. thanks again. –  Jan 27 '17 at 13:26