1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

orm: move fields fetching to a separate function to remove copy pasta

This commit is contained in:
Alexander Medvednikov 2020-06-25 14:43:07 +02:00
parent f1e17f30f6
commit afa5a134b7
4 changed files with 33 additions and 23 deletions

View File

@ -819,10 +819,12 @@ pub struct SqlStmt {
pub: pub:
kind SqlStmtKind kind SqlStmtKind
db_expr Expr // `db` in `sql db {` db_expr Expr // `db` in `sql db {`
table_name string
object_var_name string // `user` object_var_name string // `user`
table_type table.Type table_type table.Type
pos token.Position pos token.Position
pub mut:
table_name string
fields []table.Field
} }
pub struct SqlExpr { pub struct SqlExpr {

View File

@ -2683,14 +2683,7 @@ fn (c &Checker) fileis(s string) bool {
fn (mut c Checker) sql_expr(mut 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) sym := c.table.get_type_symbol(node.table_type)
info := sym.info as table.Struct info := sym.info as table.Struct
fields := info.fields.filter(it.typ in [table.string_type, table.int_type, table.bool_type] && fields := c.fetch_and_verify_orm_fields(info, node.pos, node.table_name)
'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.fields = fields
node.table_name = sym.name node.table_name = sym.name
if node.has_where { if node.has_where {
@ -2715,11 +2708,31 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type {
return node.typ return node.typ
} }
fn (mut c Checker) sql_stmt(node ast.SqlStmt) table.Type { fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type {
//vlib/v/gen/sql.v:37:18: error: undefined ident: `fields`
//vlib/v/gen/sql.v:28:12: error: unknown selector expression
sym := c.table.get_type_symbol(node.table_type)
info := sym.info as table.Struct
fields := c.fetch_and_verify_orm_fields(info, node.pos, node.table_name)
node.fields = fields
c.expr(node.db_expr) c.expr(node.db_expr)
return table.void_type return table.void_type
} }
fn (c &Checker) fetch_and_verify_orm_fields(info table.Struct, pos token.Position, table_name string) []table.Field {
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 `$table_name`', pos)
}
if fields[0].name != 'id' {
c.error('V orm: `id int` must be the first field in `$table_name`', pos)
}
return fields
}
fn (mut c Checker) fn_decl(it ast.FnDecl) { fn (mut c Checker) fn_decl(it ast.FnDecl) {
if it.is_generic && c.cur_generic_type == 0 { // need the cur_generic_type check to avoid inf. recursion if it.is_generic && c.cur_generic_type == 0 { // need the cur_generic_type check to avoid inf. recursion
// loop thru each generic type and generate a function // loop thru each generic type and generate a function

View File

@ -751,7 +751,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
g.return_statement(node) g.return_statement(node)
} }
ast.SqlStmt { ast.SqlStmt {
g.sql_insert_expr(node) g.sql_stmt(node)
} }
ast.StructDecl { ast.StructDecl {
name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) } name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) }

View File

@ -1,6 +1,5 @@
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license that can be found in the LICENSE file.
// that can be found in the LICENSE file.
module gen module gen
import v.ast import v.ast
@ -14,11 +13,7 @@ const (
enum SqlExprSide { left right } enum SqlExprSide { left right }
fn (mut g Gen) sql_insert_expr(node ast.SqlStmt) { fn (mut g Gen) sql_stmt(node ast.SqlStmt) {
sym := g.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)
g.writeln('\n\t// sql insert') g.writeln('\n\t// sql insert')
db_name := g.new_tmp_var() db_name := g.new_tmp_var()
g.sql_stmt_name = g.new_tmp_var() g.sql_stmt_name = g.new_tmp_var()
@ -26,29 +21,29 @@ fn (mut g Gen) sql_insert_expr(node ast.SqlStmt) {
g.expr(node.db_expr) g.expr(node.db_expr)
g.writeln(';') g.writeln(';')
mut q := 'insert into $node.table_name (' mut q := 'insert into $node.table_name ('
for i, field in fields { for i, field in node.fields {
if field.name == 'id' { if field.name == 'id' {
continue continue
} }
q += '$field.name' q += '$field.name'
if i < fields.len - 1 { if i < node.fields.len - 1 {
q += ', ' q += ', '
} }
} }
q += ') values (' q += ') values ('
for i, field in fields { for i, field in node.fields {
if field.name == 'id' { if field.name == 'id' {
continue continue
} }
q += '?${i+0}' q += '?${i+0}'
if i < fields.len - 1 { if i < node.fields.len - 1 {
q += ', ' q += ', '
} }
} }
q += ')' q += ')'
println(q) println(q)
g.writeln('sqlite3_stmt* $g.sql_stmt_name = ${dbtype}__DB_init_stmt($db_name, tos_lit("$q"));') g.writeln('sqlite3_stmt* $g.sql_stmt_name = ${dbtype}__DB_init_stmt($db_name, tos_lit("$q"));')
for i, field in fields { for i, field in node.fields {
if field.name == 'id' { if field.name == 'id' {
continue continue
} }