Finish ToManyRemove.
- Make Set test better.
This commit is contained in:
parent
d9931fe7ba
commit
ae99b2a649
2 changed files with 183 additions and 29 deletions
|
@ -109,25 +109,7 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
for _, rel := range related {
|
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}}, related)
|
||||||
if rel.R == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i, ri := range rel.R.{{$rel.Function.ForeignName}} {
|
|
||||||
if {{$rel.Function.Receiver}}.{{$rel.Function.LocalAssignment}} != ri.{{$rel.Function.LocalAssignment}} {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ln := len(rel.R.{{$rel.Function.ForeignName}})
|
|
||||||
if ln > 1 && i < ln-1 {
|
|
||||||
rel.R.{{$rel.Function.ForeignName}}[i], rel.R.{{$rel.Function.ForeignName}}[ln-1] =
|
|
||||||
rel.R.{{$rel.Function.ForeignName}}[ln-1], rel.R.{{$rel.Function.ForeignName}}[i]
|
|
||||||
}
|
|
||||||
rel.R.{{$rel.Function.ForeignName}} = rel.R.{{$rel.Function.ForeignName}}[:ln-1]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = nil
|
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = nil
|
||||||
{{else -}}
|
{{else -}}
|
||||||
if {{$rel.Function.Receiver}}.R != nil {
|
if {{$rel.Function.Receiver}}.R != nil {
|
||||||
|
@ -148,12 +130,87 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove{{$rel.Function.Name}} relationships from objects passed in.
|
// Remove{{$rel.Function.Name}} relationships from objects passed in.
|
||||||
// Removes related items from R.{{$rel.Function.Name}}.
|
// Removes related items from R.{{$rel.Function.Name}} (uses pointer comparison, removal does not keep order)
|
||||||
// Sets related.R.{{$rel.Function.ForeignName}}
|
// Sets related.R.{{$rel.Function.ForeignName}}.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Function.Name}}(exec boil.Executor, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Function.Name}}(exec boil.Executor, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
||||||
return nil
|
var err error
|
||||||
|
{{if .ToJoinTable -}}
|
||||||
|
query := fmt.Sprintf(
|
||||||
|
`delete from "{{.JoinTable}}" where "{{.JoinLocalColumn}}" = $1 and "{{.JoinForeignColumn}}" in (%s)`,
|
||||||
|
strmangle.Placeholders(len(related), 1, 1),
|
||||||
|
)
|
||||||
|
values := []interface{}{{"{"}}{{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}}
|
||||||
|
|
||||||
|
if boil.DebugMode {
|
||||||
|
fmt.Fprintln(boil.DebugWriter, query)
|
||||||
|
fmt.Fprintln(boil.DebugWriter, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = exec.Exec(query, values...)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to remove relationships before set")
|
||||||
|
}
|
||||||
|
{{else -}}
|
||||||
|
for _, rel := range related {
|
||||||
|
rel.{{$rel.ForeignTable.ColumnNameGo}}.Valid = false
|
||||||
|
{{if not .ToJoinTable -}}
|
||||||
|
if rel.R != nil {
|
||||||
|
rel.R.{{$rel.Function.ForeignName}} = nil
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
if err = rel.Update(exec, "{{.ForeignColumn}}"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{end -}}
|
||||||
|
|
||||||
|
{{if .ToJoinTable -}}
|
||||||
|
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}}, related)
|
||||||
|
{{end -}}
|
||||||
|
if {{$rel.Function.Receiver}}.R == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rel := range related {
|
||||||
|
for i, ri := range {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} {
|
||||||
|
if rel != ri {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ln := len({{$rel.Function.Receiver}}.R.{{$rel.Function.Name}})
|
||||||
|
if ln > 1 && i < ln-1 {
|
||||||
|
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[i] = {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[ln-1]
|
||||||
|
}
|
||||||
|
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[:ln-1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .ToJoinTable -}}
|
||||||
|
func remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}, related []*{{$rel.ForeignTable.NameGo}}) {
|
||||||
|
for _, rel := range related {
|
||||||
|
if rel.R == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for i, ri := range rel.R.{{$rel.Function.ForeignName}} {
|
||||||
|
if {{$rel.Function.Receiver}}.{{$rel.Function.LocalAssignment}} != ri.{{$rel.Function.LocalAssignment}} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ln := len(rel.R.{{$rel.Function.ForeignName}})
|
||||||
|
if ln > 1 && i < ln-1 {
|
||||||
|
rel.R.{{$rel.Function.ForeignName}}[i] = rel.R.{{$rel.Function.ForeignName}}[ln-1]
|
||||||
|
}
|
||||||
|
rel.R.{{$rel.Function.ForeignName}} = rel.R.{{$rel.Function.ForeignName}}[:ln-1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{end -}}{{- /* if join table */ -}}
|
||||||
|
{{- end -}}{{- /* if nullable foreign key */ -}}
|
||||||
{{- end -}}{{- /* if unique foreign key */ -}}
|
{{- end -}}{{- /* if unique foreign key */ -}}
|
||||||
{{- end -}}{{- /* range relationships */ -}}
|
{{- end -}}{{- /* range relationships */ -}}
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
|
|
@ -126,7 +126,7 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.Add{{$rel.Function.Name}}(tx, false, &b, &c)
|
err = a.Set{{$rel.Function.Name}}(tx, false, &b, &c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if count != 2 {
|
if count != 2 {
|
||||||
t.Error("count was wrong:", 2)
|
t.Error("count was wrong:", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.Set{{$rel.Function.Name}}(tx, true, &d, &e)
|
err = a.Set{{$rel.Function.Name}}(tx, true, &d, &e)
|
||||||
|
@ -149,7 +149,7 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if count != 2 {
|
if count != 2 {
|
||||||
t.Error("count was wrong:", 2)
|
t.Error("count was wrong:", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
{{- if .ToJoinTable}}
|
{{- if .ToJoinTable}}
|
||||||
|
@ -182,16 +182,16 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.R.{{$rel.Function.ForeignName}} != nil {
|
if b.R.{{$rel.Function.ForeignName}} != nil {
|
||||||
t.Error("relationship was not removed properly from the foreign slice")
|
t.Error("relationship was not removed properly from the foreign struct")
|
||||||
}
|
}
|
||||||
if c.R.{{$rel.Function.ForeignName}} != nil {
|
if c.R.{{$rel.Function.ForeignName}} != nil {
|
||||||
t.Error("relationship was not removed properly from the foreign slice")
|
t.Error("relationship was not removed properly from the foreign struct")
|
||||||
}
|
}
|
||||||
if d.R.{{$rel.Function.ForeignName}} != &a {
|
if d.R.{{$rel.Function.ForeignName}} != &a {
|
||||||
t.Error("relationship was not added properly to the foreign slice")
|
t.Error("relationship was not added properly to the foreign struct")
|
||||||
}
|
}
|
||||||
if e.R.{{$rel.Function.ForeignName}} != &a {
|
if e.R.{{$rel.Function.ForeignName}} != &a {
|
||||||
t.Error("relationship was not added properly to the foreign slice")
|
t.Error("relationship was not added properly to the foreign struct")
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
@ -204,6 +204,103 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
}
|
}
|
||||||
|
|
||||||
func test{{$rel.LocalTable.NameGo}}ToManyRemoveOp{{$rel.Function.Name}}(t *testing.T) {
|
func test{{$rel.LocalTable.NameGo}}ToManyRemoveOp{{$rel.Function.Name}}(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
tx := MustTx(boil.Begin())
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
var a {{$rel.LocalTable.NameGo}}
|
||||||
|
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
||||||
|
for _, x := range foreigners {
|
||||||
|
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.Add{{$rel.Function.Name}}(tx, true, foreigners...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := a.{{$rel.Function.Name}}(tx).Count()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if count != 4 {
|
||||||
|
t.Error("count was wrong:", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.Remove{{$rel.Function.Name}}(tx, foreigners[:2]...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err = a.{{$rel.Function.Name}}(tx).Count()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if count != 2 {
|
||||||
|
t.Error("count was wrong:", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{- if .ToJoinTable}}
|
||||||
|
|
||||||
|
if len(b.R.{{$rel.Function.ForeignName}}) != 0 {
|
||||||
|
t.Error("relationship was not removed properly from the slice")
|
||||||
|
}
|
||||||
|
if len(c.R.{{$rel.Function.ForeignName}}) != 0 {
|
||||||
|
t.Error("relationship was not removed properly from the slice")
|
||||||
|
}
|
||||||
|
if d.R.{{$rel.Function.ForeignName}}[0] != &a {
|
||||||
|
t.Error("relationship was not added properly to the foreign struct")
|
||||||
|
}
|
||||||
|
if e.R.{{$rel.Function.ForeignName}}[0] != &a {
|
||||||
|
t.Error("relationship was not added properly to the foreign struct")
|
||||||
|
}
|
||||||
|
{{- else}}
|
||||||
|
|
||||||
|
if b.{{$rel.ForeignTable.ColumnNameGo}}.Valid {
|
||||||
|
t.Error("want b's foreign key value to be nil")
|
||||||
|
}
|
||||||
|
if c.{{$rel.ForeignTable.ColumnNameGo}}.Valid {
|
||||||
|
t.Error("want c's foreign key value to be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.R.{{$rel.Function.ForeignName}} != nil {
|
||||||
|
t.Error("relationship was not removed properly from the foreign struct")
|
||||||
|
}
|
||||||
|
if c.R.{{$rel.Function.ForeignName}} != nil {
|
||||||
|
t.Error("relationship was not removed properly from the foreign struct")
|
||||||
|
}
|
||||||
|
if d.R.{{$rel.Function.ForeignName}} != &a {
|
||||||
|
t.Error("relationship to a should have been preserved")
|
||||||
|
}
|
||||||
|
if e.R.{{$rel.Function.ForeignName}} != &a {
|
||||||
|
t.Error("relationship to a should have been preserved")
|
||||||
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if len(a.R.{{$rel.Function.Name}}) != 2 {
|
||||||
|
t.Error("should have preserved two relationships")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removal doesn't do a stable deletion for performance so we have to flip the order
|
||||||
|
if a.R.{{$rel.Function.Name}}[1] != &d {
|
||||||
|
t.Error("relationship to d should have been preserved")
|
||||||
|
}
|
||||||
|
if a.R.{{$rel.Function.Name}}[0] != &e {
|
||||||
|
t.Error("relationship to e should have been preserved")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{- end -}}{{- /* if unique foreign key */ -}}
|
{{- end -}}{{- /* if unique foreign key */ -}}
|
||||||
|
|
Loading…
Reference in a new issue