mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
orm: support multiline statements (#9888)
This commit is contained in:
parent
9f1ac39770
commit
faf2656335
@ -65,6 +65,7 @@ pub fn (mut app App) new_article() vweb.Result {
|
||||
sql app.db {
|
||||
insert article into Article
|
||||
}
|
||||
|
||||
return app.redirect('/')
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,30 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
|
||||
name := 'Peter'
|
||||
db.exec("insert into userlist (username, age) values ('Sam', 29)")
|
||||
db.exec("insert into userlist (username, age) values ('Peter', 31)")
|
||||
db.exec("insert into userlist (username, age, is_customer) values ('Kate', 30, 1)")
|
||||
|
||||
sam := User{
|
||||
age: 29
|
||||
name: 'Sam'
|
||||
}
|
||||
|
||||
peter := User{
|
||||
age: 31
|
||||
name: 'Peter'
|
||||
}
|
||||
|
||||
k := User{
|
||||
age: 30
|
||||
name: 'Kate'
|
||||
is_customer: true
|
||||
}
|
||||
|
||||
sql db {
|
||||
insert sam into User
|
||||
insert peter into User
|
||||
insert k into User
|
||||
}
|
||||
|
||||
c := sql db {
|
||||
select count from User where id != 1
|
||||
@ -113,6 +133,7 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
insert new_user into User
|
||||
}
|
||||
|
||||
// db.insert<User>(user2)
|
||||
x := sql db {
|
||||
select from User where id == 4
|
||||
@ -136,6 +157,7 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
update User set age = 31 where name == 'Kate'
|
||||
}
|
||||
|
||||
kate2 := sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
@ -167,6 +189,7 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
update User set age = new_age, name = 'Kate N' where id == 3
|
||||
}
|
||||
|
||||
kate3 = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
@ -177,6 +200,7 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
update User set age = foo.age, name = 'Kate N' where id == 3
|
||||
}
|
||||
|
||||
kate3 = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
@ -219,6 +243,7 @@ fn test_orm_sqlite() {
|
||||
sql db {
|
||||
delete from User where age == 34
|
||||
}
|
||||
|
||||
updated_oldest := sql db {
|
||||
select from User order by age desc limit 1
|
||||
}
|
||||
|
@ -1440,8 +1440,15 @@ pub enum SqlStmtKind {
|
||||
|
||||
pub struct SqlStmt {
|
||||
pub:
|
||||
kind SqlStmtKind
|
||||
pos token.Position
|
||||
db_expr Expr // `db` in `sql db {`
|
||||
pub mut:
|
||||
lines []SqlStmtLine
|
||||
}
|
||||
|
||||
pub struct SqlStmtLine {
|
||||
pub:
|
||||
kind SqlStmtKind
|
||||
object_var_name string // `user`
|
||||
pos token.Position
|
||||
where_expr Expr
|
||||
@ -1450,7 +1457,7 @@ pub:
|
||||
pub mut:
|
||||
table_expr TypeNode
|
||||
fields []StructField
|
||||
sub_structs map[int]SqlStmt
|
||||
sub_structs map[int]SqlStmtLine
|
||||
}
|
||||
|
||||
pub struct SqlExpr {
|
||||
|
@ -6488,6 +6488,18 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||
}
|
||||
|
||||
fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
||||
c.expr(node.db_expr)
|
||||
mut typ := ast.void_type
|
||||
for mut line in node.lines {
|
||||
a := c.sql_stmt_line(mut line)
|
||||
if a != ast.void_type {
|
||||
typ = a
|
||||
}
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
|
||||
c.inside_sql = true
|
||||
defer {
|
||||
c.inside_sql = false
|
||||
@ -6501,11 +6513,10 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
||||
}
|
||||
info := table_sym.info as ast.Struct
|
||||
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name)
|
||||
mut sub_structs := map[int]ast.SqlStmt{}
|
||||
mut sub_structs := map[int]ast.SqlStmtLine{}
|
||||
for f in fields.filter(c.table.type_symbols[int(it.typ)].kind == .struct_) {
|
||||
mut n := ast.SqlStmt{
|
||||
mut n := ast.SqlStmtLine{
|
||||
pos: node.pos
|
||||
db_expr: node.db_expr
|
||||
kind: node.kind
|
||||
table_expr: ast.TypeNode{
|
||||
pos: node.table_expr.pos
|
||||
@ -6514,13 +6525,12 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
||||
object_var_name: '${node.object_var_name}.$f.name'
|
||||
}
|
||||
tmp_inside_sql := c.inside_sql
|
||||
c.sql_stmt(mut n)
|
||||
c.sql_stmt_line(mut n)
|
||||
c.inside_sql = tmp_inside_sql
|
||||
sub_structs[int(f.typ)] = n
|
||||
}
|
||||
node.fields = fields
|
||||
node.sub_structs = sub_structs.move()
|
||||
c.expr(node.db_expr)
|
||||
if node.kind == .update {
|
||||
for expr in node.update_exprs {
|
||||
c.expr(expr)
|
||||
|
@ -1215,6 +1215,15 @@ pub fn (mut f Fmt) sql_stmt(node ast.SqlStmt) {
|
||||
f.write('sql ')
|
||||
f.expr(node.db_expr)
|
||||
f.writeln(' {')
|
||||
|
||||
for line in node.lines {
|
||||
f.sql_stmt_line(line)
|
||||
}
|
||||
|
||||
f.writeln('}')
|
||||
}
|
||||
|
||||
pub fn (mut f Fmt) sql_stmt_line(node ast.SqlStmtLine) {
|
||||
table_name := util.strip_mod_name(f.table.get_type_symbol(node.table_expr.typ).name)
|
||||
f.write('\t')
|
||||
match node.kind {
|
||||
@ -1249,7 +1258,6 @@ pub fn (mut f Fmt) sql_stmt(node ast.SqlStmt) {
|
||||
f.writeln('drop table $table_name')
|
||||
}
|
||||
}
|
||||
f.writeln('}')
|
||||
}
|
||||
|
||||
pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
||||
|
@ -24,24 +24,30 @@ enum SqlType {
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_stmt(node ast.SqlStmt) {
|
||||
for line in node.lines {
|
||||
g.sql_stmt_line(line, node.db_expr)
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_stmt_line(node ast.SqlStmtLine, expr ast.Expr) {
|
||||
if node.kind == .create {
|
||||
g.sql_create_table(node)
|
||||
g.sql_create_table(node, expr)
|
||||
return
|
||||
} else if node.kind == .drop {
|
||||
g.sql_drop_table(node)
|
||||
g.sql_drop_table(node, expr)
|
||||
return
|
||||
}
|
||||
g.sql_table_name = g.table.get_type_symbol(node.table_expr.typ).name
|
||||
typ := g.parse_db_type(node.db_expr)
|
||||
typ := g.parse_db_type(expr)
|
||||
match typ {
|
||||
.sqlite3 {
|
||||
g.sqlite3_stmt(node, typ)
|
||||
g.sqlite3_stmt(node, typ, expr)
|
||||
}
|
||||
.mysql {
|
||||
g.mysql_stmt(node, typ)
|
||||
g.mysql_stmt(node, typ, expr)
|
||||
}
|
||||
.psql {
|
||||
g.psql_stmt(node, typ)
|
||||
g.psql_stmt(node, typ, expr)
|
||||
}
|
||||
else {
|
||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
||||
@ -49,17 +55,17 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_create_table(node ast.SqlStmt) {
|
||||
typ := g.parse_db_type(node.db_expr)
|
||||
fn (mut g Gen) sql_create_table(node ast.SqlStmtLine, expr ast.Expr) {
|
||||
typ := g.parse_db_type(expr)
|
||||
match typ {
|
||||
.sqlite3 {
|
||||
g.sqlite3_create_table(node, typ)
|
||||
g.sqlite3_create_table(node, typ, expr)
|
||||
}
|
||||
.mysql {
|
||||
g.mysql_create_table(node, typ)
|
||||
g.mysql_create_table(node, typ, expr)
|
||||
}
|
||||
.psql {
|
||||
g.psql_create_table(node, typ)
|
||||
g.psql_create_table(node, typ, expr)
|
||||
}
|
||||
else {
|
||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
||||
@ -67,17 +73,17 @@ fn (mut g Gen) sql_create_table(node ast.SqlStmt) {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_drop_table(node ast.SqlStmt) {
|
||||
typ := g.parse_db_type(node.db_expr)
|
||||
fn (mut g Gen) sql_drop_table(node ast.SqlStmtLine, expr ast.Expr) {
|
||||
typ := g.parse_db_type(expr)
|
||||
match typ {
|
||||
.sqlite3 {
|
||||
g.sqlite3_drop_table(node, typ)
|
||||
g.sqlite3_drop_table(node, typ, expr)
|
||||
}
|
||||
.mysql {
|
||||
g.mysql_drop_table(node, typ)
|
||||
g.mysql_drop_table(node, typ, expr)
|
||||
}
|
||||
.psql {
|
||||
g.psql_create_table(node, typ)
|
||||
g.psql_create_table(node, typ, expr)
|
||||
}
|
||||
else {
|
||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
||||
@ -136,13 +142,13 @@ fn (mut g Gen) sql_type_from_v(typ SqlType, v_typ ast.Type) string {
|
||||
|
||||
// sqlite3
|
||||
|
||||
fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) sqlite3_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.sql_i = 0
|
||||
g.writeln('\n\t// sql insert')
|
||||
db_name := g.new_tmp_var()
|
||||
g.sql_stmt_name = g.new_tmp_var()
|
||||
g.write('${c.dbtype}__DB $db_name = ')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(';')
|
||||
g.write('sqlite3_stmt* $g.sql_stmt_name = ${c.dbtype}__DB_init_stmt($db_name, _SLIT("')
|
||||
g.sql_defaults(node, typ)
|
||||
@ -161,7 +167,7 @@ fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
expr := node.sub_structs[int(field.typ)]
|
||||
tmp_sql_stmt_name := g.sql_stmt_name
|
||||
tmp_sql_table_name := g.sql_table_name
|
||||
g.sql_stmt(expr)
|
||||
g.sql_stmt_line(expr, db_expr)
|
||||
g.sql_stmt_name = tmp_sql_stmt_name
|
||||
g.sql_table_name = tmp_sql_table_name
|
||||
// get last inserted id
|
||||
@ -326,20 +332,20 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) sqlite3_create_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) sqlite3_create_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.writeln('// sqlite3 table creator')
|
||||
create_string := g.table_gen(node, typ)
|
||||
create_string := g.table_gen(node, typ, db_expr)
|
||||
g.write('sqlite__DB_exec(')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$create_string"));')
|
||||
}
|
||||
|
||||
fn (mut g Gen) sqlite3_drop_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) sqlite3_drop_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
g.writeln('// sqlite3 table drop')
|
||||
drop_string := 'DROP TABLE `$table_name`;'
|
||||
g.write('sqlite__DB_exec(')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$drop_string"));')
|
||||
}
|
||||
|
||||
@ -377,13 +383,13 @@ fn (mut g Gen) sqlite3_type_from_v(v_typ ast.Type) string {
|
||||
|
||||
// mysql
|
||||
|
||||
fn (mut g Gen) mysql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) mysql_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.sql_i = 0
|
||||
g.writeln('\n\t//mysql insert')
|
||||
db_name := g.new_tmp_var()
|
||||
g.sql_stmt_name = g.new_tmp_var()
|
||||
g.write('mysql__Connection $db_name = ')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(';')
|
||||
stmt_name := g.new_tmp_var()
|
||||
g.write('string $stmt_name = _SLIT("')
|
||||
@ -407,7 +413,7 @@ fn (mut g Gen) mysql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
expr := node.sub_structs[int(field.typ)]
|
||||
tmp_sql_stmt_name := g.sql_stmt_name
|
||||
tmp_sql_table_name := g.sql_table_name
|
||||
g.sql_stmt(expr)
|
||||
g.sql_stmt_line(expr, db_expr)
|
||||
g.sql_stmt_name = tmp_sql_stmt_name
|
||||
g.sql_table_name = tmp_sql_table_name
|
||||
|
||||
@ -618,23 +624,23 @@ fn (mut g Gen) mysql_select_expr(node ast.SqlExpr, sub bool, line string, typ Sq
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) mysql_create_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) mysql_create_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.writeln('// mysql table creator')
|
||||
create_string := g.table_gen(node, typ)
|
||||
create_string := g.table_gen(node, typ, db_expr)
|
||||
tmp := g.new_tmp_var()
|
||||
g.write('Option_mysql__Result $tmp = mysql__Connection_query(&')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$create_string"));')
|
||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
||||
}
|
||||
|
||||
fn (mut g Gen) mysql_drop_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) mysql_drop_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
g.writeln('// mysql table drop')
|
||||
drop_string := 'DROP TABLE `$table_name`;'
|
||||
tmp := g.new_tmp_var()
|
||||
g.write('Option_mysql__Result $tmp = mysql__Connection_query(&')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$drop_string"));')
|
||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
||||
}
|
||||
@ -735,7 +741,7 @@ fn (mut g Gen) mysql_buffer_typ_from_field(field ast.StructField) (string, strin
|
||||
|
||||
// psql
|
||||
|
||||
fn (mut g Gen) psql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) psql_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.sql_i = 0
|
||||
g.sql_idents = []string{}
|
||||
param_values := g.new_tmp_var()
|
||||
@ -745,7 +751,7 @@ fn (mut g Gen) psql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
db_name := g.new_tmp_var()
|
||||
g.sql_stmt_name = g.new_tmp_var()
|
||||
g.write('pg__DB $db_name = ')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(';')
|
||||
stmt_name := g.new_tmp_var()
|
||||
g.write('string $stmt_name = _SLIT("')
|
||||
@ -769,7 +775,7 @@ fn (mut g Gen) psql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
expr := node.sub_structs[int(field.typ)]
|
||||
tmp_sql_stmt_name := g.sql_stmt_name
|
||||
tmp_sql_table_name := g.sql_table_name
|
||||
g.sql_stmt(expr)
|
||||
g.sql_stmt_line(expr, db_expr)
|
||||
g.sql_stmt_name = tmp_sql_stmt_name
|
||||
g.sql_table_name = tmp_sql_table_name
|
||||
|
||||
@ -803,23 +809,23 @@ fn (mut g Gen) psql_stmt(node ast.SqlStmt, typ SqlType) {
|
||||
g.writeln('if (${res}_rows.state != 0) { IError err = ${res}_rows.err; eprintln(_STR("\\000%.*s", 2, IError_str(err))); }')
|
||||
}
|
||||
|
||||
fn (mut g Gen) psql_create_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) psql_create_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
g.writeln('// psql table creator')
|
||||
create_string := g.table_gen(node, typ)
|
||||
create_string := g.table_gen(node, typ, db_expr)
|
||||
tmp := g.new_tmp_var()
|
||||
g.write('Option_Array_pg__Row $tmp = pg__DB_exec(')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$create_string"));')
|
||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
||||
}
|
||||
|
||||
fn (mut g Gen) psql_drop_table(node ast.SqlStmt, typ SqlType) {
|
||||
fn (mut g Gen) psql_drop_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
g.writeln('// psql table drop')
|
||||
drop_string := 'DROP TABLE "$table_name";'
|
||||
tmp := g.new_tmp_var()
|
||||
g.write('Option_Array_pg__Row $tmp = pg__DB_exec(&')
|
||||
g.expr(node.db_expr)
|
||||
g.expr(db_expr)
|
||||
g.writeln(', _SLIT("$drop_string"));')
|
||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
||||
}
|
||||
@ -929,7 +935,7 @@ fn (mut g Gen) get_base_sql_select_query(node ast.SqlExpr) string {
|
||||
return sql_query
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_defaults(node ast.SqlStmt, typ SqlType, psql_data ...string) {
|
||||
fn (mut g Gen) sql_defaults(node ast.SqlStmtLine, typ SqlType, psql_data ...string) {
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
mut lit := '`'
|
||||
if typ == .psql {
|
||||
@ -981,7 +987,7 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmt, typ SqlType, psql_data ...string)
|
||||
g.write(';")')
|
||||
}
|
||||
|
||||
fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) string {
|
||||
fn (mut g Gen) table_gen(node ast.SqlStmtLine, typ SqlType, expr ast.Expr) string {
|
||||
typ_sym := g.table.get_type_symbol(node.table_expr.typ)
|
||||
struct_data := typ_sym.struct_info()
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
@ -1032,15 +1038,14 @@ fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) string {
|
||||
if converted_typ == '' {
|
||||
if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
||||
converted_typ = g.sql_type_from_v(typ, ast.int_type)
|
||||
g.sql_create_table(ast.SqlStmt{
|
||||
db_expr: node.db_expr
|
||||
g.sql_create_table(ast.SqlStmtLine{
|
||||
kind: node.kind
|
||||
pos: node.pos
|
||||
table_expr: ast.TypeNode{
|
||||
typ: field.typ
|
||||
pos: node.table_expr.pos
|
||||
}
|
||||
})
|
||||
}, expr)
|
||||
} else {
|
||||
verror('unknown type ($field.typ) for field $field.name in struct $table_name')
|
||||
continue
|
||||
|
@ -97,8 +97,10 @@ pub fn (mut w Walker) stmt(node ast.Stmt) {
|
||||
}
|
||||
ast.SqlStmt {
|
||||
w.expr(node.db_expr)
|
||||
w.expr(node.where_expr)
|
||||
w.exprs(node.update_exprs)
|
||||
for line in node.lines {
|
||||
w.expr(line.where_expr)
|
||||
w.exprs(line.update_exprs)
|
||||
}
|
||||
}
|
||||
ast.StructDecl {
|
||||
w.struct_fields(node.fields)
|
||||
|
@ -125,9 +125,25 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
}
|
||||
// println(typeof(db_expr))
|
||||
p.check(.lcbr)
|
||||
// kind := ast.SqlExprKind.select_
|
||||
//
|
||||
|
||||
mut lines := []ast.SqlStmtLine{}
|
||||
|
||||
for p.tok.kind != .rcbr {
|
||||
lines << p.parse_sql_stmt_line()
|
||||
}
|
||||
|
||||
p.next()
|
||||
pos.last_line = p.prev_tok.line_nr
|
||||
return ast.SqlStmt{
|
||||
pos: pos.extend(p.prev_tok.position())
|
||||
db_expr: db_expr
|
||||
lines: lines
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
|
||||
mut n := p.check_name() // insert
|
||||
pos := p.tok.position()
|
||||
mut kind := ast.SqlStmtKind.insert
|
||||
if n == 'delete' {
|
||||
kind = .delete
|
||||
@ -138,13 +154,11 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
table := p.check_name()
|
||||
if table != 'table' {
|
||||
p.error('expected `table` got `$table`')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
}
|
||||
typ := p.parse_type()
|
||||
typ_pos := p.tok.position()
|
||||
p.check(.rcbr)
|
||||
return ast.SqlStmt{
|
||||
db_expr: db_expr
|
||||
return ast.SqlStmtLine{
|
||||
kind: kind
|
||||
pos: pos.extend(p.prev_tok.position())
|
||||
table_expr: ast.TypeNode{
|
||||
@ -157,13 +171,11 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
table := p.check_name()
|
||||
if table != 'table' {
|
||||
p.error('expected `table` got `$table`')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
}
|
||||
typ := p.parse_type()
|
||||
typ_pos := p.tok.position()
|
||||
p.check(.rcbr)
|
||||
return ast.SqlStmt{
|
||||
db_expr: db_expr
|
||||
return ast.SqlStmtLine{
|
||||
kind: kind
|
||||
pos: pos.extend(p.prev_tok.position())
|
||||
table_expr: ast.TypeNode{
|
||||
@ -183,7 +195,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
inserted_var_name = expr.name
|
||||
} else {
|
||||
p.error('can only insert variables')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,11 +204,11 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
mut update_exprs := []ast.Expr{cap: 5}
|
||||
if kind == .insert && n != 'into' {
|
||||
p.error('expecting `into`')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
} else if kind == .update {
|
||||
if n != 'set' {
|
||||
p.error('expecting `set`')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
}
|
||||
for {
|
||||
column := p.check_name()
|
||||
@ -211,7 +223,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
}
|
||||
} else if kind == .delete && n != 'from' {
|
||||
p.error('expecting `from`')
|
||||
return ast.SqlStmt{}
|
||||
return ast.SqlStmtLine{}
|
||||
}
|
||||
|
||||
mut table_pos := p.tok.position()
|
||||
@ -220,24 +232,21 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||
table_pos = p.tok.position()
|
||||
table_type = p.parse_type()
|
||||
} else if kind == .update {
|
||||
p.check_sql_keyword('where') or { return ast.SqlStmt{} }
|
||||
p.check_sql_keyword('where') or { return ast.SqlStmtLine{} }
|
||||
where_expr = p.expr(0)
|
||||
} else if kind == .delete {
|
||||
table_pos = p.tok.position()
|
||||
table_type = p.parse_type()
|
||||
p.check_sql_keyword('where') or { return ast.SqlStmt{} }
|
||||
p.check_sql_keyword('where') or { return ast.SqlStmtLine{} }
|
||||
where_expr = p.expr(0)
|
||||
}
|
||||
p.check(.rcbr)
|
||||
pos.last_line = p.prev_tok.line_nr
|
||||
return ast.SqlStmt{
|
||||
db_expr: db_expr
|
||||
return ast.SqlStmtLine{
|
||||
table_expr: ast.TypeNode{
|
||||
typ: table_type
|
||||
pos: table_pos
|
||||
}
|
||||
object_var_name: inserted_var_name
|
||||
pos: pos.extend(p.prev_tok.position())
|
||||
pos: pos
|
||||
updated_columns: updated_columns
|
||||
update_exprs: update_exprs
|
||||
kind: kind
|
||||
|
Loading…
Reference in New Issue
Block a user