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

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