Skip to content

Commit 03be525

Browse files
author
walking devel
authored
orm: allow using reference objects in ORM insert. (#17279)
1 parent ac381f5 commit 03be525

File tree

3 files changed

+50
-10
lines changed

3 files changed

+50
-10
lines changed

vlib/orm/orm_insert_test.v

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,40 @@ mut:
2121
text string
2222
}
2323

24-
fn test_orm_insert_with_multiple_child_elements() {
25-
mut db := sqlite.connect(':memory:') or { panic(err) }
26-
24+
pub fn insert_parent(db sqlite.DB, mut parent Parent) {
2725
sql db {
28-
create table Parent
26+
insert parent into Parent
2927
}
28+
}
29+
30+
fn test_orm_insert_mut_object() {
31+
db := sqlite.connect(':memory:') or { panic(err) }
32+
3033
sql db {
34+
create table Parent
3135
create table Child
36+
create table Note
37+
}
38+
39+
mut parent := Parent{
40+
name: 'test'
3241
}
42+
43+
insert_parent(db, mut parent)
44+
45+
parents := sql db {
46+
select from Parent
47+
}
48+
49+
assert parents.len == 1
50+
}
51+
52+
fn test_orm_insert_with_multiple_child_elements() {
53+
mut db := sqlite.connect(':memory:') or { panic(err) }
54+
3355
sql db {
56+
create table Parent
57+
create table Child
3458
create table Note
3559
}
3660

vlib/v/checker/orm.v

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,14 +185,19 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
185185

186186
if node.kind == .insert && node.is_top_level {
187187
inserting_object_name := node.object_var_name
188-
inserting_object_var := node.scope.find(inserting_object_name) or {
188+
inserting_object := node.scope.find(inserting_object_name) or {
189189
c.error('undefined ident: `${inserting_object_name}`', node.pos)
190190
return ast.void_type
191191
}
192+
mut inserting_object_type := inserting_object.typ
192193

193-
if inserting_object_var.typ != node.table_expr.typ {
194+
if inserting_object_type.is_ptr() {
195+
inserting_object_type = inserting_object.typ.deref()
196+
}
197+
198+
if inserting_object_type != node.table_expr.typ {
194199
table_name := table_sym.name
195-
inserting_type_name := c.table.sym(inserting_object_var.typ).name
200+
inserting_type_name := c.table.sym(inserting_object_type).name
196201

197202
c.error('cannot use `${inserting_type_name}` as `${table_name}`', node.pos)
198203
return ast.void_type

vlib/v/gen/c/sql.v

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,16 @@ fn (mut g Gen) sql_insert(node ast.SqlStmtLine, expr string, table_name string,
174174
}
175175
g.write('),')
176176

177+
mut member_access_type := '.'
178+
179+
if node.scope != unsafe { nil } {
180+
inserting_object := node.scope.find(node.object_var_name) or { verror(err.str()) }
181+
182+
if inserting_object.typ.is_ptr() {
183+
member_access_type = '->'
184+
}
185+
}
186+
177187
g.write('.data = new_array_from_c_array(${fields.len}, ${fields.len}, sizeof(orm__Primitive),')
178188
if fields.len > 0 {
179189
g.write(' _MOV((orm__Primitive[${fields.len}]){')
@@ -193,7 +203,8 @@ fn (mut g Gen) sql_insert(node ast.SqlStmtLine, expr string, table_name string,
193203
if typ == 'time__Time' {
194204
typ = 'time'
195205
}
196-
g.write('orm__${typ}_to_primitive(${node.object_var_name}.${f.name}),')
206+
207+
g.write('orm__${typ}_to_primitive(${node.object_var_name}${member_access_type}${f.name}),')
197208
}
198209
g.write('})')
199210
} else {
@@ -210,12 +221,12 @@ fn (mut g Gen) sql_insert(node ast.SqlStmtLine, expr string, table_name string,
210221
g.writeln('orm__Primitive ${id_name} = orm__int_to_primitive(orm__Connection_name_table[${expr}._typ]._method_last_id(${expr}._object));')
211222
for i, mut arr in arrs {
212223
idx := g.new_tmp_var()
213-
g.writeln('for (int ${idx} = 0; ${idx} < ${arr.object_var_name}.${field_names[i]}.len; ${idx}++) {')
224+
g.writeln('for (int ${idx} = 0; ${idx} < ${arr.object_var_name}${member_access_type}${field_names[i]}.len; ${idx}++) {')
214225
last_ids := g.new_tmp_var()
215226
res_ := g.new_tmp_var()
216227
tmp_var := g.new_tmp_var()
217228
ctyp := g.typ(arr.table_expr.typ)
218-
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(${arr.object_var_name}.${field_names[i]}, ${idx}));')
229+
g.writeln('${ctyp} ${tmp_var} = (*(${ctyp}*)array_get(${arr.object_var_name}${member_access_type}${field_names[i]}, ${idx}));')
219230
arr.object_var_name = tmp_var
220231
mut fff := []ast.StructField{}
221232
for f in arr.fields {

0 commit comments

Comments
 (0)