feat: support unique
This commit is contained in:
parent
3a8c250180
commit
c6511a0dc6
7
model.go
7
model.go
@ -13,3 +13,10 @@ type Model struct {
|
||||
UpdatedAt time.Time
|
||||
DeletedAt DeletedAt `gorm:"index"`
|
||||
}
|
||||
|
||||
type ModelSupportUnique struct {
|
||||
ID uint `gorm:"primarykey"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedFlag DeletedFlag `gorm:"type:BIGINT UNSIGNED NOT NULL DEFAULT 0" json:"deleted_flag"`
|
||||
}
|
||||
|
@ -51,6 +51,26 @@ func (schema *Schema) ParseIndexes() map[string]Index {
|
||||
}
|
||||
|
||||
idx.Fields = append(idx.Fields, index.Fields...)
|
||||
|
||||
// create combined index for unique
|
||||
if index.Class == "UNIQUE" {
|
||||
if df := schema.LookUpField("deleted_flag"); df != nil {
|
||||
var exists bool
|
||||
for _, f := range idx.Fields {
|
||||
if f.Field.Name == df.Name {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
idx.Fields = append(idx.Fields, IndexOption{
|
||||
Field: df,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(idx.Fields, func(i, j int) bool {
|
||||
return idx.Fields[i].priority < idx.Fields[j].priority
|
||||
})
|
||||
|
80
soft_delete_unique.go
Normal file
80
soft_delete_unique.go
Normal file
@ -0,0 +1,80 @@
|
||||
package gorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/schema"
|
||||
)
|
||||
|
||||
type DeletedFlag uint
|
||||
|
||||
// // Scan implements the Scanner interface.
|
||||
// func (n *DeletedFlag) Scan(value interface{}) error {
|
||||
// return (*sql.NullTime)(n).Scan(value)
|
||||
// }
|
||||
|
||||
// // Value implements the driver Valuer interface.
|
||||
// func (n DeletedFlag) Value() (driver.Value, error) {
|
||||
// if !n.Valid {
|
||||
// return nil, nil
|
||||
// }
|
||||
// return n.Time, nil
|
||||
// }
|
||||
|
||||
// func (n DeletedFlag) MarshalJSON() ([]byte, error) {
|
||||
// if n.Valid {
|
||||
// return json.Marshal(n.Time)
|
||||
// }
|
||||
// return json.Marshal(nil)
|
||||
// }
|
||||
|
||||
// func (n *DeletedFlag) UnmarshalJSON(b []byte) error {
|
||||
// if string(b) == "null" {
|
||||
// n.Valid = false
|
||||
// return nil
|
||||
// }
|
||||
// err := json.Unmarshal(b, &n.Time)
|
||||
// if err == nil {
|
||||
// n.Valid = true
|
||||
// }
|
||||
// return err
|
||||
// }
|
||||
|
||||
func (DeletedFlag) QueryClauses(f *schema.Field) []clause.Interface {
|
||||
return []clause.Interface{SoftDeleteQueryClause{Field: f}}
|
||||
}
|
||||
|
||||
func (DeletedFlag) DeleteClauses(f *schema.Field) []clause.Interface {
|
||||
return []clause.Interface{SoftDeleteUniqueDeleteClause{Field: f}}
|
||||
}
|
||||
|
||||
type SoftDeleteUniqueDeleteClause struct {
|
||||
Field *schema.Field
|
||||
}
|
||||
|
||||
func (sd SoftDeleteUniqueDeleteClause) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (sd SoftDeleteUniqueDeleteClause) Build(clause.Builder) {
|
||||
}
|
||||
|
||||
func (sd SoftDeleteUniqueDeleteClause) MergeClause(*clause.Clause) {
|
||||
}
|
||||
|
||||
func (sd SoftDeleteUniqueDeleteClause) ModifyStatement(stmt *Statement) {
|
||||
re := regexp.MustCompile(`UPDATE (.*) WHERE `)
|
||||
if sql := stmt.SQL.String(); sql != "" {
|
||||
setClause := re.FindStringSubmatch(sql)[1]
|
||||
if setClause == "" {
|
||||
return
|
||||
}
|
||||
|
||||
newSetClause := fmt.Sprintf("%s, %s = `%s`.`id`", setClause, sd.Field.DBName, stmt.Table)
|
||||
stmt.SQL.Reset()
|
||||
stmt.SQL.WriteString(strings.Replace(sql, setClause, newSetClause, 1))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user