param count, name, index
This commit is contained in:
@@ -80,20 +80,29 @@ pub extern column-text(^stmt: any, col: int32): string
|
|||||||
// pub extern bind-blob(^stmt: any, col: int32, ^value: bytes): int32
|
// pub extern bind-blob(^stmt: any, col: int32, ^value: bytes): int32
|
||||||
// c "kk_sqlite3_bind_blob"
|
// c "kk_sqlite3_bind_blob"
|
||||||
|
|
||||||
pub extern bind-double(^stmt: any, col: int32, ^value: float64): int32
|
pub extern bind-double(^stmt: any, param: int32, ^value: float64): int32
|
||||||
c "kk_sqlite3_bind_double"
|
c "kk_sqlite3_bind_double"
|
||||||
|
|
||||||
pub extern bind-int64(^stmt: any, col: int32, value: int64): int32
|
pub extern bind-int64(^stmt: any, param: int32, value: int64): int32
|
||||||
c "kk_sqlite3_bind_int64"
|
c "kk_sqlite3_bind_int64"
|
||||||
|
|
||||||
pub extern bind-null(^stmt: any, col: int32): int32
|
pub extern bind-null(^stmt: any, param: int32): int32
|
||||||
c "kk_sqlite3_bind_null"
|
c "kk_sqlite3_bind_null"
|
||||||
|
|
||||||
pub extern bind-text(^stmt: any, col: int32, ^value: string): int32
|
pub extern bind-text(^stmt: any, param: int32, ^value: string): int32
|
||||||
c "kk_sqlite3_bind_text"
|
c "kk_sqlite3_bind_text"
|
||||||
|
|
||||||
pub extern bind-zeroblob(^stmt: any, col: int32, length: int64): int32
|
pub extern bind-zeroblob(^stmt: any, param: int32, length: int64): int32
|
||||||
c "kk_sqlite3_bind_zeroblob"
|
c "kk_sqlite3_bind_zeroblob"
|
||||||
|
|
||||||
pub extern clear-bindings(^stmt: any): int32
|
pub extern clear-bindings(^stmt: any): int32
|
||||||
c "kk_sqlite3_clear_bindings"
|
c "kk_sqlite3_clear_bindings"
|
||||||
|
|
||||||
|
pub extern parameter-count(^stmt: any): int32
|
||||||
|
c "kk_sqlite3_parameter_count"
|
||||||
|
|
||||||
|
pub extern parameter-name(^stmt: any, param: int32): string
|
||||||
|
c "kk_sqlite3_parameter_name"
|
||||||
|
|
||||||
|
pub extern parameter-index(^stmt: any, name: string): int32
|
||||||
|
c "kk_sqlite3_parameter_index"
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ static inline sqlite3 *borrow_db(kk_box_t cref, kk_context_t *_ctx) {
|
|||||||
|
|
||||||
kk_string_t kk_sqlite3_errstr(int32_t x, kk_context_t *_ctx) {
|
kk_string_t kk_sqlite3_errstr(int32_t x, kk_context_t *_ctx) {
|
||||||
const char *s = sqlite3_errstr((int)x);
|
const char *s = sqlite3_errstr((int)x);
|
||||||
|
// NOTE(zephyr): kk_string_alloc_from_utf8 calls C stdlib strlen(),
|
||||||
|
// which is not guaranteed to handle a NULL pointer.
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
return kk_string_empty();
|
return kk_string_empty();
|
||||||
}
|
}
|
||||||
@@ -116,34 +118,54 @@ kk_string_t kk_sqlite3_column_text(kk_box_t cref, int32_t col, kk_context_t *_ct
|
|||||||
return kk_string_alloc_from_qutf8n((kk_ssize_t)len, (const char *)text, _ctx);
|
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) {
|
int32_t kk_sqlite3_bind_double(kk_box_t cref, int32_t param, double value, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
return sqlite3_bind_double(stmt, col, value);
|
return sqlite3_bind_double(stmt, param, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t kk_sqlite3_bind_int64(kk_box_t cref, int32_t col, int64_t value, kk_context_t *_ctx) {
|
int32_t kk_sqlite3_bind_int64(kk_box_t cref, int32_t param, int64_t value, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
return sqlite3_bind_int64(stmt, col, (sqlite3_int64)value);
|
return sqlite3_bind_int64(stmt, param, (sqlite3_int64)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t kk_sqlite3_bind_null(kk_box_t cref, int32_t col, kk_context_t *_ctx) {
|
int32_t kk_sqlite3_bind_null(kk_box_t cref, int32_t param, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
return sqlite3_bind_null(stmt, col);
|
return sqlite3_bind_null(stmt, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t kk_sqlite3_bind_text(kk_box_t cref, int32_t col, kk_string_t value, kk_context_t *_ctx) {
|
int32_t kk_sqlite3_bind_text(kk_box_t cref, int32_t param, kk_string_t value, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
kk_ssize_t len = 0;
|
kk_ssize_t len = 0;
|
||||||
const char *text = kk_string_cbuf_borrow(value, &len, _ctx);
|
const char *text = kk_string_cbuf_borrow(value, &len, _ctx);
|
||||||
return sqlite3_bind_text64(stmt, col, text, (sqlite3_uint64)len, SQLITE_TRANSIENT, SQLITE_UTF8);
|
return sqlite3_bind_text64(stmt, param, 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) {
|
int32_t kk_sqlite3_bind_zeroblob(kk_box_t cref, int32_t param, int64_t length, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
return sqlite3_bind_zeroblob64(stmt, col, (sqlite3_uint64)length);
|
return sqlite3_bind_zeroblob64(stmt, param, (sqlite3_uint64)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t kk_sqlite3_clear_bindings(kk_box_t cref, kk_context_t *_ctx) {
|
int32_t kk_sqlite3_clear_bindings(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
return sqlite3_clear_bindings(stmt);
|
return sqlite3_clear_bindings(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_parameter_count(kk_box_t cref, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
return (int32_t)sqlite3_bind_parameter_count(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
kk_string_t kk_sqlite3_parameter_name(kk_box_t cref, int32_t param, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
const char *name = sqlite3_bind_parameter_name(stmt, (int)param);
|
||||||
|
if (name == NULL) {
|
||||||
|
return kk_string_empty();
|
||||||
|
}
|
||||||
|
return kk_string_alloc_from_utf8(name, _ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t kk_sqlite3_parameter_index(kk_box_t cref, kk_string_t name, kk_context_t *_ctx) {
|
||||||
|
sqlite3_stmt *stmt = borrow_stmt(cref, _ctx);
|
||||||
|
const char *s = kk_string_cbuf_borrow(name, NULL, _ctx);
|
||||||
|
return (int32_t)sqlite3_bind_parameter_index(stmt, s);
|
||||||
|
}
|
||||||
|
|||||||
@@ -197,3 +197,17 @@ pub fun statement/bind-zeroblob(stmt: statement, param: int, length: int64): sql
|
|||||||
// Set all bound parameters to NULL.
|
// Set all bound parameters to NULL.
|
||||||
pub fun statement/clear-bindings(stmt: statement): sqlite-result
|
pub fun statement/clear-bindings(stmt: statement): sqlite-result
|
||||||
capi/clear-bindings(stmt.cref).trusted-result
|
capi/clear-bindings(stmt.cref).trusted-result
|
||||||
|
|
||||||
|
// Get the number of bindable parameters in the statement.
|
||||||
|
pub fun statement/param-count(stmt: statement): int
|
||||||
|
capi/parameter-count(stmt.cref).int
|
||||||
|
|
||||||
|
// Get the name of a parameter.
|
||||||
|
// The first parameter number is 1.
|
||||||
|
pub fun statement/param-name(stmt: statement, param: int): string
|
||||||
|
capi/parameter-name(stmt.cref, param.int32)
|
||||||
|
|
||||||
|
// Get the index of the parameter with the given name.
|
||||||
|
// The result is suitable to pass to bind functions.
|
||||||
|
pub fun statement/param-index(stmt: statement, name: string): int
|
||||||
|
capi/parameter-index(stmt.cref, name).int
|
||||||
|
|||||||
16
test/test.kk
16
test/test.kk
@@ -10,17 +10,17 @@ tail fun do-while(f: () -> <div|e> maybe<a>): <div|e> a
|
|||||||
Nothing -> do-while(f)
|
Nothing -> do-while(f)
|
||||||
Just(r) -> r
|
Just(r) -> r
|
||||||
|
|
||||||
fun stmt(db: sqlite3, sql: string, bind: maybe<string> = Nothing)
|
fun stmt(db: sqlite3, sql: string, bind: list<(string, string)> = Nil)
|
||||||
println(sql)
|
println(sql)
|
||||||
match db.prepare(sql.slice)
|
match db.prepare(sql.slice)
|
||||||
Left(r-prep) -> println(" prepare result: " ++ r-prep.show)
|
Left(r-prep) -> println(" prepare result: " ++ r-prep.show)
|
||||||
Right((stmt, rest)) ->
|
Right((stmt, rest)) ->
|
||||||
println(" prepare remainder: " ++ rest.show)
|
println(" prepare remainder: " ++ rest.show)
|
||||||
match bind
|
println(" param count: " ++ stmt.param-count.show)
|
||||||
Nothing -> ()
|
bind.foreach() fn((name, text))
|
||||||
Just(text) ->
|
val idx = stmt.param-index(name)
|
||||||
val r = stmt.bind-text(1, text)
|
val r = stmt.bind-text(idx, text)
|
||||||
println(" bind result: " ++ r.show)
|
println(" bind " ++ name ++ " result: " ++ r.show)
|
||||||
val r-step = do-while
|
val r-step = do-while
|
||||||
val r = stmt.step
|
val r = stmt.step
|
||||||
match r
|
match r
|
||||||
@@ -29,7 +29,7 @@ fun stmt(db: sqlite3, sql: string, bind: maybe<string> = Nothing)
|
|||||||
println(" col " ++ i.show ++ ": " ++ stmt.text(i))
|
println(" col " ++ i.show ++ ": " ++ stmt.text(i))
|
||||||
Nothing
|
Nothing
|
||||||
r -> Just(r)
|
r -> Just(r)
|
||||||
println(" final step result: " ++ r-step.show)
|
println(" final step result: " ++ r-step.show)
|
||||||
val r-fin = stmt.finalize
|
val r-fin = stmt.finalize
|
||||||
println(" finalize result: " ++ r-fin.show)
|
println(" finalize result: " ++ r-fin.show)
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ pub fun main()
|
|||||||
println("open result: " ++ r-open.show)
|
println("open result: " ++ r-open.show)
|
||||||
stmt(db, "DROP TABLE IF EXISTS koka; -- reset previous test runs")
|
stmt(db, "DROP TABLE IF EXISTS koka; -- reset previous test runs")
|
||||||
stmt(db, "CREATE TABLE koka(v TEXT NOT NULL)")
|
stmt(db, "CREATE TABLE koka(v TEXT NOT NULL)")
|
||||||
stmt(db, "INSERT INTO koka VALUES (?);", Just("value inserted from koka"))
|
stmt(db, "INSERT INTO koka VALUES (?1);", [("?1", "value inserted from koka")])
|
||||||
stmt(db, "SELECT * FROM koka")
|
stmt(db, "SELECT * FROM koka")
|
||||||
val r-close = db.close
|
val r-close = db.close
|
||||||
println("close result: " ++ r-close.show)
|
println("close result: " ++ r-close.show)
|
||||||
|
|||||||
Reference in New Issue
Block a user