mirror of
https://github.com/vlang/v.git
synced 2025-09-08 23:07:19 -04:00
orm: fix code generated for fields of ?[]Type (#20032)
This commit is contained in:
parent
c19b13e165
commit
dfab24b936
@ -146,6 +146,7 @@ const skip_with_fsanitize_memory = [
|
||||
'vlib/orm/orm_custom_operators_test.v',
|
||||
'vlib/orm/orm_fk_test.v',
|
||||
'vlib/orm/orm_references_test.v',
|
||||
'vlib/orm/orm_option_array_test.v',
|
||||
'vlib/orm/orm_option_time_test.v',
|
||||
'vlib/db/sqlite/sqlite_test.v',
|
||||
'vlib/db/sqlite/sqlite_orm_test.v',
|
||||
@ -234,6 +235,7 @@ const skip_on_ubuntu_musl = [
|
||||
'vlib/orm/orm_custom_operators_test.v',
|
||||
'vlib/orm/orm_fk_test.v',
|
||||
'vlib/orm/orm_references_test.v',
|
||||
'vlib/orm/orm_option_array_test.v',
|
||||
'vlib/orm/orm_option_time_test.v',
|
||||
'vlib/v/tests/orm_enum_test.v',
|
||||
'vlib/v/tests/orm_sub_struct_test.v',
|
||||
|
45
vlib/orm/orm_option_array_test.v
Normal file
45
vlib/orm/orm_option_array_test.v
Normal file
@ -0,0 +1,45 @@
|
||||
import db.sqlite
|
||||
|
||||
struct Member {
|
||||
id int @[primary]
|
||||
children ?[]Child @[fkey: parent_id]
|
||||
}
|
||||
|
||||
struct Child {
|
||||
id int @[primary]
|
||||
parent_id int
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
mut db := sqlite.connect(':memory:') or { panic(err) }
|
||||
defer {
|
||||
db.close() or { panic(err) }
|
||||
}
|
||||
sql db {
|
||||
create table Member
|
||||
} or { println(err) }
|
||||
sql db {
|
||||
create table Child
|
||||
} or { println(err) }
|
||||
new_member := Member{
|
||||
id: 1
|
||||
children: [Child{
|
||||
id: 1
|
||||
parent_id: 1
|
||||
}, Child{
|
||||
id: 2
|
||||
parent_id: 1
|
||||
}]
|
||||
}
|
||||
sql db {
|
||||
insert new_member into Member
|
||||
}!
|
||||
|
||||
rows := sql db {
|
||||
select from Member
|
||||
}!
|
||||
|
||||
assert rows[0].children?.len == 2
|
||||
assert rows[0].children?[0].id == 1
|
||||
assert rows[0].children?[1].id == 2
|
||||
}
|
@ -276,6 +276,7 @@ fn (mut g Gen) write_orm_insert_with_last_ids(node ast.SqlStmtLine, connection_v
|
||||
mut arrs := []ast.SqlStmtLine{}
|
||||
mut fkeys := []string{}
|
||||
mut field_names := []string{}
|
||||
mut opt_fields := []int{}
|
||||
|
||||
for field in node.fields {
|
||||
sym := g.table.sym(field.typ)
|
||||
@ -289,6 +290,9 @@ fn (mut g Gen) write_orm_insert_with_last_ids(node ast.SqlStmtLine, connection_v
|
||||
} else {
|
||||
verror('missing fkey attribute')
|
||||
}
|
||||
if field.typ.has_flag(.option) {
|
||||
opt_fields << arrs.len
|
||||
}
|
||||
arrs << node.sub_structs[int(field.typ)]
|
||||
field_names << field.name
|
||||
}
|
||||
@ -433,13 +437,22 @@ fn (mut g Gen) write_orm_insert_with_last_ids(node ast.SqlStmtLine, connection_v
|
||||
}
|
||||
for i, mut arr in arrs {
|
||||
idx := g.new_tmp_var()
|
||||
g.writeln('for (int ${idx} = 0; ${idx} < ${node.object_var}${member_access_type}${arr.object_var}.len; ${idx}++) {')
|
||||
ctyp := g.typ(arr.table_expr.typ)
|
||||
is_option := opt_fields.contains(i)
|
||||
if is_option {
|
||||
g.writeln('for (int ${idx} = 0; ${node.object_var}${member_access_type}${arr.object_var}.state != 2 && ${idx} < (*(Array_${ctyp}*)${node.object_var}${member_access_type}${arr.object_var}.data).len; ${idx}++) {')
|
||||
} else {
|
||||
g.writeln('for (int ${idx} = 0; ${idx} < ${node.object_var}${member_access_type}${arr.object_var}.len; ${idx}++) {')
|
||||
}
|
||||
g.indent++
|
||||
last_ids := g.new_tmp_var()
|
||||
res_ := g.new_tmp_var()
|
||||
tmp_var := g.new_tmp_var()
|
||||
ctyp := g.typ(arr.table_expr.typ)
|
||||
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(${node.object_var}${member_access_type}${arr.object_var}, ${idx}));')
|
||||
if is_option {
|
||||
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(*(Array_${ctyp}*)${node.object_var}${member_access_type}${arr.object_var}.data, ${idx}));')
|
||||
} else {
|
||||
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(${node.object_var}${member_access_type}${arr.object_var}, ${idx}));')
|
||||
}
|
||||
arr.object_var = tmp_var
|
||||
mut fff := []ast.StructField{}
|
||||
for f in arr.fields {
|
||||
@ -941,7 +954,13 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
||||
if node.is_array {
|
||||
info := g.table.sym(node.typ).array_info()
|
||||
typ_str = g.typ(info.elem_type)
|
||||
g.writeln('${unwrapped_c_typ} ${tmp}_array = __new_array(0, ${select_unwrapped_result_var_name}.len, sizeof(${typ_str}));')
|
||||
base_typ := g.base_type(node.typ)
|
||||
if node.typ.has_flag(.option) {
|
||||
g.writeln('${unwrapped_c_typ} ${tmp}_array = { .state = 2, .err = _const_none__, .data = {EMPTY_STRUCT_INITIALIZATION} };')
|
||||
g.writeln('_option_ok(&(${base_typ}[]) { __new_array(0, ${select_unwrapped_result_var_name}.len, sizeof(${typ_str})) }, (_option *)&${tmp}_array, sizeof(${base_typ}));')
|
||||
} else {
|
||||
g.writeln('${unwrapped_c_typ} ${tmp}_array = __new_array(0, ${select_unwrapped_result_var_name}.len, sizeof(${typ_str}));')
|
||||
}
|
||||
g.writeln('for (; ${idx} < ${select_unwrapped_result_var_name}.len; ${idx}++) {')
|
||||
g.indent++
|
||||
g.write('${typ_str} ${tmp} = (${typ_str}) {')
|
||||
@ -1053,8 +1072,14 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
||||
sub_result_c_typ := g.typ(sub.typ)
|
||||
g.writeln('${sub_result_c_typ} ${sub_result_var};')
|
||||
g.write_orm_select(sql_expr_select_array, connection_var_name, sub_result_var)
|
||||
g.writeln('if (!${sub_result_var}.is_error)')
|
||||
g.writeln('\t${field_var} = *(${unwrapped_c_typ}*)${sub_result_var}.data;')
|
||||
g.writeln('if (!${sub_result_var}.is_error) {')
|
||||
if field.typ.has_flag(.option) {
|
||||
g.writeln('\t${field_var}.state = 0;')
|
||||
g.writeln('\t*(${g.base_type(field.typ)}*)${field_var}.data = *(${g.base_type(field.typ)}*)${sub_result_var}.data;')
|
||||
} else {
|
||||
g.writeln('\t${field_var} = *(${unwrapped_c_typ}*)${sub_result_var}.data;')
|
||||
}
|
||||
g.writeln('}')
|
||||
} else if field.typ.has_flag(.option) {
|
||||
prim_var := g.new_tmp_var()
|
||||
g.writeln('orm__Primitive *${prim_var} = &${array_get_call_code};')
|
||||
@ -1075,7 +1100,12 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
||||
}
|
||||
|
||||
if node.is_array {
|
||||
g.writeln('array_push(&${tmp}_array, _MOV((${typ_str}[]){ ${tmp} }));')
|
||||
if node.typ.has_flag(.option) {
|
||||
g.writeln('${tmp}_array.state = 0;')
|
||||
g.writeln('array_push((${g.base_type(node.typ)}*)&${tmp}_array.data, _MOV((${typ_str}[]){ ${tmp} }));')
|
||||
} else {
|
||||
g.writeln('array_push(&${tmp}_array, _MOV((${typ_str}[]){ ${tmp} }));')
|
||||
}
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
}
|
||||
@ -1083,11 +1113,15 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
|
||||
g.write('*(${unwrapped_c_typ}*) ${result_var}.data = ${tmp}')
|
||||
if node.is_array {
|
||||
g.write('_array')
|
||||
if node.typ.has_flag(.option) {
|
||||
g.writeln('*(${g.base_type(node.typ)}*) ${result_var}.data = *(${g.base_type(node.typ)}*)${tmp}_array.data;')
|
||||
} else {
|
||||
g.writeln('*(${unwrapped_c_typ}*) ${result_var}.data = ${tmp}_array;')
|
||||
}
|
||||
} else {
|
||||
g.writeln('*(${unwrapped_c_typ}*) ${result_var}.data = ${tmp};')
|
||||
}
|
||||
g.writeln(';')
|
||||
}
|
||||
|
||||
g.indent--
|
||||
|
Loading…
x
Reference in New Issue
Block a user