mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
orm: select many
This commit is contained in:
parent
effa0061e8
commit
6066414afa
@ -25,7 +25,7 @@ fn test_orm_sqlite() {
|
||||
name := 'sam'
|
||||
|
||||
db.exec("insert into User (name, age) values ('Sam', 29)")
|
||||
db.exec("insert into User (name) values ('Peter')")
|
||||
db.exec("insert into User (name, age) values ('Peter', 31)")
|
||||
db.exec("insert into User (name) values ('Kate')")
|
||||
nr_all_users := sql db {
|
||||
select count from User
|
||||
@ -57,6 +57,15 @@ fn test_orm_sqlite() {
|
||||
assert user.name == 'Sam'
|
||||
assert user.id == 1
|
||||
assert user.age == 29
|
||||
//
|
||||
users := sql db {
|
||||
select from User where id > 0
|
||||
}
|
||||
println(users)
|
||||
assert users.len == 3
|
||||
assert users[0].name == 'Sam'
|
||||
assert users[1].name == 'Peter'
|
||||
assert users[1].age == 31
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,7 +44,6 @@ pub struct ExprStmt {
|
||||
pub:
|
||||
expr Expr
|
||||
pos token.Position
|
||||
// is used for `x++` in `for x:=1; ; x++`
|
||||
is_expr bool
|
||||
pub mut:
|
||||
typ table.Type
|
||||
@ -567,6 +566,7 @@ pub struct Attr {
|
||||
pub:
|
||||
name string
|
||||
}
|
||||
|
||||
pub fn (attrs []Attr) contains(attr Attr) bool {
|
||||
for a in attrs {
|
||||
if attr.name == a.name {
|
||||
@ -816,6 +816,7 @@ pub:
|
||||
where_expr Expr
|
||||
has_where bool
|
||||
fields []table.Field
|
||||
is_array bool
|
||||
}
|
||||
|
||||
[inline]
|
||||
|
@ -17,11 +17,11 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
|
||||
/*
|
||||
`nr_users := sql db { ... }` =>
|
||||
```
|
||||
sql_init_stmt()
|
||||
sql_bind_int()
|
||||
sql_bind_string()
|
||||
...
|
||||
int nr_users = get_int(stmt)
|
||||
sql_init_stmt()
|
||||
sql_bind_int()
|
||||
sql_bind_string()
|
||||
...
|
||||
int nr_users = get_int(stmt)
|
||||
```
|
||||
*/
|
||||
cur_line := g.go_before_stmt(0)
|
||||
@ -65,9 +65,26 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
|
||||
} else {
|
||||
// `user := sql db { select from User where id = 1 }`
|
||||
tmp := g.new_tmp_var()
|
||||
g.write(g.typ(node.typ))
|
||||
g.writeln(' $tmp;')
|
||||
g.writeln('sqlite3_step($g.sql_stmt_name);')
|
||||
styp := g.typ(node.typ)
|
||||
mut elem_type_str := ''
|
||||
if node.is_array {
|
||||
sym := g.table.get_type_symbol(node.typ)
|
||||
info := sym.info as table.Array
|
||||
elem_type_str = g.typ(info.elem_type)
|
||||
// array_User array_tmp;
|
||||
// for { User tmp; ... array_tmp << tmp; }
|
||||
g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));')
|
||||
g.writeln('while (1) {')
|
||||
g.writeln('\t$elem_type_str $tmp;')
|
||||
} else {
|
||||
// `User tmp;`
|
||||
g.writeln('$styp $tmp;')
|
||||
}
|
||||
//
|
||||
g.writeln('int _step_res$tmp = sqlite3_step($g.sql_stmt_name);')
|
||||
if node.is_array {
|
||||
g.writeln('\tif (_step_res$tmp == SQLITE_DONE) break;')
|
||||
}
|
||||
for i, field in node.fields {
|
||||
mut func := 'sqlite3_column_int'
|
||||
if field.typ == table.string_type {
|
||||
@ -77,8 +94,16 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
|
||||
g.writeln('${tmp}.$field.name = ${func}($g.sql_stmt_name, $i);')
|
||||
}
|
||||
}
|
||||
if node.is_array {
|
||||
g.writeln('\t array_push(&${tmp}_array, _MOV(($elem_type_str[]){ $tmp }));')
|
||||
g.writeln('} // for')
|
||||
}
|
||||
g.writeln('sqlite3_finalize($g.sql_stmt_name);')
|
||||
g.writeln('$cur_line $tmp; ') // `User user = tmp;`
|
||||
if node.is_array {
|
||||
g.writeln('$cur_line ${tmp}_array; ') // `array_User users = tmp_array;`
|
||||
} else {
|
||||
g.writeln('$cur_line $tmp; ') // `User user = tmp;`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +118,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr) {
|
||||
g.expr_to_sql(it.left)
|
||||
match it.op {
|
||||
.eq { g.write(' = ') }
|
||||
.gt { g.write(' > ') }
|
||||
.and { g.write(' and ') }
|
||||
else {}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||
table_name := sym.name
|
||||
mut where_expr := ast.Expr{}
|
||||
has_where := p.tok.kind == .name && p.tok.lit == 'where'
|
||||
mut query_one := false // one object is returned, not an array
|
||||
if has_where {
|
||||
p.next()
|
||||
where_expr = p.expr(0)
|
||||
@ -34,11 +35,18 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||
if e.op == .eq && e.left is ast.Ident {
|
||||
ident := e.left as ast.Ident
|
||||
if ident.name == 'id' {
|
||||
// TODO optional
|
||||
query_one = true
|
||||
typ = table_type
|
||||
// typ = table_type.set_flag(.optional)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !query_one && !is_count {
|
||||
// return an array
|
||||
typ = table.new_type(p.table.find_or_register_array(table_type, 1, p.mod))
|
||||
}
|
||||
p.check(.rcbr)
|
||||
// /////////
|
||||
// Register this type's fields as variables so they can be used in `where`
|
||||
@ -86,5 +94,6 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||
where_expr: where_expr
|
||||
has_where: has_where
|
||||
fields: fields
|
||||
is_array: !query_one
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user