Потеря данных SQLite в таблицах - Swift 5, Xcode 11.1 - PullRequest
0 голосов
/ 23 октября 2019

В AppDelegate Я вызываю функции в структуре для создания базы данных SQLite и трех таблиц, необходимых для моего приложения. Используя функции в структурах, я вставляю, обновляю, удаляю записи в этих трех таблицах во многих контроллерах представления. Я вставил записи в первую таблицу (таблица сотрудников). Я получаю сообщения о подтверждении печати консоли, и данные заполняются в других табличных представлениях, подтверждающих вставку данных о сотрудниках (для отображения View Controller я перемещаю эти записи таблицы в массив словарей). Работая с QA-тестированием других областей применения, я обнаружил, что в табличном представлении сотрудника для записей сотрудников пусто. Я сделал точки останова, чтобы отладить проблему. Цикл while, который я использую в функции запроса, выходит без данных, которые я только что создал несколько часов назад.

Моя база данных SQLLite создается с сообщением

"Успешно открытое соединение с базой данных в / var / mobile / Containers / Data / Application / BB0FB403-7D26-4837-8BCF-97C23D195717/Documents/MyDatabaseNameHere.sqlite"

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

"Успешно открылась новая база данных в / var / mobile / Containers / Data / Application / CE3F0D84-ED0C-40A2-823A-39E2B8C972BE / Documents/MyDatabaseNameHere.sqlite"

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

Я провел много исследований по этому вопросу. База данных, кажется, находится в каталоге документов в iPhone, что, как я думаю, ожидается (а не в комплекте). Я подозреваю, что путь к файлу меняется каждый раз, в результате чего приложение пропускает таблицы с данными.

Я предполагаю, что изменение пути к файлу базы данных является причиной проблемы. Я могу ошибаться

Любая помощь приветствуется.

Отредактировано для добавления кода:

Из AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate {



func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    UserDefaults.standard.register(defaults: [String: AnyObject]())

    //if UserDefaults.standard.bool(forKey: "maintenance_identifier") {
    //    DatabaseClass.deleteRecords()
    Thread.sleep(forTimeInterval: 2.0)

// The code below can be commented out after initial creation of DB
// and tables
    let initDB = SQLiteDB()
    _ = initDB.findFile()

    let initEmp = SQLiteEmployees()
    _ = initEmp.createEmployeeTable()
    _ = initEmp.deleteEmpRecords(inEmpId: nil)
    _ = initEmp.createEmployees()
    _ = initEmp.queryEmployeeData(in_emp_id: nil)

    let initHdr = SQLiteTables()
    _ = initHdr.createHeaderTable()
    _ = initHdr.createChildTable()
    let deleteHdr = SQLiteHeader()
    _ = deleteHdr.deleteRecords()

    return true

}

структуры и функции

import Foundation
import SQLite3

struct SQLiteDB {
// open Sqlite Database
    func openDatabase() -> OpaquePointer?
    {
    var db: OpaquePointer? = nil
    let fileUrl = try!
        FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("MailTrackingDatabase2.sqlite")
    if sqlite3_open(fileUrl.path, &db) == SQLITE_OK{
        print("Successfully opened new database at \(fileUrl.path)")
    } else {
        print("Unable to open database")
        let errorMessage = String.init(cString: sqlite3_errmsg(db))
        print("Error Message = \(errorMessage)")
        return nil
    }
    return db
}

func findFile() -> OpaquePointer? {

    var db: OpaquePointer? = nil
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    let url = URL(fileURLWithPath: documentsPath)

    let fileManager = FileManager.default
    let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: url.path)!
    var db_count = 0
    while let element = enumerator.nextObject() as? String {
        guard element.hasSuffix(".sqlite")
            else { continue } 
        if db_count > 0 && element.hasSuffix(".sqlite") {
            print ("Too Many Databases open at -> \(documentsPath)")
            return nil
        }
        if sqlite3_open(documentsPath + "/" + element, &db) == SQLITE_OK{
            print("Found existing database. Successfully opened connection at \(documentsPath + "/" + element)")
            db_count += 1
        } else {
            print("Unable to open database")
            let errorMessage = String.init(cString: sqlite3_errmsg(db))
            print("Error Message = \(errorMessage)")
            return nil
        }
    }

    if db_count == 0 {
        print("going to create new DB")
        db = self.openDatabase()
    }
    return db
}

Запрос данных из таблицы сотрудников:

     // Query Employee data from SQLite DB
func queryEmployeeData (in_emp_id: String?) -> (out_emp_id: String, out_email: String, out_first_name: String, out_last_name: String, out_location: String, out_mobile: String, out_work: String, out_site: String ){

    var queryEmployeeString: String = " "

    if in_emp_id != nil {
        queryEmployeeString = "SELECT EMPLOYEE_ID, EMAIL, FIRST_NAME, LAST_NAME, LOCATION, MOBILE, WORK, SITE FROM MT_EMPLOYEES WHERE EMPLOYEE_ID = (?);"
    } else {
        queryEmployeeString = "SELECT EMPLOYEE_ID, EMAIL, FIRST_NAME, LAST_NAME, LOCATION, MOBILE, WORK, SITE FROM MT_EMPLOYEES;"
    }

    var empID       : String = " "
    var emailID     : String = " "
    var firstName   : String = " "
    var lastName    : String = " "
    var location    : String = " "
    var mobileNum   : String = " "
    var workNum     : String = " "
    var siteName    : String = " "

    let openDB = SQLiteDB()
    let db = openDB.findFile()
    var queryEmployeeStatement: OpaquePointer? = nil

    if sqlite3_prepare_v2(db, queryEmployeeString, -1, &queryEmployeeStatement, nil) == SQLITE_OK {

        if in_emp_id != nil {
           sqlite3_bind_text(queryEmployeeStatement, 1, in_emp_id, -1, nil)
        }

        while (sqlite3_step(queryEmployeeStatement) == SQLITE_ROW) {

            let queryResultCol1 = sqlite3_column_text(queryEmployeeStatement, 0)
            if queryResultCol1 != nil {
               empID  = String(cString: queryResultCol1!)
            }
            print("Employee ID from Query = \(empID)")
            let queryResultCol2 = sqlite3_column_text(queryEmployeeStatement, 1)
            if queryResultCol2 != nil {
               emailID  = String(cString: queryResultCol2!)
            }

            let queryResultCol3 = sqlite3_column_text(queryEmployeeStatement, 2)
            if queryResultCol3 != nil {
                firstName = String(cString: queryResultCol3!)
            }

            let queryResultCol4 = sqlite3_column_text(queryEmployeeStatement, 3)
            if queryResultCol4 != nil {
                lastName = String(cString: queryResultCol4!)
            }

            let queryResultCol5 = sqlite3_column_text(queryEmployeeStatement, 4)
            if queryResultCol5 != nil {
                location = String(cString: queryResultCol5!)
            }

            let queryResultCol6 = sqlite3_column_text(queryEmployeeStatement, 5)
            if queryResultCol6 != nil {
                mobileNum = String(cString: queryResultCol6!)
            }

            let queryResultCol7 = sqlite3_column_text(queryEmployeeStatement, 6)
            if queryResultCol7 != nil {
                workNum = String(cString: queryResultCol7!)
            }

            let queryResultCol8 = sqlite3_column_text(queryEmployeeStatement, 7)
            if queryResultCol8 != nil {
                siteName = String(cString: queryResultCol8!)
            }

            print("SQLiteEmployees: Employee Table Details")
            print("Employee Email: \(emailID)")
            print("Employee Site Name: \(String(describing: siteName))")

            // append values to global array of dictionary

            // static var empDict: [String: String] = [:]
            // static var arrayEmployees = Array<Dictionary<String, String>>()

            AppGlobal.empDict["empid"] =  empID
            AppGlobal.empDict["email"] = emailID
            AppGlobal.empDict["firstname"] = firstName
            AppGlobal.empDict["lastname"] = lastName
            AppGlobal.empDict["location"] = location
            AppGlobal.empDict["mobile"] = mobileNum
            AppGlobal.empDict["work"] = workNum
            AppGlobal.empDict["site"] = siteName

            AppGlobal.arrayEmployees.append(AppGlobal.empDict)
        }
     print("outside while")
    } else {
            print ("SQLiteEmployees:  Error Preparing Employee Data SQLite Query Statement")
            let errorMessage = String.init(cString: sqlite3_errmsg(db))
            print("Error Message = \(errorMessage)")
        }
    sqlite3_finalize(queryEmployeeStatement)
        return (empID, emailID, firstName, lastName, location, mobileNum, workNum, siteName)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...