mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
orm: insert
This commit is contained in:
parent
c78cfa43bc
commit
cd8392e42d
@ -80,12 +80,20 @@ fn test_orm_sqlite() {
|
||||
assert users3.len == 2
|
||||
assert users3[0].age == 29
|
||||
assert users3[1].age == 31
|
||||
//
|
||||
|
||||
//user2 := User{}
|
||||
//x := sql db {
|
||||
//insert user2 into User
|
||||
//}
|
||||
new_user := User{name:'New user' age:30}
|
||||
sql db {
|
||||
insert new_user into User
|
||||
}
|
||||
//db.insert<User>(user2)
|
||||
x := sql db {
|
||||
select from User where id == 4
|
||||
}
|
||||
println(x)
|
||||
assert x.age == 30
|
||||
assert x.id == 4
|
||||
assert x.name == 'New user'
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,8 +17,8 @@ pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | C
|
||||
|
||||
pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl |
|
||||
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
|
||||
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl |
|
||||
UnsafeStmt
|
||||
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlInsertExpr |
|
||||
StructDecl | TypeDecl | UnsafeStmt
|
||||
|
||||
pub type ScopeObject = ConstField | GlobalDecl | Var
|
||||
|
||||
@ -808,6 +808,21 @@ pub:
|
||||
foo int // todo
|
||||
}
|
||||
|
||||
/*
|
||||
pub enum SqlExprKind {
|
||||
select_
|
||||
insert
|
||||
update
|
||||
}
|
||||
*/
|
||||
pub struct SqlInsertExpr {
|
||||
pub:
|
||||
db_var_name string // `db` in `sql db {`
|
||||
table_name string
|
||||
fields []table.Field
|
||||
object_var_name string // `user`
|
||||
}
|
||||
|
||||
pub struct SqlExpr {
|
||||
pub:
|
||||
typ table.Type
|
||||
@ -820,9 +835,6 @@ pub:
|
||||
is_array bool
|
||||
}
|
||||
|
||||
pub struct SqlInsertExpr {
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (expr Expr) is_blank_ident() bool {
|
||||
match expr {
|
||||
|
@ -2011,6 +2011,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||
ast.SqlExpr {
|
||||
return c.sql_expr(node)
|
||||
}
|
||||
ast.SqlInsertExpr {
|
||||
return c.sql_insert_expr(node)
|
||||
}
|
||||
ast.StringLiteral {
|
||||
if node.language == .c {
|
||||
return table.byteptr_type
|
||||
@ -2608,6 +2611,10 @@ fn (mut c Checker) sql_expr(node ast.SqlExpr) table.Type {
|
||||
return node.typ
|
||||
}
|
||||
|
||||
fn (mut c Checker) sql_insert_expr(node ast.SqlInsertExpr) table.Type {
|
||||
return table.void_type
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -360,6 +360,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
||||
}
|
||||
f.writeln('')
|
||||
}
|
||||
ast.SqlInsertExpr {}
|
||||
ast.StructDecl {
|
||||
f.struct_decl(it)
|
||||
}
|
||||
@ -714,6 +715,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||
f.write(')')
|
||||
}
|
||||
ast.SqlExpr {}
|
||||
ast.SqlInsertExpr {}
|
||||
ast.StringLiteral {
|
||||
if node.is_raw {
|
||||
f.write('r')
|
||||
|
@ -622,6 +622,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
g.const_decl(node)
|
||||
// }
|
||||
}
|
||||
ast.Comment {}
|
||||
ast.CompIf {
|
||||
g.comp_if(node)
|
||||
}
|
||||
@ -660,6 +661,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
}
|
||||
ast.FnDecl {
|
||||
g.tmp_count = 0
|
||||
mut skip := false
|
||||
pos := g.out.buf.len
|
||||
if g.pref.build_mode == .build_module {
|
||||
@ -767,6 +769,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
g.write_autofree_stmts_when_needed(node)
|
||||
g.return_statement(node)
|
||||
}
|
||||
ast.SqlInsertExpr{
|
||||
g.sql_insert_expr(node)
|
||||
}
|
||||
ast.StructDecl {
|
||||
name := if node.language == .c { node.name.replace('.', '__') } else { c_name(node.name) }
|
||||
// g.writeln('typedef struct {')
|
||||
@ -790,9 +795,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
ast.UnsafeStmt {
|
||||
g.stmts(node.stmts)
|
||||
}
|
||||
else {
|
||||
verror('cgen.stmt(): unhandled node ' + typeof(node))
|
||||
}
|
||||
}
|
||||
g.stmt_path_pos.delete(g.stmt_path_pos.len - 1)
|
||||
}
|
||||
@ -1585,6 +1587,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||
ast.SqlExpr {
|
||||
g.sql_select_expr(node)
|
||||
}
|
||||
//ast.SqlInsertExpr {
|
||||
//g.sql_insert_expr(node)
|
||||
//}
|
||||
ast.StringLiteral {
|
||||
if node.is_raw {
|
||||
escaped_val := node.val.replace_each(['"', '\\"', '\\', '\\\\'])
|
||||
|
@ -501,6 +501,8 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||
}
|
||||
g.gen_return_stmt(it)
|
||||
}
|
||||
ast.SqlInsertExpr{
|
||||
}
|
||||
ast.StructDecl {
|
||||
g.gen_struct_decl(it)
|
||||
}
|
||||
@ -608,6 +610,9 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||
ast.SqlExpr{
|
||||
// TODO
|
||||
}
|
||||
ast.SqlInsertExpr{
|
||||
// TODO
|
||||
}
|
||||
ast.StringInterLiteral {
|
||||
g.gen_string_inter_literal(it)
|
||||
}
|
||||
|
@ -13,6 +13,45 @@ const (
|
||||
)
|
||||
|
||||
fn (mut g Gen) sql_insert_expr(node ast.SqlInsertExpr) {
|
||||
g.writeln('\n\t// sql insert')
|
||||
db_name := g.new_tmp_var()
|
||||
g.sql_stmt_name = g.new_tmp_var()
|
||||
g.writeln('${dbtype}__DB $db_name = $node.db_var_name;')
|
||||
mut q := 'insert into $node.table_name ('
|
||||
for i, field in node.fields {
|
||||
if field.name == 'id' {
|
||||
continue
|
||||
}
|
||||
q += '$field.name'
|
||||
if i < node.fields.len - 1 {
|
||||
q += ', '
|
||||
}
|
||||
}
|
||||
q += ') values ('
|
||||
for i, field in node.fields {
|
||||
if field.name == 'id' {
|
||||
continue
|
||||
}
|
||||
q += '?${i+0}'
|
||||
if i < node.fields.len - 1 {
|
||||
q += ', '
|
||||
}
|
||||
}
|
||||
q += ')'
|
||||
g.writeln('sqlite3_stmt* $g.sql_stmt_name = ${dbtype}__DB_init_stmt($db_name, tos_lit("$q"));')
|
||||
for i, field in node.fields {
|
||||
if field.name == 'id' {
|
||||
continue
|
||||
}
|
||||
x := '${node.object_var_name}.$field.name'
|
||||
if field.typ == table.string_type {
|
||||
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i+0}, ${x}.str, ${x}.len, 0);')
|
||||
} else {
|
||||
g.writeln('sqlite3_bind_int($g.sql_stmt_name, ${i+0}, $x); //insertl')
|
||||
}
|
||||
}
|
||||
g.writeln('sqlite3_step($g.sql_stmt_name);')
|
||||
g.writeln('sqlite3_finalize($g.sql_stmt_name);')
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
|
||||
@ -48,9 +87,9 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
|
||||
// g.write('${dbtype}__DB_q_int(*(${dbtype}__DB*)${node.db_var_name}.data, tos_lit("$q')
|
||||
g.sql_stmt_name = g.new_tmp_var()
|
||||
db_name := g.new_tmp_var()
|
||||
g.writeln('\n\t// sql')
|
||||
g.writeln('\n\t// sql select')
|
||||
// g.write('${dbtype}__DB $db_name = *(${dbtype}__DB*)${node.db_var_name}.data;')
|
||||
g.writeln('${dbtype}__DB $db_name = ${node.db_var_name};')
|
||||
g.writeln('${dbtype}__DB $db_name = $node.db_var_name;')
|
||||
// g.write('sqlite3_stmt* $g.sql_stmt_name = ${dbtype}__DB_init_stmt(*(${dbtype}__DB*)${node.db_var_name}.data, tos_lit("$q')
|
||||
g.write('sqlite3_stmt* $g.sql_stmt_name = ${dbtype}__DB_init_stmt($db_name, tos_lit("$q')
|
||||
if node.has_where && node.where_expr is ast.InfixExpr {
|
||||
@ -118,8 +157,8 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr) {
|
||||
// not a V variable. Need to distinguish column names from V variables.
|
||||
match expr {
|
||||
ast.InfixExpr {
|
||||
g.expr_to_sql(it.left)
|
||||
match it.op {
|
||||
g.expr_to_sql(expr.left)
|
||||
match expr.op {
|
||||
.eq { g.write(' = ') }
|
||||
.gt { g.write(' > ') }
|
||||
.lt { g.write(' < ') }
|
||||
|
@ -518,6 +518,9 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
||||
}
|
||||
.name, .key_mut, .key_static, .mul {
|
||||
if p.tok.kind == .name {
|
||||
if p.tok.lit == 'sql' {
|
||||
return p.sql_insert_expr()
|
||||
}
|
||||
if p.peek_tok.kind == .colon {
|
||||
// `label:`
|
||||
name := p.check_name()
|
||||
|
@ -6,12 +6,19 @@ module parser
|
||||
import v.ast
|
||||
import v.table
|
||||
|
||||
fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||
fn (mut p Parser) sql_expr() ast.Expr {
|
||||
// `sql db {`
|
||||
p.check_name()
|
||||
db_var_name := p.check_name()
|
||||
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)
|
||||
n := p.check_name()
|
||||
is_count := n == 'count'
|
||||
@ -97,3 +104,35 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||
is_array: !query_one
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) sql_insert_expr() ast.SqlInsertExpr {
|
||||
// `sql db {`
|
||||
p.check_name()
|
||||
db_var_name := p.check_name()
|
||||
p.check(.lcbr)
|
||||
// kind := ast.SqlExprKind.select_
|
||||
//
|
||||
p.check_name() // insert
|
||||
mut object_var_name := ''
|
||||
expr := p.expr(0)
|
||||
match expr {
|
||||
ast.Ident { object_var_name = expr.name }
|
||||
else { p.error('can only insert variables') }
|
||||
}
|
||||
n := p.check_name() // into
|
||||
if n != 'into' {
|
||||
p.error('expecting `into`')
|
||||
}
|
||||
table_type := p.parse_type() // `User`
|
||||
sym := p.table.get_type_symbol(table_type)
|
||||
info := sym.info as table.Struct
|
||||
fields := info.fields.filter(it.typ in [table.string_type, table.int_type, table.bool_type])
|
||||
table_name := sym.name
|
||||
p.check(.rcbr)
|
||||
return ast.SqlInsertExpr{
|
||||
db_var_name: db_var_name
|
||||
table_name: table_name
|
||||
fields: fields
|
||||
object_var_name: object_var_name
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user