github.com/turingchain2020/turingchain@v1.1.21/common/db/table/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 table 6 7 import ( 8 "github.com/turingchain2020/turingchain/common/db" 9 "github.com/turingchain2020/turingchain/types" 10 ) 11 12 type tabler interface { 13 getMeta() RowMeta 14 getOpt() *Option 15 indexPrefix(string) []byte 16 GetData([]byte) (*Row, error) 17 index(*Row, string) ([]byte, error) 18 getIndexKey(string, []byte, []byte) []byte 19 primaryPrefix() []byte 20 getRow(value []byte) (*Row, error) 21 } 22 23 //Query 列表查询结构 24 type Query struct { 25 table tabler 26 kvdb db.KVDB 27 } 28 29 //List 通过某个数据,查询 30 func (query *Query) List(indexName string, data types.Message, primaryKey []byte, count, direction int32) (rows []*Row, err error) { 31 var prefix []byte 32 if data != nil { 33 err := query.table.getMeta().SetPayload(data) 34 if err != nil { 35 return nil, err 36 } 37 querykey := indexName 38 if isPrimaryIndex(indexName) { 39 querykey = query.table.getOpt().Primary 40 } 41 prefix, err = query.table.getMeta().Get(querykey) 42 if err != nil { 43 return nil, err 44 } 45 } 46 return query.ListIndex(indexName, prefix, primaryKey, count, direction) 47 } 48 49 //ListOne 通过某个数据,查询一行 50 func (query *Query) ListOne(indexName string, data types.Message, primaryKey []byte) (row *Row, err error) { 51 rows, err := query.List(indexName, data, primaryKey, 1, db.ListDESC) 52 if err != nil { 53 return nil, err 54 } 55 return rows[0], nil 56 } 57 58 func isPrimaryIndex(indexName string) bool { 59 return indexName == "" || indexName == "auto" || indexName == "primary" 60 } 61 62 //ListIndex 根据索引查询列表 63 //index 用哪个index 64 //prefix 必须要符合的前缀, 可以为空 65 //primaryKey 开始查询的位置(不包含数据本身) 66 //count 最多取的数量 67 //direction 方向 68 func (query *Query) ListIndex(indexName string, prefix []byte, primaryKey []byte, count, direction int32) (rows []*Row, err error) { 69 if isPrimaryIndex(indexName) || indexName == query.table.getOpt().Primary { 70 return query.listPrimary(prefix, primaryKey, count, direction) 71 } 72 p := query.table.indexPrefix(indexName) 73 var k []byte 74 if len(primaryKey) > 0 { 75 row, err := query.table.GetData(primaryKey) 76 if err != nil { 77 return nil, err 78 } 79 key, err := query.table.index(row, indexName) 80 if err != nil { 81 return nil, err 82 } 83 //如果存在prefix 84 if prefix != nil { 85 p2 := commonPrefix(prefix, key) 86 if len(p2) != len(prefix) { 87 return nil, types.ErrNotFound 88 } 89 p = append(p, p2...) 90 } 91 k = query.table.getIndexKey(indexName, key, row.Primary) 92 } else { 93 //这个情况下 k == nil 94 p = append(p, prefix...) 95 } 96 values, err := query.kvdb.List(p, k, count, direction) 97 if err != nil { 98 return nil, err 99 } 100 for _, value := range values { 101 row, err := query.table.GetData(value) 102 if err != nil { 103 return nil, err 104 } 105 rows = append(rows, row) 106 } 107 if len(rows) == 0 { 108 return nil, types.ErrNotFound 109 } 110 return rows, nil 111 } 112 113 //ListPrimary list primary data 114 func (query *Query) listPrimary(prefix []byte, primaryKey []byte, count, direction int32) (rows []*Row, err error) { 115 p := query.table.primaryPrefix() 116 var k []byte 117 if primaryKey != nil { 118 if prefix != nil { 119 p2 := commonPrefix(prefix, primaryKey) 120 if len(p2) != len(prefix) { 121 return nil, types.ErrNotFound 122 } 123 p = append(p, p2...) 124 } 125 k = append(p, primaryKey...) 126 } else { 127 p = append(p, prefix...) 128 } 129 values, err := query.kvdb.List(p, k, count, direction) 130 if err != nil { 131 return nil, err 132 } 133 for _, value := range values { 134 row, err := query.table.getRow(value) 135 if err != nil { 136 return nil, err 137 } 138 rows = append(rows, row) 139 } 140 if len(rows) == 0 { 141 return nil, types.ErrNotFound 142 } 143 return rows, nil 144 } 145 146 func commonPrefix(key1, key2 []byte) []byte { 147 l1 := len(key1) 148 l2 := len(key2) 149 l := min(l1, l2) 150 for i := 0; i < l; i++ { 151 if key1[i] != key2[i] { 152 return key1[:i] 153 } 154 } 155 return key1[0:l] 156 } 157 158 func min(a, b int) int { 159 if a < b { 160 return a 161 } 162 return b 163 }