github.com/turingchain2020/turingchain@v1.1.21/system/dapp/query.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package dapp
     6  
     7  import (
     8  	"errors"
     9  	"reflect"
    10  
    11  	"github.com/turingchain2020/turingchain/types"
    12  	"github.com/golang/protobuf/proto"
    13  )
    14  
    15  // GetTxsByAddr find all transactions in this address by the addr prefix
    16  // query transaction are placed by default :coins in the query
    17  func (d *DriverBase) GetTxsByAddr(addr *types.ReqAddr) (types.Message, error) {
    18  	db := d.GetLocalDB()
    19  	var prefix []byte
    20  	var key []byte
    21  	var txinfos [][]byte
    22  	var err error
    23  	//取最新的交易hash列表
    24  	if addr.Flag == 0 { //所有的交易hash列表
    25  		prefix = types.CalcTxAddrHashKey(addr.GetAddr(), "")
    26  	} else if addr.Flag > 0 { //from的交易hash列表
    27  		prefix = types.CalcTxAddrDirHashKey(addr.GetAddr(), addr.Flag, "")
    28  	} else {
    29  		return nil, errors.New("flag unknown")
    30  	}
    31  	if addr.GetHeight() == -1 {
    32  		txinfos, err = db.List(prefix, nil, addr.Count, addr.GetDirection())
    33  		if err != nil {
    34  			return nil, err
    35  		}
    36  		if len(txinfos) == 0 {
    37  			return nil, errors.New("tx does not exist")
    38  		}
    39  	} else { //翻页查找指定的txhash列表
    40  		heightstr := HeightIndexStr(addr.GetHeight(), addr.GetIndex())
    41  		if addr.Flag == 0 {
    42  			key = types.CalcTxAddrHashKey(addr.GetAddr(), heightstr)
    43  		} else if addr.Flag > 0 { //from的交易hash列表
    44  			key = types.CalcTxAddrDirHashKey(addr.GetAddr(), addr.Flag, heightstr)
    45  		} else {
    46  			return nil, errors.New("flag unknown")
    47  		}
    48  		txinfos, err = db.List(prefix, key, addr.Count, addr.Direction)
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  		if len(txinfos) == 0 {
    53  			return nil, errors.New("tx does not exist")
    54  		}
    55  	}
    56  	var replyTxInfos types.ReplyTxInfos
    57  	replyTxInfos.TxInfos = make([]*types.ReplyTxInfo, len(txinfos))
    58  	for index, txinfobyte := range txinfos {
    59  		var replyTxInfo types.ReplyTxInfo
    60  		err := types.Decode(txinfobyte, &replyTxInfo)
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  		replyTxInfos.TxInfos[index] = &replyTxInfo
    65  	}
    66  	return &replyTxInfos, nil
    67  }
    68  
    69  // GetPrefixCount query the number keys of the specified prefix, for statistical
    70  func (d *DriverBase) GetPrefixCount(key *types.ReqKey) (types.Message, error) {
    71  	var counts types.Int64
    72  	db := d.GetLocalDB()
    73  	counts.Data = db.PrefixCount(key.Key)
    74  	return &counts, nil
    75  }
    76  
    77  // GetAddrTxsCount query the transaction count for the specified address ,for statistical
    78  func (d *DriverBase) GetAddrTxsCount(reqkey *types.ReqKey) (types.Message, error) {
    79  	var counts types.Int64
    80  	db := d.GetLocalDB()
    81  	TxsCount, err := db.Get(reqkey.Key)
    82  	if err != nil && err != types.ErrNotFound {
    83  		counts.Data = 0
    84  		return &counts, nil
    85  	}
    86  	if len(TxsCount) == 0 {
    87  		counts.Data = 0
    88  		return &counts, nil
    89  	}
    90  	err = types.Decode(TxsCount, &counts)
    91  	if err != nil {
    92  		counts.Data = 0
    93  		return &counts, nil
    94  	}
    95  	return &counts, nil
    96  }
    97  
    98  // Query defines query function
    99  func (d *DriverBase) Query(funcname string, params []byte) (msg types.Message, err error) {
   100  	funcmap := d.child.GetFuncMap()
   101  	funcname = "Query_" + funcname
   102  	if _, ok := funcmap[funcname]; !ok {
   103  		blog.Error(funcname+" funcname not find", "func", funcname)
   104  		return nil, types.ErrActionNotSupport
   105  	}
   106  	ty := funcmap[funcname].Type
   107  	if ty.NumIn() != 2 {
   108  		blog.Error(funcname+" err num in param", "num", ty.NumIn())
   109  		return nil, types.ErrActionNotSupport
   110  	}
   111  	paramin := ty.In(1)
   112  	if paramin.Kind() != reflect.Ptr {
   113  		blog.Error(funcname + "  param is not pointer")
   114  		return nil, types.ErrActionNotSupport
   115  	}
   116  	p := reflect.New(ty.In(1).Elem())
   117  	queryin := p.Interface()
   118  	if in, ok := queryin.(proto.Message); ok {
   119  		err := types.Decode(params, in)
   120  		if err != nil {
   121  			return nil, err
   122  		}
   123  		return types.CallQueryFunc(d.childValue, funcmap[funcname], in)
   124  	}
   125  	blog.Error(funcname + " in param is not proto.Message")
   126  	return nil, types.ErrActionNotSupport
   127  }