diff --git a/admin_client.go b/admin_client.go index 9877705..3f73c89 100644 --- a/admin_client.go +++ b/admin_client.go @@ -15,7 +15,6 @@ package zetta import ( "context" - "log" "time" "github.com/zhihu/zetta-client-go/utils/retry" @@ -41,12 +40,13 @@ type AdminClient struct { pbCli tspb.TablestoreAdminClient } -func NewAdminClient(addr string) (*AdminClient, error) { - conn, err := grpc.Dial(addr, grpc.WithInsecure()) +func NewAdminClient(addr string, opts ...grpc.DialOption) (*AdminClient, error) { + opts = append(opts, grpc.WithInsecure()) + + conn, err := grpc.Dial(addr, opts...) if err != nil { return nil, err } - log.Println(addr) return &AdminClient{ conn: conn, pbCli: tspb.NewTablestoreAdminClient(conn), diff --git a/admin_ddl.go b/admin_ddl.go index 8a4c8a0..49d5528 100644 --- a/admin_ddl.go +++ b/admin_ddl.go @@ -26,7 +26,6 @@ import ( // Create a table func (ac *AdminClient) CreateTable(ctx context.Context, db string, tableMeta *tspb.TableMeta, indexMetas []*tspb.IndexMeta) error { - tableMeta.Database = db in := &tspb.CreateTableRequest{ Database: db, TableMeta: tableMeta, diff --git a/data_client.go b/data_client.go index 4029028..84a0109 100644 --- a/data_client.go +++ b/data_client.go @@ -28,8 +28,6 @@ import ( ) const ( - SPARSE_READ = "sparseread" - // numChannels is the default value for NumChannels of client numChannels = 4 ) @@ -50,6 +48,8 @@ type DataClient struct { type DataClientConfig struct { NumChannels int // 并发度,对应 session pool + RecvMsgSize int + DialOptions []grpc.DialOption SessionPoolConfig } @@ -65,10 +65,17 @@ func NewDataClient(ctx context.Context, serverAddr, dbName string, conf DataClie if conf.MaxBurst == 0 { conf.MaxBurst = DefaultSessionPoolConfig.MaxBurst } + if conf.RecvMsgSize == 0 { + conf.RecvMsgSize = 64 * 1000 * 1000 + } dc := &DataClient{database: dbName} - dialOpts := []grpc.DialOption{grpc.WithInsecure()} + dialOpts := []grpc.DialOption{ + grpc.WithInsecure(), + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(conf.RecvMsgSize)), + } + dialOpts = append(dialOpts, conf.DialOptions...) rsTarget := ParseTarget(serverAddr) if strings.ToLower(rsTarget.Scheme) == "dns" { @@ -246,7 +253,7 @@ func (dc *DataClient) Read(ctx context.Context, table string, keys KeySet, index if err != nil { return nil, err } - keysProto, err := keys.proto() + keysProto, err := keys.keySetProto() if err != nil { return nil, err } @@ -271,6 +278,8 @@ func (dc *DataClient) Read(ctx context.Context, table string, keys KeySet, index Columns: columns, Limit: limit, } + + res, err := sh.getClient().Read(ctx, req) defer func() { if sh != nil { if shouldDropSession(err) { @@ -279,7 +288,6 @@ func (dc *DataClient) Read(ctx context.Context, table string, keys KeySet, index sh.recycle() } }() - res, err := sh.getClient().Read(ctx, req) if err != nil { return nil, err } @@ -288,8 +296,6 @@ func (dc *DataClient) Read(ctx context.Context, table string, keys KeySet, index } func (dc *DataClient) SparseRead(ctx context.Context, table, family string, rows []*SparseRow, limit int64) (*SparseResultSet, error) { - metricCount(SPARSE_READ) - t := metricStartTiming() sh, err := dc.sp.take(ctx) if err != nil { return nil, err @@ -325,12 +331,55 @@ func (dc *DataClient) SparseRead(ctx context.Context, table, family string, rows Limit: limit, } res, err := sh.getClient().SparseRead(ctx, req) + defer func() { + if sh != nil { + if shouldDropSession(err) { + sh.destroy() + } + sh.recycle() + } + }() + if err != nil { + return nil, err + } + + return BuildSparseResultSet(res), nil +} + +func (dc *DataClient) SparseScan(ctx context.Context, table, family string, keys KeySet, limit int64) (*SparseResultSet, error) { + sh, err := dc.sp.take(ctx) + if err != nil { + return nil, err + } + keysProto, err := keys.keySetProto() + if err != nil { + return nil, err + } + session := sh.getID() + + req := &tspb.SparseScanRequest{ + Session: session, + Transaction: &tspb.TransactionSelector{ + Selector: &tspb.TransactionSelector_SingleUse{ + SingleUse: &tspb.TransactionOptions{ + Mode: &tspb.TransactionOptions_ReadOnly_{ + ReadOnly: &tspb.TransactionOptions_ReadOnly{ + TimestampBound: &tspb.TransactionOptions_ReadOnly_Strong{Strong: true}, + }, + }, + }, + }, + }, + Table: table, + Family: family, + KeySet: keysProto, + Limit: limit, + } + res, err := sh.getClient().SparseScan(ctx, req) if err != nil { - metricCountError(SPARSE_READ) return nil, err } defer func() { - metricRecordTiming(t, SPARSE_READ) if sh != nil { if shouldDropSession(err) { sh.destroy() diff --git a/examples/simple/main.go b/examples/simple/main.go index 917b480..707e37c 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -65,7 +65,8 @@ func main() { func writeTable(client *zetta.DataClient) { cols := []string{"name", "age"} vals := []interface{}{"user-01", "18"} - rawMS := zetta.InsertOrUpdate(TABLE_NAME, cols, vals) + pkey := zetta.Key{"user-01"} + rawMS := zetta.InsertOrUpdate(TABLE_NAME, pkey, "default", cols, vals) err := client.Mutate(context.Background(), rawMS) if err != nil { panic(err) @@ -103,9 +104,8 @@ func readTable(client *zetta.DataClient) { PartitionToken: nil, } - keys := zetta.KeySet{ - Keys: []zetta.Key{[]interface{}{"user-01"}}, - } + keys := zetta.Key{"user-01"} + resp, err := client.Read(context.Background(), in.Table, keys, "", in.Columns, 10) if err != nil { panic(err) @@ -194,8 +194,9 @@ func createTable() { func writeMutations() { cols := []string{"id", "age"} vs := []interface{}{1, 20} + pkey := zetta.Key{"id"} mutations := []*zetta.Mutation{ - zetta.Insert(DB_NAME, cols, vs), + zetta.InsertOrUpdate(DB_NAME, pkey, "default", cols, vs), } ctx := context.Background() t, err := dataClient.Apply(ctx, mutations) diff --git a/extension.go b/extension.go index 0723e65..ef692e4 100644 --- a/extension.go +++ b/extension.go @@ -33,11 +33,12 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { } acode = t.ArrayElementType.Code } - typeErr := errTypeMismatch(code, false, ptr) - if code == tspb.TypeCode_ARRAY { - typeErr = errTypeMismatch(acode, true, ptr) + typeErr := func() error { + if code == tspb.TypeCode_ARRAY { + return errTypeMismatch(acode, true, ptr) + } + return errTypeMismatch(code, false, ptr) } - nullErr := errDstNotForNull(ptr) _, isNull := v.Kind.(*tspb.Value_NullValue) // Do the decoding based on the type of ptr. @@ -49,7 +50,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if isNull { - return nullErr + return errDstNotForNull(ptr) } x, err := getStringValue(v) if err != nil { @@ -75,7 +76,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_STRING { - return typeErr + return typeErr() } if isNull { *p = nil @@ -130,7 +131,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { } if isNull { - return nullErr + return errDstNotForNull(ptr) } x, err := getInteger64Value(v) if err != nil { @@ -178,10 +179,10 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_BOOL { - return typeErr + return typeErr() } if isNull { - return nullErr + return errDstNotForNull(ptr) } x, err := getBoolValue(v) if err != nil { @@ -193,7 +194,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_BOOL { - return typeErr + return typeErr() } if isNull { *p = NullBool{} @@ -210,7 +211,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_BOOL { - return typeErr + return typeErr() } if isNull { *p = nil @@ -230,10 +231,10 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_FLOAT64 { - return typeErr + return typeErr() } if isNull { - return nullErr + return errDstNotForNull(ptr) } x, err := getFloat64Value(v) if err != nil { @@ -245,7 +246,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_FLOAT64 { - return typeErr + return typeErr() } if isNull { *p = NullFloat64{} @@ -262,7 +263,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_FLOAT64 { - return typeErr + return typeErr() } if isNull { *p = nil @@ -280,7 +281,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { case *time.Time: var nt NullTime if isNull { - return nullErr + return errDstNotForNull(ptr) } err := parseNullTime(v, &nt, code, isNull) if err != nil { @@ -297,7 +298,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_TIMESTAMP { - return typeErr + return typeErr() } if isNull { *p = nil @@ -317,10 +318,10 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_DATE { - return typeErr + return typeErr() } if isNull { - return nullErr + return errDstNotForNull(ptr) } x, err := getStringValue(v) if err != nil { @@ -336,7 +337,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if code != tspb.TypeCode_DATE { - return typeErr + return typeErr() } if isNull { *p = NullDate{} @@ -357,7 +358,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_DATE { - return typeErr + return typeErr() } if isNull { *p = nil @@ -377,7 +378,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { return errNilDst(p) } if acode != tspb.TypeCode_STRUCT { - return typeErr + return typeErr() } if isNull { *p = nil @@ -402,7 +403,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { default: // Check if the proto encoding is for an array of structs. if !(code == tspb.TypeCode_ARRAY && acode == tspb.TypeCode_STRUCT) { - return typeErr + return typeErr() } vp := reflect.ValueOf(p) if !vp.IsValid() { @@ -410,7 +411,7 @@ func decodeSparseValue(v *tspb.Value, t *tspb.Type, ptr interface{}) error { } if !isPtrStructPtrSlice(vp.Type()) { // The container is not a pointer to a struct pointer slice. - return typeErr + return typeErr() } // Only use reflection for nil detection on slow path. // Also, IsNil panics on many types, so check it after the type check. diff --git a/go.mod b/go.mod index 60738fa..55ce2f0 100644 --- a/go.mod +++ b/go.mod @@ -3,47 +3,17 @@ module github.com/zhihu/zetta-client-go go 1.13 require ( - cloud.google.com/go v0.46.3 - cloud.google.com/go/spanner v1.1.0 // indirect - github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect - github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 // indirect - github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca // indirect - github.com/fatih/color v1.9.0 // indirect - github.com/go-openapi/strfmt v0.19.5 // indirect - - github.com/go-sql-driver/mysql v1.5.0 // indirect + cloud.google.com/go v0.50.0 github.com/gogo/protobuf v1.3.1 - github.com/golang/protobuf v1.4.1 - github.com/golang/snappy v0.0.1 // indirect + github.com/golang/protobuf v1.4.2 github.com/googleapis/gax-go/v2 v2.0.5 - github.com/jedib0t/go-pretty v4.3.0+incompatible // indirect - github.com/juju/errors v0.0.0-20200330140219-3fe23663418f // indirect github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect - github.com/k0kubun/pp v3.0.1+incompatible - github.com/mattn/go-colorable v0.1.6 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 // indirect - github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect - github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712 // indirect - github.com/pingcap/errors v0.11.4 // indirect - github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989 // indirect - github.com/pingcap/kvproto v0.0.0-20200518112156-d4aeb467de29 // indirect - github.com/pingcap/parser v3.1.1+incompatible // indirect - github.com/pingcap/tidb v2.0.11+incompatible // indirect - github.com/pingcap/tipb v0.0.0-20200522051215-f31a15d98fce // indirect - github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect - github.com/snwfdhmp/errlog v0.0.0-20191219134421-4c9e67f11ebc // indirect - github.com/spf13/cobra v1.0.0 // indirect - github.com/twinj/uuid v1.0.0 // indirect - github.com/uber/jaeger-client-go v2.23.1+incompatible // indirect - github.com/uber/jaeger-lib v2.2.0+incompatible // indirect - github.com/zhihu/zetta-proto v0.0.0-20200602094047-43d62f6b0dc7 + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/zhihu/zetta-proto v0.0.0-20210404125403-0511ff71c1a1 golang.org/x/net v0.0.0-20200513185701-a91f0712d120 google.golang.org/api v0.14.0 - google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a + google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1 + google.golang.org/grpc v1.26.0 - google.golang.org/grpc v1.25.1 - gopkg.in/alexcesaro/statsd.v2 v2.0.0 ) diff --git a/go.sum b/go.sum index 55f3360..0110f54 100644 --- a/go.sum +++ b/go.sum @@ -4,59 +4,25 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0 h1:0E3eE8MX426vUOs7aHfI7aN1BrIzzzf4ccKCSfSjGmc= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/spanner v1.1.0/go.mod h1:TzTaF9l2ZY2CIetNvVpUu6ZQy8YEOtzB6ICa5EwYjL0= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= -github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -68,141 +34,53 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40= github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7/go.mod h1:iWMfgwqYW+e8n5lC/jjNEhwcjbRDpl5NT7n2h+4UNcI= -github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef/go.mod h1:7WjlapSfwQyo6LNmIvEWzsW1hbBQfpUO4JWnuQRmva8= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= -github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc= -github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pingcap/goleveldb v0.0.0-20191226122134-f82aafb29989/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw= -github.com/pingcap/kvproto v0.0.0-20200518112156-d4aeb467de29/go.mod h1:IOdRDPLyda8GX2hE/jO7gqaCV/PNFh8BZQCQZXfIOqI= -github.com/pingcap/log v0.0.0-20191012051959-b742a5d432e9/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8= -github.com/pingcap/parser v3.1.1+incompatible/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA= -github.com/pingcap/tidb v2.0.11+incompatible/go.mod h1:I8C6jrPINP2rrVunTRd7C9fRRhQrtR43S1/CL5ix/yQ= -github.com/pingcap/tipb v0.0.0-20200522051215-f31a15d98fce/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/snwfdhmp/errlog v0.0.0-20191219134421-4c9e67f11ebc/go.mod h1:W2jTAwIgQNPZAd1VzqQs+ikk5Ei76Vbr4D5smY35hpY= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY= -github.com/uber/jaeger-client-go v2.23.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/zhihu/zetta-proto v0.0.0-20200602094047-43d62f6b0dc7 h1:pUQ4GdlZdyN0xNjnjbAVI2MwDF3za0xoqAGHjQcNTFw= -github.com/zhihu/zetta-proto v0.0.0-20200602094047-43d62f6b0dc7/go.mod h1:Od2/pnP8DVD9xe3MI5tA6wyI6NqMVaQkfdf1xkl/4og= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +github.com/zhihu/zetta-proto v0.0.0-20210404125403-0511ff71c1a1 h1:eQ/AoGQihWowqT6hqiwPUFvCqX2kxfMTJa4bkhyV6k0= +github.com/zhihu/zetta-proto v0.0.0-20210404125403-0511ff71c1a1/go.mod h1:QX8zcN0ggDykLwAmIgxRgaX9Cff27NjQr0BZ33UMk9Y= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.12.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -211,25 +89,23 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -240,21 +116,19 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -262,7 +136,6 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -279,17 +152,16 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191105231337-689d0f08e67a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191107010934-f79515f33823/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0 h1:uMf5uLi4eQMRrMKhCplNik4U4H8Z6C1br3zOtAa/aDE= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -304,37 +176,25 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1 h1:aQktFqmDE2yjveXJlVIfslDFmFnUXSqG0i6KRcJAeMc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= gopkg.in/alexcesaro/statsd.v2 v2.0.0/go.mod h1:i0ubccKGzBVNBpdGV5MocxyA/XlLUJzA7SLonnE4drU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/key.go b/key.go index 8c27b08..bc243a3 100644 --- a/key.go +++ b/key.go @@ -92,6 +92,15 @@ func (key Key) proto() (*tspb.ListValue, error) { return lv, nil } +// keySetProto lets a single Key act as a KeySet. +func (key Key) keySetProto() (*tspb.KeySet, error) { + kp, err := key.proto() + if err != nil { + return nil, err + } + return &tspb.KeySet{Keys: []*tspb.ListValue{kp}}, nil +} + func (key Key) String() string { b := &bytes.Buffer{} fmt.Fprint(b, "(") @@ -125,6 +134,15 @@ func (key Key) String() string { return b.String() } +// AsPrefix returns a KeyRange for all keys where k is the prefix. +func (key Key) AsPrefix() KeyRange { + return KeyRange{ + Start: key, + End: key, + Kind: ClosedClosed, + } +} + // mark boundary open state of left and right type KeyRangeKind int @@ -165,6 +183,15 @@ func (r KeyRange) String() string { return fmt.Sprintf("%s%s,%s%s", left, r.Start, r.End, right) } +// keySetProto lets a KeyRange act as a KeySet. +func (r KeyRange) keySetProto() (*tspb.KeySet, error) { + rp, err := r.proto() + if err != nil { + return nil, err + } + return &tspb.KeySet{Ranges: []*tspb.KeyRange{rp}}, nil +} + // proto converts KeyRange into tspb.KeyRange. func (r KeyRange) proto() (*tspb.KeyRange, error) { var err error diff --git a/keyset.go b/keyset.go index 397d710..fba0f74 100644 --- a/keyset.go +++ b/keyset.go @@ -17,79 +17,79 @@ import ( tspb "github.com/zhihu/zetta-proto/pkg/tablestore" ) -// KeySet is collection of keys and/or key ranges -// all the keys in the same table or index. and keys needn't be sorted -type KeySet struct { - // true means all rows of a table or under a index. - All bool - // a list of keys covered by KeySet - Keys []Key - // list of key ranges covered by KeySet - Ranges []KeyRange +// A KeySet defines a collection of Cloud Spanner keys and/or key ranges. All +// the keys are expected to be in the same table or index. The keys need not be +// sorted in any particular way. +// +// An individual Key can act as a KeySet, as can a KeyRange. Use the KeySets +// function to create a KeySet consisting of multiple Keys and KeyRanges. To +// obtain an empty KeySet, call KeySets with no arguments. +// +// If the same key is specified multiple times in the set (for example if two +// ranges, two keys, or a key and a range overlap), the Cloud Spanner backend +// behaves as if the key were only specified once. +type KeySet interface { + keySetProto() (*tspb.KeySet, error) } -// AllKeys returns a KeySet that represents all Keys of a table or a index. -func AllKeys() KeySet { - return KeySet{All: true} -} +type all struct{} -// Keys returns a KeySet for a set of keys. -func Keys(keys ...Key) KeySet { - ks := KeySet{Keys: make([]Key, len(keys))} - copy(ks.Keys, keys) - return ks +func (all) keySetProto() (*tspb.KeySet, error) { + return &tspb.KeySet{All: true}, nil } -// Range returns a KeySet for a range of keys. -func Range(r KeyRange) KeySet { - return KeySet{Ranges: []KeyRange{r}} +// AllKeys returns a KeySet that represents all Keys of a table or a index. +func AllKeys() KeySet { + return all{} } -// PrefixRange returns a KeySet for all keys with the given prefix, which is a key itself -func PrefixRange(prefix Key) KeySet { - return KeySet{Ranges: []KeyRange{ - { - Start: prefix, - End: prefix, - Kind: ClosedClosed, - }, - }} +// KeySets returns the union of the KeySets. If any of the KeySets is AllKeys, +// then the resulting KeySet will be equivalent to AllKeys. +func KeySets(keySets ...KeySet) KeySet { + u := make(union, len(keySets)) + copy(u, keySets) + return u } -// union key set to one unity -func UnionKeySets(keySets ...KeySet) KeySet { - s := KeySet{} - for _, ks := range keySets { - if ks.All { - return KeySet{All: true} - } - s.Keys = append(s.Keys, ks.Keys...) - s.Ranges = append(s.Ranges, ks.Ranges...) - } - return s -} +type union []KeySet -// proto converts KeySet into tspb.KeySet, which is the protobuf -// representation of KeySet. -func (keys KeySet) proto() (*tspb.KeySet, error) { - pb := &tspb.KeySet{ - Keys: make([]*tspb.ListValue, 0, len(keys.Keys)), - Ranges: make([]*tspb.KeyRange, 0, len(keys.Ranges)), - All: keys.All, - } - for _, key := range keys.Keys { - keyProto, err := key.proto() +func (u union) keySetProto() (*tspb.KeySet, error) { + upb := &tspb.KeySet{} + for _, ks := range u { + pb, err := ks.keySetProto() if err != nil { return nil, err } - pb.Keys = append(pb.Keys, keyProto) - } - for _, r := range keys.Ranges { - rProto, err := r.proto() - if err != nil { - return nil, err + if pb.All { + return pb, nil } - pb.Ranges = append(pb.Ranges, rProto) + upb.Keys = append(upb.Keys, pb.Keys...) + upb.Ranges = append(upb.Ranges, pb.Ranges...) } - return pb, nil + return upb, nil } + +// // proto converts KeySet into tspb.KeySet, which is the protobuf +// // representation of KeySet. +// func (keys KeySet) proto() (*tspb.KeySet, error) { +// pb := &tspb.KeySet{ +// Keys: make([]*tspb.ListValue, 0, len(keys.Keys)), +// Ranges: make([]*tspb.KeyRange, 0, len(keys.Ranges)), +// All: keys.All, +// } +// for _, key := range keys.Keys { +// keyProto, err := key.proto() +// if err != nil { +// return nil, err +// } +// pb.Keys = append(pb.Keys, keyProto) +// } +// for _, r := range keys.Ranges { +// rProto, err := r.proto() +// if err != nil { +// return nil, err +// } +// pb.Ranges = append(pb.Ranges, rProto) +// } +// return pb, nil +// } diff --git a/metric.go b/metric.go deleted file mode 100644 index 5fd21f0..0000000 --- a/metric.go +++ /dev/null @@ -1,43 +0,0 @@ -package zetta - -import ( - "fmt" - "log" - "os" - - "gopkg.in/alexcesaro/statsd.v2" -) - -//For quick debug, change to prometheus later. -var ( - unit = os.Getenv("ZAE_UNIT_NAME") - cli *statsd.Client - prefix = fmt.Sprintf("zetta.client.%s", unit) -) - -func init() { - var err error - cli, err = statsd.New(statsd.Address("status:8126")) - if err != nil { - log.Println("Error: statsd init:", err) - } -} - -func metricCount(op string) { - m := fmt.Sprintf("%s.%s.count", prefix, op) - cli.Increment(m) -} - -func metricCountError(op string) { - m := fmt.Sprintf("%s.%s.count.err", prefix, op) - cli.Increment(m) -} - -func metricStartTiming() statsd.Timing { - return cli.NewTiming() -} - -func metricRecordTiming(t statsd.Timing, op string) { - m := fmt.Sprintf("%s.%s", prefix, op) - cli.Timing(m, t.Duration().Seconds()*1000) -} diff --git a/mutation.go b/mutation.go index 69ca77c..c896b8e 100644 --- a/mutation.go +++ b/mutation.go @@ -137,6 +137,8 @@ type Mutation struct { // values specifies the new values for the target columns // named by Columns. values []interface{} + + family string } // column -> value 的 map 转换为 Mutation 参数 @@ -192,21 +194,23 @@ func structToMutationParams(in interface{}) ([]string, []interface{}, error) { // Insert returns a Mutation to insert a row into a table. If the row already // exists, the write or transaction fails. -func Insert(table string, cols []string, vals []interface{}) *Mutation { +func Insert(table string, ks KeySet, family string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opInsert, table: table, columns: cols, values: vals, + keySet: ks, + family: family, } } // InsertMap returns a Mutation to insert a row into a table, specified by // a map of column name to value. If the row already exists, the write or // transaction fails. -func InsertMap(table string, in map[string]interface{}) *Mutation { +func InsertMap(table string, ks KeySet, family string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) - return Insert(table, cols, vals) + return Insert(table, ks, family, cols, vals) } // InsertStruct returns a Mutation to insert a row into a table, specified by @@ -215,61 +219,65 @@ func InsertMap(table string, in map[string]interface{}) *Mutation { // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like "spanner:name" // to provide an alternative column name, or use "spanner:-" to ignore the field. -func InsertStruct(table string, in interface{}) (*Mutation, error) { +func InsertStruct(table string, ks KeySet, family string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } - return Insert(table, cols, vals), nil + return Insert(table, ks, family, cols, vals), nil } // Update returns a Mutation to update a row in a table. If the row does not // already exist, the write or transaction fails. -func Update(table string, cols []string, vals []interface{}) *Mutation { +func Update(table string, ks KeySet, family string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opUpdate, table: table, columns: cols, values: vals, + keySet: ks, + family: family, } } // UpdateMap returns a Mutation to update a row in a table, specified by // a map of column to value. If the row does not already exist, the write or // transaction fails. -func UpdateMap(table string, in map[string]interface{}) *Mutation { +func UpdateMap(table string, ks KeySet, family string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) - return Update(table, cols, vals) + return Update(table, ks, family, cols, vals) } // UpdateStruct returns a Mutation to update a row in a table, specified by a Go // struct. If the row does not already exist, the write or transaction fails. -func UpdateStruct(table string, in interface{}) (*Mutation, error) { +func UpdateStruct(table string, ks KeySet, family string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } - return Update(table, cols, vals), nil + return Update(table, ks, family, cols, vals), nil } // InsertOrUpdate returns a Mutation to insert a row into a table. If the row // already exists, it updates it instead. Any column values not explicitly // written are preserved. -func InsertOrUpdate(table string, cols []string, vals []interface{}) *Mutation { +func InsertOrUpdate(table string, ks KeySet, family string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opInsertOrUpdate, table: table, columns: cols, values: vals, + keySet: ks, + family: family, } } // InsertOrUpdateMap returns a Mutation to insert a row into a table, // specified by a map of column to value. If the row already exists, it // updates it instead. Any column values not explicitly written are preserved. -func InsertOrUpdateMap(table string, in map[string]interface{}) *Mutation { +func InsertOrUpdateMap(table string, ks KeySet, family string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) - return InsertOrUpdate(table, cols, vals) + return InsertOrUpdate(table, ks, family, cols, vals) } // InsertOrUpdateStruct returns a Mutation to insert a row into a table, @@ -279,32 +287,34 @@ func InsertOrUpdateMap(table string, in map[string]interface{}) *Mutation { // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like "spanner:name" // to provide an alternative column name, or use "spanner:-" to ignore the field. -func InsertOrUpdateStruct(table string, in interface{}) (*Mutation, error) { +func InsertOrUpdateStruct(table string, ks KeySet, family string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } - return InsertOrUpdate(table, cols, vals), nil + return InsertOrUpdate(table, ks, family, cols, vals), nil } // Replace returns a Mutation to insert a row into a table, deleting any // existing row. Unlike InsertOrUpdate, this means any values not explicitly // written become NULL. -func Replace(table string, cols []string, vals []interface{}) *Mutation { +func Replace(table string, ks KeySet, family string, cols []string, vals []interface{}) *Mutation { return &Mutation{ op: opReplace, table: table, columns: cols, values: vals, + keySet: ks, + family: family, } } // ReplaceMap returns a Mutation to insert a row into a table, deleting any // existing row. Unlike InsertOrUpdateMap, this means any values not explicitly // written become NULL. The row is specified by a map of column to value. -func ReplaceMap(table string, in map[string]interface{}) *Mutation { +func ReplaceMap(table string, ks KeySet, family string, in map[string]interface{}) *Mutation { cols, vals := mapToMutationParams(in) - return Replace(table, cols, vals) + return Replace(table, ks, family, cols, vals) } // ReplaceStruct returns a Mutation to insert a row into a table, deleting any @@ -314,47 +324,54 @@ func ReplaceMap(table string, in map[string]interface{}) *Mutation { // The in argument must be a struct or a pointer to a struct. Its exported // fields specify the column names and values. Use a field tag like "spanner:name" // to provide an alternative column name, or use "spanner:-" to ignore the field. -func ReplaceStruct(table string, in interface{}) (*Mutation, error) { +func ReplaceStruct(table string, ks KeySet, family string, in interface{}) (*Mutation, error) { cols, vals, err := structToMutationParams(in) if err != nil { return nil, err } - return Replace(table, cols, vals), nil + return Replace(table, ks, family, cols, vals), nil } // Delete removes a key from a table. Succeeds whether or not the key was // present. -func Delete(table string, ks KeySet, columns ...string) *Mutation { +func Delete(table string, ks KeySet, family string, columns ...string) *Mutation { return &Mutation{ op: opDelete, table: table, keySet: ks, columns: columns, + family: family, } } // DeleteKeyRange removes a range of keys from a table. Succeeds whether or not // the keys were present. -func DeleteKeyRange(table string, r KeyRange, columns ...string) *Mutation { +func DeleteKeyRange(table string, r KeyRange, family string, columns ...string) *Mutation { return &Mutation{ op: opDelete, table: table, - keySet: Range(r), + keySet: r, columns: columns, } } // prepareWrite generates tspb.Mutation_Write from table name, column names // and new column values. -func prepareWrite(table string, columns []string, vals []interface{}) (*tspb.Mutation_Write, error) { +func prepareWrite(table string, ks KeySet, family string, columns []string, vals []interface{}) (*tspb.Mutation_Write, error) { v, err := encodeValueArray(vals) if err != nil { return nil, err } + keySetProto, err := ks.keySetProto() + if err != nil { + return nil, err + } return &tspb.Mutation_Write{ Table: table, Columns: columns, Values: []*tspb.ListValue{v}, + KeySet: keySetProto, + Family: family, }, nil } @@ -369,7 +386,7 @@ func (m Mutation) proto() (*tspb.Mutation, error) { var pb *tspb.Mutation switch m.op { case opDelete: - keySetProto, err := m.keySet.proto() + keySetProto, err := m.keySet.keySetProto() if err != nil { return nil, err } @@ -379,29 +396,30 @@ func (m Mutation) proto() (*tspb.Mutation, error) { Table: m.table, KeySet: keySetProto, Columns: m.columns, + Family: m.family, }, }, } case opInsert: - w, err := prepareWrite(m.table, m.columns, m.values) + w, err := prepareWrite(m.table, m.keySet, m.family, m.columns, m.values) if err != nil { return nil, err } pb = &tspb.Mutation{Operation: &tspb.Mutation_Insert{Insert: w}} case opInsertOrUpdate: - w, err := prepareWrite(m.table, m.columns, m.values) + w, err := prepareWrite(m.table, m.keySet, m.family, m.columns, m.values) if err != nil { return nil, err } pb = &tspb.Mutation{Operation: &tspb.Mutation_InsertOrUpdate{InsertOrUpdate: w}} case opReplace: - w, err := prepareWrite(m.table, m.columns, m.values) + w, err := prepareWrite(m.table, m.keySet, m.family, m.columns, m.values) if err != nil { return nil, err } pb = &tspb.Mutation{Operation: &tspb.Mutation_Replace{Replace: w}} case opUpdate: - w, err := prepareWrite(m.table, m.columns, m.values) + w, err := prepareWrite(m.table, m.keySet, m.family, m.columns, m.values) if err != nil { return nil, err } @@ -425,3 +443,7 @@ func mutationsProto(ms []*Mutation) ([]*tspb.Mutation, error) { } return l, nil } + +func MutationsProto(ms []*Mutation) ([]*tspb.Mutation, error) { + return mutationsProto(ms) +} diff --git a/read_stream.go b/read_stream.go index 15ba4ce..1d10adc 100644 --- a/read_stream.go +++ b/read_stream.go @@ -467,6 +467,7 @@ func (d *resumableStreamDecoder) next() bool { log.Printf("Unexpected resumableStreamDecoder.state: %v", d.state) return false } + } } diff --git a/read_stream_test.go b/read_stream_test.go index 9732b40..c285d64 100644 --- a/read_stream_test.go +++ b/read_stream_test.go @@ -37,16 +37,32 @@ import ( "time" "github.com/golang/protobuf/proto" - "github.com/zhihu/zetta-client-go/internal/testutil" tspb "github.com/zhihu/zetta-proto/pkg/tablestore" ) var ( + + // KvMeta is the Metadata for mocked KV table. + KvMeta = tspb.ResultSetMetadata{ + RowType: &tspb.StructType{ + Fields: []*tspb.StructType_Field{ + { + Name: "Key", + Type: &tspb.Type{Code: tspb.TypeCode_STRING}, + }, + { + Name: "Value", + Type: &tspb.Type{Code: tspb.TypeCode_STRING}, + }, + }, + }, + } + // Mocked transaction timestamp. trxTs = time.Unix(1, 2) // Metadata for mocked KV table, its rows are returned by SingleUse transactions. kvMeta = func() *tspb.ResultSetMetadata { - meta := testutil.KvMeta + meta := KvMeta meta.Transaction = &tspb.Transaction{ ReadTimestamp: timestampProto(trxTs), } diff --git a/row.go b/row.go index 9c619a4..14297f2 100644 --- a/row.go +++ b/row.go @@ -176,6 +176,52 @@ func (r *Row) ColumnNames() []string { return n } +func (r *Row) SparseQualifierIndex(name string) (int, error) { + found := false + var index int + for i, cell := range r.cells { + coln := cell.Column + if name == coln { + if found { + return 0, errDupColName(name) + } + found = true + index = i + } + } + if !found { + return 0, errColNotFound(name) + } + return index, nil +} + +func (r *Row) SparseQualifiers() []string { + var n []string + for _, cell := range r.cells { + n = append(n, cell.Column) + } + return n +} + +func (r *Row) SparseRowKeys() []interface{} { + keys := []interface{}{} + for _, pkey := range r.primaryKeys { + switch pkey.Kind.(type) { + case *tspb.Value_BoolValue: + keys = append(keys, pkey.GetBoolValue()) + case *tspb.Value_BytesValue: + keys = append(keys, pkey.GetBytesValue()) + case *tspb.Value_NumberValue: + keys = append(keys, pkey.GetNumberValue()) + case *tspb.Value_IntegerValue: + keys = append(keys, pkey.GetIntegerValue()) + case *tspb.Value_StringValue: + keys = append(keys, pkey.GetStringValue()) + } + } + return keys +} + // errColIdxOutOfRange returns error for requested column index is out of the // range of the target Row's columns. func errColIdxOutOfRange(i int, r *Row) error { diff --git a/session.go b/session.go index 69b737c..0c7ba1c 100644 --- a/session.go +++ b/session.go @@ -24,7 +24,6 @@ import ( "github.com/zhihu/zetta-client-go/utils/retry" tspb "github.com/zhihu/zetta-proto/pkg/tablestore" "golang.org/x/net/context" - "google.golang.org/grpc/codes" ) // sessionHandle is an interface for transactions to access Cloud Spanner sessions safely. It is generated by sessionPool.take(). @@ -351,7 +350,7 @@ func shouldDropSession(err error) bool { // If a Cloud Spanner can no longer locate the session (for example, if session is garbage collected), then caller // should not try to return the session back into the session pool. // TODO: once gRPC can return auxilary error information, stop parsing the error message. - if ErrCode(err) == codes.NotFound && strings.Contains(ErrDesc(err), "Session not found:") { + if strings.Contains(ErrDesc(err), "Session not found:") { return true } return false diff --git a/transaction.go b/transaction.go index bd32787..330de59 100644 --- a/transaction.go +++ b/transaction.go @@ -75,7 +75,7 @@ func (t *txReadOnly) ReadUsingIndex(ctx context.Context, table, index string, ke ts *tspb.TransactionSelector err error ) - kset, err := keys.proto() + kset, err := keys.keySetProto() if err != nil { return &RowIterator{err: err} } @@ -106,8 +106,95 @@ func (t *txReadOnly) ReadUsingIndex(ctx context.Context, table, index string, ke ) } +func (t *txReadOnly) SparseStreamRead(ctx context.Context, table, family string, rows []*SparseRow, limit int64) *RowIterator { + var ( + sh *sessionHandle + ts *tspb.TransactionSelector + err error + ) + + if err != nil { + return &RowIterator{err: err} + } + if sh, ts, err = t.acquire(ctx); err != nil { + return &RowIterator{err: err} + } + // Cloud Spanner will return "Session not found" on bad sessions. + sid, client := sh.getID(), sh.getClient() + if sid == "" || client == nil { + // Might happen if transaction is closed in the middle of a API call. + return &RowIterator{err: errSessionClosed(sh)} + } + + srows := []*tspb.Row{} + for _, r := range rows { + row, err := r.proto() + if err != nil { + return &RowIterator{err: err} + } + srows = append(srows, row) + } + return stream( + ctx, + func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { + return client.StreamingSparseRead(ctx, + &tspb.SparseReadRequest{ + Session: sid, + Transaction: ts, + Table: table, + Family: family, + Rows: srows, + Limit: limit, + }) + }, + t.release, + ) +} + +func (t *txReadOnly) SparseStreamScan(ctx context.Context, table, family string, keySet KeySet, limit int64) *RowIterator { + var ( + sh *sessionHandle + ts *tspb.TransactionSelector + err error + ) + + if err != nil { + return &RowIterator{err: err} + } + if sh, ts, err = t.acquire(ctx); err != nil { + return &RowIterator{err: err} + } + // Cloud Spanner will return "Session not found" on bad sessions. + sid, client := sh.getID(), sh.getClient() + if sid == "" || client == nil { + // Might happen if transaction is closed in the middle of a API call. + return &RowIterator{err: errSessionClosed(sh)} + } + + keysProto, err := keySet.keySetProto() + if err != nil { + return &RowIterator{err: err} + } + + return stream( + ctx, + func(ctx context.Context, resumeToken []byte) (streamingReceiver, error) { + return client.StreamingSparseScan(ctx, + &tspb.SparseScanRequest{ + Session: sid, + Transaction: ts, + Table: table, + Family: family, + KeySet: keysProto, + Limit: limit, + }) + }, + t.release, + ) +} + // errRowNotFound returns error for not being able to read the row identified by key. -func errRowNotFound(table string, key Key) error { +func errRowNotFound(table string, key KeySet) error { return wrapError(codes.NotFound, "row not found(Table: %v, PrimaryKey: %v)", table, key) } @@ -115,8 +202,8 @@ func errRowNotFound(table string, key Key) error { // // If no row is present with the given key, then ReadRow returns an error where // IsRowNotFound(err) is true. -func (t *txReadOnly) ReadRow(ctx context.Context, table string, key Key, columns []string) (*Row, error) { - iter := t.Read(ctx, table, Keys(key), columns) +func (t *txReadOnly) ReadRow(ctx context.Context, table string, key KeySet, columns []string) (*Row, error) { + iter := t.Read(ctx, table, key, columns) defer iter.Stop() row, err := iter.Next() switch err { diff --git a/tx_read_write.go b/tx_read_write.go index f4171a8..9847429 100644 --- a/tx_read_write.go +++ b/tx_read_write.go @@ -199,6 +199,7 @@ func (t *ReadWriteTransaction) commit(ctx context.Context) (time.Time, error) { var ts time.Time t.mu.Lock() t.state = txClosed // No futher operations after commit. + table := t.wb[0].table mPb, err := mutationsProto(t.wb) t.mu.Unlock() if err != nil { @@ -213,6 +214,7 @@ func (t *ReadWriteTransaction) commit(ctx context.Context) (time.Time, error) { var trailer metadata.MD res, e := client.Commit(ctx, &tspb.CommitRequest{ Session: sid, + Table: table, Transaction: &tspb.CommitRequest_TransactionId{ TransactionId: t.tx, }, diff --git a/tx_write_only.go b/tx_write_only.go index f29a7b4..cb4325f 100644 --- a/tx_write_only.go +++ b/tx_write_only.go @@ -39,6 +39,8 @@ func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Muta ts time.Time sh *sessionHandle ) + + table := ms[0].table mPb, err := mutationsProto(ms) if err != nil { // Malformed mutation found, just return the error. @@ -59,6 +61,7 @@ func (t *writeOnlyTransaction) applyAtLeastOnce(ctx context.Context, ms ...*Muta res, e := sh.getClient().Commit(ctx, &tspb.CommitRequest{ Session: sh.getID(), + Table: table, Transaction: &tspb.CommitRequest_SingleUseTransaction{ SingleUseTransaction: &tspb.TransactionOptions{ Mode: &tspb.TransactionOptions_ReadWrite_{