orm: select many
parent
effa0061e8
commit
6066414afa
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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 {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue