orm: fix pg orm statements (#9909)
parent
daff481233
commit
c8e07b28e2
|
@ -107,7 +107,7 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr, sub bool, line string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) sql_bind(val string, len string, real_type ast.Type, typ SqlType, data []string) {
|
fn (mut g Gen) sql_bind(val string, len string, real_type ast.Type, typ SqlType) {
|
||||||
match typ {
|
match typ {
|
||||||
.sqlite3 {
|
.sqlite3 {
|
||||||
g.sqlite3_bind(val, len, real_type)
|
g.sqlite3_bind(val, len, real_type)
|
||||||
|
@ -116,7 +116,7 @@ fn (mut g Gen) sql_bind(val string, len string, real_type ast.Type, typ SqlType,
|
||||||
g.mysql_bind(val, real_type)
|
g.mysql_bind(val, real_type)
|
||||||
}
|
}
|
||||||
.psql {
|
.psql {
|
||||||
g.psql_bind(val, data, real_type)
|
g.psql_bind(val, real_type)
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
@ -744,29 +744,22 @@ fn (mut g Gen) mysql_buffer_typ_from_field(field ast.StructField) (string, strin
|
||||||
fn (mut g Gen) psql_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
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_lens := g.new_tmp_var()
|
|
||||||
param_formats := g.new_tmp_var()
|
|
||||||
g.writeln('\n\t//psql insert')
|
g.writeln('\n\t//psql 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('pg__DB $db_name = ')
|
g.write('pg__DB $db_name = ')
|
||||||
g.expr(db_expr)
|
g.expr(db_expr)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
stmt_name := g.new_tmp_var()
|
g.write('string $g.sql_stmt_name = _SLIT("')
|
||||||
g.write('string $stmt_name = _SLIT("')
|
g.sql_defaults(node, typ)
|
||||||
g.sql_defaults(node, typ, param_values, param_lens, param_formats)
|
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
|
|
||||||
g.writeln('char *$param_values[$g.sql_i]; //param values')
|
|
||||||
g.writeln('int $param_lens[$g.sql_i]; //param lens')
|
|
||||||
g.writeln('int $param_formats[$g.sql_i]; // param formats')
|
|
||||||
|
|
||||||
if node.kind == .insert {
|
if node.kind == .insert {
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
if g.get_sql_field_type(field) == ast.Type(-1) {
|
if g.get_sql_field_type(field) == ast.Type(-1) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
g.sql_i = i
|
||||||
g.writeln('//$field.name ($field.typ)')
|
g.writeln('//$field.name ($field.typ)')
|
||||||
x := '${node.object_var_name}.$field.name'
|
x := '${node.object_var_name}.$field.name'
|
||||||
field_type := g.get_sql_field_type(field)
|
field_type := g.get_sql_field_type(field)
|
||||||
|
@ -780,21 +773,15 @@ fn (mut g Gen) psql_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||||
g.sql_table_name = tmp_sql_table_name
|
g.sql_table_name = tmp_sql_table_name
|
||||||
|
|
||||||
res := g.new_tmp_var()
|
res := g.new_tmp_var()
|
||||||
g.write('Option_int $res = pg__DB_q_int($db_name, _SLIT("SELECT LASTVAL();"));')
|
g.writeln('Option_pg__Row $res = pg__DB_exec_one($db_name, _SLIT("SELECT LASTVAL();"));')
|
||||||
g.writeln('if (${res}.state != 0) { IError err = ${res}.err; eprintln(_STR("\\000%.*s", 2, IError_str(err))); }')
|
g.writeln('if (${res}.state != 0) { IError err = ${res}.err; eprintln(_STR("\\000%.*s", 2, IError_str(err))); }')
|
||||||
g.sql_buf = strings.new_builder(100)
|
g.sql_buf = strings.new_builder(100)
|
||||||
g.sql_bind('${res}.data', '', ast.int_type, typ, [
|
g.sql_bind('string_int((*(string*)array_get((*(pg__Row*)${res}.data).vals, 0)))',
|
||||||
(i - 1).str(),
|
'', ast.int_type, typ)
|
||||||
param_values,
|
|
||||||
param_lens,
|
|
||||||
param_formats,
|
|
||||||
])
|
|
||||||
g.writeln(g.sql_buf.str())
|
g.writeln(g.sql_buf.str())
|
||||||
} else {
|
} else {
|
||||||
g.sql_buf = strings.new_builder(100)
|
g.sql_buf = strings.new_builder(100)
|
||||||
g.sql_bind(x, '', field_type, typ, [(i - 1).str(), param_values, param_lens,
|
g.sql_bind(x, '', field_type, typ)
|
||||||
param_formats,
|
|
||||||
])
|
|
||||||
g.writeln(g.sql_buf.str())
|
g.writeln(g.sql_buf.str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -803,10 +790,7 @@ fn (mut g Gen) psql_stmt(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||||
g.sql_buf = strings.new_builder(100)
|
g.sql_buf = strings.new_builder(100)
|
||||||
g.writeln(binds)
|
g.writeln(binds)
|
||||||
|
|
||||||
res := g.new_tmp_var()
|
g.writeln('pg__DB_exec($db_name, $g.sql_stmt_name);')
|
||||||
g.writeln('PGresult * $res = PQexecParams(${db_name}.conn, ${stmt_name}.str, $g.sql_i, 0, $param_values, $param_lens, $param_formats, 0);')
|
|
||||||
g.writeln('Option_Array_pg__Row ${res}_rows = pg__DB_handle_error_or_result($db_name, $res, _SLIT("$stmt_name"));')
|
|
||||||
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.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
fn (mut g Gen) psql_create_table(node ast.SqlStmtLine, typ SqlType, db_expr ast.Expr) {
|
||||||
|
@ -862,39 +846,40 @@ fn (mut g Gen) psql_get_table_type(typ ast.Type) string {
|
||||||
return table_typ
|
return table_typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) psql_bind(val string, data []string, typ ast.Type) {
|
fn (mut g Gen) psql_bind(val string, typ ast.Type) {
|
||||||
tmp := g.new_tmp_var()
|
mut sym := g.table.get_type_symbol(typ).cname
|
||||||
g.sql_idents << tmp
|
g.sql_buf.write_string('$g.sql_stmt_name = string_replace($g.sql_stmt_name, _SLIT("\$$g.sql_i"), ')
|
||||||
g.sql_buf.write_string('char* $tmp = ')
|
if sym != 'string' {
|
||||||
if typ.is_number() {
|
mut num := false
|
||||||
g.sql_buf.writeln('(char *) htonl($val);')
|
if sym != 'bool' {
|
||||||
g.sql_buf.writeln('\t${data[1]}[${data[0]}] = &$tmp;')
|
num = true
|
||||||
g.sql_buf.writeln('\t${data[2]}[${data[0]}] = sizeof($tmp);')
|
g.sql_buf.write_string('${sym}_str(')
|
||||||
g.sql_buf.writeln('\t${data[3]}[${data[0]}] = 1;')
|
}
|
||||||
} else if typ.is_string() {
|
g.sql_buf.write_string('(($sym) $val)')
|
||||||
g.sql_buf.writeln('(char *) ${val}.str;')
|
|
||||||
g.sql_buf.writeln('\t${data[1]}[${data[0]}] = &$tmp;')
|
if sym == 'bool' {
|
||||||
g.sql_buf.writeln('\t${data[2]}[${data[0]}] = 0;')
|
g.sql_buf.write_string('? _SLIT("1") : _SLIT("0")')
|
||||||
g.sql_buf.writeln('\t${data[3]}[${data[0]}] = 0;')
|
}
|
||||||
|
|
||||||
|
if num {
|
||||||
|
g.sql_buf.write_string(')')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
g.sql_buf.writeln('(char *) htonl(0);')
|
g.sql_buf.write_string('string_add(_SLIT("\'"), string_add(((string) $val), _SLIT("\'")))')
|
||||||
g.sql_buf.writeln('if ($val) { $tmp = (char *) htonl(1); }')
|
|
||||||
g.sql_buf.writeln('\t${data[1]}[${data[0]}] = &$tmp;')
|
|
||||||
g.sql_buf.writeln('\t${data[2]}[${data[0]}] = sizeof($tmp);')
|
|
||||||
g.sql_buf.writeln('\t${data[3]}[${data[0]}] = 1;')
|
|
||||||
}
|
}
|
||||||
|
g.sql_buf.writeln(');')
|
||||||
}
|
}
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
|
|
||||||
fn (mut g Gen) sql_expr_defaults(node ast.SqlExpr, sql_typ SqlType) {
|
fn (mut g Gen) sql_expr_defaults(node ast.SqlExpr, sql_typ SqlType) {
|
||||||
if node.has_where && node.where_expr is ast.InfixExpr {
|
if node.has_where && node.where_expr is ast.InfixExpr {
|
||||||
g.expr_to_sql(node.where_expr, sql_typ, [])
|
g.expr_to_sql(node.where_expr, sql_typ)
|
||||||
}
|
}
|
||||||
if node.has_order {
|
if node.has_order {
|
||||||
g.write(' ORDER BY ')
|
g.write(' ORDER BY ')
|
||||||
g.sql_side = .left
|
g.sql_side = .left
|
||||||
g.expr_to_sql(node.order_expr, sql_typ, [])
|
g.expr_to_sql(node.order_expr, sql_typ)
|
||||||
if node.has_desc {
|
if node.has_desc {
|
||||||
g.write(' DESC ')
|
g.write(' DESC ')
|
||||||
}
|
}
|
||||||
|
@ -904,12 +889,12 @@ fn (mut g Gen) sql_expr_defaults(node ast.SqlExpr, sql_typ SqlType) {
|
||||||
if node.has_limit {
|
if node.has_limit {
|
||||||
g.write(' LIMIT ')
|
g.write(' LIMIT ')
|
||||||
g.sql_side = .right
|
g.sql_side = .right
|
||||||
g.expr_to_sql(node.limit_expr, sql_typ, [])
|
g.expr_to_sql(node.limit_expr, sql_typ)
|
||||||
}
|
}
|
||||||
if node.has_offset {
|
if node.has_offset {
|
||||||
g.write(' OFFSET ')
|
g.write(' OFFSET ')
|
||||||
g.sql_side = .right
|
g.sql_side = .right
|
||||||
g.expr_to_sql(node.offset_expr, sql_typ, [])
|
g.expr_to_sql(node.offset_expr, sql_typ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,7 +920,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.SqlStmtLine, typ SqlType, psql_data ...string) {
|
fn (mut g Gen) sql_defaults(node ast.SqlStmtLine, typ SqlType) {
|
||||||
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 {
|
||||||
|
@ -958,7 +943,7 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmtLine, typ SqlType, psql_data ...stri
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.write(') values (')
|
g.write(') VALUES (')
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
if g.get_sql_field_type(field) == ast.Type(-1) {
|
if g.get_sql_field_type(field) == ast.Type(-1) {
|
||||||
continue
|
continue
|
||||||
|
@ -972,7 +957,7 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmtLine, typ SqlType, psql_data ...stri
|
||||||
} else if node.kind == .update {
|
} else if node.kind == .update {
|
||||||
for i, col in node.updated_columns {
|
for i, col in node.updated_columns {
|
||||||
g.write(' ${g.get_field_name(g.get_struct_field(col))} = ')
|
g.write(' ${g.get_field_name(g.get_struct_field(col))} = ')
|
||||||
g.expr_to_sql(node.update_exprs[i], typ, psql_data)
|
g.expr_to_sql(node.update_exprs[i], typ)
|
||||||
if i < node.updated_columns.len - 1 {
|
if i < node.updated_columns.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
|
@ -982,7 +967,7 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmtLine, typ SqlType, psql_data ...stri
|
||||||
g.write(' WHERE ')
|
g.write(' WHERE ')
|
||||||
}
|
}
|
||||||
if node.kind == .update || node.kind == .delete {
|
if node.kind == .update || node.kind == .delete {
|
||||||
g.expr_to_sql(node.where_expr, typ, psql_data)
|
g.expr_to_sql(node.where_expr, typ)
|
||||||
}
|
}
|
||||||
g.write(';")')
|
g.write(';")')
|
||||||
}
|
}
|
||||||
|
@ -1077,7 +1062,7 @@ fn (mut g Gen) table_gen(node ast.SqlStmtLine, typ SqlType, expr ast.Expr) strin
|
||||||
fields << '/* $k */UNIQUE(${tmp.join(', ')})'
|
fields << '/* $k */UNIQUE(${tmp.join(', ')})'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ == .mysql {
|
if typ == .mysql || typ == .psql {
|
||||||
fields << 'PRIMARY KEY($lit$primary$lit)'
|
fields << 'PRIMARY KEY($lit$primary$lit)'
|
||||||
}
|
}
|
||||||
create_string += fields.join(', ')
|
create_string += fields.join(', ')
|
||||||
|
@ -1085,7 +1070,7 @@ fn (mut g Gen) table_gen(node ast.SqlStmtLine, typ SqlType, expr ast.Expr) strin
|
||||||
return create_string
|
return create_string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
||||||
// Custom handling for infix exprs (since we need e.g. `and` instead of `&&` in SQL queries),
|
// Custom handling for infix exprs (since we need e.g. `and` instead of `&&` in SQL queries),
|
||||||
// strings. Everything else (like numbers, a.b) is handled by g.expr()
|
// strings. Everything else (like numbers, a.b) is handled by g.expr()
|
||||||
//
|
//
|
||||||
|
@ -1094,7 +1079,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
||||||
match expr {
|
match expr {
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
g.sql_side = .left
|
g.sql_side = .left
|
||||||
g.expr_to_sql(expr.left, typ, psql_data)
|
g.expr_to_sql(expr.left, typ)
|
||||||
match expr.op {
|
match expr.op {
|
||||||
.ne { g.write(' != ') }
|
.ne { g.write(' != ') }
|
||||||
.eq { g.write(' = ') }
|
.eq { g.write(' = ') }
|
||||||
|
@ -1111,26 +1096,24 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
g.sql_side = .right
|
g.sql_side = .right
|
||||||
g.expr_to_sql(expr.right, typ, psql_data)
|
g.expr_to_sql(expr.right, typ)
|
||||||
}
|
}
|
||||||
ast.StringLiteral {
|
ast.StringLiteral {
|
||||||
// g.write("'$it.val'")
|
// g.write("'$it.val'")
|
||||||
g.inc_sql_i(typ)
|
g.inc_sql_i(typ)
|
||||||
g.sql_bind('"$expr.val"', expr.val.len.str(), g.sql_get_real_type(ast.string_type),
|
g.sql_bind('"$expr.val"', expr.val.len.str(), g.sql_get_real_type(ast.string_type),
|
||||||
typ, g.append_arr(g.sql_i, psql_data))
|
typ)
|
||||||
}
|
}
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
g.inc_sql_i(typ)
|
g.inc_sql_i(typ)
|
||||||
g.sql_bind(expr.val, '', g.sql_get_real_type(ast.int_type), typ, g.append_arr(g.sql_i,
|
g.sql_bind(expr.val, '', g.sql_get_real_type(ast.int_type), typ)
|
||||||
psql_data))
|
|
||||||
}
|
}
|
||||||
ast.BoolLiteral {
|
ast.BoolLiteral {
|
||||||
// true/false literals were added to Sqlite 3.23 (2018-04-02)
|
// true/false literals were added to Sqlite 3.23 (2018-04-02)
|
||||||
// but lots of apps/distros use older sqlite (e.g. Ubuntu 18.04 LTS )
|
// but lots of apps/distros use older sqlite (e.g. Ubuntu 18.04 LTS )
|
||||||
g.inc_sql_i(typ)
|
g.inc_sql_i(typ)
|
||||||
eval := if expr.val { '1' } else { '0' }
|
eval := if expr.val { '1' } else { '0' }
|
||||||
g.sql_bind(eval, '', g.sql_get_real_type(ast.byte_type), typ, g.append_arr(g.sql_i,
|
g.sql_bind(eval, '', g.sql_get_real_type(ast.byte_type), typ)
|
||||||
psql_data))
|
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
// `name == user_name` => `name == ?1`
|
// `name == user_name` => `name == ?1`
|
||||||
|
@ -1146,14 +1129,12 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
||||||
if typ == .sqlite3 {
|
if typ == .sqlite3 {
|
||||||
if ityp == ast.string_type {
|
if ityp == ast.string_type {
|
||||||
g.sql_bind('${expr.name}.str', '${expr.name}.len', g.sql_get_real_type(ityp),
|
g.sql_bind('${expr.name}.str', '${expr.name}.len', g.sql_get_real_type(ityp),
|
||||||
typ, g.append_arr(g.sql_i, psql_data))
|
typ)
|
||||||
} else {
|
} else {
|
||||||
g.sql_bind(expr.name, '', g.sql_get_real_type(ityp), typ, g.append_arr(g.sql_i,
|
g.sql_bind(expr.name, '', g.sql_get_real_type(ityp), typ)
|
||||||
psql_data))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.sql_bind('%$g.sql_i.str()', '', g.sql_get_real_type(ityp), typ,
|
g.sql_bind('%$g.sql_i.str()', '', g.sql_get_real_type(ityp), typ)
|
||||||
g.append_arr(g.sql_i, psql_data))
|
|
||||||
g.sql_idents << expr.name
|
g.sql_idents << expr.name
|
||||||
g.sql_idents_types << g.sql_get_real_type(ityp)
|
g.sql_idents_types << g.sql_get_real_type(ityp)
|
||||||
}
|
}
|
||||||
|
@ -1166,7 +1147,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
||||||
}
|
}
|
||||||
ident := expr.expr as ast.Ident
|
ident := expr.expr as ast.Ident
|
||||||
g.sql_bind(ident.name + '.' + expr.field_name, '', g.sql_get_real_type(expr.typ),
|
g.sql_bind(ident.name + '.' + expr.field_name, '', g.sql_get_real_type(expr.typ),
|
||||||
typ, g.append_arr(g.sql_i, psql_data))
|
typ)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
|
@ -1180,13 +1161,6 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) append_arr(i int, arr []string) []string {
|
|
||||||
mut tmp := []string{}
|
|
||||||
tmp << i.str()
|
|
||||||
tmp << arr
|
|
||||||
return tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g Gen) get_struct_field_typ(f string) ast.Type {
|
fn (mut g Gen) get_struct_field_typ(f string) ast.Type {
|
||||||
sym := g.table.get_type_symbol(g.table.type_idxs[g.sql_table_name])
|
sym := g.table.get_type_symbol(g.table.type_idxs[g.sql_table_name])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue