iOS SQLite.swift, по поводу обновления приложения?

Что касается великолепного и удивительного SQLite.swift, мне интересно

У вас есть приложение v7. Есть обновление до v8. Пользователь X обновляет v7 до v8 с помощью магазина приложений.

Скажем, в версии 8 мы немного изменили одну из таблиц sql, возможно, добавили столбец или переименовали столбец.

Нужно ли или нужно что-то особенное делать в SQLite.swift в этом случае?

Как с этим справиться SQLite.swift?

(Например, в Android есть удобный onUpgrade в их вспомогательный класс ... который связан с собственным набором сложных проблем.)


person Fattie    schedule 12.12.2016    source источник
comment
щедрость здесь !!!   -  person Fattie    schedule 17.12.2016


Ответы (2)


Реализация SQLiteOpenHelper довольно просто:

        db = SQLiteDatabase.openDatabase(...);

        onConfigure(db);

        int version = db.getVersion();
        if (version != mNewVersion) {
            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

Сделайте то же самое в Swift.

Чтобы узнать, как реализовать onUpgrade(), см. SQLiteOpenHelper onUpgrade () Confusion Android.

person CL.    schedule 12.12.2016
comment
Привет, CL., (1) спасибо за это (2) я понимаю принцип (3) обратите внимание, что в этом коде действительно onUpgrade является сутью вопроса (изменяйте таблицы, но сохраняя наши данные нетронутыми, насколько это возможно с логической точки зрения) ) - person Fattie; 12.12.2016
comment
Откуда он получает db.getVersion () и куда сохраняет db.setVersion (mNewVersion)? Сохраняется ли он в таблице в базе данных sqlite? - person 阿尔曼; 14.08.2017
comment
@ 阿尔曼 Он использует PRAGMA user_version, но вы также можете использовать некоторую таблицу. - person CL.; 14.08.2017

Есть 2 случая, когда вы хотите обновить базу данных:

  • Не хранятся пользовательские данные: база данных содержит только предопределенные данные, и вы хотите изменить структуру таблиц, добавить новые строки, добавить новые таблицы ....

  • Там хранятся пользовательские данные: вы хотите изменить данные, а также сохранить пользовательские данные.

В приведенном ниже примере объясняется, как можно решить первый случай. Второй случай потребует добавления дополнительной логики на основе примера.

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")
        }
    }
}

В этом примере, когда вы выпускаете новую версию приложения и хотите обновить базу данных, вам просто нужно увеличить переменную databaseVersion.

person vietlh    schedule 25.10.2018