diff --git a/bigtable/admin.go b/bigtable/admin.go index cd9d300326b8..04971957be68 100644 --- a/bigtable/admin.go +++ b/bigtable/admin.go @@ -593,6 +593,7 @@ type FamilyInfo struct { Name string GCPolicy string FullGCPolicy GCPolicy + ValueType Type } func (ac *AdminClient) getTable(ctx context.Context, table string, view btapb.Table_View) (*btapb.Table, error) { @@ -632,6 +633,7 @@ func (ac *AdminClient) TableInfo(ctx context.Context, table string) (*TableInfo, Name: name, GCPolicy: GCRuleToString(fam.GcRule), FullGCPolicy: gcRuleToPolicy(fam.GcRule), + ValueType: protoToType(fam.ValueType), }) } // we expect DeletionProtection to be in the response because Table_SCHEMA_VIEW is being used in this function diff --git a/bigtable/type.go b/bigtable/type.go index a390e8fd44b2..75cbeddb7c8f 100644 --- a/bigtable/type.go +++ b/bigtable/type.go @@ -16,7 +16,9 @@ limitations under the License. package bigtable -import btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" +import ( + btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2" +) // Type wraps the protobuf representation of a type. See the protobuf definition // for more details on types. @@ -24,6 +26,14 @@ type Type interface { proto() *btapb.Type } +type unknown[T interface{}] struct { + wrapped *T +} + +func (u unknown[T]) proto() *T { + return u.wrapped +} + // BytesEncoding represents the encoding of a Bytes type. type BytesEncoding interface { proto() *btapb.Type_Bytes_Encoding @@ -112,6 +122,14 @@ func (sum SumAggregator) fillProto(proto *btapb.Type_Aggregate) { proto.Aggregator = &btapb.Type_Aggregate_Sum_{Sum: &btapb.Type_Aggregate_Sum{}} } +type unknownAggregator struct { + wrapped *btapb.Type_Aggregate +} + +func (ua unknownAggregator) fillProto(proto *btapb.Type_Aggregate) { + proto.Aggregator = ua.wrapped.Aggregator +} + // AggregateType represents an aggregate. See types.proto for more details // on aggregate types. type AggregateType struct { @@ -127,3 +145,59 @@ func (agg AggregateType) proto() *btapb.Type { agg.Aggregator.fillProto(protoAgg) return &btapb.Type{Kind: &btapb.Type_AggregateType{AggregateType: protoAgg}} } + +func protoToType(pb *btapb.Type) Type { + if pb == nil { + return nil + } + + switch t := pb.Kind.(type) { + case *btapb.Type_Int64Type: + return int64ProtoToType(t.Int64Type) + case *btapb.Type_BytesType: + return bytesProtoToType(t.BytesType) + case *btapb.Type_AggregateType: + return aggregateProtoToType(t.AggregateType) + default: + return unknown[btapb.Type]{wrapped: pb} + } +} + +func bytesEncodingProtoToType(be *btapb.Type_Bytes_Encoding) BytesEncoding { + switch be.Encoding.(type) { + case *btapb.Type_Bytes_Encoding_Raw_: + return RawBytesEncoding{} + default: + return unknown[btapb.Type_Bytes_Encoding]{wrapped: be} + } +} + +func bytesProtoToType(b *btapb.Type_Bytes) BytesType { + return BytesType{Encoding: bytesEncodingProtoToType(b.Encoding)} +} + +func int64EncodingProtoToEncoding(ie *btapb.Type_Int64_Encoding) Int64Encoding { + switch e := ie.Encoding.(type) { + case *btapb.Type_Int64_Encoding_BigEndianBytes_: + return BigEndianBytesEncoding{Bytes: bytesProtoToType(e.BigEndianBytes.BytesType)} + default: + return unknown[btapb.Type_Int64_Encoding]{wrapped: ie} + } +} + +func int64ProtoToType(i *btapb.Type_Int64) Type { + return Int64Type{Encoding: int64EncodingProtoToEncoding(i.Encoding)} +} + +func aggregateProtoToType(agg *btapb.Type_Aggregate) Type { + it := protoToType(agg.InputType) + + var aggregator Aggregator + switch agg.Aggregator.(type) { + case *btapb.Type_Aggregate_Sum_: + aggregator = SumAggregator{} + default: + aggregator = unknownAggregator{wrapped: agg} + } + return AggregateType{Input: it, Aggregator: aggregator} +} diff --git a/bigtable/type_test.go b/bigtable/type_test.go index 4f688384ad3c..a16c7fa5bd6a 100644 --- a/bigtable/type_test.go +++ b/bigtable/type_test.go @@ -23,8 +23,8 @@ import ( "google.golang.org/protobuf/proto" ) -func TestInt64Proto(t *testing.T) { - want := &btapb.Type{ +func aggregateProto() *btapb.Type { + return &btapb.Type{ Kind: &btapb.Type_Int64Type{ Int64Type: &btapb.Type_Int64{ Encoding: &btapb.Type_Int64_Encoding{ @@ -43,6 +43,10 @@ func TestInt64Proto(t *testing.T) { }, }, } +} + +func TestInt64Proto(t *testing.T) { + want := aggregateProto() got := Int64Type{}.proto() if !proto.Equal(got, want) { @@ -85,3 +89,11 @@ func TestAggregateProto(t *testing.T) { t.Errorf("got type %v, want: %v", got, want) } } + +func TestProtoBijection(t *testing.T) { + want := aggregateProto() + got := protoToType(want).proto() + if !proto.Equal(got, want) { + t.Errorf("got type %v, want: %v", got, want) + } +}