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

     1  package coin
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"entgo.io/ent/dialect/sql"
     8  	coincrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/coin"
     9  	"github.com/NpoolPlatform/chain-middleware/pkg/db"
    10  	"github.com/NpoolPlatform/chain-middleware/pkg/db/ent"
    11  	npool "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin"
    12  
    13  	entbase "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinbase"
    14  	entextra "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinextra"
    15  	entsetting "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/setting"
    16  )
    17  
    18  type queryHandler struct {
    19  	*Handler
    20  	stm   *ent.CoinBaseSelect
    21  	infos []*npool.Coin
    22  	total uint32
    23  }
    24  
    25  func (h *queryHandler) selectCoin(stm *ent.CoinBaseQuery) {
    26  	h.stm = stm.Select(
    27  		entbase.FieldID,
    28  		entbase.FieldEntID,
    29  		entbase.FieldName,
    30  		entbase.FieldLogo,
    31  		entbase.FieldPresale,
    32  		entbase.FieldForPay,
    33  		entbase.FieldUnit,
    34  		entbase.FieldEnv,
    35  		entbase.FieldReservedAmount,
    36  		entbase.FieldDisabled,
    37  		entbase.FieldCreatedAt,
    38  		entbase.FieldUpdatedAt,
    39  	)
    40  }
    41  
    42  func (h *queryHandler) queryCoin(cli *ent.Client) error {
    43  	if h.ID == nil && h.EntID == nil {
    44  		return fmt.Errorf("invalid id")
    45  	}
    46  	stm := cli.CoinBase.Query().Where(entbase.DeletedAt(0))
    47  	if h.ID != nil {
    48  		stm.Where(entbase.ID(*h.ID))
    49  	}
    50  	if h.EntID != nil {
    51  		stm.Where(entbase.EntID(*h.EntID))
    52  	}
    53  	h.selectCoin(stm)
    54  	return nil
    55  }
    56  
    57  func (h *queryHandler) queryCoins(ctx context.Context, cli *ent.Client) error {
    58  	stm, err := coincrud.SetQueryConds(cli.CoinBase.Query(), h.Conds)
    59  	if err != nil {
    60  		return err
    61  	}
    62  	total, err := stm.Count(ctx)
    63  	if err != nil {
    64  		return err
    65  	}
    66  	h.total = uint32(total)
    67  	h.selectCoin(stm)
    68  	return nil
    69  }
    70  
    71  func (h *queryHandler) queryJoinExtra(s *sql.Selector) {
    72  	t := sql.Table(entextra.Table)
    73  	s.
    74  		LeftJoin(t).
    75  		On(
    76  			s.C(entbase.FieldEntID),
    77  			t.C(entextra.FieldCoinTypeID),
    78  		).
    79  		AppendSelect(
    80  			sql.As(t.C(entextra.FieldHomePage), "home_page"),
    81  			sql.As(t.C(entextra.FieldSpecs), "specs"),
    82  			sql.As(t.C(entextra.FieldStableUsd), "stable_usd"),
    83  		)
    84  }
    85  
    86  func (h *queryHandler) queryJoinSetting(s *sql.Selector) {
    87  	t1 := sql.Table(entsetting.Table)
    88  	s.
    89  		LeftJoin(t1).
    90  		On(
    91  			s.C(entbase.FieldEntID),
    92  			t1.C(entsetting.FieldCoinTypeID),
    93  		).
    94  		AppendSelect(
    95  			sql.As(t1.C(entsetting.FieldFeeCoinTypeID), "fee_coin_type_id"),
    96  			sql.As(t1.C(entsetting.FieldWithdrawFeeByStableUsd), "withdraw_fee_by_stable_usd"),
    97  			sql.As(t1.C(entsetting.FieldWithdrawFeeAmount), "withdraw_fee_amount"),
    98  			sql.As(t1.C(entsetting.FieldCollectFeeAmount), "collect_fee_amount"),
    99  			sql.As(t1.C(entsetting.FieldHotWalletFeeAmount), "hot_wallet_fee_amount"),
   100  			sql.As(t1.C(entsetting.FieldLowFeeAmount), "low_fee_amount"),
   101  			sql.As(t1.C(entsetting.FieldHotLowFeeAmount), "hot_low_fee_amount"),
   102  			sql.As(t1.C(entsetting.FieldHotWalletAccountAmount), "hot_wallet_account_amount"),
   103  			sql.As(t1.C(entsetting.FieldPaymentAccountCollectAmount), "payment_account_collect_amount"),
   104  			sql.As(t1.C(entsetting.FieldLeastTransferAmount), "least_transfer_amount"),
   105  			sql.As(t1.C(entsetting.FieldNeedMemo), "need_memo"),
   106  			sql.As(t1.C(entsetting.FieldRefreshCurrency), "refresh_currency"),
   107  			sql.As(t1.C(entsetting.FieldCheckNewAddressBalance), "check_new_address_balance"),
   108  		)
   109  
   110  	t2 := sql.Table(entbase.Table)
   111  	s.
   112  		LeftJoin(t2).
   113  		On(
   114  			t2.C(entbase.FieldEntID),
   115  			t1.C(entsetting.FieldFeeCoinTypeID),
   116  		).
   117  		AppendSelect(
   118  			sql.As(t2.C(entbase.FieldName), "fee_coin_name"),
   119  			sql.As(t2.C(entbase.FieldLogo), "fee_coin_logo"),
   120  			sql.As(t2.C(entbase.FieldUnit), "fee_coin_unit"),
   121  			sql.As(t2.C(entbase.FieldEnv), "fee_coin_env"),
   122  		)
   123  }
   124  
   125  func (h *queryHandler) queryJoin() {
   126  	h.stm.Modify(func(s *sql.Selector) {
   127  		h.queryJoinExtra(s)
   128  		h.queryJoinSetting(s)
   129  	})
   130  }
   131  
   132  func (h *queryHandler) scan(ctx context.Context) error {
   133  	return h.stm.Scan(ctx, &h.infos)
   134  }
   135  
   136  func (h *Handler) GetCoin(ctx context.Context) (*npool.Coin, error) {
   137  	handler := &queryHandler{
   138  		Handler: h,
   139  	}
   140  
   141  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   142  		if err := handler.queryCoin(cli); err != nil {
   143  			return err
   144  		}
   145  		handler.queryJoin()
   146  		const singleRowLimit = 2
   147  		handler.stm.Offset(0).Limit(singleRowLimit)
   148  		return handler.scan(_ctx)
   149  	})
   150  	if err != nil {
   151  		return nil, err
   152  	}
   153  	if len(handler.infos) == 0 {
   154  		return nil, nil
   155  	}
   156  	if len(handler.infos) > 1 {
   157  		return nil, fmt.Errorf("too many record")
   158  	}
   159  	return handler.infos[0], nil
   160  }
   161  
   162  func (h *Handler) GetCoins(ctx context.Context) ([]*npool.Coin, uint32, error) {
   163  	handler := &queryHandler{
   164  		Handler: h,
   165  	}
   166  
   167  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   168  		if err := handler.queryCoins(_ctx, cli); err != nil {
   169  			return err
   170  		}
   171  		handler.queryJoin()
   172  		handler.stm.
   173  			Offset(int(h.Offset)).
   174  			Limit(int(h.Limit))
   175  		return handler.scan(_ctx)
   176  	})
   177  	if err != nil {
   178  		return nil, 0, err
   179  	}
   180  
   181  	return handler.infos, handler.total, nil
   182  }
   183  
   184  func (h *Handler) GetCoinOnly(ctx context.Context) (*npool.Coin, error) {
   185  	handler := &queryHandler{
   186  		Handler: h,
   187  	}
   188  
   189  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   190  		if err := handler.queryCoins(_ctx, cli); err != nil {
   191  			return err
   192  		}
   193  		handler.queryJoin()
   194  		const singleRowLimit = 2
   195  		handler.stm.Offset(0).Limit(singleRowLimit)
   196  		return handler.scan(_ctx)
   197  	})
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  	if len(handler.infos) == 0 {
   202  		return nil, nil
   203  	}
   204  	if len(handler.infos) > 1 {
   205  		return nil, fmt.Errorf("too many records")
   206  	}
   207  
   208  	return handler.infos[0], nil
   209  }