Rob Paterson
Rob Paterson

Reputation: 101

SQLite.swift in SwiftUI app will not compile

I'm trying to read a database and copy the rows into an array in swiftUI but I don't know the correct syntax to append the array. Here is my databaseHelper.swift

import Foundation
import SQLite

class DatabaseHelper {

    var database: Connection!
    var path: String
    let buttonsTable = "Button"
    var db: String

    var english: String
    var categoryID: Int
    var indonesian: String

    init() {

        do {
            let path = Bundle.main.path(forResource: "sga", ofType: "db")!
            let database = try Connection(path, readonly: true)
            self.database = database
            print("Database initialized at path \(path)")
        } catch {
            print("error")
        }
    }

    func queryDatabase() -> [ButtonData] {
        var buttonVars = [ButtonData]()
        do {
            let buttons = try self.database.prepare(self.buttonsTable)
            for user in buttons {
             //   print("English: \(user[self.english]), ID: \(user[self.ID]), Indonesian: \(user[self.indonesian])")
                buttonVars.append(ButtonData(english: row[english], categoryID: row[categoryID], indonesian: row[indonesian]))
            }
        } catch {
            print(error)
        }
        return buttonVars
    }
}

struct ButtonData: Hashable {
    let english: String
    let categoryID: Int
    let indonesian: String
}

I'm not sure what is really happening in append statement. I want to append columns in the row but it doesn't accept anything.

The error message I am getting is...

"Cannot subscript a value of type 'Statement.Element' (aka 'Array>') with an argument of type 'String'

Thanks in advance :)

Upvotes: 0

Views: 458

Answers (1)

HalR
HalR

Reputation: 11073

buttonTable is a sqlite.swift table and needs to be more than a string.

At some point you need to define your table like this:

static let buttonsTable = Table("Button")
static let english = Expression<String>("english")
static let indonesian = Expression<String>("indonesian")
static let categoryID = Expression<Int>("categoryID")

Assuming your db already exists, you should then be able to access it.

This section looks correct:

init() {

    do {
        let path = Bundle.main.path(forResource: "sga", ofType: "db")!
        let database = try Connection(path, readonly: true)
        self.database = database
        print("Database initialized at path \(path)")
    } catch {
        print("error")
    }
}

But then you would access it like this:

   func queryDatabase() -> [ButtonData] {
        var buttonVars = [ButtonData]()
        do {
            let buttons = try self.database.prepare(self.buttonsTable)
            for row in buttons {
                buttonVars.append(ButtonData(english: row[english], categoryID: row[categoryID], indonesian: row[indonesian]))
            }
        } catch {
            print(error)
        }
        return buttonVars
    }

I'll often put my return stuff in a map, like this:

 func queryDatabase() -> [ButtonData] {
        do {
            return try self.database.prepare(self.buttonsTable).compactMap { row in
                ButtonData(english: row[english], categoryID: row[categoryID], indonesian: row[indonesian]))
            }
        } catch {
            print(error)
        }
        // Return an empty array if we caught an error
        return []
    }

Upvotes: 1

Related Questions