Avoid generating FK key names which are too long for some DBMS to handle.

Additionally, simplify the key name generation by removing a now-uneeded regexp.

Signed-off-by: Stephan Peijnik <speijnik@anexia-it.com>
This commit is contained in:
Stephan Peijnik 2016-02-03 11:32:45 +01:00
parent c7b9acefb7
commit 1200158cbc

View File

@ -1,6 +1,7 @@
package gorm package gorm
import ( import (
"crypto/md5"
"database/sql" "database/sql"
"database/sql/driver" "database/sql/driver"
"fmt" "fmt"
@ -613,8 +614,11 @@ func (scope *Scope) addIndex(unique bool, indexName string, column ...string) {
} }
func (scope *Scope) addForeignKey(field string, dest string, onDelete string, onUpdate string) { func (scope *Scope) addForeignKey(field string, dest string, onDelete string, onUpdate string) {
var keyName = fmt.Sprintf("%s_%s_%s_foreign", scope.TableName(), field, dest) // Generate a FK key suffix. This is done by using the hex-encoded MD5 sum of field_dest.
keyName = regexp.MustCompile("(_*[^a-zA-Z]+_*|_+)").ReplaceAllString(keyName, "_") // MD5 should be sufficient here, as this is not security relevant and allows avoiding constraint names
// which are too long for some DBMS to handle or contain invalid characters.
var keySuffix = strings.ToLower(fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%s_%s", field, dest)))))
var keyName = fmt.Sprintf("%s_%s_foreign", scope.TableName(), keySuffix)
var query = `ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s ON DELETE %s ON UPDATE %s;` var query = `ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s ON DELETE %s ON UPDATE %s;`
scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.QuoteIfPossible(keyName), scope.QuoteIfPossible(field), dest, onDelete, onUpdate)).Exec() scope.Raw(fmt.Sprintf(query, scope.QuotedTableName(), scope.QuoteIfPossible(keyName), scope.QuoteIfPossible(field), dest, onDelete, onUpdate)).Exec()
} }