orm: support multiline statements (#9888)
parent
9f1ac39770
commit
faf2656335
|
@ -65,6 +65,7 @@ pub fn (mut app App) new_article() vweb.Result {
|
||||||
sql app.db {
|
sql app.db {
|
||||||
insert article into Article
|
insert article into Article
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.redirect('/')
|
return app.redirect('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,30 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
create table User
|
create table User
|
||||||
}
|
}
|
||||||
|
|
||||||
name := 'Peter'
|
name := 'Peter'
|
||||||
db.exec("insert into userlist (username, age) values ('Sam', 29)")
|
|
||||||
db.exec("insert into userlist (username, age) values ('Peter', 31)")
|
sam := User{
|
||||||
db.exec("insert into userlist (username, age, is_customer) values ('Kate', 30, 1)")
|
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 {
|
c := sql db {
|
||||||
select count from User where id != 1
|
select count from User where id != 1
|
||||||
|
@ -113,6 +133,7 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
insert new_user into User
|
insert new_user into User
|
||||||
}
|
}
|
||||||
|
|
||||||
// db.insert<User>(user2)
|
// db.insert<User>(user2)
|
||||||
x := sql db {
|
x := sql db {
|
||||||
select from User where id == 4
|
select from User where id == 4
|
||||||
|
@ -136,6 +157,7 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
update User set age = 31 where name == 'Kate'
|
update User set age = 31 where name == 'Kate'
|
||||||
}
|
}
|
||||||
|
|
||||||
kate2 := sql db {
|
kate2 := sql db {
|
||||||
select from User where id == 3
|
select from User where id == 3
|
||||||
}
|
}
|
||||||
|
@ -167,6 +189,7 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
update User set age = new_age, name = 'Kate N' where id == 3
|
update User set age = new_age, name = 'Kate N' where id == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
kate3 = sql db {
|
kate3 = sql db {
|
||||||
select from User where id == 3
|
select from User where id == 3
|
||||||
}
|
}
|
||||||
|
@ -177,6 +200,7 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
update User set age = foo.age, name = 'Kate N' where id == 3
|
update User set age = foo.age, name = 'Kate N' where id == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
kate3 = sql db {
|
kate3 = sql db {
|
||||||
select from User where id == 3
|
select from User where id == 3
|
||||||
}
|
}
|
||||||
|
@ -219,6 +243,7 @@ fn test_orm_sqlite() {
|
||||||
sql db {
|
sql db {
|
||||||
delete from User where age == 34
|
delete from User where age == 34
|
||||||
}
|
}
|
||||||
|
|
||||||
updated_oldest := sql db {
|
updated_oldest := sql db {
|
||||||
select from User order by age desc limit 1
|
select from User order by age desc limit 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1440,8 +1440,15 @@ pub enum SqlStmtKind {
|
||||||
|
|
||||||
pub struct SqlStmt {
|
pub struct SqlStmt {
|
||||||
pub:
|
pub:
|
||||||
kind SqlStmtKind
|
pos token.Position
|
||||||
db_expr Expr // `db` in `sql db {`
|
db_expr Expr // `db` in `sql db {`
|
||||||
|
pub mut:
|
||||||
|
lines []SqlStmtLine
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SqlStmtLine {
|
||||||
|
pub:
|
||||||
|
kind SqlStmtKind
|
||||||
object_var_name string // `user`
|
object_var_name string // `user`
|
||||||
pos token.Position
|
pos token.Position
|
||||||
where_expr Expr
|
where_expr Expr
|
||||||
|
@ -1450,7 +1457,7 @@ pub:
|
||||||
pub mut:
|
pub mut:
|
||||||
table_expr TypeNode
|
table_expr TypeNode
|
||||||
fields []StructField
|
fields []StructField
|
||||||
sub_structs map[int]SqlStmt
|
sub_structs map[int]SqlStmtLine
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SqlExpr {
|
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 {
|
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
|
c.inside_sql = true
|
||||||
defer {
|
defer {
|
||||||
c.inside_sql = false
|
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
|
info := table_sym.info as ast.Struct
|
||||||
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, table_sym.name)
|
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_) {
|
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
|
pos: node.pos
|
||||||
db_expr: node.db_expr
|
|
||||||
kind: node.kind
|
kind: node.kind
|
||||||
table_expr: ast.TypeNode{
|
table_expr: ast.TypeNode{
|
||||||
pos: node.table_expr.pos
|
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'
|
object_var_name: '${node.object_var_name}.$f.name'
|
||||||
}
|
}
|
||||||
tmp_inside_sql := c.inside_sql
|
tmp_inside_sql := c.inside_sql
|
||||||
c.sql_stmt(mut n)
|
c.sql_stmt_line(mut n)
|
||||||
c.inside_sql = tmp_inside_sql
|
c.inside_sql = tmp_inside_sql
|
||||||
sub_structs[int(f.typ)] = n
|
sub_structs[int(f.typ)] = n
|
||||||
}
|
}
|
||||||
node.fields = fields
|
node.fields = fields
|
||||||
node.sub_structs = sub_structs.move()
|
node.sub_structs = sub_structs.move()
|
||||||
c.expr(node.db_expr)
|
|
||||||
if node.kind == .update {
|
if node.kind == .update {
|
||||||
for expr in node.update_exprs {
|
for expr in node.update_exprs {
|
||||||
c.expr(expr)
|
c.expr(expr)
|
||||||
|
|
|
@ -1215,6 +1215,15 @@ pub fn (mut f Fmt) sql_stmt(node ast.SqlStmt) {
|
||||||
f.write('sql ')
|
f.write('sql ')
|
||||||
f.expr(node.db_expr)
|
f.expr(node.db_expr)
|
||||||
f.writeln(' {')
|
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)
|
table_name := util.strip_mod_name(f.table.get_type_symbol(node.table_expr.typ).name)
|
||||||
f.write('\t')
|
f.write('\t')
|
||||||
match node.kind {
|
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('drop table $table_name')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.writeln('}')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
|
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) {
|
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 {
|
if node.kind == .create {
|
||||||
g.sql_create_table(node)
|
g.sql_create_table(node, expr)
|
||||||
return
|
return
|
||||||
} else if node.kind == .drop {
|
} else if node.kind == .drop {
|
||||||
g.sql_drop_table(node)
|
g.sql_drop_table(node, expr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.sql_table_name = g.table.get_type_symbol(node.table_expr.typ).name
|
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 {
|
match typ {
|
||||||
.sqlite3 {
|
.sqlite3 {
|
||||||
g.sqlite3_stmt(node, typ)
|
g.sqlite3_stmt(node, typ, expr)
|
||||||
}
|
}
|
||||||
.mysql {
|
.mysql {
|
||||||
g.mysql_stmt(node, typ)
|
g.mysql_stmt(node, typ, expr)
|
||||||
}
|
}
|
||||||
.psql {
|
.psql {
|
||||||
g.psql_stmt(node, typ)
|
g.psql_stmt(node, typ, expr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
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) {
|
fn (mut g Gen) sql_create_table(node ast.SqlStmtLine, expr ast.Expr) {
|
||||||
typ := g.parse_db_type(node.db_expr)
|
typ := g.parse_db_type(expr)
|
||||||
match typ {
|
match typ {
|
||||||
.sqlite3 {
|
.sqlite3 {
|
||||||
g.sqlite3_create_table(node, typ)
|
g.sqlite3_create_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
.mysql {
|
.mysql {
|
||||||
g.mysql_create_table(node, typ)
|
g.mysql_create_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
.psql {
|
.psql {
|
||||||
g.psql_create_table(node, typ)
|
g.psql_create_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
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) {
|
fn (mut g Gen) sql_drop_table(node ast.SqlStmtLine, expr ast.Expr) {
|
||||||
typ := g.parse_db_type(node.db_expr)
|
typ := g.parse_db_type(expr)
|
||||||
match typ {
|
match typ {
|
||||||
.sqlite3 {
|
.sqlite3 {
|
||||||
g.sqlite3_drop_table(node, typ)
|
g.sqlite3_drop_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
.mysql {
|
.mysql {
|
||||||
g.mysql_drop_table(node, typ)
|
g.mysql_drop_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
.psql {
|
.psql {
|
||||||
g.psql_create_table(node, typ)
|
g.psql_create_table(node, typ, expr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verror('This database type `$typ` is not implemented yet in orm') // TODO add better error
|
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
|
// 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.sql_i = 0
|
||||||
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()
|
||||||
g.write('${c.dbtype}__DB $db_name = ')
|
g.write('${c.dbtype}__DB $db_name = ')
|
||||||
g.expr(node.db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
g.write('sqlite3_stmt* $g.sql_stmt_name = ${c.dbtype}__DB_init_stmt($db_name, _SLIT("')
|
g.write('sqlite3_stmt* $g.sql_stmt_name = ${c.dbtype}__DB_init_stmt($db_name, _SLIT("')
|
||||||
g.sql_defaults(node, typ)
|
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)]
|
expr := node.sub_structs[int(field.typ)]
|
||||||
tmp_sql_stmt_name := g.sql_stmt_name
|
tmp_sql_stmt_name := g.sql_stmt_name
|
||||||
tmp_sql_table_name := g.sql_table_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_stmt_name = tmp_sql_stmt_name
|
||||||
g.sql_table_name = tmp_sql_table_name
|
g.sql_table_name = tmp_sql_table_name
|
||||||
// get last inserted id
|
// 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')
|
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.write('sqlite__DB_exec(')
|
||||||
g.expr(node.db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(', _SLIT("$create_string"));')
|
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)
|
table_name := g.get_table_name(node.table_expr)
|
||||||
g.writeln('// sqlite3 table drop')
|
g.writeln('// sqlite3 table drop')
|
||||||
drop_string := 'DROP TABLE `$table_name`;'
|
drop_string := 'DROP TABLE `$table_name`;'
|
||||||
g.write('sqlite__DB_exec(')
|
g.write('sqlite__DB_exec(')
|
||||||
g.expr(node.db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(', _SLIT("$drop_string"));')
|
g.writeln(', _SLIT("$drop_string"));')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,13 +383,13 @@ fn (mut g Gen) sqlite3_type_from_v(v_typ ast.Type) string {
|
||||||
|
|
||||||
// mysql
|
// 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.sql_i = 0
|
||||||
g.writeln('\n\t//mysql insert')
|
g.writeln('\n\t//mysql 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()
|
||||||
g.write('mysql__Connection $db_name = ')
|
g.write('mysql__Connection $db_name = ')
|
||||||
g.expr(node.db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
stmt_name := g.new_tmp_var()
|
stmt_name := g.new_tmp_var()
|
||||||
g.write('string $stmt_name = _SLIT("')
|
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)]
|
expr := node.sub_structs[int(field.typ)]
|
||||||
tmp_sql_stmt_name := g.sql_stmt_name
|
tmp_sql_stmt_name := g.sql_stmt_name
|
||||||
tmp_sql_table_name := g.sql_table_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_stmt_name = tmp_sql_stmt_name
|
||||||
g.sql_table_name = tmp_sql_table_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')
|
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()
|
tmp := g.new_tmp_var()
|
||||||
g.write('Option_mysql__Result $tmp = mysql__Connection_query(&')
|
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(', _SLIT("$create_string"));')
|
||||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
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)
|
table_name := g.get_table_name(node.table_expr)
|
||||||
g.writeln('// mysql table drop')
|
g.writeln('// mysql table drop')
|
||||||
drop_string := 'DROP TABLE `$table_name`;'
|
drop_string := 'DROP TABLE `$table_name`;'
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
g.write('Option_mysql__Result $tmp = mysql__Connection_query(&')
|
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(', _SLIT("$drop_string"));')
|
||||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
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
|
// 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_i = 0
|
||||||
g.sql_idents = []string{}
|
g.sql_idents = []string{}
|
||||||
param_values := g.new_tmp_var()
|
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()
|
db_name := g.new_tmp_var()
|
||||||
g.sql_stmt_name = g.new_tmp_var()
|
g.sql_stmt_name = g.new_tmp_var()
|
||||||
g.write('pg__DB $db_name = ')
|
g.write('pg__DB $db_name = ')
|
||||||
g.expr(node.db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
stmt_name := g.new_tmp_var()
|
stmt_name := g.new_tmp_var()
|
||||||
g.write('string $stmt_name = _SLIT("')
|
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)]
|
expr := node.sub_structs[int(field.typ)]
|
||||||
tmp_sql_stmt_name := g.sql_stmt_name
|
tmp_sql_stmt_name := g.sql_stmt_name
|
||||||
tmp_sql_table_name := g.sql_table_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_stmt_name = tmp_sql_stmt_name
|
||||||
g.sql_table_name = tmp_sql_table_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))); }')
|
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')
|
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()
|
tmp := g.new_tmp_var()
|
||||||
g.write('Option_Array_pg__Row $tmp = pg__DB_exec(')
|
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(', _SLIT("$create_string"));')
|
||||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
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)
|
table_name := g.get_table_name(node.table_expr)
|
||||||
g.writeln('// psql table drop')
|
g.writeln('// psql table drop')
|
||||||
drop_string := 'DROP TABLE "$table_name";'
|
drop_string := 'DROP TABLE "$table_name";'
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
g.write('Option_Array_pg__Row $tmp = pg__DB_exec(&')
|
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(', _SLIT("$drop_string"));')
|
||||||
g.writeln('if (${tmp}.state != 0) { IError err = ${tmp}.err; eprintln(_STR("Something went wrong\\000%.*s", 2, IError_str(err))); }')
|
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
|
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)
|
table_name := g.get_table_name(node.table_expr)
|
||||||
mut lit := '`'
|
mut lit := '`'
|
||||||
if typ == .psql {
|
if typ == .psql {
|
||||||
|
@ -981,7 +987,7 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmt, typ SqlType, psql_data ...string)
|
||||||
g.write(';")')
|
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)
|
typ_sym := g.table.get_type_symbol(node.table_expr.typ)
|
||||||
struct_data := typ_sym.struct_info()
|
struct_data := typ_sym.struct_info()
|
||||||
table_name := g.get_table_name(node.table_expr)
|
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 converted_typ == '' {
|
||||||
if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
||||||
converted_typ = g.sql_type_from_v(typ, ast.int_type)
|
converted_typ = g.sql_type_from_v(typ, ast.int_type)
|
||||||
g.sql_create_table(ast.SqlStmt{
|
g.sql_create_table(ast.SqlStmtLine{
|
||||||
db_expr: node.db_expr
|
|
||||||
kind: node.kind
|
kind: node.kind
|
||||||
pos: node.pos
|
pos: node.pos
|
||||||
table_expr: ast.TypeNode{
|
table_expr: ast.TypeNode{
|
||||||
typ: field.typ
|
typ: field.typ
|
||||||
pos: node.table_expr.pos
|
pos: node.table_expr.pos
|
||||||
}
|
}
|
||||||
})
|
}, expr)
|
||||||
} else {
|
} else {
|
||||||
verror('unknown type ($field.typ) for field $field.name in struct $table_name')
|
verror('unknown type ($field.typ) for field $field.name in struct $table_name')
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -97,8 +97,10 @@ pub fn (mut w Walker) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.SqlStmt {
|
ast.SqlStmt {
|
||||||
w.expr(node.db_expr)
|
w.expr(node.db_expr)
|
||||||
w.expr(node.where_expr)
|
for line in node.lines {
|
||||||
w.exprs(node.update_exprs)
|
w.expr(line.where_expr)
|
||||||
|
w.exprs(line.update_exprs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
w.struct_fields(node.fields)
|
w.struct_fields(node.fields)
|
||||||
|
|
|
@ -125,9 +125,25 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
}
|
}
|
||||||
// println(typeof(db_expr))
|
// println(typeof(db_expr))
|
||||||
p.check(.lcbr)
|
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
|
mut n := p.check_name() // insert
|
||||||
|
pos := p.tok.position()
|
||||||
mut kind := ast.SqlStmtKind.insert
|
mut kind := ast.SqlStmtKind.insert
|
||||||
if n == 'delete' {
|
if n == 'delete' {
|
||||||
kind = .delete
|
kind = .delete
|
||||||
|
@ -138,13 +154,11 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
table := p.check_name()
|
table := p.check_name()
|
||||||
if table != 'table' {
|
if table != 'table' {
|
||||||
p.error('expected `table` got `$table`')
|
p.error('expected `table` got `$table`')
|
||||||
return ast.SqlStmt{}
|
return ast.SqlStmtLine{}
|
||||||
}
|
}
|
||||||
typ := p.parse_type()
|
typ := p.parse_type()
|
||||||
typ_pos := p.tok.position()
|
typ_pos := p.tok.position()
|
||||||
p.check(.rcbr)
|
return ast.SqlStmtLine{
|
||||||
return ast.SqlStmt{
|
|
||||||
db_expr: db_expr
|
|
||||||
kind: kind
|
kind: kind
|
||||||
pos: pos.extend(p.prev_tok.position())
|
pos: pos.extend(p.prev_tok.position())
|
||||||
table_expr: ast.TypeNode{
|
table_expr: ast.TypeNode{
|
||||||
|
@ -157,13 +171,11 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
table := p.check_name()
|
table := p.check_name()
|
||||||
if table != 'table' {
|
if table != 'table' {
|
||||||
p.error('expected `table` got `$table`')
|
p.error('expected `table` got `$table`')
|
||||||
return ast.SqlStmt{}
|
return ast.SqlStmtLine{}
|
||||||
}
|
}
|
||||||
typ := p.parse_type()
|
typ := p.parse_type()
|
||||||
typ_pos := p.tok.position()
|
typ_pos := p.tok.position()
|
||||||
p.check(.rcbr)
|
return ast.SqlStmtLine{
|
||||||
return ast.SqlStmt{
|
|
||||||
db_expr: db_expr
|
|
||||||
kind: kind
|
kind: kind
|
||||||
pos: pos.extend(p.prev_tok.position())
|
pos: pos.extend(p.prev_tok.position())
|
||||||
table_expr: ast.TypeNode{
|
table_expr: ast.TypeNode{
|
||||||
|
@ -183,7 +195,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
inserted_var_name = expr.name
|
inserted_var_name = expr.name
|
||||||
} else {
|
} else {
|
||||||
p.error('can only insert variables')
|
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}
|
mut update_exprs := []ast.Expr{cap: 5}
|
||||||
if kind == .insert && n != 'into' {
|
if kind == .insert && n != 'into' {
|
||||||
p.error('expecting `into`')
|
p.error('expecting `into`')
|
||||||
return ast.SqlStmt{}
|
return ast.SqlStmtLine{}
|
||||||
} else if kind == .update {
|
} else if kind == .update {
|
||||||
if n != 'set' {
|
if n != 'set' {
|
||||||
p.error('expecting `set`')
|
p.error('expecting `set`')
|
||||||
return ast.SqlStmt{}
|
return ast.SqlStmtLine{}
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
column := p.check_name()
|
column := p.check_name()
|
||||||
|
@ -211,7 +223,7 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
}
|
}
|
||||||
} else if kind == .delete && n != 'from' {
|
} else if kind == .delete && n != 'from' {
|
||||||
p.error('expecting `from`')
|
p.error('expecting `from`')
|
||||||
return ast.SqlStmt{}
|
return ast.SqlStmtLine{}
|
||||||
}
|
}
|
||||||
|
|
||||||
mut table_pos := p.tok.position()
|
mut table_pos := p.tok.position()
|
||||||
|
@ -220,24 +232,21 @@ fn (mut p Parser) sql_stmt() ast.SqlStmt {
|
||||||
table_pos = p.tok.position()
|
table_pos = p.tok.position()
|
||||||
table_type = p.parse_type()
|
table_type = p.parse_type()
|
||||||
} else if kind == .update {
|
} 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)
|
where_expr = p.expr(0)
|
||||||
} else if kind == .delete {
|
} else if kind == .delete {
|
||||||
table_pos = p.tok.position()
|
table_pos = p.tok.position()
|
||||||
table_type = p.parse_type()
|
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)
|
where_expr = p.expr(0)
|
||||||
}
|
}
|
||||||
p.check(.rcbr)
|
return ast.SqlStmtLine{
|
||||||
pos.last_line = p.prev_tok.line_nr
|
|
||||||
return ast.SqlStmt{
|
|
||||||
db_expr: db_expr
|
|
||||||
table_expr: ast.TypeNode{
|
table_expr: ast.TypeNode{
|
||||||
typ: table_type
|
typ: table_type
|
||||||
pos: table_pos
|
pos: table_pos
|
||||||
}
|
}
|
||||||
object_var_name: inserted_var_name
|
object_var_name: inserted_var_name
|
||||||
pos: pos.extend(p.prev_tok.position())
|
pos: pos
|
||||||
updated_columns: updated_columns
|
updated_columns: updated_columns
|
||||||
update_exprs: update_exprs
|
update_exprs: update_exprs
|
||||||
kind: kind
|
kind: kind
|
||||||
|
|
Loading…
Reference in New Issue