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

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