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

     1  package appcoin
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  
     8  	"entgo.io/ent/dialect/sql"
     9  	"github.com/shopspring/decimal"
    10  
    11  	"github.com/NpoolPlatform/chain-middleware/pkg/db"
    12  	"github.com/NpoolPlatform/chain-middleware/pkg/db/ent"
    13  
    14  	appcoincrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/app/coin"
    15  	npool "github.com/NpoolPlatform/message/npool/chain/mw/v1/app/coin"
    16  
    17  	entappcoin "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/appcoin"
    18  	entcoinbase "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinbase"
    19  	entcoinextra "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/coinextra"
    20  	entappexrate "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/exchangerate"
    21  	entsetting "github.com/NpoolPlatform/chain-middleware/pkg/db/ent/setting"
    22  )
    23  
    24  type queryHandler struct {
    25  	*Handler
    26  	stm   *ent.AppCoinSelect
    27  	infos []*npool.Coin
    28  	total uint32
    29  }
    30  
    31  func (h *queryHandler) selectAppCoin(stm *ent.AppCoinQuery) {
    32  	h.stm = stm.Select(
    33  		entappcoin.FieldID,
    34  		entappcoin.FieldEntID,
    35  		entappcoin.FieldAppID,
    36  		entappcoin.FieldCoinTypeID,
    37  		entappcoin.FieldName,
    38  		entappcoin.FieldDisplayNames,
    39  		entappcoin.FieldLogo,
    40  		entappcoin.FieldForPay,
    41  		entappcoin.FieldWithdrawAutoReviewAmount,
    42  		entappcoin.FieldProductPage,
    43  		entappcoin.FieldDisabled,
    44  		entappcoin.FieldCreatedAt,
    45  		entappcoin.FieldUpdatedAt,
    46  		entappcoin.FieldDisplay,
    47  		entappcoin.FieldDailyRewardAmount,
    48  		entappcoin.FieldDisplayIndex,
    49  		entappcoin.FieldMaxAmountPerWithdraw,
    50  	)
    51  }
    52  
    53  func (h *queryHandler) queryAppCoin(cli *ent.Client) error {
    54  	if h.ID == nil && h.EntID == nil {
    55  		return fmt.Errorf("invalid id")
    56  	}
    57  	stm := cli.AppCoin.Query().Where(entappcoin.DeletedAt(0))
    58  	if h.ID != nil {
    59  		stm.Where(entappcoin.ID(*h.ID))
    60  	}
    61  	if h.EntID != nil {
    62  		stm.Where(entappcoin.EntID(*h.EntID))
    63  	}
    64  	h.selectAppCoin(stm)
    65  	return nil
    66  }
    67  
    68  func (h *queryHandler) queryAppCoins(ctx context.Context, cli *ent.Client) error {
    69  	stm, err := appcoincrud.SetQueryConds(cli.AppCoin.Query(), h.Conds)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	total, err := stm.Count(ctx)
    75  	if err != nil {
    76  		return err
    77  	}
    78  	h.total = uint32(total)
    79  
    80  	h.selectAppCoin(stm)
    81  	return nil
    82  }
    83  
    84  func (h *queryHandler) queryJoinCoinBase(s *sql.Selector) {
    85  	t := sql.Table(entcoinbase.Table)
    86  	s.LeftJoin(t).
    87  		On(
    88  			s.C(entappcoin.FieldCoinTypeID),
    89  			t.C(entcoinbase.FieldEntID),
    90  		).
    91  		OnP(
    92  			sql.EQ(t.C(entcoinbase.FieldDeletedAt), 0),
    93  		).
    94  		AppendSelect(
    95  			sql.As(t.C(entcoinbase.FieldName), "coin_name"),
    96  			sql.As(t.C(entcoinbase.FieldUnit), "unit"),
    97  			sql.As(t.C(entcoinbase.FieldEnv), "env"),
    98  			sql.As(t.C(entcoinbase.FieldPresale), "presale"),
    99  			sql.As(t.C(entcoinbase.FieldReservedAmount), "reserved_amount"),
   100  			sql.As(t.C(entcoinbase.FieldDisabled), "coin_disabled"),
   101  			sql.As(t.C(entcoinbase.FieldForPay), "coin_for_pay"),
   102  		)
   103  }
   104  
   105  func (h *queryHandler) queryJoinCoinExtra(s *sql.Selector) {
   106  	t := sql.Table(entcoinextra.Table)
   107  	s.LeftJoin(t).
   108  		On(
   109  			s.C(entappcoin.FieldCoinTypeID),
   110  			t.C(entcoinextra.FieldCoinTypeID),
   111  		).
   112  		OnP(
   113  			sql.EQ(t.C(entcoinextra.FieldDeletedAt), 0),
   114  		).
   115  		AppendSelect(
   116  			sql.As(t.C(entcoinextra.FieldHomePage), "home_page"),
   117  			sql.As(t.C(entcoinextra.FieldSpecs), "specs"),
   118  			sql.As(t.C(entcoinextra.FieldStableUsd), "stable_usd"),
   119  		)
   120  }
   121  
   122  func (h *queryHandler) queryJoinCoinSetting(s *sql.Selector) {
   123  	t1 := sql.Table(entsetting.Table)
   124  	s.
   125  		LeftJoin(t1).
   126  		On(
   127  			s.C(entappcoin.FieldCoinTypeID),
   128  			t1.C(entsetting.FieldCoinTypeID),
   129  		).
   130  		OnP(
   131  			sql.EQ(t1.C(entsetting.FieldDeletedAt), 0),
   132  		).
   133  		AppendSelect(
   134  			sql.As(t1.C(entsetting.FieldFeeCoinTypeID), "fee_coin_type_id"),
   135  			sql.As(t1.C(entsetting.FieldWithdrawFeeByStableUsd), "withdraw_fee_by_stable_usd"),
   136  			sql.As(t1.C(entsetting.FieldWithdrawFeeAmount), "withdraw_fee_amount"),
   137  			sql.As(t1.C(entsetting.FieldCollectFeeAmount), "collect_fee_amount"),
   138  			sql.As(t1.C(entsetting.FieldHotWalletFeeAmount), "hot_wallet_fee_amount"),
   139  			sql.As(t1.C(entsetting.FieldLowFeeAmount), "low_fee_amount"),
   140  			sql.As(t1.C(entsetting.FieldHotLowFeeAmount), "hot_low_fee_amount"),
   141  			sql.As(t1.C(entsetting.FieldHotWalletAccountAmount), "hot_wallet_account_amount"),
   142  			sql.As(t1.C(entsetting.FieldPaymentAccountCollectAmount), "payment_account_collect_amount"),
   143  			sql.As(t1.C(entsetting.FieldLeastTransferAmount), "least_transfer_amount"),
   144  			sql.As(t1.C(entsetting.FieldNeedMemo), "need_memo"),
   145  			sql.As(t1.C(entsetting.FieldCheckNewAddressBalance), "check_new_address_balance"),
   146  		)
   147  
   148  	t2 := sql.Table(entcoinbase.Table)
   149  	s.
   150  		LeftJoin(t2).
   151  		On(
   152  			t1.C(entsetting.FieldFeeCoinTypeID),
   153  			t2.C(entcoinbase.FieldEntID),
   154  		).
   155  		OnP(
   156  			sql.EQ(t2.C(entcoinbase.FieldDeletedAt), 0),
   157  		).
   158  		AppendSelect(
   159  			sql.As(t2.C(entcoinbase.FieldName), "fee_coin_name"),
   160  			sql.As(t2.C(entcoinbase.FieldLogo), "fee_coin_logo"),
   161  			sql.As(t2.C(entcoinbase.FieldUnit), "fee_coin_unit"),
   162  			sql.As(t2.C(entcoinbase.FieldEnv), "fee_coin_env"),
   163  		)
   164  }
   165  
   166  func (h *queryHandler) queryJoinExrate(s *sql.Selector) {
   167  	t := sql.Table(entappexrate.Table)
   168  	s.LeftJoin(t).
   169  		On(
   170  			s.C(entappcoin.FieldCoinTypeID),
   171  			t.C(entappexrate.FieldCoinTypeID),
   172  		).
   173  		On(
   174  			s.C(entappcoin.FieldAppID),
   175  			t.C(entappexrate.FieldAppID),
   176  		).
   177  		OnP(
   178  			sql.EQ(t.C(entappexrate.FieldDeletedAt), 0),
   179  		).
   180  		AppendSelect(
   181  			sql.As(t.C(entappexrate.FieldMarketValue), "market_value"),
   182  			sql.As(t.C(entappexrate.FieldSettleValue), "settle_value"),
   183  			sql.As(t.C(entappexrate.FieldSettlePercent), "settle_percent"),
   184  			sql.As(t.C(entappexrate.FieldSettleTips), "settle_tips"),
   185  			sql.As(t.C(entappexrate.FieldSetter), "setter"),
   186  		)
   187  }
   188  
   189  func (h *queryHandler) queryJoin() {
   190  	h.stm.Modify(func(s *sql.Selector) {
   191  		h.queryJoinCoinBase(s)
   192  		h.queryJoinCoinExtra(s)
   193  		h.queryJoinCoinSetting(s)
   194  		h.queryJoinExrate(s)
   195  	})
   196  }
   197  
   198  func (h *queryHandler) scan(ctx context.Context) error {
   199  	return h.stm.Scan(ctx, &h.infos)
   200  }
   201  
   202  func (h *queryHandler) formalize() {
   203  	for _, info := range h.infos {
   204  		_ = json.Unmarshal([]byte(info.DisplayNamesStr), &info.DisplayNames)
   205  		if !info.CoinForPay {
   206  			info.ForPay = info.CoinForPay
   207  		}
   208  		if !info.Disabled {
   209  			info.Disabled = info.CoinDisabled
   210  		}
   211  		if info.MarketValue == "" {
   212  			info.MarketValue = decimal.NewFromInt(0).String()
   213  		}
   214  		if info.SettleValue == "" {
   215  			info.SettleValue = decimal.NewFromInt(0).String()
   216  		}
   217  		if info.MaxAmountPerWithdraw == "" {
   218  			info.MaxAmountPerWithdraw = decimal.NewFromInt(0).String()
   219  		}
   220  		_ = json.Unmarshal([]byte(info.SettleTipsStr), &info.SettleTips)
   221  	}
   222  }
   223  
   224  func (h *Handler) GetCoin(ctx context.Context) (*npool.Coin, error) {
   225  	handler := &queryHandler{
   226  		Handler: h,
   227  	}
   228  
   229  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   230  		if err := handler.queryAppCoin(cli); err != nil {
   231  			return err
   232  		}
   233  		handler.queryJoin()
   234  		const singleRowLimit = 2
   235  		handler.stm.Offset(0).Limit(singleRowLimit)
   236  		return handler.scan(_ctx)
   237  	})
   238  	if err != nil {
   239  		return nil, err
   240  	}
   241  	if len(handler.infos) == 0 {
   242  		return nil, nil
   243  	}
   244  	if len(handler.infos) > 1 {
   245  		return nil, fmt.Errorf("too many records")
   246  	}
   247  
   248  	handler.formalize()
   249  	return handler.infos[0], nil
   250  }
   251  
   252  func (h *Handler) GetCoins(ctx context.Context) ([]*npool.Coin, uint32, error) {
   253  	handler := &queryHandler{
   254  		Handler: h,
   255  	}
   256  
   257  	err := db.WithClient(ctx, func(_ctx context.Context, cli *ent.Client) error {
   258  		if err := handler.queryAppCoins(_ctx, cli); err != nil {
   259  			return err
   260  		}
   261  		handler.queryJoin()
   262  		handler.stm.
   263  			Order(ent.Asc(entappcoin.FieldDisplayIndex)).
   264  			Offset(int(h.Offset)).
   265  			Limit(int(h.Limit))
   266  		return handler.scan(ctx)
   267  	})
   268  	if err != nil {
   269  		return nil, 0, err
   270  	}
   271  
   272  	handler.formalize()
   273  	return handler.infos, handler.total, nil
   274  }