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  }