package gorm import ( "fmt" "strings" ) type JoinTableHandler interface { Table(*DB, *Relationship) string Add(*DB, *Relationship, interface{}, interface{}) error Delete(*DB, *Relationship) error Scope(*DB, *Relationship) *DB } type defaultJoinTableHandler struct{} func (s *defaultJoinTableHandler) Table(db *DB, relationship *Relationship) string { return relationship.JoinTable } func (s *defaultJoinTableHandler) Add(db *DB, relationship *Relationship, foreignValue interface{}, associationValue interface{}) error { scope := db.NewScope("") quotedForeignDBName := scope.Quote(relationship.ForeignDBName) quotedAssociationDBName := scope.Quote(relationship.AssociationForeignDBName) table := s.Table(db, relationship) sql := fmt.Sprintf( "INSERT INTO %v (%v) SELECT ?,? %v WHERE NOT EXISTS (SELECT * FROM %v WHERE %v = ? AND %v = ?);", scope.Quote(table), strings.Join([]string{quotedForeignDBName, quotedAssociationDBName}, ","), scope.Dialect().SelectFromDummyTable(), scope.Quote(table), quotedForeignDBName, quotedAssociationDBName, ) return db.Exec(sql, foreignValue, associationValue, foreignValue, associationValue).Error } func (s *defaultJoinTableHandler) Delete(db *DB, relationship *Relationship) error { return db.Table(s.Table(db, relationship)).Delete("").Error } func (s *defaultJoinTableHandler) Scope(db *DB, relationship *Relationship) *DB { return db.Table(s.Table(db, relationship)) } var DefaultJoinTableHandler = &defaultJoinTableHandler{}