0

SQLite.Swift 版本有效。使用 GRDB 版本时,应用程序崩溃,我收到以下错误。线程 1:致命错误:数据库方法不可重入。

我在 GRDB 版本上做错了什么。

这是 SQLite.Swift 版本。

static func getCommon_CategoryXX(trick_Category_XRef_Table: String, category_Table: String, trickID: Int64) -> String
{
    let trick_Type_XRef_Table = Table(trick_Category_XRef_Table)
    let type_ID_Trick_XRef = Expression<Int64>("Type_ID")
    let trick_ID_Type_XRef = Expression<Int64>("Common_ID")
    
    let itemTypse_Table = Table(category_Table)
    let itemID = Expression<Int64>("ItemID")
    let itemName = Expression<String>("Item_Name")
            
    var categoty_Name: String = ""
    
    let theQuery = trick_Type_XRef_Table.join(.inner, itemTypse_Table, on: itemID == type_ID_Trick_XRef).filter(trick_ID_Type_XRef == trickID).select(itemName)
    
    do {
        for theName in try Database.shared.databaseConnection!.prepare(theQuery)
        {
            categoty_Name = theName[itemName]
        }
    } catch {
        print("Couldn't get the category type name! \(category_Table) \(error)")
    }
    // print(categoty_Name)
    // print("Cat XRef Table \(trick_Category_XRef_Table)")
    // print("Cat Table \(category_Table)")
    
    return categoty_Name
}

这就是我所拥有的 GRDB 版本。

static func getCommon_Category(trick_Category_XRef_Table: String, category_Table: String, trickID: Int64) -> String {

    var categoty_Name: String = ""
    
    do {
        try Database_GRDB.shared.databaseConnection!.read { db in
            categoty_Name = try (String.fetchOne(db, sql: "SELECT Item_Name FROM " + category_Table + " INNER JOIN " + trick_Category_XRef_Table + " ON ItemID = Type_ID WHERE Common_ID = ?", arguments: [trickID]) ?? "")
        }
                    
    } catch {
        print("Couldn't get the category type name! \(category_Table) \(error)")
    }
    // print(categoty_Name)
    // print("Cat XRef Table \(trick_Category_XRef_Table)")
    // print("Cat Table \(category_Table)")
    return categoty_Name
}
4

1 回答 1

-1

所以我最终建立了第二个 Db 连接并将其设置为全局。似乎工作正常。

这是导致问题的区域。我使用顶部的原始 Db 连接和 3 ModelData.getCommon_Category 的全局连接。

    func getitem_List() -> [item_List]
    {
        var theArray = [item_List]()
        
        do {
            try Database_GRDB.shared.databaseConnection!.read { db in
                for theData in try item_List.fetchAll(db, sql: "SELECT * FROM My_items ORDER BY item_Name")
                {
                    let theType = ModelData.getCommon_Category(item_Category_XRef_Table: "item_Type_XRef", category_Table: "item_Types", itemID: theData.itemID)
                    let theStyle = ModelData.getCommon_Category(item_Category_XRef_Table: "item_Style_XRef", category_Table: "item_Styles", itemID: theData.itemID)
                    let theSupplier = ModelData.getCommon_Category(item_Category_XRef_Table: "item_Supplier_XRef", category_Table: "Manufacturers_List", itemID: theData.itemID)
                    
                    theArray.append(item_List(itemID: theData.itemID, item_Name: theData.item_Name, itemType: theType, manufacturer: theSupplier, itemStyle: theStyle, item_ForSale: theData.item_ForSale, item_Sold: theData.item_Sold, Practice_item: theData.Practice_item))
                }
            }
        } catch {
            print("Getting item list failed: \(error)")
        }
        return theArray
    }


    static func getCommon_Category(item_Category_XRef_Table: String, category_Table: String, itemID: Int64) -> String
    {
        var categoty_Name: String = ""
        
        do {
            try dbQueue_GRDB.read { db in
                categoty_Name = try (String.fetchOne(db, sql: "SELECT Item_Name FROM " + category_Table + " INNER JOIN " + item_Category_XRef_Table + " ON ItemID = Type_ID WHERE Common_ID = ?", arguments: [itemID]) ?? "")
            }
            
        } catch {
            print("Couldn't get the category type name! \(category_Table) \(error)")
        }
//         print(categoty_Name)
//         print("Cat XRef Table \(item_Category_XRef_Table)")
//         print("Cat Table \(category_Table)")
        return categoty_Name
    }

我创建了第二个 Db 连接作为全局连接。

var dbQueue_GRDB = DatabaseQueue()

static func openTheDB()
{
    do {
        let fileUrl = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("SmartWare_MagicWare.sqlite")
        dbQueue_GRDB = try DatabaseQueue(path: fileUrl.path)
        
        // print("Database is open")
    } catch {
        print("Opening the Db failed! \(error)")
    }
}

这是我原来的 Db 连接。

class Database_GRDB
{
    static let shared = Database_GRDB()
    
    // GRDB
    public let databaseConnection: DatabaseQueue?
    
    private init()
    {
        do
        {
            let fileUrl = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("MyApp.sqlite")
            
            // GRDB
            let dbConnection = try DatabaseQueue(path: fileUrl.path)
            self.databaseConnection = dbConnection
            
        } catch {
            databaseConnection = nil
            print("Cannot connect to Database. \(error)")
        }
    }
}
于 2021-03-18T01:14:27.700 回答