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 */}}