github.com/tsuna/gohbase@v0.0.0-20250731002811-4ffcadfba63e/hrpc/get.go (about) 1 // Copyright (C) 2015 The GoHBase Authors. All rights reserved. 2 // This file is part of GoHBase. 3 // Use of this source code is governed by the Apache License 2.0 4 // that can be found in the COPYING file. 5 6 package hrpc 7 8 import ( 9 "context" 10 11 "github.com/tsuna/gohbase/pb" 12 "google.golang.org/protobuf/proto" 13 ) 14 15 // Get represents a Get HBase call. 16 type Get struct { 17 base 18 baseQuery 19 // Don't return any KeyValue, just say whether the row key exists in the 20 // table or not. 21 existsOnly bool 22 skipbatch bool 23 } 24 25 // baseGet returns a Get struct with default values set. 26 func baseGet(ctx context.Context, table []byte, key []byte, 27 options ...func(Call) error) (*Get, error) { 28 g := &Get{ 29 base: base{ 30 key: key, 31 table: table, 32 ctx: ctx, 33 resultch: make(chan RPCResult, 1), 34 }, 35 baseQuery: newBaseQuery(), 36 } 37 err := applyOptions(g, options...) 38 if err != nil { 39 return nil, err 40 } 41 return g, nil 42 } 43 44 // NewGet creates a new Get request for the given table and row key. 45 func NewGet(ctx context.Context, table, key []byte, 46 options ...func(Call) error) (*Get, error) { 47 return baseGet(ctx, table, key, options...) 48 } 49 50 // NewGetStr creates a new Get request for the given table and row key. 51 func NewGetStr(ctx context.Context, table, key string, 52 options ...func(Call) error) (*Get, error) { 53 return NewGet(ctx, []byte(table), []byte(key), options...) 54 } 55 56 // Name returns the name of this RPC call. 57 func (g *Get) Name() string { 58 return "Get" 59 } 60 61 // Description returns the description of this RPC call. 62 func (g *Get) Description() string { 63 return g.Name() 64 } 65 66 // SkipBatch returns true if the Get request shouldn't be batched, 67 // but should be sent to Region Server right away. 68 func (g *Get) SkipBatch() bool { 69 return g.skipbatch 70 } 71 72 func (g *Get) setSkipBatch(v bool) { 73 g.skipbatch = v 74 } 75 76 // ExistsOnly makes this Get request not return any KeyValue, merely whether 77 // or not the given row key exists in the table. 78 func (g *Get) ExistsOnly() { 79 g.existsOnly = true 80 } 81 82 // ToProto converts this RPC into a protobuf message. 83 func (g *Get) ToProto() proto.Message { 84 get := &pb.GetRequest{ 85 Region: g.regionSpecifier(), 86 Get: &pb.Get{ 87 Row: g.key, 88 Column: familiesToColumn(g.families), 89 TimeRange: &pb.TimeRange{}, 90 }, 91 } 92 93 /* added support for limit number of cells per row */ 94 if g.storeLimit != DefaultMaxResultsPerColumnFamily { 95 get.Get.StoreLimit = &g.storeLimit 96 } 97 if g.storeOffset != 0 { 98 get.Get.StoreOffset = &g.storeOffset 99 } 100 101 if g.maxVersions != DefaultMaxVersions { 102 get.Get.MaxVersions = &g.maxVersions 103 } 104 if g.fromTimestamp != MinTimestamp { 105 get.Get.TimeRange.From = &g.fromTimestamp 106 } 107 if g.toTimestamp != MaxTimestamp { 108 get.Get.TimeRange.To = &g.toTimestamp 109 } 110 if g.existsOnly { 111 get.Get.ExistenceOnly = proto.Bool(true) 112 } 113 if g.cacheBlocks != DefaultCacheBlocks { 114 get.Get.CacheBlocks = &g.cacheBlocks 115 } 116 if g.consistency != DefaultConsistency { 117 get.Get.Consistency = g.consistency.toProto() 118 } 119 get.Get.Filter = g.filter 120 return get 121 } 122 123 // NewResponse creates an empty protobuf message to read the response of this 124 // RPC. 125 func (g *Get) NewResponse() proto.Message { 126 return &pb.GetResponse{} 127 } 128 129 // DeserializeCellBlocks deserializes get result from cell blocks 130 func (g *Get) DeserializeCellBlocks(m proto.Message, b []byte) (uint32, error) { 131 resp := m.(*pb.GetResponse) 132 if resp.Result == nil { 133 // TODO: is this possible? 134 return 0, nil 135 } 136 cells, read, err := deserializeCellBlocks(b, uint32(resp.Result.GetAssociatedCellCount())) 137 if err != nil { 138 return 0, err 139 } 140 resp.Result.Cell = append(resp.Result.Cell, cells...) 141 return read, nil 142 } 143 144 // familiesToColumn takes a map from strings to lists of strings, and converts 145 // them into protobuf Columns 146 func familiesToColumn(families map[string][]string) []*pb.Column { 147 cols := make([]*pb.Column, len(families)) 148 counter := 0 149 for family, qualifiers := range families { 150 bytequals := make([][]byte, len(qualifiers)) 151 for i, qual := range qualifiers { 152 bytequals[i] = []byte(qual) 153 } 154 cols[counter] = &pb.Column{ 155 Family: []byte(family), 156 Qualifier: bytequals, 157 } 158 counter++ 159 } 160 return cols 161 }