github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/templates/main/07_relationship_to_one_eager.go.tpl (about)

     1  {{- if or .Table.IsJoinTable .Table.IsView -}}
     2  {{- else -}}
     3  	{{- range $fkey := .Table.FKeys -}}
     4  		{{- $ltable := $.Aliases.Table $fkey.Table -}}
     5  		{{- $ftable := $.Aliases.Table $fkey.ForeignTable -}}
     6  		{{- $rel := $ltable.Relationship $fkey.Name -}}
     7  		{{- $arg := printf "maybe%s" $ltable.UpSingular -}}
     8  		{{- $col := $ltable.Column $fkey.Column -}}
     9  		{{- $fcol := $ftable.Column $fkey.ForeignColumn -}}
    10  		{{- $usesPrimitives := usesPrimitives $.Tables $fkey.Table $fkey.Column $fkey.ForeignTable $fkey.ForeignColumn -}}
    11  		{{- $canSoftDelete := (getTable $.Tables $fkey.ForeignTable).CanSoftDelete $.AutoColumns.Deleted }}
    12  // Load{{$rel.Foreign}} allows an eager lookup of values, cached into the
    13  // loaded structs of the objects. This is for an N-1 relationship.
    14  func ({{$ltable.DownSingular}}L) Load{{$rel.Foreign}}({{if $.NoContext}}e boil.Executor{{else}}ctx context.Context, e boil.ContextExecutor{{end}}, singular bool, {{$arg}} interface{}, mods queries.Applicator) error {
    15  	var slice []*{{$ltable.UpSingular}}
    16  	var object *{{$ltable.UpSingular}}
    17  
    18  	if singular {
    19  		var ok bool
    20  		object, ok = {{$arg}}.(*{{$ltable.UpSingular}})
    21  		if !ok {
    22  			object = new({{$ltable.UpSingular}})
    23  			ok = queries.SetFromEmbeddedStruct(&object, &{{$arg}})
    24  			if !ok {
    25  				return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", object, {{$arg}}))
    26  			}
    27  		}
    28  	} else {
    29  		s, ok := {{$arg}}.(*[]*{{$ltable.UpSingular}})
    30  		if ok {
    31  			slice = *s
    32  		} else {
    33  			ok = queries.SetFromEmbeddedStruct(&slice, {{$arg}})
    34  			if !ok {
    35  				return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", slice, {{$arg}}))
    36  			}
    37  		}
    38  	}
    39  
    40  	args := make([]interface{}, 0, 1)
    41  	if singular {
    42  		if object.R == nil {
    43  			object.R = &{{$ltable.DownSingular}}R{}
    44  		}
    45  		{{if $usesPrimitives -}}
    46  		args = append(args, object.{{$col}})
    47  		{{else -}}
    48  		if !queries.IsNil(object.{{$col}}) {
    49  			args = append(args, object.{{$col}})
    50  		}
    51  		{{end}}
    52  	} else {
    53  		Outer:
    54  		for _, obj := range slice {
    55  			if obj.R == nil {
    56  				obj.R = &{{$ltable.DownSingular}}R{}
    57  			}
    58  
    59  			for _, a := range args {
    60  				{{if $usesPrimitives -}}
    61  				if a == obj.{{$col}} {
    62  				{{else -}}
    63  				if queries.Equal(a, obj.{{$col}}) {
    64  				{{end -}}
    65  					continue Outer
    66  				}
    67  			}
    68  
    69  			{{if $usesPrimitives -}}
    70  			args = append(args, obj.{{$col}})
    71  			{{else -}}
    72  			if !queries.IsNil(obj.{{$col}}) {
    73  				args = append(args, obj.{{$col}})
    74  			}
    75  			{{end}}
    76  		}
    77  	}
    78  
    79  	if len(args) == 0 {
    80  		return nil
    81  	}
    82  
    83  	query := NewQuery(
    84  	    qm.From(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}`),
    85  	    qm.WhereIn(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}.{{.ForeignColumn}} in ?`, args...),
    86  	    {{if and $.AddSoftDeletes $canSoftDelete -}}
    87  	    qmhelper.WhereIsNull(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}.{{or $.AutoColumns.Deleted "deleted_at"}}`),
    88  	    {{- end}}
    89      )
    90  	if mods != nil {
    91  		mods.Apply(query)
    92  	}
    93  
    94  	{{if $.NoContext -}}
    95  	results, err := query.Query(e)
    96  	{{else -}}
    97  	results, err := query.QueryContext(ctx, e)
    98  	{{end -}}
    99  	if err != nil {
   100  		return errors.Wrap(err, "failed to eager load {{$ftable.UpSingular}}")
   101  	}
   102  
   103  	var resultSlice []*{{$ftable.UpSingular}}
   104  	if err = queries.Bind(results, &resultSlice); err != nil {
   105  		return errors.Wrap(err, "failed to bind eager loaded slice {{$ftable.UpSingular}}")
   106  	}
   107  
   108  	if err = results.Close(); err != nil {
   109  		return errors.Wrap(err, "failed to close results of eager load for {{.ForeignTable}}")
   110  	}
   111  	if err = results.Err(); err != nil {
   112  		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for {{.ForeignTable}}")
   113  	}
   114  
   115  	{{if not $.NoHooks -}}
   116  	if len({{$ftable.DownSingular}}AfterSelectHooks) != 0 {
   117  		for _, obj := range resultSlice {
   118  			if err := obj.doAfterSelectHooks({{if $.NoContext}}e{{else}}ctx, e{{end}}); err != nil {
   119  				return err
   120  			}
   121  		}
   122  	}
   123  	{{- end}}
   124  
   125  	if len(resultSlice) == 0 {
   126  		return nil
   127  	}
   128  
   129  	if singular {
   130  		foreign := resultSlice[0]
   131  		object.R.{{$rel.Foreign}} = foreign
   132  		{{if not $.NoBackReferencing -}}
   133  		if foreign.R == nil {
   134  			foreign.R = &{{$ftable.DownSingular}}R{}
   135  		}
   136  			{{if $fkey.Unique -}}
   137  		foreign.R.{{$rel.Local}} = object
   138  			{{else -}}
   139  		foreign.R.{{$rel.Local}} = append(foreign.R.{{$rel.Local}}, object)
   140  			{{end -}}
   141  		{{end -}}
   142  		return nil
   143  	}
   144  
   145  	for _, local := range slice {
   146  		for _, foreign := range resultSlice {
   147  			{{if $usesPrimitives -}}
   148  			if local.{{$col}} == foreign.{{$fcol}} {
   149  			{{else -}}
   150  			if queries.Equal(local.{{$col}}, foreign.{{$fcol}}) {
   151  			{{end -}}
   152  				local.R.{{$rel.Foreign}} = foreign
   153  				{{if not $.NoBackReferencing -}}
   154  				if foreign.R == nil {
   155  					foreign.R = &{{$ftable.DownSingular}}R{}
   156  				}
   157  					{{if $fkey.Unique -}}
   158  				foreign.R.{{$rel.Local}} = local
   159  					{{else -}}
   160  				foreign.R.{{$rel.Local}} = append(foreign.R.{{$rel.Local}}, local)
   161  					{{end -}}
   162  				{{end -}}
   163  				break
   164  			}
   165  		}
   166  	}
   167  
   168  	return nil
   169  }
   170  {{end -}}{{/* range */}}
   171  {{end}}{{/* join table */}}