orm: move type logic to checker, so that sql queries can be used before type def
parent
a1bad50b2f
commit
786be1d1c3
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
- coroutines
|
- coroutines
|
||||||
- bring back lock{}
|
- bring back lock{}
|
||||||
|
- thread safe arrays/maps
|
||||||
- C2V translator
|
- C2V translator
|
||||||
- doom.v
|
- doom.v
|
||||||
- rune type, replace ustring with []rune
|
- rune type, replace ustring with []rune
|
||||||
|
|
|
@ -11,14 +11,6 @@ struct Module {
|
||||||
//nr_downloads int
|
//nr_downloads int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct User {
|
|
||||||
id int
|
|
||||||
age int
|
|
||||||
name string
|
|
||||||
is_customer bool
|
|
||||||
skipped_string string [skip]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_orm_sqlite() {
|
fn test_orm_sqlite() {
|
||||||
db := sqlite.connect(':memory:') or { panic(err) }
|
db := sqlite.connect(':memory:') or { panic(err) }
|
||||||
db.exec("drop table if exists User")
|
db.exec("drop table if exists User")
|
||||||
|
@ -131,6 +123,15 @@ fn test_orm_sqlite() {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
id int
|
||||||
|
age int
|
||||||
|
name string
|
||||||
|
is_customer bool
|
||||||
|
skipped_string string [skip]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn test_orm_pg() {
|
fn test_orm_pg() {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -822,6 +822,7 @@ pub:
|
||||||
table_name string
|
table_name string
|
||||||
object_var_name string // `user`
|
object_var_name string // `user`
|
||||||
table_type table.Type
|
table_type table.Type
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SqlExpr {
|
pub struct SqlExpr {
|
||||||
|
@ -829,11 +830,14 @@ pub:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
is_count bool
|
is_count bool
|
||||||
db_expr Expr // `db` in `sql db {`
|
db_expr Expr // `db` in `sql db {`
|
||||||
table_name string
|
|
||||||
where_expr Expr
|
where_expr Expr
|
||||||
has_where bool
|
has_where bool
|
||||||
fields []table.Field
|
|
||||||
is_array bool
|
is_array bool
|
||||||
|
table_type table.Type
|
||||||
|
pos token.Position
|
||||||
|
pub mut:
|
||||||
|
table_name string
|
||||||
|
fields []table.Field
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
|
|
@ -1841,7 +1841,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||||
c.scope_returns = true
|
c.scope_returns = true
|
||||||
}
|
}
|
||||||
ast.SqlStmt {
|
ast.SqlStmt {
|
||||||
c.sql_insert_expr(node)
|
c.sql_stmt(node)
|
||||||
}
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
c.struct_decl(it)
|
c.struct_decl(it)
|
||||||
|
@ -2680,7 +2680,34 @@ fn (c &Checker) fileis(s string) bool {
|
||||||
return c.file.path.contains(s)
|
return c.file.path.contains(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) sql_expr(node ast.SqlExpr) table.Type {
|
fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type {
|
||||||
|
sym := c.table.get_type_symbol(node.table_type)
|
||||||
|
info := sym.info as table.Struct
|
||||||
|
fields := info.fields.filter(it.typ in [table.string_type, table.int_type, table.bool_type] &&
|
||||||
|
'skip' !in it.attrs)
|
||||||
|
if fields.len == 0 {
|
||||||
|
c.error('V orm: select: empty fields in `$node.table_name`', node.pos)
|
||||||
|
}
|
||||||
|
if fields[0].name != 'id' {
|
||||||
|
c.error('V orm: `id int` must be the first field in `$node.table_name`', node.pos)
|
||||||
|
}
|
||||||
|
node.fields = fields
|
||||||
|
node.table_name = sym.name
|
||||||
|
if node.has_where {
|
||||||
|
// Register this type's fields as variables so they can be used in `where`
|
||||||
|
// expressions
|
||||||
|
scope := c.file.scope.innermost(node.pos.pos)
|
||||||
|
for field in fields {
|
||||||
|
// println('registering sql field var $field.name')
|
||||||
|
scope.register(field.name, ast.Var{
|
||||||
|
name: field.name
|
||||||
|
typ: field.typ
|
||||||
|
is_mut: true
|
||||||
|
is_used: true
|
||||||
|
is_changed: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
if node.has_where {
|
if node.has_where {
|
||||||
c.expr(node.where_expr)
|
c.expr(node.where_expr)
|
||||||
}
|
}
|
||||||
|
@ -2688,7 +2715,7 @@ fn (mut c Checker) sql_expr(node ast.SqlExpr) table.Type {
|
||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) sql_insert_expr(node ast.SqlStmt) table.Type {
|
fn (mut c Checker) sql_stmt(node ast.SqlStmt) table.Type {
|
||||||
c.expr(node.db_expr)
|
c.expr(node.db_expr)
|
||||||
return table.void_type
|
return table.void_type
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,10 @@ import v.table
|
||||||
|
|
||||||
fn (mut p Parser) sql_expr() ast.Expr {
|
fn (mut p Parser) sql_expr() ast.Expr {
|
||||||
// `sql db {`
|
// `sql db {`
|
||||||
|
pos := p.tok.position()
|
||||||
p.check_name()
|
p.check_name()
|
||||||
db_expr := p.expr(0)
|
db_expr := p.expr(0)
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
// kind := ast.SqlExprKind.select_
|
|
||||||
//
|
|
||||||
/*
|
|
||||||
if p.tok.kind == .name && p.tok.lit == 'insert' {
|
|
||||||
return p.sql_insert_expr(db_var_name)
|
|
||||||
// kind = .insert
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
p.check(.key_select)
|
p.check(.key_select)
|
||||||
n := p.check_name()
|
n := p.check_name()
|
||||||
is_count := n == 'count'
|
is_count := n == 'count'
|
||||||
|
@ -28,8 +21,6 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
||||||
typ = table.int_type
|
typ = table.int_type
|
||||||
}
|
}
|
||||||
table_type := p.parse_type() // `User`
|
table_type := p.parse_type() // `User`
|
||||||
sym := p.table.get_type_symbol(table_type)
|
|
||||||
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
|
mut query_one := false // one object is returned, not an array
|
||||||
|
@ -65,48 +56,24 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
||||||
typ = table_type
|
typ = table_type
|
||||||
}
|
}
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
// /////////
|
|
||||||
// Register this type's fields as variables so they can be used in `where`
|
|
||||||
// expressions
|
|
||||||
// fields := typ.fields.filter(typ == 'string' || typ == 'int')
|
|
||||||
// fields := typ.fields
|
|
||||||
// get only string and int fields
|
|
||||||
// mut fields := []Var
|
|
||||||
info := sym.info as table.Struct
|
|
||||||
fields := info.fields.filter(it.typ in [table.string_type, table.int_type, table.bool_type] &&
|
|
||||||
'skip' !in it.attrs)
|
|
||||||
if fields.len == 0 {
|
|
||||||
p.error('V orm: select: empty fields in `$table_name`')
|
|
||||||
}
|
|
||||||
if fields[0].name != 'id' {
|
|
||||||
p.error('V orm: `id int` must be the first field in `$table_name`')
|
|
||||||
}
|
|
||||||
for field in fields {
|
|
||||||
// println('registering sql field var $field.name')
|
|
||||||
p.scope.register(field.name, ast.Var{
|
|
||||||
name: field.name
|
|
||||||
typ: field.typ
|
|
||||||
is_mut: true
|
|
||||||
is_used: true
|
|
||||||
is_changed: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// ////////////
|
|
||||||
return ast.SqlExpr{
|
return ast.SqlExpr{
|
||||||
is_count: is_count
|
is_count: is_count
|
||||||
typ: typ
|
typ: typ
|
||||||
db_expr: db_expr
|
db_expr: db_expr
|
||||||
table_name: table_name
|
//table_name: table_name
|
||||||
|
table_type: table_type
|
||||||
where_expr: where_expr
|
where_expr: where_expr
|
||||||
has_where: has_where
|
has_where: has_where
|
||||||
fields: fields
|
//fields: fields
|
||||||
is_array: !query_one
|
is_array: !query_one
|
||||||
|
pos: pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert user into User
|
// insert user into User
|
||||||
// update User set nr_oders=nr_orders+1 where id == user_id
|
// update User set nr_oders=nr_orders+1 where id == user_id
|
||||||
fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
|
pos := p.tok.position()
|
||||||
p.inside_match = true
|
p.inside_match = true
|
||||||
defer {
|
defer {
|
||||||
p.inside_match = false
|
p.inside_match = false
|
||||||
|
@ -172,6 +139,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
table_name: table_name
|
table_name: table_name
|
||||||
table_type: table_type
|
table_type: table_type
|
||||||
object_var_name: inserted_var_name
|
object_var_name: inserted_var_name
|
||||||
|
pos: pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue