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

     1  {{- if or .Table.IsJoinTable .Table.IsView -}}
     2  {{- else -}}
     3  	{{- range $rel := .Table.ToManyRelationships -}}
     4  		{{- $ltable := $.Aliases.Table $rel.Table -}}
     5  		{{- $ftable := $.Aliases.Table $rel.ForeignTable -}}
     6  		{{- $relAlias := $.Aliases.ManyRelationship $rel.ForeignTable $rel.Name $rel.JoinTable $rel.JoinLocalFKeyName -}}
     7  		{{- $col := $ltable.Column $rel.Column -}}
     8  		{{- $fcol := $ftable.Column $rel.ForeignColumn -}}
     9  		{{- $usesPrimitives := usesPrimitives $.Tables $rel.Table $rel.Column $rel.ForeignTable $rel.ForeignColumn -}}
    10  		{{- $arg := printf "maybe%s" $ltable.UpSingular -}}
    11  		{{- $schemaForeignTable := $rel.ForeignTable | $.SchemaTable -}}
    12  		{{- $canSoftDelete := (getTable $.Tables $rel.ForeignTable).CanSoftDelete $.AutoColumns.Deleted }}
    13  // Load{{$relAlias.Local}} allows an eager lookup of values, cached into the
    14  // loaded structs of the objects. This is for a 1-M or N-M relationship.
    15  func ({{$ltable.DownSingular}}L) Load{{$relAlias.Local}}({{if $.NoContext}}e boil.Executor{{else}}ctx context.Context, e boil.ContextExecutor{{end}}, singular bool, {{$arg}} interface{}, mods queries.Applicator) error {
    16  	var slice []*{{$ltable.UpSingular}}
    17  	var object *{{$ltable.UpSingular}}
    18  
    19  	if singular {
    20  		var ok bool
    21  		object, ok = {{$arg}}.(*{{$ltable.UpSingular}})
    22  		if !ok {
    23  			object = new({{$ltable.UpSingular}})
    24  			ok = queries.SetFromEmbeddedStruct(&object, &{{$arg}})
    25  			if !ok {
    26  				return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", object, {{$arg}}))
    27  			}
    28  		}
    29  	} else {
    30  		s, ok := {{$arg}}.(*[]*{{$ltable.UpSingular}})
    31  		if ok {
    32  			slice = *s
    33  		} else {
    34  			ok = queries.SetFromEmbeddedStruct(&slice, {{$arg}})
    35  			if !ok {
    36  				return errors.New(fmt.Sprintf("failed to set %T from embedded struct %T", slice, {{$arg}}))
    37  			}
    38  		}
    39  	}
    40  
    41  	args := make([]interface{}, 0, 1)
    42  	if singular {
    43  		if object.R == nil {
    44  			object.R = &{{$ltable.DownSingular}}R{}
    45  		}
    46  		args = append(args, object.{{$col}})
    47  	} else {
    48  		Outer:
    49  		for _, obj := range slice {
    50  			if obj.R == nil {
    51  				obj.R = &{{$ltable.DownSingular}}R{}
    52  			}
    53  
    54  			for _, a := range args {
    55  				{{if $usesPrimitives -}}
    56  				if a == obj.{{$col}} {
    57  				{{else -}}
    58  				if queries.Equal(a, obj.{{$col}}) {
    59  				{{end -}}
    60  					continue Outer
    61  				}
    62  			}
    63  
    64  			args = append(args, obj.{{$col}})
    65  		}
    66  	}
    67  
    68  	if len(args) == 0 {
    69  		return nil
    70  	}
    71  
    72  		{{if .ToJoinTable -}}
    73  			{{- $schemaJoinTable := .JoinTable | $.SchemaTable -}}
    74  			{{- $foreignTable := getTable $.Tables .ForeignTable -}}
    75  	query := NewQuery(
    76  		qm.Select("{{$foreignTable.Columns | columnNames | $.QuoteMap | prefixStringSlice (print $schemaForeignTable ".") | join ", "}}, {{id 0 | $.Quotes}}.{{.JoinLocalColumn | $.Quotes}}"),
    77  		qm.From("{{$schemaForeignTable}}"),
    78  		qm.InnerJoin("{{$schemaJoinTable}} as {{id 0 | $.Quotes}} on {{$schemaForeignTable}}.{{.ForeignColumn | $.Quotes}} = {{id 0 | $.Quotes}}.{{.JoinForeignColumn | $.Quotes}}"),
    79  		qm.WhereIn("{{id 0 | $.Quotes}}.{{.JoinLocalColumn | $.Quotes}} in ?", args...),
    80  		{{if and $.AddSoftDeletes $canSoftDelete -}}
    81  		qmhelper.WhereIsNull("{{$schemaForeignTable}}.{{or $.AutoColumns.Deleted "deleted_at" | $.Quotes}}"),
    82  		{{- end}}
    83  	)
    84  		{{else -}}
    85  	query := NewQuery(
    86  	    qm.From(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}`),
    87  	    qm.WhereIn(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}.{{.ForeignColumn}} in ?`, args...),
    88  	    {{if and $.AddSoftDeletes $canSoftDelete -}}
    89  	    qmhelper.WhereIsNull(`{{if $.Dialect.UseSchema}}{{$.Schema}}.{{end}}{{.ForeignTable}}.{{or $.AutoColumns.Deleted "deleted_at"}}`),
    90  	    {{- end}}
    91      )
    92  		{{end -}}
    93  	if mods != nil {
    94  		mods.Apply(query)
    95  	}
    96  
    97  	{{if $.NoContext -}}
    98  	results, err := query.Query(e)
    99  	{{else -}}
   100  	results, err := query.QueryContext(ctx, e)
   101  	{{end -}}
   102  	if err != nil {
   103  		return errors.Wrap(err, "failed to eager load {{.ForeignTable}}")
   104  	}
   105  
   106  	var resultSlice []*{{$ftable.UpSingular}}
   107  	{{if .ToJoinTable -}}
   108  	{{- $foreignTable := getTable $.Tables .ForeignTable -}}
   109  	{{- $joinTable := getTable $.Tables .JoinTable -}}
   110  	{{- $localCol := $joinTable.GetColumn .JoinLocalColumn}}
   111  	var localJoinCols []{{$localCol.Type}}
   112  	for results.Next() {
   113  		one := new({{$ftable.UpSingular}})
   114  		var localJoinCol {{$localCol.Type}}
   115  
   116  		err = results.Scan({{$foreignTable.Columns | columnNames | stringMap (aliasCols $ftable) | prefixStringSlice "&one." | join ", "}}, &localJoinCol)
   117  		if err != nil {
   118  			return errors.Wrap(err, "failed to scan eager loaded results for {{.ForeignTable}}")
   119  		}
   120  		if err = results.Err(); err != nil {
   121  			return errors.Wrap(err, "failed to plebian-bind eager loaded slice {{.ForeignTable}}")
   122  		}
   123  
   124  		resultSlice = append(resultSlice, one)
   125  		localJoinCols = append(localJoinCols, localJoinCol)
   126  	}
   127  	{{- else -}}
   128  	if err = queries.Bind(results, &resultSlice); err != nil {
   129  		return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable}}")
   130  	}
   131  	{{- end}}
   132  
   133  	if err = results.Close(); err != nil {
   134  		return errors.Wrap(err, "failed to close results in eager load on {{.ForeignTable}}")
   135  	}
   136  	if err = results.Err(); err != nil {
   137  		return errors.Wrap(err, "error occurred during iteration of eager loaded relations for {{.ForeignTable}}")
   138  	}
   139  
   140  	{{if not $.NoHooks -}}
   141  	if len({{$ftable.DownSingular}}AfterSelectHooks) != 0 {
   142  		for _, obj := range resultSlice {
   143  			if err := obj.doAfterSelectHooks({{if $.NoContext}}e{{else}}ctx, e{{end -}}); err != nil {
   144  				return err
   145  			}
   146  		}
   147  	}
   148  
   149  	{{- end}}
   150  	if singular {
   151  		object.R.{{$relAlias.Local}} = resultSlice
   152  		{{if not $.NoBackReferencing -}}
   153  		for _, foreign := range resultSlice {
   154  			if foreign.R == nil {
   155  				foreign.R = &{{$ftable.DownSingular}}R{}
   156  			}
   157  			{{if .ToJoinTable -}}
   158  			foreign.R.{{$relAlias.Foreign}} = append(foreign.R.{{$relAlias.Foreign}}, object)
   159  			{{else -}}
   160  			foreign.R.{{$relAlias.Foreign}} = object
   161  			{{end -}}
   162  		}
   163  		{{end -}}
   164  		return nil
   165  	}
   166  
   167  	{{if .ToJoinTable -}}
   168  	for i, foreign := range resultSlice {
   169  		localJoinCol := localJoinCols[i]
   170  		for _, local := range slice {
   171  			{{if $usesPrimitives -}}
   172  			if local.{{$col}} == localJoinCol {
   173  			{{else -}}
   174  			if queries.Equal(local.{{$col}}, localJoinCol) {
   175  			{{end -}}
   176  				local.R.{{$relAlias.Local}} = append(local.R.{{$relAlias.Local}}, foreign)
   177  				{{if not $.NoBackReferencing -}}
   178  				if foreign.R == nil {
   179  					foreign.R = &{{$ftable.DownSingular}}R{}
   180  				}
   181  				foreign.R.{{$relAlias.Foreign}} = append(foreign.R.{{$relAlias.Foreign}}, local)
   182  				{{end -}}
   183  				break
   184  			}
   185  		}
   186  	}
   187  	{{else -}}
   188  	for _, foreign := range resultSlice {
   189  		for _, local := range slice {
   190  			{{if $usesPrimitives -}}
   191  			if local.{{$col}} == foreign.{{$fcol}} {
   192  			{{else -}}
   193  			if queries.Equal(local.{{$col}}, foreign.{{$fcol}}) {
   194  			{{end -}}
   195  				local.R.{{$relAlias.Local}} = append(local.R.{{$relAlias.Local}}, foreign)
   196  				{{if not $.NoBackReferencing -}}
   197  				if foreign.R == nil {
   198  					foreign.R = &{{$ftable.DownSingular}}R{}
   199  				}
   200  				foreign.R.{{$relAlias.Foreign}} = local
   201  				{{end -}}
   202  				break
   203  			}
   204  		}
   205  	}
   206  	{{end}}
   207  
   208  	return nil
   209  }
   210  
   211  {{end -}}{{/* range tomany */}}
   212  {{- end -}}{{/* if IsJoinTable */}}