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 }