dimanche 8 mai 2016

Swift 2 sqlite - library routine called out of sequence

I am using below code to insert records to sqlite. SQLite DB is already created and sqlite file exists in the right place. However, when i run my test it gives an error: Any help on this is appreciated. Already spent some time on this. By the way, am new to SWIFT :(

"sqlite3_errmsg(carParkDB) UnsafePointer 0x000000010f44a863 "library routine called out of sequence"

Error appears at the first bind statement

sqlite3_bind_text(insertStmt, 1, carParkData.dataSource.rawValue, -1, SQLITE_TRANSIENT)

Below is my DAOImpl

import Foundation

class CarParkDaoImpl : CarParkDao{

var carParkDB : COpaquePointer = nil
var insertStmt: COpaquePointer = nil

let SQLITE_TRANSIENT = unsafeBitCast(-1, sqlite3_destructor_type.self)

func initializeDB(){
    let carParkDataSQ = Constants.Paths.path + "/CarParkData.sqlite"
    print("Sqlite file: \(carParkDataSQ)")

    if(sqlite3_open(carParkDataSQ, &carParkDB) == SQLITE_OK){
        let ret:Int32 = sqlite3_exec(carParkDB, Constants.CAR_PARK_SQL.createSql, nil, nil, nil);
        if ( ret != SQLITE_OK){
            print("Failed to create table: \(Constants.CAR_PARK_SQL.createSql)")
            print("Error:  \(sqlite3_errmsg(carParkDB))")
            closeDB()
        }
    }else{
        print("Falied to open : \(carParkDataSQ)")
        print("Error:  \(sqlite3_errmsg(carParkDB))")
        closeDB()
    }
}

func closeDB(){
    sqlite3_close(carParkDB)
}


init(){
    initializeDB()
}

/**
 Responsible to insert the car park data

 - Parameter carParkData: CarParkData.
 - returns Bool
 */
func insert(carParkData: CarParkData) -> Bool{
    prepareInsStatments()
    var ret: Bool = false
    sqlite3_bind_text(insertStmt, 1, carParkData.dataSource.rawValue, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStmt, 2, carParkData.address, -1, SQLITE_TRANSIENT)
    sqlite3_bind_double(insertStmt, 3, carParkData.latitude)
    sqlite3_bind_double(insertStmt, 4, carParkData.longitude)
    sqlite3_bind_int(insertStmt, 5, Int32(carParkData.ltaCarParkID))
    sqlite3_bind_text(insertStmt, 6, carParkData.ltaArea, -1, SQLITE_TRANSIENT)
    sqlite3_bind_int(insertStmt, 7, Int32(carParkData.ltaLots))
    sqlite3_bind_double(insertStmt, 8, carParkData.ltaPrice)
    sqlite3_bind_text(insertStmt, 9, carParkData.hdbShortTermParking, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStmt, 10, carParkData.hdbCarParkType, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStmt, 11, carParkData.hdbFreeParking, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStmt, 12, carParkData.hdbNightParking, -1, SQLITE_TRANSIENT)
    sqlite3_bind_int(insertStmt, 13, Int32(carParkData.hdbId))
    sqlite3_bind_text(insertStmt, 14, carParkData.hdbAdHocParking, -1, SQLITE_TRANSIENT)
    sqlite3_bind_text(insertStmt, 15, carParkData.hdbCarParkNo, -1, SQLITE_TRANSIENT)
    let rc:Int32 = sqlite3_bind_text(insertStmt, 16, carParkData.hdbTypeOfParking, -1, SQLITE_TRANSIENT)

    if (rc != SQLITE_OK) {
        print(stderr, "failed to prepare statement: %s\n",
                sqlite3_errmsg(carParkDB));
        sqlite3_close(carParkDB);
        return ret;
    }

    if(sqlite3_step(insertStmt) == SQLITE_DONE){
        ret = true;
    }
    sqlite3_reset(insertStmt)
    sqlite3_clear_bindings(insertStmt)
    return ret
}


/**
 Responsible to finalize all the prepared statements
 */
func finalize(){
    sqlite3_finalize(insertStmt)
    sqlite3_finalize(updateStmt)
    sqlite3_finalize(deleteStmt)
    sqlite3_finalize(selectAllStmt)
    sqlite3_finalize(selectByIdStmt)
    sqlite3_finalize(selectByDataSourceStmt)
}




func prepareInsStatments(){
    let stmt = Constants.CAR_PARK_SQL.insertSql.cStringUsingEncoding(NSUTF8StringEncoding)
    let ret:Int32 = sqlite3_prepare_v2(carParkDB, stmt!, -1, &insertStmt, nil)
    if (ret != SQLITE_OK) {
        print(stderr, "failed to prepare statement: %s\n",
                sqlite3_errmsg(carParkDB));
        sqlite3_close(carParkDB);
    }
}

}

Here is my insert sql

   static let insertSql:String =
        "INSERT INTO CAR_PARK_DATA ( DATASOURCE, ADDRESS, LATITUDE, LONGITUDE "
            + " , LTA_CAR_PARK_ID, LTA_AREA, LTA_LOTS, LTA_PRICE, HDB_SHORT_TERM_PAKING "
            + " , HDB_CAR_PARK_TYPE, HDB_FREE_PARKING, HDB_NIGHT_PARKING, HDB_ID "
            + " , HDB_ADHOC_PARKING, HDB_CAR_PARK_NO, HDB_TYPE_PARK_SYSTEM ) "
            + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "

Here is my test method

func testInsert(){
    carParkData = CarParkData(dataType: DataSourceType.LTA.rawValue, address: "This is Test address", latitude: 100.0, longitude: 200.0, carParkID : 10, ltaCarParkID : 20, ltaArea: "LTA Area", ltaLots: 20, hdbShortTermParking: "Test HDB Short Praking", hdbCarParkType: "HDB Car Park Type", hdbFreeParking: "HDB Free Parking", hdbNightParking: "HDB Night Parking", hdbId : 30, hdbAdHocParking: "HDB Ad Hoc Parking", hdbCarParkNo: "HDB Car Park No", hdbTypeOfParking: "HDB Parking type", ltaPrice: 10.96778, favourite: true)
    var val:Bool = carParkDao.insert(carParkData);
    XCTAssertTrue(val)

Aucun commentaire:

Enregistrer un commentaire