Add RemoveForeignKey functionality.
Works for mssql, mysql, postgresql. Droping foreign keys for sqlite isn't supported without a work-around.
This commit is contained in:
		
							parent
							
								
									9acaa33324
								
							
						
					
					
						commit
						7b743bdd2b
					
				@ -29,6 +29,8 @@ type Dialect interface {
 | 
				
			|||||||
	HasForeignKey(tableName string, foreignKeyName string) bool
 | 
						HasForeignKey(tableName string, foreignKeyName string) bool
 | 
				
			||||||
	// RemoveIndex remove index
 | 
						// RemoveIndex remove index
 | 
				
			||||||
	RemoveIndex(tableName string, indexName string) error
 | 
						RemoveIndex(tableName string, indexName string) error
 | 
				
			||||||
 | 
						// RemoveForeignKey remove foreign key
 | 
				
			||||||
 | 
						RemoveForeignKey(tableName string, foreignKeyName string) error
 | 
				
			||||||
	// HasTable check has table or not
 | 
						// HasTable check has table or not
 | 
				
			||||||
	HasTable(tableName string) bool
 | 
						HasTable(tableName string) bool
 | 
				
			||||||
	// HasColumn check has column or not
 | 
						// HasColumn check has column or not
 | 
				
			||||||
 | 
				
			|||||||
@ -105,6 +105,11 @@ func (s commonDialect) HasForeignKey(tableName string, foreignKeyName string) bo
 | 
				
			|||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s commonDialect) RemoveForeignKey(tableName string, foreignKeyName string) error {
 | 
				
			||||||
 | 
						_, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v DROP CONSTRAINT %v", tableName, foreignKeyName))
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s commonDialect) HasTable(tableName string) bool {
 | 
					func (s commonDialect) HasTable(tableName string) bool {
 | 
				
			||||||
	var count int
 | 
						var count int
 | 
				
			||||||
	s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?", s.CurrentDatabase(), tableName).Scan(&count)
 | 
						s.db.QueryRow("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?", s.CurrentDatabase(), tableName).Scan(&count)
 | 
				
			||||||
 | 
				
			|||||||
@ -132,6 +132,11 @@ func (s mysql) HasForeignKey(tableName string, foreignKeyName string) bool {
 | 
				
			|||||||
	return count > 0
 | 
						return count > 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s mysql) RemoveForeignKey(tableName string, foreignKeyName string) error {
 | 
				
			||||||
 | 
						_, err := s.db.Exec(fmt.Sprintf("ALTER TABLE %v DROP FOREIGN KEY %v", s.Quote(tableName), foreignKeyName))
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s mysql) CurrentDatabase() (name string) {
 | 
					func (s mysql) CurrentDatabase() (name string) {
 | 
				
			||||||
	s.db.QueryRow("SELECT DATABASE()").Scan(&name)
 | 
						s.db.QueryRow("SELECT DATABASE()").Scan(&name)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								main.go
									
									
									
									
									
								
							@ -602,6 +602,14 @@ func (s *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate
 | 
				
			|||||||
	return scope.db
 | 
						return scope.db
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RemoveForeignKey Removes foreign key from the given scope, e.g:
 | 
				
			||||||
 | 
					//     db.Model(&User{}).RemoveForeignKey("user_city_id_city_id_foreign")
 | 
				
			||||||
 | 
					func (s *DB) RemoveForeignKey(keyName string) *DB {
 | 
				
			||||||
 | 
						scope := s.NewScope(s.Value)
 | 
				
			||||||
 | 
						scope.removeForeignKey(keyName)
 | 
				
			||||||
 | 
						return scope.db
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Association start `Association Mode` to handler relations things easir in that mode, refer: https://jinzhu.github.io/gorm/associations.html#association-mode
 | 
					// Association start `Association Mode` to handler relations things easir in that mode, refer: https://jinzhu.github.io/gorm/associations.html#association-mode
 | 
				
			||||||
func (s *DB) Association(column string) *Association {
 | 
					func (s *DB) Association(column string) *Association {
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
				
			|||||||
@ -191,6 +191,16 @@ type Comment struct {
 | 
				
			|||||||
	Post    Post
 | 
						Post    Post
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Class struct {
 | 
				
			||||||
 | 
						Id   int64
 | 
				
			||||||
 | 
						Year string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Student struct {
 | 
				
			||||||
 | 
						Id      int64
 | 
				
			||||||
 | 
						ClassID int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Scanner
 | 
					// Scanner
 | 
				
			||||||
type NullValue struct {
 | 
					type NullValue struct {
 | 
				
			||||||
	Id      int64
 | 
						Id      int64
 | 
				
			||||||
@ -254,7 +264,7 @@ func runMigration() {
 | 
				
			|||||||
		DB.Exec(fmt.Sprintf("drop table %v;", table))
 | 
							DB.Exec(fmt.Sprintf("drop table %v;", table))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	values := []interface{}{&Short{}, &ReallyLongThingThatReferencesShort{}, &ReallyLongTableNameToTestMySQLNameLengthLimit{}, &NotSoLongTableName{}, &Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}, &Animal{}, &User{}, &JoinTable{}, &Post{}, &Category{}, &Comment{}, &Cat{}, &Dog{}, &Hamster{}, &Toy{}, &ElementWithIgnoredField{}}
 | 
						values := []interface{}{&Short{}, &ReallyLongThingThatReferencesShort{}, &ReallyLongTableNameToTestMySQLNameLengthLimit{}, &NotSoLongTableName{}, &Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}, &Animal{}, &User{}, &JoinTable{}, &Post{}, &Category{}, &Comment{}, &Cat{}, &Dog{}, &Hamster{}, &Toy{}, &ElementWithIgnoredField{}, &Class{}, &Student{}}
 | 
				
			||||||
	for _, value := range values {
 | 
						for _, value := range values {
 | 
				
			||||||
		DB.DropTable(value)
 | 
							DB.DropTable(value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -332,6 +342,25 @@ func TestIndexes(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestForeignKeys(t *testing.T) {
 | 
				
			||||||
 | 
						if err := DB.Model(&Student{}).AddForeignKey("class_id", "classes (id)", "RESTRICT", "RESTRICT").Error; err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Got error while trying to create foreign key: %+v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scope := DB.NewScope(&Student{})
 | 
				
			||||||
 | 
						if !scope.Dialect().HasForeignKey(scope.TableName(), "student_class_id_class_id_foreign") {
 | 
				
			||||||
 | 
							t.Errorf("Student should have foreign key students_class_id_classes_id_foreign")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := DB.Model(&Student{}).RemoveForeignKey("students_class_id_classes_id_foreign").Error; err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Got error while trying to remove foreign key: %+v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if scope.Dialect().HasForeignKey(scope.TableName(), "student_class_id_class_id_foreign") {
 | 
				
			||||||
 | 
							t.Errorf("Student should no longer have foreign key students_class_id_classes_id_foreign")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type EmailWithIdx struct {
 | 
					type EmailWithIdx struct {
 | 
				
			||||||
	Id           int64
 | 
						Id           int64
 | 
				
			||||||
	UserId       int64
 | 
						UserId       int64
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								scope.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								scope.go
									
									
									
									
									
								
							@ -1168,6 +1168,14 @@ func (scope *Scope) removeIndex(indexName string) {
 | 
				
			|||||||
	scope.Dialect().RemoveIndex(scope.TableName(), indexName)
 | 
						scope.Dialect().RemoveIndex(scope.TableName(), indexName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (scope *Scope) removeForeignKey(keyName string) {
 | 
				
			||||||
 | 
						if !scope.Dialect().HasForeignKey(scope.TableName(), keyName) {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scope.Dialect().RemoveForeignKey(scope.TableName(), keyName)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (scope *Scope) autoMigrate() *Scope {
 | 
					func (scope *Scope) autoMigrate() *Scope {
 | 
				
			||||||
	tableName := scope.TableName()
 | 
						tableName := scope.TableName()
 | 
				
			||||||
	quotedTableName := scope.QuotedTableName()
 | 
						quotedTableName := scope.QuotedTableName()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user