pg: fix exec & exec_param_many (#6782)
parent
b0053d8910
commit
7108f89b69
68
vlib/pg/pg.v
68
vlib/pg/pg.v
|
@ -16,8 +16,7 @@ pub mut:
|
||||||
vals []string
|
vals []string
|
||||||
}
|
}
|
||||||
|
|
||||||
struct C.PGResult {
|
struct C.PGResult
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub:
|
pub:
|
||||||
|
@ -32,19 +31,21 @@ fn C.PQconnectdb(a byteptr) &C.PGconn
|
||||||
|
|
||||||
fn C.PQerrorMessage(voidptr) byteptr
|
fn C.PQerrorMessage(voidptr) byteptr
|
||||||
|
|
||||||
fn C.PQgetvalue(voidptr, int, int) byteptr
|
fn C.PQgetvalue(&C.PGResult, int, int) byteptr
|
||||||
|
|
||||||
fn C.PQstatus(voidptr) int
|
fn C.PQstatus(voidptr) int
|
||||||
|
|
||||||
fn C.PQntuples(voidptr) int
|
fn C.PQresultStatus(voidptr) int
|
||||||
|
|
||||||
fn C.PQnfields(voidptr) int
|
fn C.PQntuples(&C.PGResult) int
|
||||||
|
|
||||||
fn C.PQexec(voidptr) voidptr
|
fn C.PQnfields(&C.PGResult) int
|
||||||
|
|
||||||
fn C.PQexecParams(voidptr) voidptr
|
fn C.PQexec(voidptr) &C.PGResult
|
||||||
|
|
||||||
fn C.PQclear(voidptr) voidptr
|
fn C.PQexecParams(voidptr) &C.PGResult
|
||||||
|
|
||||||
|
fn C.PQclear(&C.PGResult) voidptr
|
||||||
|
|
||||||
fn C.PQfinish(voidptr)
|
fn C.PQfinish(voidptr)
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ pub fn connect(config Config) ?DB {
|
||||||
fn res_to_rows(res voidptr) []Row {
|
fn res_to_rows(res voidptr) []Row {
|
||||||
nr_rows := C.PQntuples(res)
|
nr_rows := C.PQntuples(res)
|
||||||
nr_cols := C.PQnfields(res)
|
nr_cols := C.PQnfields(res)
|
||||||
|
|
||||||
mut rows := []Row{}
|
mut rows := []Row{}
|
||||||
for i in 0 .. nr_rows {
|
for i in 0 .. nr_rows {
|
||||||
mut row := Row{}
|
mut row := Row{}
|
||||||
|
@ -85,6 +87,7 @@ fn res_to_rows(res voidptr) []Row {
|
||||||
}
|
}
|
||||||
rows << row
|
rows << row
|
||||||
}
|
}
|
||||||
|
|
||||||
C.PQclear(res)
|
C.PQclear(res)
|
||||||
return rows
|
return rows
|
||||||
}
|
}
|
||||||
|
@ -139,13 +142,7 @@ pub fn (db DB) q_strings(query string) ?[]Row {
|
||||||
// row set on success
|
// row set on success
|
||||||
pub fn (db DB) exec(query string) ?[]Row {
|
pub fn (db DB) exec(query string) ?[]Row {
|
||||||
res := C.PQexec(db.conn, query.str)
|
res := C.PQexec(db.conn, query.str)
|
||||||
e := unsafe {C.PQerrorMessage(db.conn).vstring()}
|
return db.handle_error_or_result(res, 'exec')
|
||||||
if e != '' {
|
|
||||||
error_msg := '$e'
|
|
||||||
C.PQclear(res)
|
|
||||||
return error(error_msg)
|
|
||||||
}
|
|
||||||
return res_to_rows(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rows_first_or_empty(rows []Row) ?Row {
|
fn rows_first_or_empty(rows []Row) ?Row {
|
||||||
|
@ -165,41 +162,30 @@ pub fn (db DB) exec_one(query string) ?Row {
|
||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
|
|
||||||
// The entire function can be considered unsafe because of the malloc and the
|
// exec_param_many executes a query with the provided parameters
|
||||||
// free. This prevents warnings and doesn't seem to affect behavior.
|
pub fn (db DB) exec_param_many(query string, params []string) ?[]Row {
|
||||||
pub fn (db DB) exec_param_many(query string, params []string) []Row {
|
mut param_vals := []charptr{ len: params.len }
|
||||||
unsafe {
|
for i in 0 .. params.len {
|
||||||
mut param_vals := &byteptr(malloc(params.len * 8))
|
param_vals[i] = params[i].str
|
||||||
for i in 0 .. params.len {
|
|
||||||
param_vals[i] = params[i].str
|
|
||||||
}
|
|
||||||
res := C.PQexecParams(db.conn, query.str, params.len, 0, param_vals, 0, 0, 0)
|
|
||||||
free(param_vals)
|
|
||||||
return db.handle_error_or_result(res, 'exec_param_many')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res := C.PQexecParams(db.conn, query.str, params.len, 0, param_vals.data, 0, 0, 0)
|
||||||
|
return db.handle_error_or_result(res, 'exec_param_many')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (db DB) exec_param2(query string, param string, param2 string) []Row {
|
pub fn (db DB) exec_param2(query string, param string, param2 string) ?[]Row {
|
||||||
mut param_vals := [2]byteptr{}
|
return db.exec_param_many(query, [param, param2])
|
||||||
param_vals[0] = param.str
|
|
||||||
param_vals[1] = param2.str
|
|
||||||
res := C.PQexecParams(db.conn, query.str, 2, 0, param_vals, 0, 0, 0)
|
|
||||||
return db.handle_error_or_result(res, 'exec_param2')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (db DB) exec_param(query string, param string) []Row {
|
pub fn (db DB) exec_param(query string, param string) ?[]Row {
|
||||||
mut param_vals := [1]byteptr{}
|
return db.exec_param_many(query, [param])
|
||||||
param_vals[0] = param.str
|
|
||||||
res := C.PQexecParams(db.conn, query.str, 1, 0, param_vals, 0, 0, 0)
|
|
||||||
return db.handle_error_or_result(res, 'exec_param')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db DB) handle_error_or_result(res voidptr, elabel string) []Row {
|
fn (db DB) handle_error_or_result(res voidptr, elabel string) ?[]Row {
|
||||||
e := unsafe {C.PQerrorMessage(db.conn).vstring()}
|
e := unsafe {C.PQerrorMessage(db.conn).vstring()}
|
||||||
if e != '' {
|
if e != '' {
|
||||||
println('pg $elabel error:')
|
C.PQclear(res)
|
||||||
println(e)
|
return error('pg $elabel error:\n$e')
|
||||||
return res_to_rows(res)
|
|
||||||
}
|
}
|
||||||
return res_to_rows(res)
|
return res_to_rows(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,8 @@ pub fn (db DB) exec(query string) ([]Row, int) {
|
||||||
}
|
}
|
||||||
rows << row
|
rows << row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C.sqlite3_finalize(stmt)
|
||||||
return rows, res
|
return rows, res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue