github.com/NpoolPlatform/chain-middleware@v0.0.0-20240228100535-eb1bcf896eb9/pkg/mw/coin/usedfor/query.go (about)

     1  package coinusedfor
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	types "github.com/NpoolPlatform/message/npool/basetypes/chain/v1"
     8  	npool "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin/usedfor"
     9  
    10  	"github.com/NpoolPlatform/chain-middleware/pkg/db"
    11  	"github.com/NpoolPlatform/chain-middleware/pkg/db/ent"
    12  
    13  	coinusedforcrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/coin/usedfor"
    14  	entcoinbase "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinbase"
    15  	entcoinusedfor "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinusedfor"
    16  
    17  	"entgo.io/ent/dialect/sql"
    18  )
    19  
    20  type queryHandler struct {
    21  	*Handler
    22  	stm   *ent.CoinUsedForSelect
    23  	infos []*npool.CoinUsedFor
    24  	total uint32
    25  }
    26  
    27  func (h *queryHandler) selectCoinUsedFor(stm *ent.CoinUsedForQuery) {
    28  	h.stm = stm.Select(
    29  		entcoinusedfor.FieldID,
    30  		entcoinusedfor.FieldEntID,
    31  		entcoinusedfor.FieldCoinTypeID,
    32  		entcoinusedfor.FieldUsedFor,
    33  		entcoinusedfor.FieldPriority,
    34  		entcoinusedfor.FieldCreatedAt,
    35  		entcoinusedfor.FieldUpdatedAt,
    36  	)
    37  }
    38  
    39  func (h *queryHandler) queryCoinUsedFor(cli *ent.Client) error {
    40  	if h.ID == nil && h.EntID == nil {
    41  		return fmt.Errorf("invalid id")
    42  	}
    43  	stm := cli.CoinUsedFor.Query().Where(entcoinusedfor.DeletedAt(0))
    44  	if h.ID != nil {
    45  		stm.Where(entcoinusedfor.ID(*h.ID))
    46  	}
    47  	if h.EntID != nil {
    48  		stm.Where(entcoinusedfor.EntID(*h.EntID))
    49  	}
    50  	h.selectCoinUsedFor(stm)
    51  	return nil
    52  }
    53  
    54  func (h *queryHandler) queryCoinUsedFors(ctx context.Context, cli *ent.Client) error {
    55  	stm, err := coinusedforcrud.SetQueryConds(cli.CoinUsedFor.Query(), h.Conds)
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	total, err := stm.Count(ctx)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	h.total = uint32(total)
    65  
    66  	h.selectCoinUsedFor(stm)
    67  	return nil
    68  }
    69  
    70  func (h *queryHandler) queryJoinCoin(s *sql.Selector) {
    71  	t := sql.Table(entcoinbase.Table)
    72  	s.
    73  		LeftJoin(t).
    74  		On(
    75  			s.C(entcoinusedfor.FieldCoinTypeID),
    76  			t.C(entcoinbase.FieldEntID),
    77  		).
    78  		AppendSelect(
    79  			sql.As(t.C(entcoinbase.FieldName), "coin_name"),
    80  			sql.As(t.C(entcoinbase.FieldLogo), "coin_logo"),
    81  			sql.As(t.C(entcoinbase.FieldUnit), "coin_unit"),
    82  			sql.As(t.C(entcoinbase.FieldEnv), "coin_env"),
    83  		)
    84  }
    85  
    86  func (h *queryHandler) queryJoin() {
    87  	h.stm.Modify(func(s *sql.Selector) {
    88  		h.queryJoinCoin(s)
    89  	})
    90  }
    91  
    92  func (h *queryHandler) scan(ctx context.Context) error {
    93  	return h.stm.Scan(ctx, &h.infos)
    94  }
    95  
    96  func (h *queryHandler) formalize() {
    97  	for _, info := range h.infos {
    98  		info.UsedFor = types.CoinUsedFor(types.CoinUsedFor_value[info.UsedForStr])
    99  	}
   100  }
   101  
   102  func (h *Handler) GetCoinUsedFor(ctx context.Context) (*npool.CoinUsedFor, error) {
   103  	handler := &queryHandler{
   104  		Handler: h,
   105  	}
   106  
   107  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   108  		if err := handler.queryCoinUsedFor(cli); err != nil {
   109  			return err
   110  		}
   111  		handler.queryJoin()
   112  		const singleRowLimit = 2
   113  		handler.stm.Offset(0).Limit(singleRowLimit)
   114  		return handler.scan(_ctx)
   115  	})
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	if len(handler.infos) == 0 {
   120  		return nil, nil
   121  	}
   122  	if len(handler.infos) > 1 {
   123  		return nil, fmt.Errorf("too many record")
   124  	}
   125  
   126  	handler.formalize()
   127  	return handler.infos[0], nil
   128  }
   129  
   130  func (h *Handler) GetCoinUsedFors(ctx context.Context) ([]*npool.CoinUsedFor, uint32, error) {
   131  	handler := &queryHandler{
   132  		Handler: h,
   133  	}
   134  
   135  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   136  		if err := handler.queryCoinUsedFors(ctx, cli); err != nil {
   137  			return err
   138  		}
   139  		handler.queryJoin()
   140  		handler.stm.
   141  			Order(ent.Asc(entcoinusedfor.FieldPriority)).
   142  			Offset(int(h.Offset)).
   143  			Limit(int(h.Limit))
   144  		return handler.scan(_ctx)
   145  	})
   146  	if err != nil {
   147  		return nil, 0, err
   148  	}
   149  
   150  	handler.formalize()
   151  	return handler.infos, handler.total, nil
   152  }