orm: insert
parent
c78cfa43bc
commit
cd8392e42d
|
@ -80,12 +80,20 @@ fn test_orm_sqlite() {
|
||||||
assert users3.len == 2
|
assert users3.len == 2
|
||||||
assert users3[0].age == 29
|
assert users3[0].age == 29
|
||||||
assert users3[1].age == 31
|
assert users3[1].age == 31
|
||||||
|
//
|
||||||
|
|
||||||
//user2 := User{}
|
new_user := User{name:'New user' age:30}
|
||||||
//x := sql db {
|
sql db {
|
||||||
//insert user2 into User
|
insert new_user into User
|
||||||
//}
|
}
|
||||||
//db.insert<User>(user2)
|
//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 |
|
pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl |
|
||||||
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
|
DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt |
|
||||||
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl |
|
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlInsertExpr |
|
||||||
UnsafeStmt
|
StructDecl | TypeDecl | UnsafeStmt
|
||||||
|
|
||||||
pub type ScopeObject = ConstField | GlobalDecl | Var
|
pub type ScopeObject = ConstField | GlobalDecl | Var
|
||||||
|
|
||||||
|
@ -808,6 +808,21 @@ pub:
|
||||||
foo int // todo
|
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 struct SqlExpr {
|
||||||
pub:
|
pub:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
|
@ -820,9 +835,6 @@ pub:
|
||||||
is_array bool
|
is_array bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SqlInsertExpr {
|
|
||||||
}
|
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (expr Expr) is_blank_ident() bool {
|
pub fn (expr Expr) is_blank_ident() bool {
|
||||||
match expr {
|
match expr {
|
||||||
|
|
|
@ -2011,6 +2011,9 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
||||||
ast.SqlExpr {
|
ast.SqlExpr {
|
||||||
return c.sql_expr(node)
|
return c.sql_expr(node)
|
||||||
}
|
}
|
||||||
|
ast.SqlInsertExpr {
|
||||||
|
return c.sql_insert_expr(node)
|
||||||
|
}
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
if node.language == .c {
|
if node.language == .c {
|
||||||
return table.byteptr_type
|
return table.byteptr_type
|
||||||
|
@ -2608,6 +2611,10 @@ 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.SqlInsertExpr) table.Type {
|
||||||
|
return table.void_type
|
||||||
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -360,6 +360,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
f.writeln('')
|
f.writeln('')
|
||||||
}
|
}
|
||||||
|
ast.SqlInsertExpr {}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
f.struct_decl(it)
|
f.struct_decl(it)
|
||||||
}
|
}
|
||||||
|
@ -714,6 +715,7 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||||
f.write(')')
|
f.write(')')
|
||||||
}
|
}
|
||||||
ast.SqlExpr {}
|
ast.SqlExpr {}
|
||||||
|
ast.SqlInsertExpr {}
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
if node.is_raw {
|
if node.is_raw {
|
||||||
f.write('r')
|
f.write('r')
|
||||||
|
|
|
@ -622,6 +622,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
g.const_decl(node)
|
g.const_decl(node)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
ast.Comment {}
|
||||||
ast.CompIf {
|
ast.CompIf {
|
||||||
g.comp_if(node)
|
g.comp_if(node)
|
||||||
}
|
}
|
||||||
|
@ -660,6 +661,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
|
g.tmp_count = 0
|
||||||
mut skip := false
|
mut skip := false
|
||||||
pos := g.out.buf.len
|
pos := g.out.buf.len
|
||||||
if g.pref.build_mode == .build_module {
|
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.write_autofree_stmts_when_needed(node)
|
||||||
g.return_statement(node)
|
g.return_statement(node)
|
||||||
}
|
}
|
||||||
|
ast.SqlInsertExpr{
|
||||||
|
g.sql_insert_expr(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) }
|
||||||
// g.writeln('typedef struct {')
|
// g.writeln('typedef struct {')
|
||||||
|
@ -790,9 +795,6 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
ast.UnsafeStmt {
|
ast.UnsafeStmt {
|
||||||
g.stmts(node.stmts)
|
g.stmts(node.stmts)
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
verror('cgen.stmt(): unhandled node ' + typeof(node))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
g.stmt_path_pos.delete(g.stmt_path_pos.len - 1)
|
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 {
|
ast.SqlExpr {
|
||||||
g.sql_select_expr(node)
|
g.sql_select_expr(node)
|
||||||
}
|
}
|
||||||
|
//ast.SqlInsertExpr {
|
||||||
|
//g.sql_insert_expr(node)
|
||||||
|
//}
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
if node.is_raw {
|
if node.is_raw {
|
||||||
escaped_val := node.val.replace_each(['"', '\\"', '\\', '\\\\'])
|
escaped_val := node.val.replace_each(['"', '\\"', '\\', '\\\\'])
|
||||||
|
|
|
@ -501,6 +501,8 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
g.gen_return_stmt(it)
|
g.gen_return_stmt(it)
|
||||||
}
|
}
|
||||||
|
ast.SqlInsertExpr{
|
||||||
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
g.gen_struct_decl(it)
|
g.gen_struct_decl(it)
|
||||||
}
|
}
|
||||||
|
@ -608,6 +610,9 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
ast.SqlExpr{
|
ast.SqlExpr{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
ast.SqlInsertExpr{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
ast.StringInterLiteral {
|
ast.StringInterLiteral {
|
||||||
g.gen_string_inter_literal(it)
|
g.gen_string_inter_literal(it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,45 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
fn (mut g Gen) sql_insert_expr(node ast.SqlInsertExpr) {
|
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) {
|
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.write('${dbtype}__DB_q_int(*(${dbtype}__DB*)${node.db_var_name}.data, tos_lit("$q')
|
||||||
g.sql_stmt_name = g.new_tmp_var()
|
g.sql_stmt_name = g.new_tmp_var()
|
||||||
db_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.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(*(${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')
|
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 {
|
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.
|
// not a V variable. Need to distinguish column names from V variables.
|
||||||
match expr {
|
match expr {
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
g.expr_to_sql(it.left)
|
g.expr_to_sql(expr.left)
|
||||||
match it.op {
|
match expr.op {
|
||||||
.eq { g.write(' = ') }
|
.eq { g.write(' = ') }
|
||||||
.gt { g.write(' > ') }
|
.gt { g.write(' > ') }
|
||||||
.lt { 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 {
|
.name, .key_mut, .key_static, .mul {
|
||||||
if p.tok.kind == .name {
|
if p.tok.kind == .name {
|
||||||
|
if p.tok.lit == 'sql' {
|
||||||
|
return p.sql_insert_expr()
|
||||||
|
}
|
||||||
if p.peek_tok.kind == .colon {
|
if p.peek_tok.kind == .colon {
|
||||||
// `label:`
|
// `label:`
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
|
|
|
@ -6,12 +6,19 @@ module parser
|
||||||
import v.ast
|
import v.ast
|
||||||
import v.table
|
import v.table
|
||||||
|
|
||||||
fn (mut p Parser) sql_expr() ast.SqlExpr {
|
fn (mut p Parser) sql_expr() ast.Expr {
|
||||||
// `sql db {`
|
// `sql db {`
|
||||||
p.check_name()
|
p.check_name()
|
||||||
db_var_name := p.check_name()
|
db_var_name := p.check_name()
|
||||||
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'
|
||||||
|
@ -97,3 +104,35 @@ fn (mut p Parser) sql_expr() ast.SqlExpr {
|
||||||
is_array: !query_one
|
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