package identity import ( "github.com/rs/xid" "gorm.io/gorm" "gorm.io/gorm/schema" "reflect" ) 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 } if field = db.Statement.Schema.LookUpField("ID"); field == nil { return } if 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("ID", identity.NextID()) } } } func New() *Identify { return &Identify{} }