【问题标题】:Converting app from SQLite.swift to GRDB.swift将应用程序从 SQLite.swift 转换为 GRDB.swift
【发布时间】:2021-01-03 01:38:13
【问题描述】:

我正在尝试将我的几个应用程序转换为使用 GRDB.swift。有人有或知道我在哪里可以找到一个文件让我开始吗?我已经阅读了大多数 GRDB 文档,但我没有得到它。下面是一个示例场景。

这是我能够从 SQLite.sift 转换的

class Database
{
    static let shared = Database()
    public let databaseConnection: DatabaseQueue?
    
    private init()
    {
        do
        {
            let fileUrl = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("MyDaatbase.sqlite")
            
            // GRDB
            let databaseConnection = try DatabaseQueue(path: fileUrl.path)
            self.databaseConnection = databaseConnection
        } catch {
            databaseConnection = nil
            let nserror = error as NSError
            print("Cannot connect to Database. Error is: \(nserror), \(nserror.userInfo)")
        }
    }
}

有人可以将其转换为 GRDB 以帮助我开始吗?

static func isAnimation() -> Bool
    {
        let theTable = Table("Settings")
        let theColumn = Expression<String>("AnimateNav")
        var theStatus = false
        
        do {
            for theAnswer in try Database.shared.databaseConnection!.prepare(theTable.select(theColumn)) {
                //print(theAnswer[theColumn])
                let theStatusText = (theAnswer[theColumn])
                
                theStatus = theStatusText == "true" ? true : false
            }
        } catch {
            print("Getting the isAnimation Status failed! Error: \(error)")
        }
        return theStatus
    }

【问题讨论】:

    标签: ios sqlite.swift grdb


    【解决方案1】:

    您可以使用原始 SQL:

    static func isAnimation() -> Bool {
        var theStatus = false
        do {
            let animateNav = try Database.shared.databaseConnection!.read { db in
                String.fetchOne(db, sql: "SELECT AnimateNav FROM Settings")
            }
            theStatus = animateNav == "true" ? true : false
        } catch {
            print("Getting the isAnimation Status failed! Error: \(error)")
        }
        return theStatus
    }
    

    您还可以为Settings 表定义Record type,这是首选的GRDB 方式:

    // Settings.swift
    struct Settings: Codable, FetchableRecord, TableRecord {
        var animateNav: String
        // other properties for other columns in the Settings table
        ...
    }
    
    // Your file
    static func isAnimation() -> Bool {
        var theStatus = false
        do {
            let settings = try Database.shared.databaseConnection!.read { db in
                try Settings.fetchOne(db)
            }
            theStatus = settings?.animateNav == "true" ? true : false
        } catch {
            print("Getting the isAnimation Status failed! Error: \(error)")
        }
        return theStatus
    }
    

    【讨论】:

    • 非常感谢您的回复。我喜欢使用 Struct 的第二个设置。就一件事。 LC 让我包含完整的选择语句:尝试 Settings.fetchOne(db, sql: "SELECT AnimateNav FROM Settings")。我认为这是正确的,而您只是匆忙而忽略了它。
    • 很高兴您感到舒适。 Settings.fetchOne(db)(没有原始 sql)需要 Setting 结构以符合 TableRecord 协议,我忘了在示例代码中添加,是的。我已经更新了。
    • 再次感谢。添加 TableRecord 协议使事情变得更好。那么 Xcode/GRDB 是如何知道要在表中选择哪一列的呢?结构中的项目名称是否需要与表中的列匹配? sql: "从设置中选择 AnimateNav"
    • TableRecord 使用类型名称来提供默认表名(您可以覆盖它),并默认选择所有列(您也可以覆盖)。 Codable records 提供了一个默认的 init(row:) 初始化程序,它将编译器生成的编码键映射到数据库列。许多问题的答案都写在文档中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 2017-12-08
    • 2013-09-28
    • 1970-01-01
    • 2013-02-07
    • 2011-07-16
    相关资源
    最近更新 更多