orm: bool support; vweb fixes

pull/3029/head
Alexander Medvednikov 2019-12-09 17:10:44 +03:00
parent 32b0225079
commit 6f49d4c1d2
6 changed files with 36 additions and 15 deletions

View File

@ -25,7 +25,8 @@ fn main() {
// V syntax can be used to build queries
println('----------------------------------------------------------------')
bg_customers := db.select from Customer where country == 'Bulgaria' && id != 2
country := 'Bulgaria'
bg_customers := db.select from Customer where country == country && id != 2
for customer in bg_customers {
println('$customer.country | $customer.id - $customer.name')
}

View File

@ -190,6 +190,9 @@ pub fn (s string) replace(rep, with string) string {
return tos(b, new_len)
}
pub fn (s string) bool() bool {
return s == 'true' || s == 't' // TODO t for pg, remove
}
pub fn (s string) int() int {
return int(strconv.common_parse_int(s,0,32, false, false))

View File

@ -51,14 +51,19 @@ fn (p mut Parser) bterm() string {
is_ustr := typ=='ustring'
is_float := typ[0] == `f` && (typ in ['f64', 'f32']) &&
!(p.cur_fn.name in ['f64_abs', 'f32_abs']) &&
!(p.cur_fn.name == 'eq')
is_array := typ.contains('array_')
p.cur_fn.name != 'eq'
is_array := typ.starts_with('array_')
expr_type := typ
tok := p.tok
/*
if tok == .assign {
p.error('no = ')
}
*/
if tok in [.eq, .gt, .lt, .le, .ge, .ne] {
//TODO: remove when array comparing is supported
if is_array {
p.error('array comparing is not supported yet')
p.error('array comparison is not supported yet')
}
p.fspace()
@ -161,14 +166,11 @@ fn (p mut Parser) name_expr() string {
}
return temp_type
}
mut name := p.lit
// generic type check
if name in p.cur_fn.dispatch_of.inst.keys() {
name = p.cur_fn.dispatch_of.inst[name]
}
// Raw string (`s := r'hello \n ')
if name == 'r' && p.peek() == .str && p.prev_tok != .str_dollar {
p.string_expr()

View File

@ -746,7 +746,7 @@ pub fn (v &V) get_user_files() []string {
if v.pref.is_test && v.pref.is_stats {
user_files << filepath.join(preludes_path,'tests_with_stats.v')
}
// v volt/slack_test.v: compile all .v files to get the environment
// I need to implement user packages! TODO
is_test_with_imports := dir.ends_with('_test.v') &&

View File

@ -32,6 +32,7 @@ fn sql_params2params_gen(sql_params []string, sql_types []string, qprefix string
return params_gen
}
// `db.select from User where id == 1 && nr_bookings > 0`
fn (p mut Parser) select_query(fn_ph int) string {
// NB: qprefix and { p.sql_i, p.sql_params, p.sql_types } SHOULD be reset for each query,
@ -49,7 +50,8 @@ fn (p mut Parser) select_query(fn_ph int) string {
p.check_name()
}
table_name := p.check_name()
// Register this type's fields as variables so they can be used in where expressions
// Register this type's fields as variables so they can be used in `where`
// expressions
typ := p.table.find_type(table_name)
if typ.name == '' {
p.error('unknown type `$table_name`')
@ -58,7 +60,8 @@ fn (p mut Parser) select_query(fn_ph int) string {
// get only string and int fields
mut fields := []Var
for i, field in typ.fields {
if field.typ != 'string' && field.typ != 'int' {
if !(field.typ in ['string', 'int', 'bool']) {
println('orm: skipping $field.name')
continue
}
fields << field
@ -81,12 +84,13 @@ fn (p mut Parser) select_query(fn_ph int) string {
}
for field in fields {
//println('registering sql field var $field.name')
if field.typ != 'string' && field.typ != 'int' {
if !(field.typ in ['string', 'int', 'bool']) {
println('orm: skipping $field.name')
continue
}
p.register_var({ field | is_used:true })
p.register_var({ field | is_mut: true, is_used:true, is_changed:true })
}
q += table_name
q += table_name + 's'
// `where` statement
if p.tok == .name && p.lit == 'where' {
p.next()
@ -123,6 +127,9 @@ fn (p mut Parser) select_query(fn_ph int) string {
if field.typ == 'int' {
cast = 'v_string_int'
}
else if field.typ == 'bool' {
cast = 'string_bool'
}
obj_gen.writeln('${qprefix}${tmp}.$field.name = ' +
'${cast}(*(string*)array_get(${qprefix}row.vals, $i));')
}

View File

@ -41,26 +41,34 @@ pub:
// TODO Response
mut:
headers string // response headers
done bool
}
pub fn (ctx Context) html(html string) {
if ctx.done { return }
//println('HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n$ctx.headers\r\n\r\n$html')
ctx.conn.write('HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n$ctx.headers\r\n\r\n$html') or { panic(err) }
}
pub fn (ctx Context) text(s string) {
ctx.conn.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n$ctx.headers\r\n\r\n $s') or { panic(err) }
pub fn (ctx mut Context) text(s string) {
if ctx.done { return }
ctx.conn.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n' +
'$ctx.headers\r\n$s') or { panic(err) }
ctx.done = true
}
pub fn (ctx Context) json(s string) {
if ctx.done { return }
ctx.conn.write('HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n$ctx.headers\r\n\r\n$s') or { panic(err) }
}
pub fn (ctx Context) redirect(url string) {
if ctx.done { return }
ctx.conn.write('HTTP/1.1 302 Found\r\nLocation: $url\r\n$ctx.headers\r\n\r\n') or { panic(err) }
}
pub fn (ctx Context) not_found(s string) {
if ctx.done { return }
ctx.conn.write(HTTP_404) or { panic(err) }
}