mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
make << work with appending arrays; PostgreSQL driver
This commit is contained in:
@@ -69,13 +69,6 @@ fn array_repeat(val voidptr, nr_repeats, elm_size int) array {
|
||||
return arr
|
||||
}
|
||||
|
||||
pub fn (a mut array) append_array(b array) {
|
||||
for i := 0; i < b.len; i++ {
|
||||
val := b[i]
|
||||
a._push(val)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (a mut array) sort_with_compare(compare voidptr) {
|
||||
C.qsort(a.data, a.len, a.element_size, compare)
|
||||
}
|
||||
@@ -178,6 +171,7 @@ fn (arr mut array) _push(val voidptr) {
|
||||
arr.len++
|
||||
}
|
||||
|
||||
// `val` is array.data
|
||||
pub fn (arr mut array) _push_many(val voidptr, size int) {
|
||||
if arr.len >= arr.cap - size {
|
||||
cap := (arr.len + size) * 2
|
||||
|
||||
@@ -141,7 +141,7 @@ fn test_slice() {
|
||||
fn test_push_many() {
|
||||
mut a := [1, 2, 3]
|
||||
b := [4, 5, 6]
|
||||
a._push_many(b.data, b.len)
|
||||
a << b
|
||||
assert a.len == 6
|
||||
assert a[0] == 1
|
||||
assert a[3] == 4
|
||||
|
||||
@@ -567,7 +567,7 @@ fn (ctx &GG) _draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
|
||||
// #free(runes.data);
|
||||
}
|
||||
|
||||
fn (ctx &GG) draw_text_def(x, y int, text string) {
|
||||
pub fn (ctx &GG) draw_text_def(x, y int, text string) {
|
||||
cfg := gx.TextCfg {
|
||||
color: gx.Black,
|
||||
size: DEFAULT_FONT_SIZE,
|
||||
|
||||
38
vlib/os/os.v
38
vlib/os/os.v
@@ -108,12 +108,7 @@ fn parse_windows_cmd_line(cmd byteptr) []string {
|
||||
//pub fn read_file(path string) ?string {
|
||||
pub fn read_file(path string) ?string {
|
||||
mut res := ''
|
||||
mut mode := 'r'
|
||||
777 // TODO
|
||||
// Need 'rb' on windows to avoid the \r\n mess.
|
||||
$if windows {
|
||||
mode = 'rb'
|
||||
}
|
||||
mut mode := 'rb'
|
||||
cpath := path.cstr()
|
||||
fp := C.fopen(cpath, mode.cstr())
|
||||
if isnil(fp) {
|
||||
@@ -132,31 +127,6 @@ pub fn read_file(path string) ?string {
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn read_file_opt(path string) ?string {
|
||||
mut res := ''
|
||||
mut mode := 'r'
|
||||
777 // TODO
|
||||
// Need 'rb' on windows to avoid the \r\n mess.
|
||||
$if windows {
|
||||
mode = 'rb'
|
||||
}
|
||||
cpath := path.cstr()
|
||||
fp := C.fopen(cpath, mode.cstr())
|
||||
if isnil(fp) {
|
||||
return error('failed to open file "$path"')
|
||||
}
|
||||
C.fseek(fp, 0, SEEK_END)
|
||||
fsize := C.ftell(fp)
|
||||
// C.fseek(fp, 0, SEEK_SET) // same as C.rewind(fp) below
|
||||
C.rewind(fp)
|
||||
mut str := malloc(fsize + 1)
|
||||
C.fread(str, fsize, 1, fp)
|
||||
C.fclose(fp)
|
||||
str[fsize] = 0
|
||||
res = tos(str, fsize)
|
||||
return res
|
||||
}
|
||||
|
||||
// file_size returns the size of the file located in `path`.
|
||||
pub fn file_size(path string) int {
|
||||
s := C.stat{}
|
||||
@@ -208,7 +178,7 @@ fn read_ulines(path string) []ustring {
|
||||
pub fn open(path string) ?File {
|
||||
cpath := path.cstr()
|
||||
file := File {
|
||||
cfile: C.fopen(cpath, 'r')
|
||||
cfile: C.fopen(cpath, 'rb')
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to open file "$path"')
|
||||
@@ -220,7 +190,7 @@ pub fn open(path string) ?File {
|
||||
pub fn create(path string) ?File {
|
||||
cpath := path.cstr()
|
||||
file := File {
|
||||
cfile: C.fopen(cpath, 'w')
|
||||
cfile: C.fopen(cpath, 'wb')
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to create file "$path"')
|
||||
@@ -231,7 +201,7 @@ pub fn create(path string) ?File {
|
||||
pub fn open_append(path string) ?File {
|
||||
cpath := path.cstr()
|
||||
file := File {
|
||||
cfile: C.fopen(cpath, 'a')
|
||||
cfile: C.fopen(cpath, 'ab')
|
||||
}
|
||||
if isnil(file.cfile) {
|
||||
return error('failed to create file "$path"')
|
||||
|
||||
115
vlib/pg/pg.v
Normal file
115
vlib/pg/pg.v
Normal file
@@ -0,0 +1,115 @@
|
||||
module pg
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
#flag -lpq
|
||||
#flag linux -I/usr/include/postgresql
|
||||
#include <libpq-fe.h>
|
||||
|
||||
struct DB {
|
||||
mut:
|
||||
conn *C.PGconn
|
||||
}
|
||||
|
||||
struct Row {
|
||||
pub:
|
||||
vals []string
|
||||
}
|
||||
|
||||
import const (
|
||||
CONNECTION_OK
|
||||
)
|
||||
|
||||
struct C.PGResult { }
|
||||
|
||||
fn C.PQconnectdb(a byteptr) *C.PGconn
|
||||
fn C.PQerrorMessage(voidptr) byteptr
|
||||
|
||||
pub fn connect(dbname, user string) DB {
|
||||
conninfo := 'host=localhost user=$user dbname=$dbname'
|
||||
conn:=C.PQconnectdb(conninfo.cstr())
|
||||
status := C.PQstatus(conn)
|
||||
if status != CONNECTION_OK {
|
||||
error_msg := C.PQerrorMessage(conn)
|
||||
eprintln('Connection to a PG database failed: ' + string(error_msg))
|
||||
exit(1)
|
||||
}
|
||||
return DB {conn: conn}
|
||||
}
|
||||
|
||||
fn res_to_rows(res voidptr) []pg.Row {
|
||||
nr_rows := C.PQntuples(res)
|
||||
nr_cols := C.PQnfields(res)
|
||||
mut rows := []pg.Row
|
||||
for i := 0; i < nr_rows; i++ {
|
||||
mut row := Row{}
|
||||
for j := 0; j < nr_cols; j++ {
|
||||
val := C.PQgetvalue(res, i, j)
|
||||
row.vals << string(val)
|
||||
}
|
||||
rows << row
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
pub fn (db DB) q_int(query string) int {
|
||||
rows := db.exec(query)
|
||||
if rows.len == 0 {
|
||||
println('q_int "$query" not found')
|
||||
return 0
|
||||
}
|
||||
row := rows[0]
|
||||
if row.vals.len == 0 {
|
||||
return 0
|
||||
}
|
||||
val := row.vals[0]
|
||||
return val.int()
|
||||
}
|
||||
|
||||
pub fn (db DB) q_string(query string) string {
|
||||
rows := db.exec(query)
|
||||
if rows.len == 0 {
|
||||
println('q_string "$query" not found')
|
||||
return ''
|
||||
}
|
||||
row := rows[0]
|
||||
if row.vals.len == 0 {
|
||||
return ''
|
||||
}
|
||||
val := row.vals[0]
|
||||
return val
|
||||
}
|
||||
|
||||
pub fn (db DB) q_strings(query string) []pg.Row {
|
||||
return db.exec(query)
|
||||
}
|
||||
|
||||
pub fn (db DB) exec(query string) []pg.Row {
|
||||
res := C.PQexec(db.conn, query.cstr())
|
||||
e := string(C.PQerrorMessage(db.conn))
|
||||
if e != '' {
|
||||
println('pg exec error:')
|
||||
println(e)
|
||||
return res_to_rows(res)
|
||||
}
|
||||
return res_to_rows(res)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
pub fn (db DB) exec_param2(query string, param, param2 string) []pg.Row {
|
||||
mut param_vals := [2]byteptr
|
||||
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 res_to_rows(res)
|
||||
}
|
||||
|
||||
pub fn (db DB) exec_param(query string, param string) []pg.Row {
|
||||
mut param_vals := [1]byteptr
|
||||
param_vals[0] = param.str
|
||||
res := C.PQexecParams(db.conn, query.str, 1, 0, param_vals, 0, 0, 0)
|
||||
return res_to_rows(res)
|
||||
}
|
||||
|
||||
4
vlib/pg/pg_lin.v
Normal file
4
vlib/pg/pg_lin.v
Normal file
@@ -0,0 +1,4 @@
|
||||
module pg
|
||||
|
||||
#flag -I/usr/include/postgresql
|
||||
// #flag `pkg-config --cflags libpq`
|
||||
2
vlib/pg/pg_mac.v
Normal file
2
vlib/pg/pg_mac.v
Normal file
@@ -0,0 +1,2 @@
|
||||
module pg
|
||||
|
||||
@@ -18,11 +18,13 @@ pub fn new_builder(initial_size int) Builder {
|
||||
|
||||
pub fn (b mut Builder) write(s string) {
|
||||
b.buf._push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
b.len += s.len
|
||||
}
|
||||
|
||||
pub fn (b mut Builder) writeln(s string) {
|
||||
b.buf._push_many(s.str, s.len)
|
||||
//b.buf << []byte(s) // TODO
|
||||
b.buf << `\n`
|
||||
b.len += s.len + 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user