Init V4 community edition (#2265)
* Init V4 community edition * Init V4 community edition
This commit is contained in:
132
ent/schema/common.go
Normal file
132
ent/schema/common.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/mixin"
|
||||
gen "github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/hook"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/intercept"
|
||||
)
|
||||
|
||||
// CommonMixin implements the soft delete pattern for schemas and common audit features.
|
||||
type CommonMixin struct {
|
||||
mixin.Schema
|
||||
}
|
||||
|
||||
// Fields of the CommonMixin.
|
||||
func (CommonMixin) Fields() []ent.Field {
|
||||
return commonFields()
|
||||
}
|
||||
|
||||
type softDeleteKey struct{}
|
||||
|
||||
// SkipSoftDelete returns a new context that skips the soft-delete interceptor/mutators.
|
||||
func SkipSoftDelete(parent context.Context) context.Context {
|
||||
return context.WithValue(parent, softDeleteKey{}, true)
|
||||
}
|
||||
|
||||
// Interceptors of the CommonMixin.
|
||||
func (d CommonMixin) Interceptors() []ent.Interceptor {
|
||||
return softDeleteInterceptors(d)
|
||||
}
|
||||
|
||||
// Hooks of the CommonMixin.
|
||||
func (d CommonMixin) Hooks() []ent.Hook {
|
||||
return commonHooks(d)
|
||||
}
|
||||
|
||||
// P adds a storage-level predicate to the queries and mutations.
|
||||
func (d CommonMixin) P(w interface{ WhereP(...func(*sql.Selector)) }) {
|
||||
p(d, w)
|
||||
}
|
||||
|
||||
// Indexes of the CommonMixin.
|
||||
func (CommonMixin) Indexes() []ent.Index {
|
||||
return []ent.Index{}
|
||||
}
|
||||
|
||||
func softDeleteInterceptors(d interface {
|
||||
P(w interface {
|
||||
WhereP(...func(*sql.Selector))
|
||||
})
|
||||
}) []ent.Interceptor {
|
||||
return []ent.Interceptor{
|
||||
intercept.TraverseFunc(func(ctx context.Context, q intercept.Query) error {
|
||||
// Skip soft-delete, means include soft-deleted entities.
|
||||
if skip, _ := ctx.Value(softDeleteKey{}).(bool); skip {
|
||||
return nil
|
||||
}
|
||||
d.P(q)
|
||||
return nil
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func p(d interface{ Fields() []ent.Field }, w interface{ WhereP(...func(*sql.Selector)) }) {
|
||||
w.WhereP(
|
||||
sql.FieldIsNull(d.Fields()[2].Descriptor().Name),
|
||||
)
|
||||
}
|
||||
|
||||
func commonFields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.Time("created_at").
|
||||
Immutable().
|
||||
Default(time.Now).
|
||||
SchemaType(map[string]string{
|
||||
dialect.MySQL: "datetime",
|
||||
}),
|
||||
field.Time("updated_at").
|
||||
Default(time.Now).
|
||||
UpdateDefault(time.Now).
|
||||
SchemaType(map[string]string{
|
||||
dialect.MySQL: "datetime",
|
||||
}),
|
||||
field.Time("deleted_at").
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{
|
||||
dialect.MySQL: "datetime",
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
func commonHooks(d interface {
|
||||
P(w interface {
|
||||
WhereP(...func(*sql.Selector))
|
||||
})
|
||||
}) []ent.Hook {
|
||||
return []ent.Hook{
|
||||
hook.On(
|
||||
func(next ent.Mutator) ent.Mutator {
|
||||
return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
// Skip soft-delete, means delete the entity permanently.
|
||||
if skip, _ := ctx.Value(softDeleteKey{}).(bool); skip {
|
||||
return next.Mutate(ctx, m)
|
||||
}
|
||||
mx, ok := m.(interface {
|
||||
SetOp(ent.Op)
|
||||
Client() *gen.Client
|
||||
SetDeletedAt(time.Time)
|
||||
WhereP(...func(*sql.Selector))
|
||||
})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type in soft-delete %T", m)
|
||||
}
|
||||
d.P(mx)
|
||||
mx.SetOp(ent.OpUpdate)
|
||||
mx.SetDeletedAt(time.Now())
|
||||
return mx.Client().Mutate(ctx, m)
|
||||
})
|
||||
},
|
||||
ent.OpDeleteOne|ent.OpDelete,
|
||||
),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user