refactor(数据库): 迁移持久层到 Ent 并清理 GORM
将仓储层/基础设施改为 Ent + 原生 SQL 执行路径,并移除 AutoMigrate 与 GORM 依赖。 重构内容包括: - 仓储层改用 Ent/SQL(含 usage_log/account 等复杂查询),统一错误映射 - 基础设施与 setup 初始化切换为 Ent + SQL migrations - 集成测试与 fixtures 迁移到 Ent 事务模型 - 清理遗留 GORM 模型/依赖,补充迁移与文档说明 - 增加根目录 Makefile 便于前后端编译 测试: - go test -tags unit ./... - go test -tags integration ./...
This commit is contained in:
419
backend/ent/intercept/intercept.go
Normal file
419
backend/ent/intercept/intercept.go
Normal file
@@ -0,0 +1,419 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package intercept
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/Wei-Shaw/sub2api/ent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/account"
|
||||
"github.com/Wei-Shaw/sub2api/ent/accountgroup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/apikey"
|
||||
"github.com/Wei-Shaw/sub2api/ent/group"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
"github.com/Wei-Shaw/sub2api/ent/proxy"
|
||||
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
|
||||
"github.com/Wei-Shaw/sub2api/ent/setting"
|
||||
"github.com/Wei-Shaw/sub2api/ent/user"
|
||||
"github.com/Wei-Shaw/sub2api/ent/userallowedgroup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/usersubscription"
|
||||
)
|
||||
|
||||
// The Query interface represents an operation that queries a graph.
|
||||
// By using this interface, users can write generic code that manipulates
|
||||
// query builders of different types.
|
||||
type Query interface {
|
||||
// Type returns the string representation of the query type.
|
||||
Type() string
|
||||
// Limit the number of records to be returned by this query.
|
||||
Limit(int)
|
||||
// Offset to start from.
|
||||
Offset(int)
|
||||
// Unique configures the query builder to filter duplicate records.
|
||||
Unique(bool)
|
||||
// Order specifies how the records should be ordered.
|
||||
Order(...func(*sql.Selector))
|
||||
// WhereP appends storage-level predicates to the query builder. Using this method, users
|
||||
// can use type-assertion to append predicates that do not depend on any generated package.
|
||||
WhereP(...func(*sql.Selector))
|
||||
}
|
||||
|
||||
// The Func type is an adapter that allows ordinary functions to be used as interceptors.
|
||||
// Unlike traversal functions, interceptors are skipped during graph traversals. Note that the
|
||||
// implementation of Func is different from the one defined in entgo.io/ent.InterceptFunc.
|
||||
type Func func(context.Context, Query) error
|
||||
|
||||
// Intercept calls f(ctx, q) and then applied the next Querier.
|
||||
func (f Func) Intercept(next ent.Querier) ent.Querier {
|
||||
return ent.QuerierFunc(func(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
query, err := NewQuery(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := f(ctx, query); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return next.Query(ctx, q)
|
||||
})
|
||||
}
|
||||
|
||||
// The TraverseFunc type is an adapter to allow the use of ordinary function as Traverser.
|
||||
// If f is a function with the appropriate signature, TraverseFunc(f) is a Traverser that calls f.
|
||||
type TraverseFunc func(context.Context, Query) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseFunc) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseFunc) Traverse(ctx context.Context, q ent.Query) error {
|
||||
query, err := NewQuery(q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f(ctx, query)
|
||||
}
|
||||
|
||||
// The AccountFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type AccountFunc func(context.Context, *ent.AccountQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f AccountFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.AccountQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.AccountQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseAccount type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseAccount func(context.Context, *ent.AccountQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseAccount) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseAccount) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.AccountQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.AccountQuery", q)
|
||||
}
|
||||
|
||||
// The AccountGroupFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type AccountGroupFunc func(context.Context, *ent.AccountGroupQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f AccountGroupFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.AccountGroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.AccountGroupQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseAccountGroup type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseAccountGroup func(context.Context, *ent.AccountGroupQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseAccountGroup) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseAccountGroup) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.AccountGroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.AccountGroupQuery", q)
|
||||
}
|
||||
|
||||
// The ApiKeyFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type ApiKeyFunc func(context.Context, *ent.ApiKeyQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f ApiKeyFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.ApiKeyQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.ApiKeyQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseApiKey type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseApiKey func(context.Context, *ent.ApiKeyQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseApiKey) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseApiKey) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.ApiKeyQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.ApiKeyQuery", q)
|
||||
}
|
||||
|
||||
// The GroupFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type GroupFunc func(context.Context, *ent.GroupQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f GroupFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.GroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.GroupQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseGroup type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseGroup func(context.Context, *ent.GroupQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseGroup) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseGroup) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.GroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.GroupQuery", q)
|
||||
}
|
||||
|
||||
// The ProxyFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type ProxyFunc func(context.Context, *ent.ProxyQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f ProxyFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.ProxyQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.ProxyQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseProxy type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseProxy func(context.Context, *ent.ProxyQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseProxy) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseProxy) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.ProxyQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.ProxyQuery", q)
|
||||
}
|
||||
|
||||
// The RedeemCodeFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type RedeemCodeFunc func(context.Context, *ent.RedeemCodeQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f RedeemCodeFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.RedeemCodeQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.RedeemCodeQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseRedeemCode type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseRedeemCode func(context.Context, *ent.RedeemCodeQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseRedeemCode) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseRedeemCode) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.RedeemCodeQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.RedeemCodeQuery", q)
|
||||
}
|
||||
|
||||
// The SettingFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type SettingFunc func(context.Context, *ent.SettingQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f SettingFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.SettingQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.SettingQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseSetting type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseSetting func(context.Context, *ent.SettingQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseSetting) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseSetting) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.SettingQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.SettingQuery", q)
|
||||
}
|
||||
|
||||
// The UserFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type UserFunc func(context.Context, *ent.UserQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f UserFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.UserQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.UserQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseUser type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseUser func(context.Context, *ent.UserQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseUser) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseUser) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.UserQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.UserQuery", q)
|
||||
}
|
||||
|
||||
// The UserAllowedGroupFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type UserAllowedGroupFunc func(context.Context, *ent.UserAllowedGroupQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f UserAllowedGroupFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.UserAllowedGroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.UserAllowedGroupQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseUserAllowedGroup type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseUserAllowedGroup func(context.Context, *ent.UserAllowedGroupQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseUserAllowedGroup) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseUserAllowedGroup) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.UserAllowedGroupQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.UserAllowedGroupQuery", q)
|
||||
}
|
||||
|
||||
// The UserSubscriptionFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type UserSubscriptionFunc func(context.Context, *ent.UserSubscriptionQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f UserSubscriptionFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.UserSubscriptionQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.UserSubscriptionQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseUserSubscription type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseUserSubscription func(context.Context, *ent.UserSubscriptionQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseUserSubscription) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseUserSubscription) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.UserSubscriptionQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.UserSubscriptionQuery", q)
|
||||
}
|
||||
|
||||
// NewQuery returns the generic Query interface for the given typed query.
|
||||
func NewQuery(q ent.Query) (Query, error) {
|
||||
switch q := q.(type) {
|
||||
case *ent.AccountQuery:
|
||||
return &query[*ent.AccountQuery, predicate.Account, account.OrderOption]{typ: ent.TypeAccount, tq: q}, nil
|
||||
case *ent.AccountGroupQuery:
|
||||
return &query[*ent.AccountGroupQuery, predicate.AccountGroup, accountgroup.OrderOption]{typ: ent.TypeAccountGroup, tq: q}, nil
|
||||
case *ent.ApiKeyQuery:
|
||||
return &query[*ent.ApiKeyQuery, predicate.ApiKey, apikey.OrderOption]{typ: ent.TypeApiKey, tq: q}, nil
|
||||
case *ent.GroupQuery:
|
||||
return &query[*ent.GroupQuery, predicate.Group, group.OrderOption]{typ: ent.TypeGroup, tq: q}, nil
|
||||
case *ent.ProxyQuery:
|
||||
return &query[*ent.ProxyQuery, predicate.Proxy, proxy.OrderOption]{typ: ent.TypeProxy, tq: q}, nil
|
||||
case *ent.RedeemCodeQuery:
|
||||
return &query[*ent.RedeemCodeQuery, predicate.RedeemCode, redeemcode.OrderOption]{typ: ent.TypeRedeemCode, tq: q}, nil
|
||||
case *ent.SettingQuery:
|
||||
return &query[*ent.SettingQuery, predicate.Setting, setting.OrderOption]{typ: ent.TypeSetting, tq: q}, nil
|
||||
case *ent.UserQuery:
|
||||
return &query[*ent.UserQuery, predicate.User, user.OrderOption]{typ: ent.TypeUser, tq: q}, nil
|
||||
case *ent.UserAllowedGroupQuery:
|
||||
return &query[*ent.UserAllowedGroupQuery, predicate.UserAllowedGroup, userallowedgroup.OrderOption]{typ: ent.TypeUserAllowedGroup, tq: q}, nil
|
||||
case *ent.UserSubscriptionQuery:
|
||||
return &query[*ent.UserSubscriptionQuery, predicate.UserSubscription, usersubscription.OrderOption]{typ: ent.TypeUserSubscription, tq: q}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown query type %T", q)
|
||||
}
|
||||
}
|
||||
|
||||
type query[T any, P ~func(*sql.Selector), R ~func(*sql.Selector)] struct {
|
||||
typ string
|
||||
tq interface {
|
||||
Limit(int) T
|
||||
Offset(int) T
|
||||
Unique(bool) T
|
||||
Order(...R) T
|
||||
Where(...P) T
|
||||
}
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) Type() string {
|
||||
return q.typ
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) Limit(limit int) {
|
||||
q.tq.Limit(limit)
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) Offset(offset int) {
|
||||
q.tq.Offset(offset)
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) Unique(unique bool) {
|
||||
q.tq.Unique(unique)
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) Order(orders ...func(*sql.Selector)) {
|
||||
rs := make([]R, len(orders))
|
||||
for i := range orders {
|
||||
rs[i] = orders[i]
|
||||
}
|
||||
q.tq.Order(rs...)
|
||||
}
|
||||
|
||||
func (q query[T, P, R]) WhereP(ps ...func(*sql.Selector)) {
|
||||
p := make([]P, len(ps))
|
||||
for i := range ps {
|
||||
p[i] = ps[i]
|
||||
}
|
||||
q.tq.Where(p...)
|
||||
}
|
||||
Reference in New Issue
Block a user