Prepared queries can be many times faster depending on use case. So, I think 
they should have been part of stdlib but I guess its too late for v1.

Here is what I meant by "diving into sqlite3.nim"
    
    
    import sqlite3, db_sqlite, strutils, strformat
    
    let dbname = ":memory:"
    let db = open(dbName, "", "", "")
    db.exec(sql"DROP TABLE IF EXISTS test")
    
    let createTableStr = sql"""CREATE TABLE test(
        id INTEGER,
        data BLOB
      )
      """
    
    db.exec(createTableStr)
    
    
    var data : seq[float64]
    data.add(0)
    data.add(1)
    data.add(2)
    data.add(3.14)
    echo "Data to write: ", data
    var bufSize = int(sizeof(float64)/sizeof(byte))*(data.len)
    
    # Insert prepared
    let insert_query = "INSERT INTO test (id, data) VALUES (?, ?)"
    var stmt : PStmt = nil
    var tail : ptr cstring
    
    var err = 
prepare_v2(cast[PSqlite3](db),insert_query.cstring,insert_query.len.cint,stmt,tail)
    if err != SQLITE_OK:
        raise newException(CatchableError,"Query failed")
    
    # repeat
    if stmt.bind_int(1,1) != SQLITE_OK:
        raise newException(CatchableError,"Bind error")
    
    if stmt.bind_blob(2,unsafeAddr(data[0]),bufSize.int32,SQLITE_STATIC) != 
SQLITE_OK:
        raise newException(CatchableError,"Bind error")
    
    err = stmt.step()
    if err != SQLITE_DONE:
        raise newException(CatchableError,"Query couldnt be executed")
    discard stmt.reset()
    # until all inserted
    discard stmt.finalize()
    
    # Select prepared
    var data_read : seq[float64]
    let select_query = "SELECT id,data FROM test"
    
    err = 
prepare_v2(cast[PSqlite3](db),select_query.cstring,select_query.len.cint,stmt,tail)
    if err != SQLITE_OK:
        raise newException(CatchableError,"Query failed")
    
    while true:
        err = stmt.step()
        if err == SQLITE_DONE:
            discard stmt.finalize()
            break
        else:
            if err == SQLITE_ROW:
                var id = stmt.column_int64(0)
                bufsize = stmt.column_bytes(1)
                if bufsize mod sizeof(float64) != 0:
                    raise newException(CatchableError,"Incorrect data")
                var cnt = bufsize div sizeof(float64)
                data_read.setLen(cnt)
                if cnt>0:
                    var buf = stmt.column_blob(1)
                    copyMem(unsafeAddr(data_read[0]),buf,bufsize)
                echo fmt"Row-> id:{id}, data: {data_read}"
            else:
                raise newException(CatchableError,"Query step error")
    
    db_sqlite.close(db)
    
    
    Run

Reply via email to