diff --git a/0.3_roadmap.txt b/0.3_roadmap.txt index 39e8b44406..cc8c76d28b 100644 --- a/0.3_roadmap.txt +++ b/0.3_roadmap.txt @@ -7,6 +7,7 @@ - C2V translator - doom.v - rune type, replace ustring with []rune +- maps with non-string keys diff --git a/vlib/orm/orm_test.v b/vlib/orm/orm_test.v index 0d56d0a57e..4b0e796de1 100644 --- a/vlib/orm/orm_test.v +++ b/vlib/orm/orm_test.v @@ -106,13 +106,11 @@ fn test_orm_sqlite() { kate := sql db { select from User where id == 3 } - println(kate) assert kate.is_customer == true // customer := sql db { select from User where is_customer == true limit 1 } - println(customer) assert customer.is_customer == true assert customer.name == 'Kate' // @@ -122,19 +120,48 @@ fn test_orm_sqlite() { kate2 := sql db { select from User where id == 3 } - println(kate2) assert kate2.age == 31 assert kate2.name == 'Kate' // sql db { update User set age = 32, name = 'Kate N' where name == 'Kate' } - kate3 := sql db { + mut kate3 := sql db { + select from User where id == 3 + } + assert kate3.age == 32 + assert kate3.name == 'Kate N' + // + /* + sql db { + update User set age = age + 1, name = 'Kate N' where name == 'Kate' + } + kate3 = sql db { select from User where id == 3 } println(kate3) assert kate3.age == 32 assert kate3.name == 'Kate N' + */ + new_age := 33 + sql db { + update User set age = new_age, name = 'Kate N' where id == 3 + } + kate3 = sql db { + select from User where id == 3 + } + assert kate3.age == 33 + assert kate3.name == 'Kate N' + // + foo := Foo{34} + sql db { + update User set age = foo.age, name = 'Kate N' where id == 3 + } + kate3 = sql db { + select from User where id == 3 + } + assert kate3.age == 34 + assert kate3.name == 'Kate N' } struct User { @@ -145,6 +172,10 @@ struct User { skipped_string string [skip] } +struct Foo { + age int +} + fn test_orm_pg() { diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 6d7c8b8b9c..89b1f5a7a9 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -105,7 +105,8 @@ pub: expr Expr field_name string pub mut: - expr_type table.Type + expr_type table.Type // type of `Foo` in `Foo.bar` + typ table.Type // type of the entire thing (`Foo.bar`) } // module declaration diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index bd2f9745a2..555d262385 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1252,6 +1252,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T // variadic if typ.has_flag(.variadic) { if field_name == 'len' { + selector_expr.typ = table.int_type return table.int_type } } @@ -1259,6 +1260,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T if sym.mod != c.mod && !field.is_pub { c.error('field `${sym.name}.$field_name` is not public', selector_expr.pos) } + selector_expr.typ = field.typ return field.typ } if sym.kind != .struct_ { @@ -2721,6 +2723,11 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type { fields := c.fetch_and_verify_orm_fields(info, node.pos, node.table_name) node.fields = fields c.expr(node.db_expr) + if node.kind== .update { + for expr in node.update_exprs { + c.expr(expr) + } + } return table.void_type } diff --git a/vlib/v/gen/sql.v b/vlib/v/gen/sql.v index 2132ec5f3d..164e4d589a 100644 --- a/vlib/v/gen/sql.v +++ b/vlib/v/gen/sql.v @@ -273,10 +273,23 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr) { } else if typ == table.int_type { g.sql_bind_int(expr.name) } else { - verror('bad sql type $typ') + verror('bad sql type=$typ ident_name=$expr.name') } } } + ast.SelectorExpr { + g.inc_sql_i() + if expr.typ == table.int_type { + if expr.expr !is ast.Ident { + verror('orm selector not ident') + } + ident := expr.expr as ast.Ident + g.sql_bind_int(ident.name + '.' + expr.field_name) + } + else { + verror('bad sql type=$expr.typ selector expr=$expr.field_name') + } + } else { g.expr(expr) }