(tx *gorm.DB, rel *schema.Relationship, conds []interface{}, preloads map[string][]interface{})
| 183 | } |
| 184 | |
| 185 | func preload(tx *gorm.DB, rel *schema.Relationship, conds []interface{}, preloads map[string][]interface{}) error { |
| 186 | var ( |
| 187 | reflectValue = tx.Statement.ReflectValue |
| 188 | relForeignKeys []string |
| 189 | relForeignFields []*schema.Field |
| 190 | foreignFields []*schema.Field |
| 191 | foreignValues [][]interface{} |
| 192 | identityMap = map[string][]reflect.Value{} |
| 193 | inlineConds []interface{} |
| 194 | ) |
| 195 | |
| 196 | if rel.JoinTable != nil { |
| 197 | var ( |
| 198 | joinForeignFields = make([]*schema.Field, 0, len(rel.References)) |
| 199 | joinRelForeignFields = make([]*schema.Field, 0, len(rel.References)) |
| 200 | joinForeignKeys = make([]string, 0, len(rel.References)) |
| 201 | ) |
| 202 | |
| 203 | for _, ref := range rel.References { |
| 204 | if ref.OwnPrimaryKey { |
| 205 | joinForeignKeys = append(joinForeignKeys, ref.ForeignKey.DBName) |
| 206 | joinForeignFields = append(joinForeignFields, ref.ForeignKey) |
| 207 | foreignFields = append(foreignFields, ref.PrimaryKey) |
| 208 | } else if ref.PrimaryValue != "" { |
| 209 | tx = tx.Where(clause.Eq{Column: ref.ForeignKey.DBName, Value: ref.PrimaryValue}) |
| 210 | } else { |
| 211 | joinRelForeignFields = append(joinRelForeignFields, ref.ForeignKey) |
| 212 | relForeignKeys = append(relForeignKeys, ref.PrimaryKey.DBName) |
| 213 | relForeignFields = append(relForeignFields, ref.PrimaryKey) |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | joinIdentityMap, joinForeignValues := schema.GetIdentityFieldValuesMap(tx.Statement.Context, reflectValue, foreignFields) |
| 218 | if len(joinForeignValues) == 0 { |
| 219 | return nil |
| 220 | } |
| 221 | |
| 222 | joinResults := rel.JoinTable.MakeSlice().Elem() |
| 223 | column, values := schema.ToQueryValues(clause.CurrentTable, joinForeignKeys, joinForeignValues) |
| 224 | if err := tx.Where(clause.IN{Column: column, Values: values}).Find(joinResults.Addr().Interface()).Error; err != nil { |
| 225 | return err |
| 226 | } |
| 227 | |
| 228 | // convert join identity map to relation identity map |
| 229 | fieldValues := make([]interface{}, len(joinForeignFields)) |
| 230 | joinFieldValues := make([]interface{}, len(joinRelForeignFields)) |
| 231 | for i := 0; i < joinResults.Len(); i++ { |
| 232 | joinIndexValue := joinResults.Index(i) |
| 233 | for idx, field := range joinForeignFields { |
| 234 | fieldValues[idx], _ = field.ValueOf(tx.Statement.Context, joinIndexValue) |
| 235 | } |
| 236 | |
| 237 | for idx, field := range joinRelForeignFields { |
| 238 | joinFieldValues[idx], _ = field.ValueOf(tx.Statement.Context, joinIndexValue) |
| 239 | } |
| 240 | |
| 241 | if results, ok := joinIdentityMap[utils.ToStringKey(fieldValues...)]; ok { |
| 242 | joinKey := utils.ToStringKey(joinFieldValues...) |
no test coverage detected