如何在sqlite中升级数据库版本并在swift中的表中添加新列

时间:2016-04-25 05:55:36

标签: ios swift sqlite

我已经为我的应用程序创建了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()
    }

2 个答案:

答案 0 :(得分:2)

以下代码在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")
        }
    }
}

答案 1 :(得分:0)

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

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