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