orm: select many

pull/5404/head
Alexander Medvednikov 2020-06-17 14:18:32 +02:00
parent effa0061e8
commit 6066414afa
4 changed files with 56 additions and 11 deletions

View File

@ -25,7 +25,7 @@ fn test_orm_sqlite() {
name := 'sam' name := 'sam'
db.exec("insert into User (name, age) values ('Sam', 29)") 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')") db.exec("insert into User (name) values ('Kate')")
nr_all_users := sql db { nr_all_users := sql db {
select count from User select count from User
@ -57,6 +57,15 @@ fn test_orm_sqlite() {
assert user.name == 'Sam' assert user.name == 'Sam'
assert user.id == 1 assert user.id == 1
assert user.age == 29 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
} }

View File

@ -44,7 +44,6 @@ pub struct ExprStmt {
pub: pub:
expr Expr expr Expr
pos token.Position pos token.Position
// is used for `x++` in `for x:=1; ; x++`
is_expr bool is_expr bool
pub mut: pub mut:
typ table.Type typ table.Type
@ -567,6 +566,7 @@ pub struct Attr {
pub: pub:
name string name string
} }
pub fn (attrs []Attr) contains(attr Attr) bool { pub fn (attrs []Attr) contains(attr Attr) bool {
for a in attrs { for a in attrs {
if attr.name == a.name { if attr.name == a.name {
@ -816,6 +816,7 @@ pub:
where_expr Expr where_expr Expr
has_where bool has_where bool
fields []table.Field fields []table.Field
is_array bool
} }
[inline] [inline]

View File

@ -65,9 +65,26 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
} else { } else {
// `user := sql db { select from User where id = 1 }` // `user := sql db { select from User where id = 1 }`
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
g.write(g.typ(node.typ)) styp := g.typ(node.typ)
g.writeln(' $tmp;') mut elem_type_str := ''
g.writeln('sqlite3_step($g.sql_stmt_name);') 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 { for i, field in node.fields {
mut func := 'sqlite3_column_int' mut func := 'sqlite3_column_int'
if field.typ == table.string_type { if field.typ == table.string_type {
@ -77,9 +94,17 @@ fn (mut g Gen) sql_expr(node ast.SqlExpr) {
g.writeln('${tmp}.$field.name = ${func}($g.sql_stmt_name, $i);') 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('sqlite3_finalize($g.sql_stmt_name);')
if node.is_array {
g.writeln('$cur_line ${tmp}_array; ') // `array_User users = tmp_array;`
} else {
g.writeln('$cur_line $tmp; ') // `User user = tmp;` g.writeln('$cur_line $tmp; ') // `User user = tmp;`
} }
}
} }
fn (mut g Gen) expr_to_sql(expr ast.Expr) { fn (mut g Gen) expr_to_sql(expr ast.Expr) {
@ -93,6 +118,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr) {
g.expr_to_sql(it.left) g.expr_to_sql(it.left)
match it.op { match it.op {
.eq { g.write(' = ') } .eq { g.write(' = ') }
.gt { g.write(' > ') }
.and { g.write(' and ') } .and { g.write(' and ') }
else {} else {}
} }

View File

@ -25,6 +25,7 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
table_name := sym.name table_name := sym.name
mut where_expr := ast.Expr{} mut where_expr := ast.Expr{}
has_where := p.tok.kind == .name && p.tok.lit == 'where' has_where := p.tok.kind == .name && p.tok.lit == 'where'
mut query_one := false // one object is returned, not an array
if has_where { if has_where {
p.next() p.next()
where_expr = p.expr(0) 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 { if e.op == .eq && e.left is ast.Ident {
ident := e.left as ast.Ident ident := e.left as ast.Ident
if ident.name == 'id' { if ident.name == 'id' {
// TODO optional
query_one = true
typ = table_type 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) p.check(.rcbr)
// ///////// // /////////
// Register this type's fields as variables so they can be used in `where` // 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 where_expr: where_expr
has_where: has_where has_where: has_where
fields: fields fields: fields
is_array: !query_one
} }
} }