rest/plugins/identity/identified.go

62 lines
1.4 KiB
Go

package identity
import (
"reflect"
"github.com/rs/xid"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type Identify struct {
}
func (identity *Identify) Name() string {
return "gorm:identity"
}
func (identity *Identify) Initialize(db *gorm.DB) (err error) {
err = db.Callback().Create().Before("gorm:create").Register("rest_auto_identified", identity.Grant)
return
}
func (identity *Identify) NextID() string {
return xid.New().String()
}
func (identity *Identify) Grant(db *gorm.DB) {
var (
err error
field *schema.Field
)
if db.Statement.Schema == nil {
return
}
for _, column := range db.Statement.Schema.Fields {
if column.PrimaryKey {
field = column
break
}
}
if field == nil || field.DataType != schema.String {
return
}
if db.Statement.ReflectValue.Kind() == reflect.Array || db.Statement.ReflectValue.Kind() == reflect.Slice {
for i := 0; i < db.Statement.ReflectValue.Len(); i++ {
if _, zero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue.Index(i)); zero {
if err = field.Set(db.Statement.Context, db.Statement.ReflectValue.Index(i), identity.NextID()); err != nil {
_ = db.AddError(err)
}
}
}
} else {
if _, zero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue); zero {
db.Statement.SetColumn(field.Name, identity.NextID())
}
}
}
func New() *Identify {
return &Identify{}
}