【问题标题】:How to upgrade database version in sqlite and add new column in table in swift如何在sqlite中升级数据库版本并在swift中的表中添加新列
【发布时间】:2016-04-25 05:55:36
【问题描述】:

我已经为我的应用程序创建了 sqlite 表,但现在我想在表中添加一个新列到数据库中。 ALTER TABLE 将帮助我解决这个问题,但首先我想检查数据库版本。 我正在使用 PRAGMA user_version 检查用户版本并更新 user_version 但它总是将 user_version 返回为 0。

var database: FMDatabase? = nil

    class func getInstance() -> ModelManager{
        if(sharedInstance.database == nil){
            sharedInstance.database = FMDatabase(path: Util.getPath("XXXX.sqlite"))
        }
        return sharedInstance
    }


    func userVersion(){
        sharedInstance.database!.open()
        var userVer = Int()
        let resultSet = sharedInstance.database?.executeQuery("pragma user_version", withArgumentsInArray: nil)
        userVer =  Int(resultSet!.intForColumn("user_version"))
        print("user version : ",userVer)
        sharedInstance.database!.close()
    }

    func updateUserVersion(){
        sharedInstance.database!.open()
        sharedInstance.database?.executeUpdate("PRAGMA user_version=1", withArgumentsInArray: nil)
        sharedInstance.database!.close()
    }

【问题讨论】:

    标签: ios swift sqlite


    【解决方案1】:

    以下代码适用于 Swift 4

    import UIKit
    import FMDB
    
    class DataConnection: NSObject {
        static let databaseVersion = 2
        static var isDatabaseUpdated = false
        static var database: FMDatabase? = nil
        class func databaseSetup() {
            if database == nil {
                let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
                let dpPath = docsDir.appendingPathComponent("database.sqlite")
                let file = FileManager.default
                if(!file.fileExists(atPath: dpPath.path)) {
                    copyDatabase(file: file, dpPath: dpPath)
                    database = FMDatabase(path: dpPath.path)
                    do {
                        database!.open()
                        try database!.executeUpdate("PRAGMA user_version = \(databaseVersion)", values: nil)
                        database!.close()
                        isDatabaseUpdated = true
                    }catch {
                        print("Error on updating user_version")
                    }
                }else {
                    database = FMDatabase(path: dpPath.path)
                    if !isDatabaseUpdated {
                        var currentVersion = 0
                        do {
                            database!.open()
                            let resultSet: FMResultSet! = try database!.executeQuery("pragma user_version", values: nil)
                            while resultSet.next() {
                                currentVersion = Int(resultSet.int(forColumn: "user_version"))
                            }
                            database!.close()
                        }catch {
                            print("Error on getting user_version")
                        }
    
                        if databaseVersion > currentVersion {
                            do {
                                try file.removeItem(at: dpPath)
                            }catch {
                                print("Error on getting user_version")
                            }
                            copyDatabase(file: file, dpPath: dpPath)
                            database = FMDatabase(path: dpPath.path)
                            do {
                                database!.open()
                                try database!.executeUpdate("PRAGMA user_version = \(databaseVersion)", values: nil)
                                database!.close()
                                isDatabaseUpdated = true
                            }catch {
                                print("Error on updating user_version")
                            }
                        }else {
                            isDatabaseUpdated = true
                        }
                    }
                }
            }
        }
    
        private class func copyDatabase(file: FileManager, dpPath: URL){
            let dpPathApp = Bundle.main.path(forResource: "database", ofType: "sqlite")
            print("resPath: "+String(describing: dpPathApp))
            do {
                try file.copyItem(atPath: dpPathApp!, toPath: dpPath.path)
                print("copyItemAtPath success")
            } catch {
                print("copyItemAtPath fail")
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      在访问 intForColumn 之前,您需要在 resultSet 上调用 next() 方法,以便它加载第一行。

      此外,由于您使用 FMDB,请查看https://github.com/groue/GRDB.swift:它是 SQLite 的 Swift 包装器,FMDB 用户看起来很熟悉。但这次你只需写let userVer = Int.fetchOne(db, "pragma user_version")

      【讨论】:

        猜你喜欢
        • 2011-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 2016-03-14
        • 1970-01-01
        相关资源
        最近更新 更多