diff --git a/sqlite/capi.kk b/sqlite/capi.kk index 07cccf5..ff91e4a 100644 --- a/sqlite/capi.kk +++ b/sqlite/capi.kk @@ -71,3 +71,21 @@ pub extern column-integer(^stmt: any, col: int32): int pub extern column-text(^stmt: any, col: int32): string c "kk_sqlite3_column_text" + +// pub extern bind-blob(^stmt: any, col: int32, ^value: bytes): int32 +// c "kk_sqlite3_bind_blob" + +pub extern bind-double(^stmt: any, col: int32, ^value: float64): int32 + c "kk_sqlite3_bind_double" + +pub extern bind-int64(^stmt: any, col: int32, value: int64): int32 + c "kk_sqlite3_bind_int64" + +pub extern bind-null(^stmt: any, col: int32): int32 + c "kk_sqlite3_bind_null" + +pub extern bind-text(^stmt: any, col: int32, ^value: string): int32 + c "kk_sqlite3_bind_text" + +pub extern bind-zeroblob(^stmt: any, col: int32, length: int64): int32 + c "kk_sqlite3_bind_zeroblob" diff --git a/sqlite/sqlite-inline.c b/sqlite/sqlite-inline.c index a8f883f..db9a5d9 100644 --- a/sqlite/sqlite-inline.c +++ b/sqlite/sqlite-inline.c @@ -115,3 +115,30 @@ kk_string_t kk_sqlite3_column_text(kk_box_t cref, int32_t col, kk_context_t *_ct int len = sqlite3_column_bytes(stmt, (int)col); return kk_string_alloc_from_qutf8n((kk_ssize_t)len, (const char *)text, _ctx); } + +int32_t kk_sqlite3_bind_double(kk_box_t cref, int32_t col, double value, kk_context_t *_ctx) { + sqlite3_stmt *stmt = borrow_stmt(cref, _ctx); + return sqlite3_bind_double(stmt, col, value); +} + +int32_t kk_sqlite3_bind_int64(kk_box_t cref, int32_t col, int64_t value, kk_context_t *_ctx) { + sqlite3_stmt *stmt = borrow_stmt(cref, _ctx); + return sqlite3_bind_int64(stmt, col, (sqlite3_int64)value); +} + +int32_t kk_sqlite3_bind_null(kk_box_t cref, int32_t col, kk_context_t *_ctx) { + sqlite3_stmt *stmt = borrow_stmt(cref, _ctx); + return sqlite3_bind_null(stmt, col); +} + +int32_t kk_sqlite3_bind_text(kk_box_t cref, int32_t col, kk_string_t value, kk_context_t *_ctx) { + sqlite3_stmt *stmt = borrow_stmt(cref, _ctx); + kk_ssize_t len = 0; + const char *text = kk_string_cbuf_borrow(value, &len, _ctx); + return sqlite3_bind_text64(stmt, col, text, (sqlite3_uint64)len, SQLITE_TRANSIENT, SQLITE_UTF8); +} + +int32_t kk_sqlite3_bind_zeroblob(kk_box_t cref, int32_t col, int64_t length, kk_context_t *_ctx) { + sqlite3_stmt *stmt = borrow_stmt(cref, _ctx); + return sqlite3_bind_zeroblob64(stmt, col, (sqlite3_uint64)length); +} diff --git a/sqlite/sqlite3.kk b/sqlite/sqlite3.kk index aa2ec60..50e9645 100644 --- a/sqlite/sqlite3.kk +++ b/sqlite/sqlite3.kk @@ -168,3 +168,18 @@ pub fun statement/int(stmt: statement, col: int): int // The leftmost column is numbeered 0. pub fun statement/text(stmt: statement, col: int): string capi/column-text(stmt.cref, col.int32) + +pub fun statement/bind-float64(stmt: statement, col: int, value: float64): sqlite-result + capi/bind-double(stmt.cref, col.int32, value).trusted-result + +pub fun statement/bind-int64(stmt: statement, col: int, value: int64): sqlite-result + capi/bind-int64(stmt.cref, col.int32, value).trusted-result + +pub fun statement/bind-null(stmt: statement, col: int): sqlite-result + capi/bind-null(stmt.cref, col.int32).trusted-result + +pub fun statement/bind-text(stmt: statement, col: int, value: string): sqlite-result + capi/bind-text(stmt.cref, col.int32, value).trusted-result + +pub fun statement/bind-zeroblob(stmt: statement, col: int, length: int64): sqlite-result + capi/bind-zeroblob(stmt.cref, col.int32, length).trusted-result diff --git a/test/test.kk b/test/test.kk index efbeb3b..cc8da20 100644 --- a/test/test.kk +++ b/test/test.kk @@ -10,12 +10,17 @@ tail fun do-while(f: () -> maybe): a Nothing -> do-while(f) Just(r) -> r -fun stmt(db: sqlite3, sql: string) +fun stmt(db: sqlite3, sql: string, bind: maybe = Nothing) println(sql) match db.prepare(sql.slice) Left(r-prep) -> println(" prepare result: " ++ r-prep.show) Right((stmt, rest)) -> println(" prepare remainder: " ++ rest.show) + match bind + Nothing -> () + Just(text) -> + val r = stmt.bind-text(1, text) + println(" bind result: " ++ r.show) val r-step = do-while val r = stmt.step match r @@ -34,7 +39,7 @@ pub fun main() println("open result: " ++ r-open.show) stmt(db, "DROP TABLE IF EXISTS koka; -- reset previous test runs") stmt(db, "CREATE TABLE koka(v TEXT NOT NULL)") - stmt(db, "INSERT INTO koka VALUES ('value inserted from koka');") + stmt(db, "INSERT INTO koka VALUES (?);", Just("value inserted from koka")) stmt(db, "SELECT * FROM koka") val r-close = db.close println("close result: " ++ r-close.show)