fix(server): sql server not allow multiple null
multiple null values for unique constrained column is not allowed on sqlserver Resolves #278
This commit is contained in:
parent
8449821d1b
commit
7fc69dcc55
|
@ -1,6 +1,7 @@
|
||||||
package sql
|
package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -21,6 +22,16 @@ type provider struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
phoneNumberIndexName = "UQ_phone_number"
|
||||||
|
phoneNumberColumnName = "phone_number"
|
||||||
|
)
|
||||||
|
|
||||||
|
type indexInfo struct {
|
||||||
|
IndexName string `json:"index_name"`
|
||||||
|
ColumnName string `json:"column_name"`
|
||||||
|
}
|
||||||
|
|
||||||
// NewProvider returns a new SQL provider
|
// NewProvider returns a new SQL provider
|
||||||
func NewProvider() (*provider, error) {
|
func NewProvider() (*provider, error) {
|
||||||
var sqlDB *gorm.DB
|
var sqlDB *gorm.DB
|
||||||
|
@ -65,6 +76,32 @@ func NewProvider() (*provider, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unique constraint on phone number does not work with multiple null values for sqlserver
|
||||||
|
// for more information check https://stackoverflow.com/a/767702
|
||||||
|
if dbType == constants.DbTypeSqlserver {
|
||||||
|
var indexInfos []indexInfo
|
||||||
|
// remove index on phone number if present with different name
|
||||||
|
res := sqlDB.Raw("SELECT i.name AS index_name, i.type_desc AS index_algorithm, CASE i.is_unique WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_unique, ac.Name AS column_name FROM sys.tables AS t INNER JOIN sys.indexes AS i ON t.object_id = i.object_id INNER JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id INNER JOIN sys.all_columns AS ac ON ic.object_id = ac.object_id AND ic.column_id = ac.column_id WHERE t.name = 'authorizer_users' AND SCHEMA_NAME(t.schema_id) = 'dbo';").Scan(&indexInfos)
|
||||||
|
if res.Error != nil {
|
||||||
|
return nil, res.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, val := range indexInfos {
|
||||||
|
if val.ColumnName == phoneNumberColumnName && val.IndexName != phoneNumberIndexName {
|
||||||
|
// drop index & create new
|
||||||
|
if res := sqlDB.Exec(fmt.Sprintf(`ALTER TABLE authorizer_users DROP CONSTRAINT "%s";`, val.IndexName)); res.Error != nil {
|
||||||
|
return nil, res.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// create index
|
||||||
|
if res := sqlDB.Exec(fmt.Sprintf("CREATE UNIQUE NONCLUSTERED INDEX %s ON authorizer_users(phone_number) WHERE phone_number IS NOT NULL;", phoneNumberIndexName)); res.Error != nil {
|
||||||
|
return nil, res.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &provider{
|
return &provider{
|
||||||
db: sqlDB,
|
db: sqlDB,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user