1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

sqlite: modify exec functions + other fixes

This commit is contained in:
toman222 2020-02-02 02:56:09 +01:00 committed by GitHub
parent 0ef1ba9ad2
commit 932392a7fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 37 deletions

View File

@ -14,7 +14,8 @@ fn main() {
name := db.q_string('select name from users where id = 1') name := db.q_string('select name from users where id = 1')
assert name == 'Sam' assert name == 'Sam'
users := db.exec('select * from users') users, code := db.exec('select * from users')
println("SQL Result code: $code")
for row in users { for row in users {
println(row.vals) println(row.vals)
} }

View File

@ -5,8 +5,8 @@ module sqlite
#flag freebsd -Wl -L/usr/local/lib -lsqlite3 #flag freebsd -Wl -L/usr/local/lib -lsqlite3
#include "sqlite3.h" #include "sqlite3.h"
struct C.sqlite3 struct C.sqlite3 {}
struct C.sqlite3_stmt struct C.sqlite3_stmt {}
pub struct DB { pub struct DB {
mut: mut:
@ -18,12 +18,24 @@ pub mut:
vals []string vals []string
} }
fn C.sqlite3_column_text(voidptr, int) byteptr
fn C.sqlite3_column_int(voidptr, int) int
fn C.sqlite3_open()
fn C.sqlite3_step() int
fn C.sqlite3_prepare_v2()
fn C.sqlite3_finalize()
fn C.sqlite3_column_count(voidptr) int
// Opens the connection with a database.
pub fn connect(path string) DB { pub fn connect(path string) DB {
db := &C.sqlite3(0) db := &C.sqlite3(0)
C.sqlite3_open(path.str, &db) C.sqlite3_open(path.str, &db)
return DB {conn: db} return DB{
conn: db
}
} }
// Returns a single cell with value int.
pub fn (db DB) q_int(query string) int { pub fn (db DB) q_int(query string) int {
stmt := &C.sqlite3_stmt(0) stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0) C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
@ -33,14 +45,7 @@ pub fn (db DB) q_int(query string) int {
return res return res
} }
fn C.sqlite3_column_text(voidptr, int) byteptr // Returns a single cell with value string.
fn C.sqlite3_column_int(voidptr, int) int
fn C.sqlite3_open()
fn C.sqlite3_step() int
fn C.sqlite3_prepare_v2()
fn C.sqlite3_finalize()
fn C.sqlite3_column_count(voidptr) int
pub fn (db DB) q_string(query string) string { pub fn (db DB) q_string(query string) string {
stmt := &C.sqlite3_stmt(0) stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0) C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
@ -51,36 +56,48 @@ pub fn (db DB) q_string(query string) string {
} }
pub fn (db DB) exec(query string) []Row { // Execute the query on db, return an array of all the results, alongside any result code.
// Result codes: https://www.sqlite.org/rescode.html
pub fn (db DB) exec(query string) ([]Row,int) {
stmt := &C.sqlite3_stmt(0) stmt := &C.sqlite3_stmt(0)
C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0) C.sqlite3_prepare_v2(db.conn, query.str, -1, &stmt, 0)
nr_cols := C.sqlite3_column_count(stmt) nr_cols := C.sqlite3_column_count(stmt)
//println('nr cols $nr_cols') mut res := 0
mut rows := []Row mut rows := []Row
for { for {
ret := C.sqlite3_step(stmt) res = C.sqlite3_step(stmt)
if ret != 0x64 { // Result Code SQLITE_ROW; Another row is available
if res != 100 {
break break
} }
mut row := Row{} mut row := Row{}
for i in 0 .. nr_cols { for i in 0 .. nr_cols {
val := tos_clone(C.sqlite3_column_text(stmt, i)) val := tos_clone(C.sqlite3_column_text(stmt, i))
row.vals << val row.vals << val
//println(val)
} }
rows << row rows << row
} }
return rows return rows,res
} }
// Execute a query, handle error code
// Return the first row from the resulting table
pub fn (db DB) exec_one(query string) ?Row { pub fn (db DB) exec_one(query string) ?Row {
rows := db.exec(query) rows,code := db.exec(query)
if rows.len == 0 || code != 101 {
return error('SQL Error: Rows #$rows.len Return code $code')
}
return rows[0] return rows[0]
} }
/* // In case you don't expect any result, but still want an error code
// e.g. INSERT INTO ... VALUES (...)
pub fn (db DB) exec_none(query string) int {
_,code := db.exec(query)
return code
}
/* TODO
pub fn (db DB) exec_param(query string, param string) []Row { pub fn (db DB) exec_param(query string, param string) []Row {
} }
*/ */

View File

@ -10,14 +10,20 @@ fn test_sqlite() {
db.exec("insert into users (name) values ('Kate')") db.exec("insert into users (name) values ('Kate')")
nr_users := db.q_int('select count(*) from users') nr_users := db.q_int('select count(*) from users')
println('nr users = $nr_users') assert nr_users == 3
name := db.q_string('select name from users where id = 1') name := db.q_string('select name from users where id = 1')
assert name == 'Sam' assert name == 'Sam'
users := db.exec('select * from users') users, mut code := db.exec('select * from users')
assert users.len == 3 assert users.len == 3
for row in users { assert code == 101
println(row.vals)
code = db.exec_none('vacuum')
assert code == 101
user := db.exec_one('select * from users where id = 3') or {
panic(err)
} }
assert user.vals.len == 2
} }