|
|
@ -40,6 +40,9 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) {
|
|
|
|
.mysql {
|
|
|
|
.mysql {
|
|
|
|
g.mysql_stmt(node, typ)
|
|
|
|
g.mysql_stmt(node, typ)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.psql {
|
|
|
|
|
|
|
|
g.psql_stmt(node, typ)
|
|
|
|
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -55,6 +58,9 @@ fn (mut g Gen) sql_create_table(node ast.SqlStmt) {
|
|
|
|
.mysql {
|
|
|
|
.mysql {
|
|
|
|
g.mysql_create_table(node, typ)
|
|
|
|
g.mysql_create_table(node, typ)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.psql {
|
|
|
|
|
|
|
|
g.psql_create_table(node, typ)
|
|
|
|
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -70,6 +76,9 @@ fn (mut g Gen) sql_drop_table(node ast.SqlStmt) {
|
|
|
|
.mysql {
|
|
|
|
.mysql {
|
|
|
|
g.mysql_drop_table(node, typ)
|
|
|
|
g.mysql_drop_table(node, typ)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.psql {
|
|
|
|
|
|
|
|
g.psql_create_table(node, typ)
|
|
|
|
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -92,7 +101,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) {
|
|
|
|
fn (mut g Gen) sql_bind(val string, len string, real_type ast.Type, typ SqlType, data []string) {
|
|
|
|
match typ {
|
|
|
|
match typ {
|
|
|
|
.sqlite3 {
|
|
|
|
.sqlite3 {
|
|
|
|
g.sqlite3_bind(val, len, real_type)
|
|
|
|
g.sqlite3_bind(val, len, real_type)
|
|
|
@ -100,6 +109,9 @@ fn (mut g Gen) sql_bind(val string, len string, real_type ast.Type, typ SqlType)
|
|
|
|
.mysql {
|
|
|
|
.mysql {
|
|
|
|
g.mysql_bind(val, real_type)
|
|
|
|
g.mysql_bind(val, real_type)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.psql {
|
|
|
|
|
|
|
|
g.psql_bind(val, data, real_type)
|
|
|
|
|
|
|
|
}
|
|
|
|
else {}
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -112,6 +124,9 @@ fn (mut g Gen) sql_type_from_v(typ SqlType, v_typ ast.Type) string {
|
|
|
|
.mysql {
|
|
|
|
.mysql {
|
|
|
|
return g.mysql_get_table_type(v_typ)
|
|
|
|
return g.mysql_get_table_type(v_typ)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.psql {
|
|
|
|
|
|
|
|
return g.psql_get_table_type(v_typ)
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
// add error
|
|
|
|
// add error
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -141,7 +156,7 @@ fn (mut g Gen) sqlite3_stmt(node ast.SqlStmt, typ SqlType) {
|
|
|
|
x := '${node.object_var_name}.$field.name'
|
|
|
|
x := '${node.object_var_name}.$field.name'
|
|
|
|
if field.typ == ast.string_type {
|
|
|
|
if field.typ == ast.string_type {
|
|
|
|
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, (char*)${x}.str, ${x}.len, 0);')
|
|
|
|
g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, (char*)${x}.str, ${x}.len, 0);')
|
|
|
|
} else if g.table.type_symbols[int(field.typ)].kind == .struct_ {
|
|
|
|
} else if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
|
|
|
// insert again
|
|
|
|
// insert again
|
|
|
|
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
|
|
|
@ -271,7 +286,7 @@ fn (mut g Gen) sqlite3_select_expr(node ast.SqlExpr, sub bool, line string, sql_
|
|
|
|
g.writeln('if ($string_data != NULL) {')
|
|
|
|
g.writeln('if ($string_data != NULL) {')
|
|
|
|
g.writeln('\t${tmp}.$field.name = tos_clone($string_data);')
|
|
|
|
g.writeln('\t${tmp}.$field.name = tos_clone($string_data);')
|
|
|
|
g.writeln('}')
|
|
|
|
g.writeln('}')
|
|
|
|
} else if g.table.type_symbols[int(field.typ)].kind == .struct_ {
|
|
|
|
} else if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
|
|
|
id_name := g.new_tmp_var()
|
|
|
|
id_name := g.new_tmp_var()
|
|
|
|
g.writeln('//parse struct start')
|
|
|
|
g.writeln('//parse struct start')
|
|
|
|
g.writeln('int $id_name = ${func}($g.sql_stmt_name, $i);')
|
|
|
|
g.writeln('int $id_name = ${func}($g.sql_stmt_name, $i);')
|
|
|
@ -322,10 +337,10 @@ fn (mut g Gen) sqlite3_create_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
fn (mut g Gen) sqlite3_drop_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
fn (mut g Gen) sqlite3_drop_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
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')
|
|
|
|
create_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(node.db_expr)
|
|
|
|
g.writeln(', _SLIT("$create_string"));')
|
|
|
|
g.writeln(', _SLIT("$drop_string"));')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) sqlite3_bind(val string, len string, typ ast.Type) {
|
|
|
|
fn (mut g Gen) sqlite3_bind(val string, len string, typ ast.Type) {
|
|
|
@ -387,7 +402,7 @@ fn (mut g Gen) mysql_stmt(node ast.SqlStmt, typ SqlType) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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'
|
|
|
|
if g.table.type_symbols[int(field.typ)].kind == .struct_ {
|
|
|
|
if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
|
|
|
// insert again
|
|
|
|
// insert again
|
|
|
|
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
|
|
|
@ -616,11 +631,11 @@ fn (mut g Gen) mysql_create_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
fn (mut g Gen) mysql_drop_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
fn (mut g Gen) mysql_drop_table(node ast.SqlStmt, typ SqlType) {
|
|
|
|
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')
|
|
|
|
create_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(node.db_expr)
|
|
|
|
g.writeln(', _SLIT("$create_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))); }')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -659,10 +674,10 @@ fn (mut g Gen) mysql_get_table_type(typ ast.Type) string {
|
|
|
|
table_typ = 'BIGINT'
|
|
|
|
table_typ = 'BIGINT'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast.f32_type {
|
|
|
|
ast.f32_type {
|
|
|
|
table_typ = 'BIGINT'
|
|
|
|
table_typ = 'FLOAT'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast.f64_type {
|
|
|
|
ast.f64_type {
|
|
|
|
table_typ = 'BIGINT'
|
|
|
|
table_typ = 'DOUBLE'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast.string_type {
|
|
|
|
ast.string_type {
|
|
|
|
table_typ = 'TEXT'
|
|
|
|
table_typ = 'TEXT'
|
|
|
@ -718,16 +733,162 @@ fn (mut g Gen) mysql_buffer_typ_from_field(field ast.StructField) (string, strin
|
|
|
|
return buf_typ, sym
|
|
|
|
return buf_typ, sym
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// psql
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) psql_stmt(node ast.SqlStmt, typ SqlType) {
|
|
|
|
|
|
|
|
g.sql_i = 0
|
|
|
|
|
|
|
|
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')
|
|
|
|
|
|
|
|
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.writeln(';')
|
|
|
|
|
|
|
|
stmt_name := g.new_tmp_var()
|
|
|
|
|
|
|
|
g.write('string $stmt_name = _SLIT("')
|
|
|
|
|
|
|
|
g.sql_defaults(node, typ, param_values, param_lens, param_formats)
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
|
|
|
for i, field in node.fields {
|
|
|
|
|
|
|
|
if g.get_sql_field_type(field) == ast.Type(-1) {
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
g.writeln('//$field.name ($field.typ)')
|
|
|
|
|
|
|
|
x := '${node.object_var_name}.$field.name'
|
|
|
|
|
|
|
|
field_type := g.get_sql_field_type(field)
|
|
|
|
|
|
|
|
if g.table.get_type_symbol(field.typ).kind == .struct_ {
|
|
|
|
|
|
|
|
// insert again
|
|
|
|
|
|
|
|
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_name = tmp_sql_stmt_name
|
|
|
|
|
|
|
|
g.sql_table_name = tmp_sql_table_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res := g.new_tmp_var()
|
|
|
|
|
|
|
|
g.write('Option_int $res = pg__DB_q_int($db_name, _SLIT("SELECT LASTVAL();"));')
|
|
|
|
|
|
|
|
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_bind('${res}.data', '', ast.int_type, typ, [
|
|
|
|
|
|
|
|
(i - 1).str(),
|
|
|
|
|
|
|
|
param_values,
|
|
|
|
|
|
|
|
param_lens,
|
|
|
|
|
|
|
|
param_formats,
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
g.writeln(g.sql_buf.str())
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
g.sql_buf = strings.new_builder(100)
|
|
|
|
|
|
|
|
g.sql_bind(x, '', field_type, typ, [(i - 1).str(), param_values, param_lens,
|
|
|
|
|
|
|
|
param_formats,
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
g.writeln(g.sql_buf.str())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
binds := g.sql_buf.str()
|
|
|
|
|
|
|
|
g.sql_buf = strings.new_builder(100)
|
|
|
|
|
|
|
|
g.writeln(binds)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res := g.new_tmp_var()
|
|
|
|
|
|
|
|
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.SqlStmt, typ SqlType) {
|
|
|
|
|
|
|
|
g.writeln('// psql table creator')
|
|
|
|
|
|
|
|
create_string := g.table_gen(node, typ)
|
|
|
|
|
|
|
|
tmp := g.new_tmp_var()
|
|
|
|
|
|
|
|
g.write('Option_Array_pg__Row $tmp = pg__DB_exec(')
|
|
|
|
|
|
|
|
g.expr(node.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) {
|
|
|
|
|
|
|
|
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.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))); }')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) psql_get_table_type(typ ast.Type) string {
|
|
|
|
|
|
|
|
mut table_typ := ''
|
|
|
|
|
|
|
|
match typ {
|
|
|
|
|
|
|
|
ast.i8_type, ast.byte_type, ast.bool_type {
|
|
|
|
|
|
|
|
table_typ = 'CHAR(1)'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.i16_type, ast.u16_type {
|
|
|
|
|
|
|
|
table_typ = 'SMALLINT'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.int_type, ast.u32_type {
|
|
|
|
|
|
|
|
table_typ = 'INT'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.i64_type, ast.u64_type {
|
|
|
|
|
|
|
|
table_typ = 'BIGINT'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.f32_type {
|
|
|
|
|
|
|
|
table_typ = 'FLOAT4'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.f64_type {
|
|
|
|
|
|
|
|
table_typ = 'FLOAT8'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast.string_type {
|
|
|
|
|
|
|
|
table_typ = 'TEXT'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
-1 {
|
|
|
|
|
|
|
|
table_typ = 'SERIAL'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return table_typ
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) psql_bind(val string, data []string, typ ast.Type) {
|
|
|
|
|
|
|
|
tmp := g.new_tmp_var()
|
|
|
|
|
|
|
|
g.sql_idents << tmp
|
|
|
|
|
|
|
|
g.sql_buf.write_string('char* $tmp = ')
|
|
|
|
|
|
|
|
if typ.is_number() {
|
|
|
|
|
|
|
|
g.sql_buf.writeln('(char *) htonl($val);')
|
|
|
|
|
|
|
|
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;')
|
|
|
|
|
|
|
|
} else if typ.is_string() {
|
|
|
|
|
|
|
|
g.sql_buf.writeln('(char *) ${val}.str;')
|
|
|
|
|
|
|
|
g.sql_buf.writeln('\t${data[1]}[${data[0]}] = &$tmp;')
|
|
|
|
|
|
|
|
g.sql_buf.writeln('\t${data[2]}[${data[0]}] = 0;')
|
|
|
|
|
|
|
|
g.sql_buf.writeln('\t${data[3]}[${data[0]}] = 0;')
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
g.sql_buf.writeln('(char *) htonl(0);')
|
|
|
|
|
|
|
|
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;')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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 ')
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -737,12 +898,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, [])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -768,21 +929,25 @@ 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) {
|
|
|
|
fn (mut g Gen) sql_defaults(node ast.SqlStmt, 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 := '`'
|
|
|
|
|
|
|
|
if typ == .psql {
|
|
|
|
|
|
|
|
lit = '\\"'
|
|
|
|
|
|
|
|
}
|
|
|
|
if node.kind == .insert {
|
|
|
|
if node.kind == .insert {
|
|
|
|
g.write('INSERT INTO `$table_name` (')
|
|
|
|
g.write('INSERT INTO $lit$table_name$lit (')
|
|
|
|
} else if node.kind == .update {
|
|
|
|
} else if node.kind == .update {
|
|
|
|
g.write('UPDATE `$table_name` SET ')
|
|
|
|
g.write('UPDATE $lit$table_name$lit SET ')
|
|
|
|
} else if node.kind == .delete {
|
|
|
|
} else if node.kind == .delete {
|
|
|
|
g.write('DELETE FROM `$table_name` ')
|
|
|
|
g.write('DELETE FROM $lit$table_name$lit ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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.write('`${g.get_field_name(field)}`')
|
|
|
|
g.write('$lit${g.get_field_name(field)}$lit')
|
|
|
|
if i < node.fields.len - 1 {
|
|
|
|
if i < node.fields.len - 1 {
|
|
|
|
g.write(', ')
|
|
|
|
g.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -792,21 +957,16 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmt, typ SqlType) {
|
|
|
|
if g.get_sql_field_type(field) == ast.Type(-1) {
|
|
|
|
if g.get_sql_field_type(field) == ast.Type(-1) {
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if typ == .sqlite3 {
|
|
|
|
g.inc_sql_i(typ)
|
|
|
|
g.write('?${i + 0}')
|
|
|
|
|
|
|
|
} else if typ == .mysql {
|
|
|
|
|
|
|
|
g.write('?')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if i < node.fields.len - 1 {
|
|
|
|
if i < node.fields.len - 1 {
|
|
|
|
g.write(', ')
|
|
|
|
g.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.sql_i++
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.write(')')
|
|
|
|
g.write(')')
|
|
|
|
} 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)
|
|
|
|
g.expr_to_sql(node.update_exprs[i], typ, psql_data)
|
|
|
|
if i < node.updated_columns.len - 1 {
|
|
|
|
if i < node.updated_columns.len - 1 {
|
|
|
|
g.write(', ')
|
|
|
|
g.write(', ')
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -816,16 +976,20 @@ fn (mut g Gen) sql_defaults(node ast.SqlStmt, typ SqlType) {
|
|
|
|
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)
|
|
|
|
g.expr_to_sql(node.where_expr, typ, psql_data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.write('")')
|
|
|
|
g.write(';")')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) string {
|
|
|
|
fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) 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)
|
|
|
|
mut create_string := 'CREATE TABLE IF NOT EXISTS `$table_name` ('
|
|
|
|
mut lit := '`'
|
|
|
|
|
|
|
|
if typ == .psql {
|
|
|
|
|
|
|
|
lit = '\\"'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mut create_string := 'CREATE TABLE IF NOT EXISTS $lit$table_name$lit ('
|
|
|
|
|
|
|
|
|
|
|
|
mut fields := []string{}
|
|
|
|
mut fields := []string{}
|
|
|
|
|
|
|
|
|
|
|
@ -882,7 +1046,7 @@ fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) string {
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stmt = '`$name` $converted_typ'
|
|
|
|
stmt = '$lit$name$lit $converted_typ'
|
|
|
|
|
|
|
|
|
|
|
|
if field.has_default_expr && typ != .mysql {
|
|
|
|
if field.has_default_expr && typ != .mysql {
|
|
|
|
stmt += ' DEFAULT '
|
|
|
|
stmt += ' DEFAULT '
|
|
|
@ -903,20 +1067,20 @@ fn (mut g Gen) table_gen(node ast.SqlStmt, typ SqlType) string {
|
|
|
|
for k, v in unique {
|
|
|
|
for k, v in unique {
|
|
|
|
mut tmp := []string{}
|
|
|
|
mut tmp := []string{}
|
|
|
|
for f in v {
|
|
|
|
for f in v {
|
|
|
|
tmp << '`$f`'
|
|
|
|
tmp << '$lit$f$lit'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fields << '/* $k */UNIQUE(${tmp.join(', ')})'
|
|
|
|
fields << '/* $k */UNIQUE(${tmp.join(', ')})'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if typ == .mysql {
|
|
|
|
if typ == .mysql {
|
|
|
|
fields << 'PRIMARY KEY(`$primary`)'
|
|
|
|
fields << 'PRIMARY KEY($lit$primary$lit)'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
create_string += fields.join(', ')
|
|
|
|
create_string += fields.join(', ')
|
|
|
|
create_string += ');'
|
|
|
|
create_string += ');'
|
|
|
|
return create_string
|
|
|
|
return create_string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType, psql_data []string) {
|
|
|
|
// 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()
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -925,7 +1089,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
match expr {
|
|
|
|
match expr {
|
|
|
|
ast.InfixExpr {
|
|
|
|
ast.InfixExpr {
|
|
|
|
g.sql_side = .left
|
|
|
|
g.sql_side = .left
|
|
|
|
g.expr_to_sql(expr.left, typ)
|
|
|
|
g.expr_to_sql(expr.left, typ, psql_data)
|
|
|
|
match expr.op {
|
|
|
|
match expr.op {
|
|
|
|
.ne { g.write(' != ') }
|
|
|
|
.ne { g.write(' != ') }
|
|
|
|
.eq { g.write(' = ') }
|
|
|
|
.eq { g.write(' = ') }
|
|
|
@ -942,24 +1106,26 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
else {}
|
|
|
|
else {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.sql_side = .right
|
|
|
|
g.sql_side = .right
|
|
|
|
g.expr_to_sql(expr.right, typ)
|
|
|
|
g.expr_to_sql(expr.right, typ, psql_data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
typ, g.append_arr(g.sql_i, psql_data))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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.sql_bind(expr.val, '', g.sql_get_real_type(ast.int_type), typ, g.append_arr(g.sql_i,
|
|
|
|
|
|
|
|
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.sql_bind(eval, '', g.sql_get_real_type(ast.byte_type), typ, g.append_arr(g.sql_i,
|
|
|
|
|
|
|
|
psql_data))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast.Ident {
|
|
|
|
ast.Ident {
|
|
|
|
// `name == user_name` => `name == ?1`
|
|
|
|
// `name == user_name` => `name == ?1`
|
|
|
@ -975,12 +1141,14 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
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)
|
|
|
|
typ, g.append_arr(g.sql_i, psql_data))
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
g.sql_bind(expr.name, '', g.sql_get_real_type(ityp), typ)
|
|
|
|
g.sql_bind(expr.name, '', g.sql_get_real_type(ityp), typ, g.append_arr(g.sql_i,
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -993,7 +1161,7 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
typ, g.append_arr(g.sql_i, psql_data))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
g.expr(expr)
|
|
|
|
g.expr(expr)
|
|
|
@ -1007,6 +1175,13 @@ fn (mut g Gen) expr_to_sql(expr ast.Expr, typ SqlType) {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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])
|
|
|
|
|
|
|
|
|
|
|
@ -1035,8 +1210,12 @@ fn (mut g Gen) sql_get_real_type(typ ast.Type) ast.Type {
|
|
|
|
|
|
|
|
|
|
|
|
fn (mut g Gen) inc_sql_i(typ SqlType) {
|
|
|
|
fn (mut g Gen) inc_sql_i(typ SqlType) {
|
|
|
|
g.sql_i++
|
|
|
|
g.sql_i++
|
|
|
|
if typ == .sqlite3 {
|
|
|
|
if typ == .psql {
|
|
|
|
g.write('?')
|
|
|
|
g.write('$')
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
g.write('?') // used in sqlite `?i` and mysql `?`
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if typ != .mysql {
|
|
|
|
g.write('$g.sql_i')
|
|
|
|
g.write('$g.sql_i')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1066,6 +1245,9 @@ fn (mut g Gen) parse_db_from_type_string(name string) SqlType {
|
|
|
|
'mysql.Connection' {
|
|
|
|
'mysql.Connection' {
|
|
|
|
return .mysql
|
|
|
|
return .mysql
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
'pg.DB' {
|
|
|
|
|
|
|
|
return .psql
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
return .unknown
|
|
|
|
return .unknown
|
|
|
|
}
|
|
|
|
}
|
|
|
|