Menyimpan data ke dalam database sqlite3 di Swift

Oct 16 2020

Saya sedang mengerjakan aplikasi yang menggunakan PencilKit. Saya mencoba menyimpan gambar PK dalam bentuk data dalam database sqlite3 tetapi tidak menyimpan. Saya berasumsi masalahnya ada pada fungsi simpan, bukan yang mengambil data gambar untuk ditampilkan karena baris gambar dalam database kosong ketika saya melakukan kueri langsung di terminal.

func save(canvas: Canvas) {
    // connect to database
    connect()
    
    // canvas.drawing is already in the form of data not PK drawing here
    let drawingData = canvas.drawing
    
    drawingData.withUnsafeBytes { drawingBuffer in
        
        let drawingPtr = drawingBuffer.baseAddress!

        var statement: OpaquePointer!
        
        if sqlite3_prepare_v2(database, "UPDATE drawings SET drawing = ? WHERE rowid = ?", -1, &statement, nil) != SQLITE_OK {
            print("Could not create (update) query")
        }
        
        sqlite3_bind_blob(statement, 1, drawingPtr, -1, nil)
        sqlite3_bind_int(statement, 2, Int32(canvas.id))
        
        if sqlite3_step(statement) != SQLITE_DONE {
            print("Could not execute update statement")
        }
        
        sqlite3_finalize(statement)

    }
}

Jawaban

2 Rob Oct 16 2020 at 13:01

Beberapa pengamatan:

  1. Dengan sqlite3_bind_blob, parameter keempat adalah ukuran, yang diperlukan, dan tidak boleh negatif. Dengan sqlite3_bind_text, Anda dapat memasukkan -1nilai karena string C diakhiri dengan null dan dapat mengetahui di mana string berakhir, tetapi tidak dapat melakukannya dengan blob.

    Seperti yang dikatakan dalam dokumentasi :

    Jika parameter keempat sqlite3_bind_blob()adalah negatif, maka perilakunya tidak ditentukan.

    Jadi, mungkin:

    guard let blob = drawingBuffer.baseAddress else { return }
    let count = Int32(drawingBuffer.count)
    

    Lalu:

    sqlite3_bind_blob(statement, 1, blob, count, nil)
    
  2. Selain itu, jika panggilan SQLite gagal, Anda harus mencetak kesalahan tersebut, jika tidak, Anda akan buta, mis

    let errorMessage = sqlite3_errmsg(database).map { String(cString: $0) } ?? "Unknown error"
    print("failure preparing UPDATE statement: \(errorMessage)")
    

    Anda harus melakukannya setiap kali Anda memeriksa kode pengembalian SQLite. Seringkali ini akan memudahkan untuk mendiagnosis mengapa panggilan gagal.