Move loaders off R to a new struct L

This commit is contained in:
Patrick O'brien 2016-09-02 11:01:20 +10:00
parent b5d3b60b3a
commit fd07a1a6a7
7 changed files with 36 additions and 21 deletions

View file

@ -23,6 +23,7 @@ var (
const (
loadMethodPrefix = "Load"
relationshipStructName = "R"
loaderStructName = "L"
sentinel = uint64(255)
)
@ -142,14 +143,14 @@ func loadRelationships(exec Executor, toLoad []string, obj interface{}, singular
}
current := toLoad[0]
r, found := typ.FieldByName(relationshipStructName)
// It's possible a Relationship struct doesn't exist on the struct.
l, found := typ.FieldByName(loaderStructName)
// It's possible a Loaders struct doesn't exist on the struct.
if !found {
return errors.Errorf("attempted to load %s but no R struct was found", current)
return errors.Errorf("attempted to load %s but no L struct was found", current)
}
// Attempt to find the LoadRelationshipName function
loadMethod, found := r.Type.MethodByName(loadMethodPrefix + current)
loadMethod, found := l.Type.MethodByName(loadMethodPrefix + current)
if !found {
return errors.Errorf("could not find %s%s method for eager loading", loadMethodPrefix, current)
}
@ -161,12 +162,11 @@ func loadRelationships(exec Executor, toLoad []string, obj interface{}, singular
}
methodArgs := []reflect.Value{
reflect.Indirect(reflect.New(r.Type)),
reflect.Indirect(reflect.New(l.Type)),
execArg,
reflect.ValueOf(singular),
reflect.ValueOf(obj),
}
resp := loadMethod.Func.Call(methodArgs)
if resp[0].Interface() != nil {
return errors.Wrapf(resp[0].Interface().(error), "failed to eager load %s", current)

View file

@ -282,37 +282,46 @@ var loadFunctionNestedCalled int
type testRStruct struct {
}
type testLStruct struct {
}
type testNestedStruct struct {
ID int
R *testNestedRStruct
L *testNestedLStruct
}
type testNestedRStruct struct {
ToEagerLoad *testNestedStruct
}
type testNestedLStruct struct {
}
type testNestedSlice struct {
ID int
R *testNestedRSlice
L *testNestedLSlice
}
type testNestedRSlice struct {
ToEagerLoad []*testNestedSlice
}
type testNestedLSlice struct {
}
func (r *testRStruct) LoadTestOne(exec Executor, singular bool, obj interface{}) error {
func (r *testLStruct) LoadTestOne(exec Executor, singular bool, obj interface{}) error {
loadFunctionCalled = true
return nil
}
func (r *testNestedRStruct) LoadToEagerLoad(exec Executor, singular bool, obj interface{}) error {
func (r *testNestedLStruct) LoadToEagerLoad(exec Executor, singular bool, obj interface{}) error {
switch x := obj.(type) {
case *testNestedStruct:
x.R = &testNestedRStruct{
&testNestedStruct{ID: 5},
&testNestedStruct{ID: 4},
}
case *[]*testNestedStruct:
for _, r := range *x {
r.R = &testNestedRStruct{
&testNestedStruct{ID: 5},
&testNestedStruct{ID: 4},
}
}
}
@ -320,7 +329,7 @@ func (r *testNestedRStruct) LoadToEagerLoad(exec Executor, singular bool, obj in
return nil
}
func (r *testNestedRSlice) LoadToEagerLoad(exec Executor, singular bool, obj interface{}) error {
func (r *testNestedLSlice) LoadToEagerLoad(exec Executor, singular bool, obj interface{}) error {
switch x := obj.(type) {
case *testNestedSlice:
@ -345,6 +354,7 @@ func TestLoadRelationshipsSlice(t *testing.T) {
testSlice := []*struct {
ID int
R *testRStruct
L *testLStruct
}{}
if err := loadRelationships(nil, []string{"TestOne"}, &testSlice, false); err != nil {
@ -363,6 +373,7 @@ func TestLoadRelationshipsSingular(t *testing.T) {
testSingular := struct {
ID int
R *testRStruct
L *testLStruct
}{}
if err := loadRelationships(nil, []string{"TestOne"}, &testSingular, true); err != nil {
@ -378,7 +389,7 @@ func TestLoadRelationshipsSliceNested(t *testing.T) {
// t.Parallel() Function uses globals
testSlice := []*testNestedStruct{
{
ID: 5,
ID: 2,
},
}
loadFunctionNestedCalled = 0
@ -391,7 +402,7 @@ func TestLoadRelationshipsSliceNested(t *testing.T) {
testSliceSlice := []*testNestedSlice{
{
ID: 5,
ID: 2,
},
}
loadFunctionNestedCalled = 0
@ -406,7 +417,7 @@ func TestLoadRelationshipsSliceNested(t *testing.T) {
func TestLoadRelationshipsSingularNested(t *testing.T) {
// t.Parallel() Function uses globals
testSingular := testNestedStruct{
ID: 5,
ID: 3,
}
loadFunctionNestedCalled = 0
if err := loadRelationships(nil, []string{"ToEagerLoad", "ToEagerLoad", "ToEagerLoad"}, &testSingular, true); err != nil {
@ -417,7 +428,7 @@ func TestLoadRelationshipsSingularNested(t *testing.T) {
}
testSingularSlice := testNestedSlice{
ID: 5,
ID: 3,
}
loadFunctionNestedCalled = 0
if err := loadRelationships(nil, []string{"ToEagerLoad", "ToEagerLoad", "ToEagerLoad"}, &testSingularSlice, true); err != nil {

View file

@ -13,6 +13,7 @@ type {{$modelName}} struct {
{{- if .Table.IsJoinTable -}}
{{- else}}
R *{{$modelNameCamel}}R `boil:"-" json:"-" toml:"-" yaml:"-"`
L *{{$modelNameCamel}}L `boil:"-" json:"-" toml:"-" yaml:"-"`
{{end -}}
}
@ -34,4 +35,7 @@ type {{$modelNameCamel}}R struct {
{{end -}}{{/* if ForeignColumnUnique */}}
{{- end -}}{{/* range tomany */}}
}
// {{$modelNameCamel}}L is where Load methods for each relationship are stored.
type {{$modelNameCamel}}L struct{}
{{end -}}

View file

@ -6,7 +6,7 @@
{{- $slice := printf "%sSlice" .LocalTable.NameGo -}}
// Load{{.Function.Name}} allows an eager lookup of values, cached into the
// loaded structs of the objects.
func (r *{{$varNameSingular}}R) Load{{.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
func (t *{{$varNameSingular}}L) Load{{.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
var slice []*{{.LocalTable.NameGo}}
var object *{{.LocalTable.NameGo}}

View file

@ -12,7 +12,7 @@
{{- $slice := printf "%sSlice" $txt.LocalTable.NameGo -}}
// Load{{$txt.Function.Name}} allows an eager lookup of values, cached into the
// loaded structs of the objects.
func (r *{{$varNameSingular}}R) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
func (t *{{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
var slice []*{{$txt.LocalTable.NameGo}}
var object *{{$txt.LocalTable.NameGo}}

View file

@ -75,7 +75,7 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
}
slice := {{$rel.LocalTable.NameGo}}Slice{&a}
if err = a.R.Load{{$rel.Function.Name}}(tx, false, &slice); err != nil {
if err = a.L.Load{{$rel.Function.Name}}(tx, false, &slice); err != nil {
t.Fatal(err)
}
if got := len(a.R.{{$rel.Function.Name}}); got != 2 {
@ -83,7 +83,7 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
}
a.R.{{$rel.Function.Name}} = nil
if err = a.R.Load{{$rel.Function.Name}}(tx, true, &a); err != nil {
if err = a.L.Load{{$rel.Function.Name}}(tx, true, &a); err != nil {
t.Fatal(err)
}
if got := len(a.R.{{$rel.Function.Name}}); got != 2 {

View file

@ -42,7 +42,7 @@ func test{{.LocalTable.NameGo}}ToOne{{.ForeignTable.NameGo}}_{{.Function.Name}}(
}
slice := {{.LocalTable.NameGo}}Slice{&local}
if err = local.R.Load{{.Function.Name}}(tx, false, &slice); err != nil {
if err = local.L.Load{{.Function.Name}}(tx, false, &slice); err != nil {
t.Fatal(err)
}
if local.R.{{.Function.Name}} == nil {
@ -50,7 +50,7 @@ func test{{.LocalTable.NameGo}}ToOne{{.ForeignTable.NameGo}}_{{.Function.Name}}(
}
local.R.{{.Function.Name}} = nil
if err = local.R.Load{{.Function.Name}}(tx, true, &local); err != nil {
if err = local.L.Load{{.Function.Name}}(tx, true, &local); err != nil {
t.Fatal(err)
}
if local.R.{{.Function.Name}} == nil {