mirror of
https://github.com/vlang/v.git
synced 2025-09-09 23:39:39 -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_custom_operators_test.v',
|
||||||
'vlib/orm/orm_fk_test.v',
|
'vlib/orm/orm_fk_test.v',
|
||||||
'vlib/orm/orm_references_test.v',
|
'vlib/orm/orm_references_test.v',
|
||||||
|
'vlib/orm/orm_option_array_test.v',
|
||||||
'vlib/orm/orm_option_time_test.v',
|
'vlib/orm/orm_option_time_test.v',
|
||||||
'vlib/db/sqlite/sqlite_test.v',
|
'vlib/db/sqlite/sqlite_test.v',
|
||||||
'vlib/db/sqlite/sqlite_orm_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_custom_operators_test.v',
|
||||||
'vlib/orm/orm_fk_test.v',
|
'vlib/orm/orm_fk_test.v',
|
||||||
'vlib/orm/orm_references_test.v',
|
'vlib/orm/orm_references_test.v',
|
||||||
|
'vlib/orm/orm_option_array_test.v',
|
||||||
'vlib/orm/orm_option_time_test.v',
|
'vlib/orm/orm_option_time_test.v',
|
||||||
'vlib/v/tests/orm_enum_test.v',
|
'vlib/v/tests/orm_enum_test.v',
|
||||||
'vlib/v/tests/orm_sub_struct_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 arrs := []ast.SqlStmtLine{}
|
||||||
mut fkeys := []string{}
|
mut fkeys := []string{}
|
||||||
mut field_names := []string{}
|
mut field_names := []string{}
|
||||||
|
mut opt_fields := []int{}
|
||||||
|
|
||||||
for field in node.fields {
|
for field in node.fields {
|
||||||
sym := g.table.sym(field.typ)
|
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 {
|
} else {
|
||||||
verror('missing fkey attribute')
|
verror('missing fkey attribute')
|
||||||
}
|
}
|
||||||
|
if field.typ.has_flag(.option) {
|
||||||
|
opt_fields << arrs.len
|
||||||
|
}
|
||||||
arrs << node.sub_structs[int(field.typ)]
|
arrs << node.sub_structs[int(field.typ)]
|
||||||
field_names << field.name
|
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 {
|
for i, mut arr in arrs {
|
||||||
idx := g.new_tmp_var()
|
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++
|
g.indent++
|
||||||
last_ids := g.new_tmp_var()
|
last_ids := g.new_tmp_var()
|
||||||
res_ := g.new_tmp_var()
|
res_ := g.new_tmp_var()
|
||||||
tmp_var := g.new_tmp_var()
|
tmp_var := g.new_tmp_var()
|
||||||
ctyp := g.typ(arr.table_expr.typ)
|
if is_option {
|
||||||
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(${node.object_var}${member_access_type}${arr.object_var}, ${idx}));')
|
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
|
arr.object_var = tmp_var
|
||||||
mut fff := []ast.StructField{}
|
mut fff := []ast.StructField{}
|
||||||
for f in arr.fields {
|
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 {
|
if node.is_array {
|
||||||
info := g.table.sym(node.typ).array_info()
|
info := g.table.sym(node.typ).array_info()
|
||||||
typ_str = g.typ(info.elem_type)
|
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.writeln('for (; ${idx} < ${select_unwrapped_result_var_name}.len; ${idx}++) {')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.write('${typ_str} ${tmp} = (${typ_str}) {')
|
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)
|
sub_result_c_typ := g.typ(sub.typ)
|
||||||
g.writeln('${sub_result_c_typ} ${sub_result_var};')
|
g.writeln('${sub_result_c_typ} ${sub_result_var};')
|
||||||
g.write_orm_select(sql_expr_select_array, connection_var_name, 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('if (!${sub_result_var}.is_error) {')
|
||||||
g.writeln('\t${field_var} = *(${unwrapped_c_typ}*)${sub_result_var}.data;')
|
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) {
|
} else if field.typ.has_flag(.option) {
|
||||||
prim_var := g.new_tmp_var()
|
prim_var := g.new_tmp_var()
|
||||||
g.writeln('orm__Primitive *${prim_var} = &${array_get_call_code};')
|
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 {
|
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.indent--
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
@ -1083,11 +1113,15 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
|||||||
g.indent--
|
g.indent--
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
|
|
||||||
g.write('*(${unwrapped_c_typ}*) ${result_var}.data = ${tmp}')
|
|
||||||
if node.is_array {
|
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--
|
g.indent--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user