Define association API, add conds to when preloading

This commit is contained in:
Jinzhu 2020-05-14 20:54:50 +08:00
parent 92b812408c
commit f999240e10
2 changed files with 58 additions and 6 deletions

View File

@ -1,9 +1,61 @@
package gorm package gorm
import (
"fmt"
"github.com/jinzhu/gorm/schema"
)
// Association Mode contains some helper methods to handle relationship things easily. // Association Mode contains some helper methods to handle relationship things easily.
type Association struct { type Association struct {
DB *DB
Relationship *schema.Relationship
Error error
} }
func (db *DB) Association(column string) *Association { func (db *DB) Association(column string) *Association {
return nil association := &Association{DB: db}
if err := db.Statement.Parse(db.Statement.Model); err == nil {
association.Relationship = db.Statement.Schema.Relationships.Relations[column]
if association.Relationship == nil {
association.Error = fmt.Errorf("%w: %v", ErrUnsupportedRelation, column)
}
} else {
association.Error = err
}
return association
}
func (association *Association) Find(out interface{}, conds ...interface{}) error {
if association.Error == nil {
for _, ref := range association.Relationship.References {
if ref.OwnPrimaryKey {
}
}
}
return association.Error
}
func (association *Association) Append(values ...interface{}) error {
return association.Error
}
func (association *Association) Replace(values ...interface{}) error {
return association.Error
}
func (association *Association) Delete(values ...interface{}) error {
return association.Error
}
func (association *Association) Clear() error {
return association.Error
}
func (association *Association) Count() int {
return 0
} }

View File

@ -84,7 +84,7 @@ func getIdentityFieldValuesMap(reflectValue reflect.Value, fields []*schema.Fiel
return dataResults, results return dataResults, results
} }
func preloadData(tx *gorm.DB, resultSchema *schema.Schema, foreignKeys []string, foreignValues [][]interface{}) reflect.Value { func preloadData(tx *gorm.DB, resultSchema *schema.Schema, foreignKeys []string, foreignValues [][]interface{}, conds []interface{}) reflect.Value {
slice := reflect.MakeSlice(reflect.SliceOf(resultSchema.ModelType), 0, 0) slice := reflect.MakeSlice(reflect.SliceOf(resultSchema.ModelType), 0, 0)
results := reflect.New(slice.Type()) results := reflect.New(slice.Type())
results.Elem().Set(slice) results.Elem().Set(slice)
@ -94,12 +94,12 @@ func preloadData(tx *gorm.DB, resultSchema *schema.Schema, foreignKeys []string,
for idx, r := range foreignValues { for idx, r := range foreignValues {
queryValues[idx] = r[0] queryValues[idx] = r[0]
} }
tx.Where(clause.IN{Column: foreignKeys[0], Values: queryValues}).Find(results.Interface()) tx.Where(clause.IN{Column: foreignKeys[0], Values: queryValues}).Find(results.Interface(), conds...)
} else { } else {
for idx, r := range foreignValues { for idx, r := range foreignValues {
queryValues[idx] = r queryValues[idx] = r
} }
tx.Where(clause.IN{Column: foreignKeys, Values: queryValues}).Find(results.Interface()) tx.Where(clause.IN{Column: foreignKeys, Values: queryValues}).Find(results.Interface(), conds...)
} }
return results.Elem() return results.Elem()
@ -139,7 +139,7 @@ func preload(db *gorm.DB, rels []*schema.Relationship, conds []interface{}) {
} }
joinIdentityMap, joinForeignValues := getIdentityFieldValuesMap(reflectValue, joinForeignFields) joinIdentityMap, joinForeignValues := getIdentityFieldValuesMap(reflectValue, joinForeignFields)
joinResults := preloadData(tx, rel.JoinTable, joinForeignKeys, joinForeignValues) joinResults := preloadData(tx, rel.JoinTable, joinForeignKeys, joinForeignValues, nil)
// convert join identity map to relation identity map // convert join identity map to relation identity map
fieldValues := make([]reflect.Value, len(foreignFields)) fieldValues := make([]reflect.Value, len(foreignFields))
@ -177,7 +177,7 @@ func preload(db *gorm.DB, rels []*schema.Relationship, conds []interface{}) {
identityMap, foreignValues = getIdentityFieldValuesMap(reflectValue, foreignFields) identityMap, foreignValues = getIdentityFieldValuesMap(reflectValue, foreignFields)
} }
reflectResults := preloadData(tx, rel.FieldSchema, relForeignKeys, foreignValues) reflectResults := preloadData(tx, rel.FieldSchema, relForeignKeys, foreignValues, conds)
fieldValues := make([]reflect.Value, len(foreignFields)) fieldValues := make([]reflect.Value, len(foreignFields))
for i := 0; i < reflectResults.Len(); i++ { for i := 0; i < reflectResults.Len(); i++ {