cgen: zero_struct_field(); orm: zero un-inited fields

pull/5477/head
Alexander Medvednikov 2020-06-24 12:53:36 +02:00
parent 5f36874c9b
commit cf7ac7be7f
3 changed files with 48 additions and 18 deletions

View File

@ -16,6 +16,7 @@ struct User {
age int
name string
is_customer bool
skipped_string string [skip]
}
fn test_orm_sqlite() {

View File

@ -2531,12 +2531,15 @@ fn (mut g Gen) go_back_out(n int) {
g.out.go_back(n)
}
fn (mut g Gen) struct_init(struct_init ast.StructInit) {
skip_init := ['strconv__ftoa__Uf32', 'strconv__ftoa__Uf64', 'strconv__Float64u', 'struct stat',
const (
skip_struct_init = ['strconv__ftoa__Uf32', 'strconv__ftoa__Uf64', 'strconv__Float64u', 'struct stat',
'struct addrinfo'
]
)
fn (mut g Gen) struct_init(struct_init ast.StructInit) {
styp := g.typ(struct_init.typ)
if styp in skip_init {
if styp in skip_struct_init {
g.go_back_out(3)
return
}
@ -2587,13 +2590,15 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
}
}
// The rest of the fields are zeroed.
mut nr_info_fields := 0
// `inited_fields` is a list of fields that have been init'ed, they are skipped
//mut nr_fields := 0
if sym.kind == .struct_ {
info := sym.info as table.Struct
if info.is_union && struct_init.fields.len > 1 {
verror('union must not have more than 1 initializer')
}
nr_info_fields = info.fields.len
//g.zero_struct_fields(info, inited_fields)
//nr_fields = info.fields.len
for field in info.fields {
if field.name in inited_fields {
sfield := struct_init.fields[inited_fields[field.name]]
@ -2625,16 +2630,10 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
// TODO handle/require optionals in inits
continue
}
field_name := c_name(field.name)
g.write('\t.$field_name = ')
if field.has_default_expr {
g.expr(ast.fe2ex(field.default_expr))
} else {
g.write(g.type_default(field.typ))
}
g.writeln(',')
g.zero_struct_field(field)
initialized = true
}
}
// if struct_init.fields.len == 0 && info.fields.len == 0 {
if !initialized {
@ -2646,6 +2645,20 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
}
}
fn (mut g Gen) zero_struct_field(field table.Field) {
field_name := c_name(field.name)
g.write('\t.$field_name = ')
if field.has_default_expr {
g.expr(ast.fe2ex(field.default_expr))
} else {
g.write(g.type_default(field.typ))
}
g.writeln(',')
}
//fn (mut g Gen) zero_struct_fields(info table.Struct, inited_fields map[string]int) {
//}
// { user | name: 'new name' }
fn (mut g Gen) assoc(node ast.Assoc) {
g.writeln('// assoc')

View File

@ -124,15 +124,31 @@ fn (mut g Gen) sql_select_expr(node ast.SqlExpr) {
if node.is_array {
// array_User array_tmp;
// for { User tmp; ... array_tmp << tmp; }
sym := g.table.get_type_symbol(node.typ)
info := sym.info as table.Array
elem_type_str = g.typ(info.elem_type)
array_sym := g.table.get_type_symbol(node.typ)
array_info := array_sym.info as table.Array
elem_type_str = g.typ(array_info.elem_type)
g.writeln('$styp ${tmp}_array = __new_array(0, 10, sizeof($elem_type_str));')
g.writeln('while (1) {')
g.writeln('\t$elem_type_str $tmp;')
g.writeln('\t$elem_type_str $tmp = ($elem_type_str) {')
//
sym := g.table.get_type_symbol(array_info.elem_type)
info := sym.info as table.Struct
for field in info.fields {
g.zero_struct_field(field)
}
g.writeln('};')
} else {
// `User tmp;`
g.writeln('$styp $tmp;')
g.writeln('$styp $tmp = ($styp){')
// Zero fields, (only the [skip] ones?)
// If we don't, string values are going to be nil etc for fields that are not returned
// by the db engine.
sym := g.table.get_type_symbol(node.typ)
info := sym.info as table.Struct
for field in info.fields {
g.zero_struct_field(field)
}
g.writeln('};')
}
//
g.writeln('int _step_res$tmp = sqlite3_step($g.sql_stmt_name);')