Help Pleasee
Help Pleasee

Reputation: 211

Swift3 sqlite3_open() open an existing file

let file_url = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil,create: false).appendingPathComponent("asd.db")
var db:OpaquePointer? = nil
if sqlite3_open(file_url.path, &db) == SQLITE_OK
{
    print("Successfully opened connection database!!")
    var q:OpaquePointer? = nil
    if sqlite3_prepare_v2(db, "SELECT * FROM aaa", -1, &q, nil) == SQLITE_OK
    {
        if sqlite3_step(q) == SQLITE_ROW
        {
            let res = sqlite3_column_text(q, 1)
            let name = String(cString: res!)            }
        else
        {
            print("ERROR1!!!!!")
        }
    }
    else
    {
        print("ERROR!2!!!!")
    }
}

I have database file named "asd.db" in the proejct and I am trying to open and read data from the database.

I don't know why but sqlite3_open in not able to find my database file, so it's creates new one without my tables.

How can I fix it?

Upvotes: 2

Views: 4042

Answers (1)

Rob
Rob

Reputation: 437802

  1. If you don't want SQLite to create new databases, use sqlite3_open_v2 (with SQLITE_OPEN_READWRITE, but not the SQLITE_OPEN_CREATE option) rather than sqlite3_open.

  2. If you ran the app once and you have a blank database in your documents folder, delete the app and reinstall to get rid of that blank database.

  3. If you included a database "in your project" (and assuming you added it to the target in question), then that means that the database will be found in your bundle.

    The standard process is to write a routine to see if the database exists in the documents folder, and if not, copy it from the bundle to the documents folder before trying to open it from the documents folder.

    Or, alternatively, just try opening it in the documents folder, and if that fails because the file is not found, copy it from the bundle to the documents folder and try again. For example:

    var db:OpaquePointer? = nil
    
    /// Open database
    ///
    /// - returns: Return `true` if successful; return `false` on error.
    
    func openDatabase() -> Bool {
        do {
            let manager = FileManager.default
    
            let documentsURL = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("asd.db")
    
            var rc = sqlite3_open_v2(documentsURL.path, &db, SQLITE_OPEN_READWRITE, nil)
            if rc == SQLITE_CANTOPEN {
                let bundleURL = Bundle.main.url(forResource: "asd", withExtension: "db")!
                try manager.copyItem(at: bundleURL, to: documentsURL)
                rc = sqlite3_open_v2(documentsURL.path, &db, SQLITE_OPEN_READWRITE, nil)
            }
    
            if rc != SQLITE_OK {
                print("Error: \(rc)")
                return false
            }
    
            return true
        } catch {
            print(error)
            return false
        }
    }
    

Upvotes: 7

Related Questions