From afa5a134b77456edb66907b949d0685da1d43262 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 25 Jun 2020 14:43:07 +0200 Subject: [PATCH] orm: move fields fetching to a separate function to remove copy pasta --- vlib/v/ast/ast.v | 4 +++- vlib/v/checker/checker.v | 31 ++++++++++++++++++++++--------- vlib/v/gen/cgen.v | 2 +- vlib/v/gen/sql.v | 19 +++++++------------ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index ebb3b69dd3..8c665187f7 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -819,10 +819,12 @@ pub struct SqlStmt { pub: kind SqlStmtKind db_expr Expr // `db` in `sql db {` - table_name string object_var_name string // `user` table_type table.Type pos token.Position +pub mut: + table_name string + fields []table.Field } pub struct SqlExpr { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8630acccfe..fa40e56aaa 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2683,14 +2683,7 @@ fn (c &Checker) fileis(s string) bool { 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) - } + fields := c.fetch_and_verify_orm_fields(info, node.pos, node.table_name) node.fields = fields node.table_name = sym.name if node.has_where { @@ -2715,11 +2708,31 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { 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) 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) { 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 diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index e5f402d207..4e9920a33a 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -751,7 +751,7 @@ fn (mut g Gen) stmt(node ast.Stmt) { g.return_statement(node) } ast.SqlStmt { - g.sql_insert_expr(node) + g.sql_stmt(node) } ast.StructDecl { name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) } diff --git a/vlib/v/gen/sql.v b/vlib/v/gen/sql.v index 380be0c211..07d371e420 100644 --- a/vlib/v/gen/sql.v +++ b/vlib/v/gen/sql.v @@ -1,6 +1,5 @@ // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. -// Use of this source code is governed by an MIT license -// that can be found in the LICENSE file. +// Use of this source code is governed by an MIT license that can be found in the LICENSE file. module gen import v.ast @@ -14,11 +13,7 @@ const ( enum SqlExprSide { left right } -fn (mut g Gen) sql_insert_expr(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) +fn (mut g Gen) sql_stmt(node ast.SqlStmt) { g.writeln('\n\t// sql insert') db_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.writeln(';') mut q := 'insert into $node.table_name (' - for i, field in fields { + for i, field in node.fields { if field.name == 'id' { continue } q += '$field.name' - if i < fields.len - 1 { + if i < node.fields.len - 1 { q += ', ' } } q += ') values (' - for i, field in fields { + for i, field in node.fields { if field.name == 'id' { continue } q += '?${i+0}' - if i < fields.len - 1 { + if i < node.fields.len - 1 { q += ', ' } } q += ')' println(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' { continue }