Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

41
vendor/github.com/tsuna/gohbase/hrpc/BUILD.bazel generated vendored Normal file
View File

@@ -0,0 +1,41 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"call.go",
"checkandput.go",
"create.go",
"delete.go",
"disable.go",
"enable.go",
"get.go",
"mutate.go",
"procedure.go",
"query.go",
"scan.go",
"status.go",
],
importmap = "go-common/vendor/github.com/tsuna/gohbase/hrpc",
importpath = "github.com/tsuna/gohbase/hrpc",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/tsuna/gohbase/filter:go_default_library",
"//vendor/github.com/tsuna/gohbase/pb:go_default_library",
"@com_github_golang_protobuf//proto:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

276
vendor/github.com/tsuna/gohbase/hrpc/call.go generated vendored Normal file
View File

@@ -0,0 +1,276 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"encoding/binary"
"errors"
"fmt"
"unsafe"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// RegionInfo represents HBase region.
type RegionInfo interface {
IsUnavailable() bool
AvailabilityChan() <-chan struct{}
MarkUnavailable() bool
MarkAvailable()
MarkDead()
Context() context.Context
String() string
ID() uint64
Name() []byte
StartKey() []byte
StopKey() []byte
Namespace() []byte
Table() []byte
SetClient(RegionClient)
Client() RegionClient
}
// RegionClient represents HBase region client.
type RegionClient interface {
Close()
Addr() string
QueueRPC(Call)
String() string
}
// Call represents an HBase RPC call.
type Call interface {
Table() []byte
Name() string
Key() []byte
Region() RegionInfo
SetRegion(region RegionInfo)
ToProto() proto.Message
// Returns a newly created (default-state) protobuf in which to store the
// response of this call.
NewResponse() proto.Message
ResultChan() chan RPCResult
Context() context.Context
}
type withOptions interface {
Options() []func(Call) error
setOptions([]func(Call) error)
}
// Batchable interface should be implemented by calls that can be batched into MultiRequest
type Batchable interface {
// SkipBatch returns true if a call shouldn't be batched into MultiRequest and
// should be sent right away.
SkipBatch() bool
setSkipBatch(v bool)
}
// SkipBatch is an option for batchable requests (Get and Mutate) to tell
// the client to skip batching and just send the request to Region Server
// right away.
func SkipBatch() func(Call) error {
return func(c Call) error {
if b, ok := c.(Batchable); ok {
b.setSkipBatch(true)
return nil
}
return errors.New("'SkipBatch' option only works with Get and Mutate requests")
}
}
// hasQueryOptions is interface that needs to be implemented by calls
// that allow to provide Families and Filters options.
type hasQueryOptions interface {
setFamilies(families map[string][]string)
setFilter(filter *pb.Filter)
setTimeRangeUint64(from, to uint64)
setMaxVersions(versions uint32)
setMaxResultsPerColumnFamily(maxresults uint32)
setResultOffset(offset uint32)
}
// RPCResult is struct that will contain both the resulting message from an RPC
// call, and any errors that may have occurred related to making the RPC call.
type RPCResult struct {
Msg proto.Message
Error error
}
type base struct {
ctx context.Context
table []byte
key []byte
options []func(Call) error
region RegionInfo
resultch chan RPCResult
}
func (b *base) Context() context.Context {
return b.ctx
}
func (b *base) Region() RegionInfo {
return b.region
}
func (b *base) SetRegion(region RegionInfo) {
b.region = region
}
func (b *base) regionSpecifier() *pb.RegionSpecifier {
return &pb.RegionSpecifier{
Type: pb.RegionSpecifier_REGION_NAME.Enum(),
Value: []byte(b.region.Name()),
}
}
func (b *base) setOptions(options []func(Call) error) {
b.options = options
}
// Options returns all the options passed to this call
func (b *base) Options() []func(Call) error {
return b.options
}
func applyOptions(call Call, options ...func(Call) error) error {
call.(withOptions).setOptions(options)
for _, option := range options {
err := option(call)
if err != nil {
return err
}
}
return nil
}
func (b *base) Table() []byte {
return b.table
}
func (b *base) Key() []byte {
return b.key
}
func (b *base) ResultChan() chan RPCResult {
return b.resultch
}
// Cell is the smallest level of granularity in returned results.
// Represents a single cell in HBase (a row will have one cell for every qualifier).
type Cell pb.Cell
func (c *Cell) String() string {
return (*pb.Cell)(c).String()
}
// cellFromCellBlock deserializes a cell from a reader
func cellFromCellBlock(b []byte) (*pb.Cell, uint32, error) {
if len(b) < 4 {
return nil, 0, fmt.Errorf(
"buffer is too small: expected %d, got %d", 4, len(b))
}
kvLen := binary.BigEndian.Uint32(b[0:4])
if len(b) < int(kvLen)+4 {
return nil, 0, fmt.Errorf(
"buffer is too small: expected %d, got %d", int(kvLen)+4, len(b))
}
rowKeyLen := binary.BigEndian.Uint32(b[4:8])
valueLen := binary.BigEndian.Uint32(b[8:12])
keyLen := binary.BigEndian.Uint16(b[12:14])
b = b[14:]
key := b[:keyLen]
b = b[keyLen:]
familyLen := uint8(b[0])
b = b[1:]
family := b[:familyLen]
b = b[familyLen:]
qualifierLen := rowKeyLen - uint32(keyLen) - uint32(familyLen) - 2 - 1 - 8 - 1
if 4 /*rowKeyLen*/ +4 /*valueLen*/ +2 /*keyLen*/ +
uint32(keyLen)+1 /*familyLen*/ +uint32(familyLen)+qualifierLen+
8 /*timestamp*/ +1 /*cellType*/ +valueLen != kvLen {
return nil, 0, fmt.Errorf("HBase has lied about KeyValue length: expected %d, got %d",
kvLen, 4+4+2+uint32(keyLen)+1+uint32(familyLen)+qualifierLen+8+1+valueLen)
}
qualifier := b[:qualifierLen]
b = b[qualifierLen:]
timestamp := binary.BigEndian.Uint64(b[:8])
b = b[8:]
cellType := uint8(b[0])
b = b[1:]
value := b[:valueLen]
return &pb.Cell{
Row: key,
Family: family,
Qualifier: qualifier,
Timestamp: &timestamp,
Value: value,
CellType: pb.CellType(cellType).Enum(),
}, kvLen + 4, nil
}
func deserializeCellBlocks(b []byte, cellsLen uint32) ([]*pb.Cell, uint32, error) {
cells := make([]*pb.Cell, cellsLen)
var readLen uint32
for i := 0; i < int(cellsLen); i++ {
c, l, err := cellFromCellBlock(b[readLen:])
if err != nil {
return nil, readLen, err
}
cells[i] = c
readLen += l
}
return cells, readLen, nil
}
// Result holds a slice of Cells as well as miscellaneous information about the response.
type Result struct {
Cells []*Cell
Stale bool
Partial bool
// Exists is only set if existance_only was set in the request query.
Exists *bool
}
func extractBool(v *bool) bool {
return v != nil && *v
}
// ToLocalResult takes a protobuf Result type and converts it to our own
// Result type in constant time.
func ToLocalResult(pbr *pb.Result) *Result {
if pbr == nil {
return &Result{}
}
return &Result{
// Should all be O(1) operations.
Cells: toLocalCells(pbr),
Stale: extractBool(pbr.Stale),
Partial: extractBool(pbr.Partial),
Exists: pbr.Exists,
}
}
func toLocalCells(pbr *pb.Result) []*Cell {
return *(*[]*Cell)(unsafe.Pointer(pbr))
}
// We can now define any helper functions on Result that we want.

66
vendor/github.com/tsuna/gohbase/hrpc/checkandput.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
// Copyright (C) 2016 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/filter"
"github.com/tsuna/gohbase/pb"
)
// CheckAndPut performs a provided Put operation if the value specified
// by condition equals to the one set in the HBase.
type CheckAndPut struct {
*Mutate
family []byte
qualifier []byte
comparator *pb.Comparator
}
// NewCheckAndPut creates a new CheckAndPut request that will compare provided
// expectedValue with the on in HBase located at put's row and provided family:qualifier,
// and if they are equal, perform the provided put request on the row
func NewCheckAndPut(put *Mutate, family string,
qualifier string, expectedValue []byte) (*CheckAndPut, error) {
if put.mutationType != pb.MutationProto_PUT {
return nil, fmt.Errorf("'CheckAndPut' only takes 'Put' request")
}
// The condition that needs to match for the edit to be applied.
exp := filter.NewByteArrayComparable(expectedValue)
cmp, err := filter.NewBinaryComparator(exp).ConstructPBComparator()
if err != nil {
return nil, err
}
// CheckAndPut is not batchable as MultiResponse doesn't return Processed field
// for Mutate Action
put.setSkipBatch(true)
return &CheckAndPut{
Mutate: put,
family: []byte(family),
qualifier: []byte(qualifier),
comparator: cmp,
}, nil
}
// ToProto converts the RPC into a protobuf message
func (cp *CheckAndPut) ToProto() proto.Message {
mutateRequest := cp.toProto()
mutateRequest.Condition = &pb.Condition{
Row: cp.key,
Family: cp.family,
Qualifier: cp.qualifier,
CompareType: pb.CompareType_EQUAL.Enum(),
Comparator: cp.comparator,
}
return mutateRequest
}

112
vendor/github.com/tsuna/gohbase/hrpc/create.go generated vendored Normal file
View File

@@ -0,0 +1,112 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// CreateTable represents a CreateTable HBase call
type CreateTable struct {
base
families map[string]map[string]string
splitKeys [][]byte
}
var defaultAttributes = map[string]string{
"BLOOMFILTER": "ROW",
"VERSIONS": "3",
"IN_MEMORY": "false",
"KEEP_DELETED_CELLS": "false",
"DATA_BLOCK_ENCODING": "FAST_DIFF",
"TTL": "2147483647",
"COMPRESSION": "NONE",
"MIN_VERSIONS": "0",
"BLOCKCACHE": "true",
"BLOCKSIZE": "65536",
"REPLICATION_SCOPE": "0",
}
// NewCreateTable creates a new CreateTable request that will create the given
// table in HBase. 'families' is a map of column family name to its attributes.
// For use by the admin client.
func NewCreateTable(ctx context.Context, table []byte,
families map[string]map[string]string,
options ...func(*CreateTable)) *CreateTable {
ct := &CreateTable{
base: base{
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
families: make(map[string]map[string]string, len(families)),
}
for _, option := range options {
option(ct)
}
for family, attrs := range families {
ct.families[family] = make(map[string]string, len(defaultAttributes))
for k, dv := range defaultAttributes {
if v, ok := attrs[k]; ok {
ct.families[family][k] = v
} else {
ct.families[family][k] = dv
}
}
}
return ct
}
// SplitKeys will return an option that will set the split keys for the created table
func SplitKeys(sk [][]byte) func(*CreateTable) {
return func(ct *CreateTable) {
ct.splitKeys = sk
}
}
// Name returns the name of this RPC call.
func (ct *CreateTable) Name() string {
return "CreateTable"
}
// ToProto converts the RPC into a protobuf message
func (ct *CreateTable) ToProto() proto.Message {
pbFamilies := make([]*pb.ColumnFamilySchema, 0, len(ct.families))
for family, attrs := range ct.families {
f := &pb.ColumnFamilySchema{
Name: []byte(family),
Attributes: make([]*pb.BytesBytesPair, 0, len(attrs)),
}
for k, v := range attrs {
f.Attributes = append(f.Attributes, &pb.BytesBytesPair{
First: []byte(k),
Second: []byte(v),
})
}
pbFamilies = append(pbFamilies, f)
}
return &pb.CreateTableRequest{
TableSchema: &pb.TableSchema{
TableName: &pb.TableName{
// TODO: handle namespaces
Namespace: []byte("default"),
Qualifier: ct.table,
},
ColumnFamilies: pbFamilies,
},
SplitKeys: ct.splitKeys,
}
}
// NewResponse creates an empty protobuf message to read the response of this
// RPC.
func (ct *CreateTable) NewResponse() proto.Message {
return &pb.CreateTableResponse{}
}

52
vendor/github.com/tsuna/gohbase/hrpc/delete.go generated vendored Normal file
View File

@@ -0,0 +1,52 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// DeleteTable represents a DeleteTable HBase call
type DeleteTable struct {
base
}
// NewDeleteTable creates a new DeleteTable request that will delete the
// given table in HBase. For use by the admin client.
func NewDeleteTable(ctx context.Context, table []byte) *DeleteTable {
return &DeleteTable{
base{
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
}
}
// Name returns the name of this RPC call.
func (dt *DeleteTable) Name() string {
return "DeleteTable"
}
// ToProto converts the RPC into a protobuf message
func (dt *DeleteTable) ToProto() proto.Message {
return &pb.DeleteTableRequest{
TableName: &pb.TableName{
// TODO: hadle namespaces properly
Namespace: []byte("default"),
Qualifier: dt.table,
},
}
}
// NewResponse creates an empty protobuf message to read the response of this
// RPC.
func (dt *DeleteTable) NewResponse() proto.Message {
return &pb.DeleteTableResponse{}
}

52
vendor/github.com/tsuna/gohbase/hrpc/disable.go generated vendored Normal file
View File

@@ -0,0 +1,52 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// DisableTable represents a DisableTable HBase call
type DisableTable struct {
base
}
// NewDisableTable creates a new DisableTable request that will disable the
// given table in HBase. For use by the admin client.
func NewDisableTable(ctx context.Context, table []byte) *DisableTable {
return &DisableTable{
base{
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
}
}
// Name returns the name of this RPC call.
func (dt *DisableTable) Name() string {
return "DisableTable"
}
// ToProto converts the RPC into a protobuf message
func (dt *DisableTable) ToProto() proto.Message {
return &pb.DisableTableRequest{
TableName: &pb.TableName{
// TODO: handle namespaces
Namespace: []byte("default"),
Qualifier: dt.table,
},
}
}
// NewResponse creates an empty protobuf message to read the response of this
// RPC.
func (dt *DisableTable) NewResponse() proto.Message {
return &pb.DisableTableResponse{}
}

52
vendor/github.com/tsuna/gohbase/hrpc/enable.go generated vendored Normal file
View File

@@ -0,0 +1,52 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// EnableTable represents a EnableTable HBase call
type EnableTable struct {
base
}
// NewEnableTable creates a new EnableTable request that will enable the
// given table in HBase. For use by the admin client.
func NewEnableTable(ctx context.Context, table []byte) *EnableTable {
return &EnableTable{
base{
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
}
}
// Name returns the name of this RPC call.
func (et *EnableTable) Name() string {
return "EnableTable"
}
// ToProto converts the RPC into a protobuf message
func (et *EnableTable) ToProto() proto.Message {
return &pb.EnableTableRequest{
TableName: &pb.TableName{
// TODO: handle namespaces
Namespace: []byte("default"),
Qualifier: et.table,
},
}
}
// NewResponse creates an empty protobuf message to read the response of this
// RPC.
func (et *EnableTable) NewResponse() proto.Message {
return &pb.EnableTableResponse{}
}

150
vendor/github.com/tsuna/gohbase/hrpc/get.go generated vendored Normal file
View File

@@ -0,0 +1,150 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// Get represents a Get HBase call.
type Get struct {
base
baseQuery
// Don't return any KeyValue, just say whether the row key exists in the
// table or not.
existsOnly bool
skipbatch bool
}
// baseGet returns a Get struct with default values set.
func baseGet(ctx context.Context, table []byte, key []byte,
options ...func(Call) error) (*Get, error) {
g := &Get{
base: base{
key: key,
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
baseQuery: newBaseQuery(),
}
err := applyOptions(g, options...)
if err != nil {
return nil, err
}
return g, nil
}
// NewGet creates a new Get request for the given table and row key.
func NewGet(ctx context.Context, table, key []byte,
options ...func(Call) error) (*Get, error) {
return baseGet(ctx, table, key, options...)
}
// NewGetStr creates a new Get request for the given table and row key.
func NewGetStr(ctx context.Context, table, key string,
options ...func(Call) error) (*Get, error) {
return NewGet(ctx, []byte(table), []byte(key), options...)
}
// Name returns the name of this RPC call.
func (g *Get) Name() string {
return "Get"
}
// SkipBatch returns true if the Get request shouldn't be batched,
// but should be sent to Region Server right away.
func (g *Get) SkipBatch() bool {
return g.skipbatch
}
func (g *Get) setSkipBatch(v bool) {
g.skipbatch = v
}
// ExistsOnly makes this Get request not return any KeyValue, merely whether
// or not the given row key exists in the table.
func (g *Get) ExistsOnly() {
g.existsOnly = true
}
// ToProto converts this RPC into a protobuf message.
func (g *Get) ToProto() proto.Message {
get := &pb.GetRequest{
Region: g.regionSpecifier(),
Get: &pb.Get{
Row: g.key,
Column: familiesToColumn(g.families),
TimeRange: &pb.TimeRange{},
},
}
/* added support for limit number of cells per row */
if g.storeLimit != DefaultMaxResultsPerColumnFamily {
get.Get.StoreLimit = &g.storeLimit
}
if g.storeOffset != 0 {
get.Get.StoreOffset = &g.storeOffset
}
if g.maxVersions != DefaultMaxVersions {
get.Get.MaxVersions = &g.maxVersions
}
if g.fromTimestamp != MinTimestamp {
get.Get.TimeRange.From = &g.fromTimestamp
}
if g.toTimestamp != MaxTimestamp {
get.Get.TimeRange.To = &g.toTimestamp
}
if g.existsOnly {
get.Get.ExistenceOnly = proto.Bool(true)
}
get.Get.Filter = g.filter
return get
}
// NewResponse creates an empty protobuf message to read the response of this
// RPC.
func (g *Get) NewResponse() proto.Message {
return &pb.GetResponse{}
}
// DeserializeCellBlocks deserializes get result from cell blocks
func (g *Get) DeserializeCellBlocks(m proto.Message, b []byte) (uint32, error) {
resp := m.(*pb.GetResponse)
if resp.Result == nil {
// TODO: is this possible?
return 0, nil
}
cells, read, err := deserializeCellBlocks(b, uint32(resp.Result.GetAssociatedCellCount()))
if err != nil {
return 0, err
}
resp.Result.Cell = append(resp.Result.Cell, cells...)
return read, nil
}
// familiesToColumn takes a map from strings to lists of strings, and converts
// them into protobuf Columns
func familiesToColumn(families map[string][]string) []*pb.Column {
cols := make([]*pb.Column, len(families))
counter := 0
for family, qualifiers := range families {
bytequals := make([][]byte, len(qualifiers))
for i, qual := range qualifiers {
bytequals[i] = []byte(qual)
}
cols[counter] = &pb.Column{
Family: []byte(family),
Qualifier: bytequals,
}
counter++
}
return cols
}

397
vendor/github.com/tsuna/gohbase/hrpc/mutate.go generated vendored Normal file
View File

@@ -0,0 +1,397 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"encoding/binary"
"errors"
"time"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
var (
// ErrNotAStruct is returned by any of the *Ref functions when something
// other than a struct is passed in to their data argument
ErrNotAStruct = errors.New("data must be a struct")
// ErrUnsupportedUints is returned when this message is serialized and uints
// are unsupported on your platform (this will probably never happen)
ErrUnsupportedUints = errors.New("uints are unsupported on your platform")
// ErrUnsupportedInts is returned when this message is serialized and ints
// are unsupported on your platform (this will probably never happen)
ErrUnsupportedInts = errors.New("ints are unsupported on your platform")
attributeNameTTL = "_ttl"
)
// DurabilityType is used to set durability for Durability option
type DurabilityType int32
const (
// UseDefault is USER_DEFAULT
UseDefault DurabilityType = iota
// SkipWal is SKIP_WAL
SkipWal
// AsyncWal is ASYNC_WAL
AsyncWal
// SyncWal is SYNC_WAL
SyncWal
// FsyncWal is FSYNC_WAL
FsyncWal
)
// Mutate represents a mutation on HBase.
type Mutate struct {
base
mutationType pb.MutationProto_MutationType //*int32
// values is a map of column families to a map of column qualifiers to bytes
values map[string]map[string][]byte
ttl []byte
timestamp uint64
durability DurabilityType
deleteOneVersion bool
skipbatch bool
}
// TTL sets a time-to-live for mutation queries.
// The value will be in millisecond resolution.
func TTL(t time.Duration) func(Call) error {
return func(o Call) error {
m, ok := o.(*Mutate)
if !ok {
return errors.New("'TTL' option can only be used with mutation queries")
}
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(t.Nanoseconds()/1e6))
m.ttl = buf
return nil
}
}
// Timestamp sets timestamp for mutation queries.
// The time object passed will be rounded to a millisecond resolution, as by default,
// if no timestamp is provided, HBase sets it to current time in milliseconds.
// In order to have custom time precision, use TimestampUint64 call option for
// mutation requests and corresponding TimeRangeUint64 for retrieval requests.
func Timestamp(ts time.Time) func(Call) error {
return func(o Call) error {
m, ok := o.(*Mutate)
if !ok {
return errors.New("'Timestamp' option can only be used with mutation queries")
}
m.timestamp = uint64(ts.UnixNano() / 1e6)
return nil
}
}
// TimestampUint64 sets timestamp for mutation queries.
func TimestampUint64(ts uint64) func(Call) error {
return func(o Call) error {
m, ok := o.(*Mutate)
if !ok {
return errors.New("'TimestampUint64' option can only be used with mutation queries")
}
m.timestamp = ts
return nil
}
}
// Durability sets durability for mutation queries.
func Durability(d DurabilityType) func(Call) error {
return func(o Call) error {
m, ok := o.(*Mutate)
if !ok {
return errors.New("'Durability' option can only be used with mutation queries")
}
if d < UseDefault || d > FsyncWal {
return errors.New("invalid durability value")
}
m.durability = d
return nil
}
}
// DeleteOneVersion is a delete option that can be passed in order to delete only
// one latest version of the specified qualifiers. Without timestamp specified,
// it will have no effect for delete specific column families request.
// If a Timestamp option is passed along, only the version at that timestamp will be removed
// for delete specific column families and/or qualifier request.
// This option cannot be used for delete entire row request.
func DeleteOneVersion() func(Call) error {
return func(o Call) error {
m, ok := o.(*Mutate)
if !ok {
return errors.New("'DeleteOneVersion' option can only be used with mutation queries")
}
m.deleteOneVersion = true
return nil
}
}
// baseMutate returns a Mutate struct without the mutationType filled in.
func baseMutate(ctx context.Context, table, key []byte, values map[string]map[string][]byte,
options ...func(Call) error) (*Mutate, error) {
m := &Mutate{
base: base{
table: table,
key: key,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
values: values,
timestamp: MaxTimestamp,
}
err := applyOptions(m, options...)
if err != nil {
return nil, err
}
return m, nil
}
// NewPut creates a new Mutation request to insert the given
// family-column-values in the given row key of the given table.
func NewPut(ctx context.Context, table, key []byte,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
m, err := baseMutate(ctx, table, key, values, options...)
if err != nil {
return nil, err
}
m.mutationType = pb.MutationProto_PUT
return m, nil
}
// NewPutStr is just like NewPut but takes table and key as strings.
func NewPutStr(ctx context.Context, table, key string,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
return NewPut(ctx, []byte(table), []byte(key), values, options...)
}
// NewDel is used to perform Delete operations on a single row.
// To delete entire row, values should be nil.
//
// To delete specific families, qualifiers map should be nil:
// map[string]map[string][]byte{
// "cf1": nil,
// "cf2": nil,
// }
//
// To delete specific qualifiers:
// map[string]map[string][]byte{
// "cf": map[string][]byte{
// "q1": nil,
// "q2": nil,
// },
// }
//
// To delete all versions before and at a timestamp, pass hrpc.Timestamp() option.
// By default all versions will be removed.
//
// To delete only a specific version at a timestamp, pass hrpc.DeleteOneVersion() option
// along with a timestamp. For delete specific qualifiers request, if timestamp is not
// passed, only the latest version will be removed. For delete specific families request,
// the timestamp should be passed or it will have no effect as it's an expensive
// operation to perform.
func NewDel(ctx context.Context, table, key []byte,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
m, err := baseMutate(ctx, table, key, values, options...)
if err != nil {
return nil, err
}
if len(m.values) == 0 && m.deleteOneVersion {
return nil, errors.New(
"'DeleteOneVersion' option cannot be specified for delete entire row request")
}
m.mutationType = pb.MutationProto_DELETE
return m, nil
}
// NewDelStr is just like NewDel but takes table and key as strings.
func NewDelStr(ctx context.Context, table, key string,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
return NewDel(ctx, []byte(table), []byte(key), values, options...)
}
// NewApp creates a new Mutation request to append the given
// family-column-values into the existing cells in HBase (or create them if
// needed), in given row key of the given table.
func NewApp(ctx context.Context, table, key []byte,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
m, err := baseMutate(ctx, table, key, values, options...)
if err != nil {
return nil, err
}
m.mutationType = pb.MutationProto_APPEND
return m, nil
}
// NewAppStr is just like NewApp but takes table and key as strings.
func NewAppStr(ctx context.Context, table, key string,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
return NewApp(ctx, []byte(table), []byte(key), values, options...)
}
// NewIncSingle creates a new Mutation request that will increment the given value
// by amount in HBase under the given table, key, family and qualifier.
func NewIncSingle(ctx context.Context, table, key []byte, family, qualifier string,
amount int64, options ...func(Call) error) (*Mutate, error) {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, uint64(amount))
value := map[string]map[string][]byte{family: map[string][]byte{qualifier: buf}}
return NewInc(ctx, table, key, value, options...)
}
// NewIncStrSingle is just like NewIncSingle but takes table and key as strings.
func NewIncStrSingle(ctx context.Context, table, key, family, qualifier string,
amount int64, options ...func(Call) error) (*Mutate, error) {
return NewIncSingle(ctx, []byte(table), []byte(key), family, qualifier, amount, options...)
}
// NewInc creates a new Mutation request that will increment the given values
// in HBase under the given table and key.
func NewInc(ctx context.Context, table, key []byte,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
m, err := baseMutate(ctx, table, key, values, options...)
if err != nil {
return nil, err
}
m.mutationType = pb.MutationProto_INCREMENT
return m, nil
}
// NewIncStr is just like NewInc but takes table and key as strings.
func NewIncStr(ctx context.Context, table, key string,
values map[string]map[string][]byte, options ...func(Call) error) (*Mutate, error) {
return NewInc(ctx, []byte(table), []byte(key), values, options...)
}
// Name returns the name of this RPC call.
func (m *Mutate) Name() string {
return "Mutate"
}
// SkipBatch returns true if the Mutate request shouldn't be batched,
// but should be sent to Region Server right away.
func (m *Mutate) SkipBatch() bool {
return m.skipbatch
}
func (m *Mutate) setSkipBatch(v bool) {
m.skipbatch = v
}
func (m *Mutate) toProto() *pb.MutateRequest {
var ts *uint64
if m.timestamp != MaxTimestamp {
ts = &m.timestamp
}
// We need to convert everything in the values field
// to a protobuf ColumnValue
cvs := make([]*pb.MutationProto_ColumnValue, len(m.values))
i := 0
for k, v := range m.values {
// And likewise, each item in each column needs to be converted to a
// protobuf QualifierValue
// if it's a delete, figure out the type
var dt *pb.MutationProto_DeleteType
if m.mutationType == pb.MutationProto_DELETE {
if len(v) == 0 {
// delete the whole column family
if m.deleteOneVersion {
dt = pb.MutationProto_DELETE_FAMILY_VERSION.Enum()
} else {
dt = pb.MutationProto_DELETE_FAMILY.Enum()
}
// add empty qualifier
if v == nil {
v = make(map[string][]byte)
}
v[""] = nil
} else {
// delete specific qualifiers
if m.deleteOneVersion {
dt = pb.MutationProto_DELETE_ONE_VERSION.Enum()
} else {
dt = pb.MutationProto_DELETE_MULTIPLE_VERSIONS.Enum()
}
}
}
qvs := make([]*pb.MutationProto_ColumnValue_QualifierValue, len(v))
j := 0
for k1, v1 := range v {
qvs[j] = &pb.MutationProto_ColumnValue_QualifierValue{
Qualifier: []byte(k1),
Value: v1,
Timestamp: ts,
DeleteType: dt,
}
j++
}
cvs[i] = &pb.MutationProto_ColumnValue{
Family: []byte(k),
QualifierValue: qvs,
}
i++
}
mProto := &pb.MutationProto{
Row: m.key,
MutateType: &m.mutationType,
ColumnValue: cvs,
Durability: pb.MutationProto_Durability(m.durability).Enum(),
Timestamp: ts,
}
if len(m.ttl) > 0 {
mProto.Attribute = append(mProto.Attribute, &pb.NameBytesPair{
Name: &attributeNameTTL,
Value: m.ttl,
})
}
return &pb.MutateRequest{
Region: m.regionSpecifier(),
Mutation: mProto,
}
}
// ToProto converts this mutate RPC into a protobuf message
func (m *Mutate) ToProto() proto.Message {
return m.toProto()
}
// NewResponse creates an empty protobuf message to read the response of this RPC.
func (m *Mutate) NewResponse() proto.Message {
return &pb.MutateResponse{}
}
// DeserializeCellBlocks deserializes mutate result from cell blocks
func (m *Mutate) DeserializeCellBlocks(pm proto.Message, b []byte) (uint32, error) {
resp := pm.(*pb.MutateResponse)
if resp.Result == nil {
// TODO: is this possible?
return 0, nil
}
cells, read, err := deserializeCellBlocks(b, uint32(resp.Result.GetAssociatedCellCount()))
if err != nil {
return 0, err
}
resp.Result.Cell = append(resp.Result.Cell, cells...)
return read, nil
}

46
vendor/github.com/tsuna/gohbase/hrpc/procedure.go generated vendored Normal file
View File

@@ -0,0 +1,46 @@
// Copyright (C) 2016 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// GetProcedureState represents a call to HBase to check status of a procedure
type GetProcedureState struct {
base
procID uint64
}
// NewGetProcedureState creates a new GetProcedureState request. For use by the admin client.
func NewGetProcedureState(ctx context.Context, procID uint64) *GetProcedureState {
return &GetProcedureState{
base: base{
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
procID: procID,
}
}
// Name returns the name of this RPC call.
func (ps *GetProcedureState) Name() string {
return "getProcedureResult"
}
// ToProto converts the RPC into a protobuf message
func (ps *GetProcedureState) ToProto() proto.Message {
return &pb.GetProcedureResultRequest{ProcId: &ps.procID}
}
// NewResponse creates an empty protobuf message to read the response of this RPC.
func (ps *GetProcedureState) NewResponse() proto.Message {
return &pb.GetProcedureResultResponse{}
}

153
vendor/github.com/tsuna/gohbase/hrpc/query.go generated vendored Normal file
View File

@@ -0,0 +1,153 @@
// Copyright (C) 2017 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"errors"
"math"
"time"
"github.com/tsuna/gohbase/filter"
"github.com/tsuna/gohbase/pb"
)
// baseQuery bundles common fields that can be provided for quering requests: Scans and Gets
type baseQuery struct {
families map[string][]string
filter *pb.Filter
fromTimestamp uint64
toTimestamp uint64
maxVersions uint32
storeLimit uint32
storeOffset uint32
}
// newBaseQuery return baseQuery with all default values
func newBaseQuery() baseQuery {
return baseQuery{
storeLimit: DefaultMaxResultsPerColumnFamily,
fromTimestamp: MinTimestamp,
toTimestamp: MaxTimestamp,
maxVersions: DefaultMaxVersions,
}
}
func (bq *baseQuery) setFamilies(families map[string][]string) {
bq.families = families
}
func (bq *baseQuery) setFilter(filter *pb.Filter) {
bq.filter = filter
}
func (bq *baseQuery) setTimeRangeUint64(from, to uint64) {
bq.fromTimestamp = from
bq.toTimestamp = to
}
func (bq *baseQuery) setMaxVersions(versions uint32) {
bq.maxVersions = versions
}
func (bq *baseQuery) setMaxResultsPerColumnFamily(maxresults uint32) {
bq.storeLimit = maxresults
}
func (bq *baseQuery) setResultOffset(offset uint32) {
bq.storeOffset = offset
}
// Families option adds families constraint to a Scan or Get request.
func Families(f map[string][]string) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
c.setFamilies(f)
return nil
}
return errors.New("'Families' option can only be used with Get or Scan request")
}
}
// Filters option adds filters constraint to a Scan or Get request.
func Filters(f filter.Filter) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
pbF, err := f.ConstructPBFilter()
if err != nil {
return err
}
c.setFilter(pbF)
return nil
}
return errors.New("'Filters' option can only be used with Get or Scan request")
}
}
// TimeRange is used as a parameter for request creation. Adds TimeRange constraint to a request.
// It will get values in range [from, to[ ('to' is exclusive).
func TimeRange(from, to time.Time) func(Call) error {
return TimeRangeUint64(uint64(from.UnixNano()/1e6), uint64(to.UnixNano()/1e6))
}
// TimeRangeUint64 is used as a parameter for request creation.
// Adds TimeRange constraint to a request.
// from and to should be in milliseconds
// // It will get values in range [from, to[ ('to' is exclusive).
func TimeRangeUint64(from, to uint64) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
if from >= to {
// or equal is becuase 'to' is exclusive
return errors.New("'from' timestamp is greater or equal to 'to' timestamp")
}
c.setTimeRangeUint64(from, to)
return nil
}
return errors.New("'TimeRange' option can only be used with Get or Scan request")
}
}
// MaxVersions is used as a parameter for request creation.
// Adds MaxVersions constraint to a request.
func MaxVersions(versions uint32) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
if versions > math.MaxInt32 {
return errors.New("'MaxVersions' exceeds supported number of versions")
}
c.setMaxVersions(versions)
return nil
}
return errors.New("'MaxVersions' option can only be used with Get or Scan request")
}
}
// MaxResultsPerColumnFamily is an option for Get or Scan requests that sets the maximum
// number of cells returned per column family in a row.
func MaxResultsPerColumnFamily(maxresults uint32) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
if maxresults > math.MaxInt32 {
return errors.New(
"'MaxResultsPerColumnFamily' exceeds supported number of value results")
}
c.setMaxResultsPerColumnFamily(maxresults)
return nil
}
return errors.New(
"'MaxResultsPerColumnFamily' option can only be used with Get or Scan request")
}
}
// ResultOffset is a option for Scan or Get requests that sets the offset for cells
// within a column family.
func ResultOffset(offset uint32) func(Call) error {
return func(hc Call) error {
if c, ok := hc.(hasQueryOptions); ok {
if offset > math.MaxInt32 {
return errors.New("'ResultOffset' exceeds supported offset value")
}
c.setResultOffset(offset)
return nil
}
return errors.New("'ResultOffset' option can only be used with Get or Scan request")
}
}

333
vendor/github.com/tsuna/gohbase/hrpc/scan.go generated vendored Normal file
View File

@@ -0,0 +1,333 @@
// Copyright (C) 2015 The GoHBase Authors. All rights reserved.
// This file is part of GoHBase.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.
package hrpc
import (
"context"
"errors"
"fmt"
"math"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
const (
// DefaultMaxVersions defualt value for maximum versions to return for scan queries
DefaultMaxVersions uint32 = 1
// MinTimestamp default value for minimum timestamp for scan queries
MinTimestamp uint64 = 0
// MaxTimestamp default value for maximum timestamp for scan queries
MaxTimestamp = math.MaxUint64
// DefaultMaxResultSize Maximum number of bytes fetched when calling a scanner's
// next method. The default value is 2MB, which is good for 1ge networks.
// With faster and/or high latency networks this value should be increased.
DefaultMaxResultSize = 2097152
// DefaultNumberOfRows is default maximum number of rows fetched by scanner
DefaultNumberOfRows = math.MaxInt32
// DefaultMaxResultsPerColumnFamily is the default max number of cells fetched
// per column family for each row
DefaultMaxResultsPerColumnFamily = math.MaxInt32
)
// Scanner is used to read data sequentially from HBase.
// Scanner will be automatically closed if there's no more data to read,
// otherwise Close method should be called.
type Scanner interface {
// Next returns a row at a time.
// Once all rows are returned, subsequent calls will return io.EOF error.
//
// In case of an error, only the first call to Next() will return partial
// result (could be not a complete row) and the actual error,
// the subsequent calls will return io.EOF error.
Next() (*Result, error)
// Close should be called if it is desired to stop scanning before getting all of results.
// If you call Next() after calling Close() you might still get buffered results.
// Othwerwise, in case all results have been delivered or in case of an error, the Scanner
// will be closed automatically.
Close() error
}
// Scan represents a scanner on an HBase table.
type Scan struct {
base
baseQuery
startRow []byte
stopRow []byte
scannerID uint64
maxResultSize uint64
numberOfRows uint32
reversed bool
closeScanner bool
allowPartialResults bool
}
// baseScan returns a Scan struct with default values set.
func baseScan(ctx context.Context, table []byte,
options ...func(Call) error) (*Scan, error) {
s := &Scan{
base: base{
table: table,
ctx: ctx,
resultch: make(chan RPCResult, 1),
},
baseQuery: newBaseQuery(),
scannerID: math.MaxUint64,
maxResultSize: DefaultMaxResultSize,
numberOfRows: DefaultNumberOfRows,
reversed: false,
}
err := applyOptions(s, options...)
if err != nil {
return nil, err
}
return s, nil
}
func (s *Scan) String() string {
return fmt.Sprintf("Scan{Table=%q StartRow=%q StopRow=%q TimeRange=(%d, %d) "+
"MaxVersions=%d NumberOfRows=%d MaxResultSize=%d Familes=%v Filter=%v "+
"StoreLimit=%d StoreOffset=%d ScannerID=%d Close=%v}",
s.table, s.startRow, s.stopRow, s.fromTimestamp, s.toTimestamp,
s.maxVersions, s.numberOfRows, s.maxResultSize, s.families, s.filter,
s.storeLimit, s.storeOffset, s.scannerID, s.closeScanner)
}
// NewScan creates a scanner for the given table.
func NewScan(ctx context.Context, table []byte, options ...func(Call) error) (*Scan, error) {
return baseScan(ctx, table, options...)
}
// NewScanRange creates a scanner for the given table and key range.
// The range is half-open, i.e. [startRow; stopRow[ -- stopRow is not
// included in the range.
func NewScanRange(ctx context.Context, table, startRow, stopRow []byte,
options ...func(Call) error) (*Scan, error) {
scan, err := baseScan(ctx, table, options...)
if err != nil {
return nil, err
}
scan.startRow = startRow
scan.stopRow = stopRow
scan.key = startRow
return scan, nil
}
// NewScanStr creates a scanner for the given table.
func NewScanStr(ctx context.Context, table string, options ...func(Call) error) (*Scan, error) {
return NewScan(ctx, []byte(table), options...)
}
// NewScanRangeStr creates a scanner for the given table and key range.
// The range is half-open, i.e. [startRow; stopRow[ -- stopRow is not
// included in the range.
func NewScanRangeStr(ctx context.Context, table, startRow, stopRow string,
options ...func(Call) error) (*Scan, error) {
return NewScanRange(ctx, []byte(table), []byte(startRow), []byte(stopRow), options...)
}
// Name returns the name of this RPC call.
func (s *Scan) Name() string {
return "Scan"
}
// StopRow returns the end key (exclusive) of this scanner.
func (s *Scan) StopRow() []byte {
return s.stopRow
}
// StartRow returns the start key (inclusive) of this scanner.
func (s *Scan) StartRow() []byte {
return s.startRow
}
// IsClosing returns wether this scan closes scanner prematurely
func (s *Scan) IsClosing() bool {
return s.closeScanner
}
// AllowPartialResults returns true if client handles partials.
func (s *Scan) AllowPartialResults() bool {
return s.allowPartialResults
}
// Reversed returns true if scanner scans in reverse.
func (s *Scan) Reversed() bool {
return s.reversed
}
// NumberOfRows returns how many rows this scan
// fetches from regionserver in a single response.
func (s *Scan) NumberOfRows() uint32 {
return s.numberOfRows
}
// ToProto converts this Scan into a protobuf message
func (s *Scan) ToProto() proto.Message {
scan := &pb.ScanRequest{
Region: s.regionSpecifier(),
CloseScanner: &s.closeScanner,
NumberOfRows: &s.numberOfRows,
// tell server that we can process results that are only part of a row
ClientHandlesPartials: proto.Bool(true),
// tell server that we "handle" heartbeats by ignoring them
// since we don't really time out our scans (unless context was cancelled)
ClientHandlesHeartbeats: proto.Bool(true),
}
if s.scannerID != math.MaxUint64 {
scan.ScannerId = &s.scannerID
return scan
}
scan.Scan = &pb.Scan{
Column: familiesToColumn(s.families),
StartRow: s.startRow,
StopRow: s.stopRow,
TimeRange: &pb.TimeRange{},
MaxResultSize: &s.maxResultSize,
}
if s.maxVersions != DefaultMaxVersions {
scan.Scan.MaxVersions = &s.maxVersions
}
/* added support for limit number of cells per row */
if s.storeLimit != DefaultMaxResultsPerColumnFamily {
scan.Scan.StoreLimit = &s.storeLimit
}
if s.storeOffset != 0 {
scan.Scan.StoreOffset = &s.storeOffset
}
if s.fromTimestamp != MinTimestamp {
scan.Scan.TimeRange.From = &s.fromTimestamp
}
if s.toTimestamp != MaxTimestamp {
scan.Scan.TimeRange.To = &s.toTimestamp
}
if s.reversed {
scan.Scan.Reversed = &s.reversed
}
scan.Scan.Filter = s.filter
return scan
}
// NewResponse creates an empty protobuf message to read the response
// of this RPC.
func (s *Scan) NewResponse() proto.Message {
return &pb.ScanResponse{}
}
// DeserializeCellBlocks deserializes scan results from cell blocks
func (s *Scan) DeserializeCellBlocks(m proto.Message, b []byte) (uint32, error) {
scanResp := m.(*pb.ScanResponse)
partials := scanResp.GetPartialFlagPerResult()
scanResp.Results = make([]*pb.Result, len(partials))
var readLen uint32
for i, numCells := range scanResp.GetCellsPerResult() {
cells, l, err := deserializeCellBlocks(b[readLen:], numCells)
if err != nil {
return 0, err
}
scanResp.Results[i] = &pb.Result{
Cell: cells,
Partial: proto.Bool(partials[i]),
}
readLen += l
}
return readLen, nil
}
// ScannerID is an option for scan requests.
// This is an internal option to fetch the next set of results for an ongoing scan.
func ScannerID(id uint64) func(Call) error {
return func(s Call) error {
scan, ok := s.(*Scan)
if !ok {
return errors.New("'ScannerID' option can only be used with Scan queries")
}
scan.scannerID = id
return nil
}
}
// CloseScanner is an option for scan requests.
// Closes scanner after the first result is returned. This is an internal option
// but could be useful if you know that your scan result fits into one response
// in order to save an extra request.
func CloseScanner() func(Call) error {
return func(s Call) error {
scan, ok := s.(*Scan)
if !ok {
return errors.New("'Close' option can only be used with Scan queries")
}
scan.closeScanner = true
return nil
}
}
// MaxResultSize is an option for scan requests.
// Maximum number of bytes fetched when calling a scanner's next method.
// MaxResultSize takes priority over NumberOfRows.
func MaxResultSize(n uint64) func(Call) error {
return func(g Call) error {
scan, ok := g.(*Scan)
if !ok {
return errors.New("'MaxResultSize' option can only be used with Scan queries")
}
if n == 0 {
return errors.New("'MaxResultSize' option must be greater than 0")
}
scan.maxResultSize = n
return nil
}
}
// NumberOfRows is an option for scan requests.
// Specifies how many rows are fetched with each request to regionserver.
// Should be > 0, avoid extremely low values such as 1 because a request
// to regionserver will be made for every row.
func NumberOfRows(n uint32) func(Call) error {
return func(g Call) error {
scan, ok := g.(*Scan)
if !ok {
return errors.New("'NumberOfRows' option can only be used with Scan queries")
}
scan.numberOfRows = n
return nil
}
}
// AllowPartialResults is an option for scan requests.
// This option should be provided if the client has really big rows and
// wants to avoid OOM errors on her side. With this option provided, Next()
// will return partial rows.
func AllowPartialResults() func(Call) error {
return func(g Call) error {
scan, ok := g.(*Scan)
if !ok {
return errors.New("'AllowPartialResults' option can only be used with Scan queries")
}
scan.allowPartialResults = true
return nil
}
}
// Reversed is a Scan-only option which allows you to scan in reverse key order
// To use it the startKey would be greater than the end key
func Reversed() func(Call) error {
return func(g Call) error {
scan, ok := g.(*Scan)
if !ok {
return errors.New("'Reversed' option can only be used with Scan queries")
}
scan.reversed = true
return nil
}
}

39
vendor/github.com/tsuna/gohbase/hrpc/status.go generated vendored Normal file
View File

@@ -0,0 +1,39 @@
package hrpc
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/tsuna/gohbase/pb"
)
// ClusterStatus to represent a cluster status request
type ClusterStatus struct {
base
}
// NewClusterStatus creates a new ClusterStatusStruct with default fields
func NewClusterStatus() *ClusterStatus {
return &ClusterStatus{
base{
ctx: context.Background(),
table: []byte{},
resultch: make(chan RPCResult, 1),
},
}
}
// Name returns the name of the rpc function
func (c *ClusterStatus) Name() string {
return "GetClusterStatus"
}
// ToProto returns the Protobuf message to be sent
func (c *ClusterStatus) ToProto() proto.Message {
return &pb.GetClusterStatusRequest{}
}
// NewResponse returns the empty protobuf response
func (c *ClusterStatus) NewResponse() proto.Message {
return &pb.GetClusterStatusResponse{}
}