| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815 |
- // Copyright (c) 2015 The gocql Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package gocql
- import (
- "strconv"
- "testing"
- )
- // Tests V1 and V2 metadata "compilation" from example data which might be returned
- // from metadata schema queries (see getKeyspaceMetadata, getTableMetadata, and getColumnMetadata)
- func TestCompileMetadata(t *testing.T) {
- // V1 tests - these are all based on real examples from the integration test ccm cluster
- keyspace := &KeyspaceMetadata{
- Name: "V1Keyspace",
- }
- tables := []TableMetadata{
- {
- // This table, found in the system keyspace, has no key aliases or column aliases
- Keyspace: "V1Keyspace",
- Name: "Schema",
- KeyValidator: "org.apache.cassandra.db.marshal.BytesType",
- Comparator: "org.apache.cassandra.db.marshal.UTF8Type",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{},
- ColumnAliases: []string{},
- ValueAlias: "",
- },
- {
- // This table, found in the system keyspace, has key aliases, column aliases, and a value alias.
- Keyspace: "V1Keyspace",
- Name: "hints",
- KeyValidator: "org.apache.cassandra.db.marshal.UUIDType",
- Comparator: "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.TimeUUIDType,org.apache.cassandra.db.marshal.Int32Type)",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{"target_id"},
- ColumnAliases: []string{"hint_id", "message_version"},
- ValueAlias: "mutation",
- },
- {
- // This table, found in the system keyspace, has a comparator with collections, but no column aliases
- Keyspace: "V1Keyspace",
- Name: "peers",
- KeyValidator: "org.apache.cassandra.db.marshal.InetAddressType",
- Comparator: "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.ColumnToCollectionType(746f6b656e73:org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.UTF8Type)))",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{"peer"},
- ColumnAliases: []string{},
- ValueAlias: "",
- },
- {
- // This table, found in the system keyspace, has a column alias, but not a composite comparator
- Keyspace: "V1Keyspace",
- Name: "IndexInfo",
- KeyValidator: "org.apache.cassandra.db.marshal.UTF8Type",
- Comparator: "org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UTF8Type)",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{"table_name"},
- ColumnAliases: []string{"index_name"},
- ValueAlias: "",
- },
- {
- // This table, found in the gocql_test keyspace following an integration test run, has a composite comparator with collections as well as a column alias
- Keyspace: "V1Keyspace",
- Name: "wiki_page",
- KeyValidator: "org.apache.cassandra.db.marshal.UTF8Type",
- Comparator: "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.TimeUUIDType,org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.ColumnToCollectionType(74616773:org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.UTF8Type),6174746163686d656e7473:org.apache.cassandra.db.marshal.MapType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.BytesType)))",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{"title"},
- ColumnAliases: []string{"revid"},
- ValueAlias: "",
- },
- {
- // This is a made up example with multiple unnamed aliases
- Keyspace: "V1Keyspace",
- Name: "no_names",
- KeyValidator: "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UUIDType,org.apache.cassandra.db.marshal.UUIDType)",
- Comparator: "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.Int32Type)",
- DefaultValidator: "org.apache.cassandra.db.marshal.BytesType",
- KeyAliases: []string{},
- ColumnAliases: []string{},
- ValueAlias: "",
- },
- }
- columns := []ColumnMetadata{
- // Here are the regular columns from the peers table for testing regular columns
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "data_center", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "host_id", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UUIDType"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "rack", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "release_version", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "rpc_address", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.InetAddressType"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "schema_version", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UUIDType"},
- {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "tokens", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.UTF8Type)"},
- }
- compileMetadata(1, keyspace, tables, columns, nil, nil, nil)
- assertKeyspaceMetadata(
- t,
- keyspace,
- &KeyspaceMetadata{
- Name: "V1Keyspace",
- Tables: map[string]*TableMetadata{
- "Schema": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "key",
- Type: NativeType{typ: TypeBlob},
- },
- },
- ClusteringColumns: []*ColumnMetadata{},
- Columns: map[string]*ColumnMetadata{
- "key": {
- Name: "key",
- Type: NativeType{typ: TypeBlob},
- Kind: ColumnPartitionKey,
- },
- },
- },
- "hints": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "target_id",
- Type: NativeType{typ: TypeUUID},
- },
- },
- ClusteringColumns: []*ColumnMetadata{
- {
- Name: "hint_id",
- Type: NativeType{typ: TypeTimeUUID},
- Order: ASC,
- },
- {
- Name: "message_version",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- },
- },
- Columns: map[string]*ColumnMetadata{
- "target_id": {
- Name: "target_id",
- Type: NativeType{typ: TypeUUID},
- Kind: ColumnPartitionKey,
- },
- "hint_id": {
- Name: "hint_id",
- Type: NativeType{typ: TypeTimeUUID},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "message_version": {
- Name: "message_version",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "mutation": {
- Name: "mutation",
- Type: NativeType{typ: TypeBlob},
- Kind: ColumnRegular,
- },
- },
- },
- "peers": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "peer",
- Type: NativeType{typ: TypeInet},
- },
- },
- ClusteringColumns: []*ColumnMetadata{},
- Columns: map[string]*ColumnMetadata{
- "peer": {
- Name: "peer",
- Type: NativeType{typ: TypeInet},
- Kind: ColumnPartitionKey,
- },
- "data_center": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "data_center", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type", Type: NativeType{typ: TypeVarchar}},
- "host_id": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "host_id", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UUIDType", Type: NativeType{typ: TypeUUID}},
- "rack": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "rack", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type", Type: NativeType{typ: TypeVarchar}},
- "release_version": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "release_version", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UTF8Type", Type: NativeType{typ: TypeVarchar}},
- "rpc_address": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "rpc_address", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.InetAddressType", Type: NativeType{typ: TypeInet}},
- "schema_version": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "schema_version", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.UUIDType", Type: NativeType{typ: TypeUUID}},
- "tokens": {Keyspace: "V1Keyspace", Table: "peers", Kind: ColumnRegular, Name: "tokens", ComponentIndex: 0, Validator: "org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.UTF8Type)", Type: CollectionType{NativeType: NativeType{typ: TypeSet}}},
- },
- },
- "IndexInfo": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "table_name",
- Type: NativeType{typ: TypeVarchar},
- },
- },
- ClusteringColumns: []*ColumnMetadata{
- {
- Name: "index_name",
- Type: NativeType{typ: TypeVarchar},
- Order: DESC,
- },
- },
- Columns: map[string]*ColumnMetadata{
- "table_name": {
- Name: "table_name",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnPartitionKey,
- },
- "index_name": {
- Name: "index_name",
- Type: NativeType{typ: TypeVarchar},
- Order: DESC,
- Kind: ColumnClusteringKey,
- },
- "value": {
- Name: "value",
- Type: NativeType{typ: TypeBlob},
- Kind: ColumnRegular,
- },
- },
- },
- "wiki_page": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "title",
- Type: NativeType{typ: TypeVarchar},
- },
- },
- ClusteringColumns: []*ColumnMetadata{
- {
- Name: "revid",
- Type: NativeType{typ: TypeTimeUUID},
- Order: ASC,
- },
- },
- Columns: map[string]*ColumnMetadata{
- "title": {
- Name: "title",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnPartitionKey,
- },
- "revid": {
- Name: "revid",
- Type: NativeType{typ: TypeTimeUUID},
- Kind: ColumnClusteringKey,
- },
- },
- },
- "no_names": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "key",
- Type: NativeType{typ: TypeUUID},
- },
- {
- Name: "key2",
- Type: NativeType{typ: TypeUUID},
- },
- },
- ClusteringColumns: []*ColumnMetadata{
- {
- Name: "column",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- },
- {
- Name: "column2",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- },
- {
- Name: "column3",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- },
- },
- Columns: map[string]*ColumnMetadata{
- "key": {
- Name: "key",
- Type: NativeType{typ: TypeUUID},
- Kind: ColumnPartitionKey,
- },
- "key2": {
- Name: "key2",
- Type: NativeType{typ: TypeUUID},
- Kind: ColumnPartitionKey,
- },
- "column": {
- Name: "column",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "column2": {
- Name: "column2",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "column3": {
- Name: "column3",
- Type: NativeType{typ: TypeInt},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "value": {
- Name: "value",
- Type: NativeType{typ: TypeBlob},
- Kind: ColumnRegular,
- },
- },
- },
- },
- },
- )
- // V2 test - V2+ protocol is simpler so here are some toy examples to verify that the mapping works
- keyspace = &KeyspaceMetadata{
- Name: "V2Keyspace",
- }
- tables = []TableMetadata{
- {
- Keyspace: "V2Keyspace",
- Name: "Table1",
- },
- {
- Keyspace: "V2Keyspace",
- Name: "Table2",
- },
- }
- columns = []ColumnMetadata{
- {
- Keyspace: "V2Keyspace",
- Table: "Table1",
- Name: "KEY1",
- Kind: ColumnPartitionKey,
- ComponentIndex: 0,
- Validator: "org.apache.cassandra.db.marshal.UTF8Type",
- },
- {
- Keyspace: "V2Keyspace",
- Table: "Table1",
- Name: "Key1",
- Kind: ColumnPartitionKey,
- ComponentIndex: 0,
- Validator: "org.apache.cassandra.db.marshal.UTF8Type",
- },
- {
- Keyspace: "V2Keyspace",
- Table: "Table2",
- Name: "Column1",
- Kind: ColumnPartitionKey,
- ComponentIndex: 0,
- Validator: "org.apache.cassandra.db.marshal.UTF8Type",
- },
- {
- Keyspace: "V2Keyspace",
- Table: "Table2",
- Name: "Column2",
- Kind: ColumnClusteringKey,
- ComponentIndex: 0,
- Validator: "org.apache.cassandra.db.marshal.UTF8Type",
- },
- {
- Keyspace: "V2Keyspace",
- Table: "Table2",
- Name: "Column3",
- Kind: ColumnClusteringKey,
- ComponentIndex: 1,
- Validator: "org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UTF8Type)",
- },
- {
- Keyspace: "V2Keyspace",
- Table: "Table2",
- Name: "Column4",
- Kind: ColumnRegular,
- Validator: "org.apache.cassandra.db.marshal.UTF8Type",
- },
- }
- compileMetadata(2, keyspace, tables, columns, nil, nil, nil)
- assertKeyspaceMetadata(
- t,
- keyspace,
- &KeyspaceMetadata{
- Name: "V2Keyspace",
- Tables: map[string]*TableMetadata{
- "Table1": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "Key1",
- Type: NativeType{typ: TypeVarchar},
- },
- },
- ClusteringColumns: []*ColumnMetadata{},
- Columns: map[string]*ColumnMetadata{
- "KEY1": {
- Name: "KEY1",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnPartitionKey,
- },
- "Key1": {
- Name: "Key1",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnPartitionKey,
- },
- },
- },
- "Table2": {
- PartitionKey: []*ColumnMetadata{
- {
- Name: "Column1",
- Type: NativeType{typ: TypeVarchar},
- },
- },
- ClusteringColumns: []*ColumnMetadata{
- {
- Name: "Column2",
- Type: NativeType{typ: TypeVarchar},
- Order: ASC,
- },
- {
- Name: "Column3",
- Type: NativeType{typ: TypeVarchar},
- Order: DESC,
- },
- },
- Columns: map[string]*ColumnMetadata{
- "Column1": {
- Name: "Column1",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnPartitionKey,
- },
- "Column2": {
- Name: "Column2",
- Type: NativeType{typ: TypeVarchar},
- Order: ASC,
- Kind: ColumnClusteringKey,
- },
- "Column3": {
- Name: "Column3",
- Type: NativeType{typ: TypeVarchar},
- Order: DESC,
- Kind: ColumnClusteringKey,
- },
- "Column4": {
- Name: "Column4",
- Type: NativeType{typ: TypeVarchar},
- Kind: ColumnRegular,
- },
- },
- },
- },
- },
- )
- }
- // Helper function for asserting that actual metadata returned was as expected
- func assertKeyspaceMetadata(t *testing.T, actual, expected *KeyspaceMetadata) {
- if len(expected.Tables) != len(actual.Tables) {
- t.Errorf("Expected len(%s.Tables) to be %v but was %v", expected.Name, len(expected.Tables), len(actual.Tables))
- }
- for keyT := range expected.Tables {
- et := expected.Tables[keyT]
- at, found := actual.Tables[keyT]
- if !found {
- t.Errorf("Expected %s.Tables[%s] but was not found", expected.Name, keyT)
- } else {
- if keyT != at.Name {
- t.Errorf("Expected %s.Tables[%s].Name to be %v but was %v", expected.Name, keyT, keyT, at.Name)
- }
- if len(et.PartitionKey) != len(at.PartitionKey) {
- t.Errorf("Expected len(%s.Tables[%s].PartitionKey) to be %v but was %v", expected.Name, keyT, len(et.PartitionKey), len(at.PartitionKey))
- } else {
- for i := range et.PartitionKey {
- if et.PartitionKey[i].Name != at.PartitionKey[i].Name {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].Name to be '%v' but was '%v'", expected.Name, keyT, i, et.PartitionKey[i].Name, at.PartitionKey[i].Name)
- }
- if expected.Name != at.PartitionKey[i].Keyspace {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].Keyspace to be '%v' but was '%v'", expected.Name, keyT, i, expected.Name, at.PartitionKey[i].Keyspace)
- }
- if keyT != at.PartitionKey[i].Table {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].Table to be '%v' but was '%v'", expected.Name, keyT, i, keyT, at.PartitionKey[i].Table)
- }
- if et.PartitionKey[i].Type.Type() != at.PartitionKey[i].Type.Type() {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].Type.Type to be %v but was %v", expected.Name, keyT, i, et.PartitionKey[i].Type.Type(), at.PartitionKey[i].Type.Type())
- }
- if i != at.PartitionKey[i].ComponentIndex {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].ComponentIndex to be %v but was %v", expected.Name, keyT, i, i, at.PartitionKey[i].ComponentIndex)
- }
- if ColumnPartitionKey != at.PartitionKey[i].Kind {
- t.Errorf("Expected %s.Tables[%s].PartitionKey[%d].Kind to be '%v' but was '%v'", expected.Name, keyT, i, ColumnPartitionKey, at.PartitionKey[i].Kind)
- }
- }
- }
- if len(et.ClusteringColumns) != len(at.ClusteringColumns) {
- t.Errorf("Expected len(%s.Tables[%s].ClusteringColumns) to be %v but was %v", expected.Name, keyT, len(et.ClusteringColumns), len(at.ClusteringColumns))
- } else {
- for i := range et.ClusteringColumns {
- if at.ClusteringColumns[i] == nil {
- t.Fatalf("Unexpected nil value: %s.Tables[%s].ClusteringColumns[%d]", expected.Name, keyT, i)
- }
- if et.ClusteringColumns[i].Name != at.ClusteringColumns[i].Name {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Name to be '%v' but was '%v'", expected.Name, keyT, i, et.ClusteringColumns[i].Name, at.ClusteringColumns[i].Name)
- }
- if expected.Name != at.ClusteringColumns[i].Keyspace {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Keyspace to be '%v' but was '%v'", expected.Name, keyT, i, expected.Name, at.ClusteringColumns[i].Keyspace)
- }
- if keyT != at.ClusteringColumns[i].Table {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Table to be '%v' but was '%v'", expected.Name, keyT, i, keyT, at.ClusteringColumns[i].Table)
- }
- if et.ClusteringColumns[i].Type.Type() != at.ClusteringColumns[i].Type.Type() {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Type.Type to be %v but was %v", expected.Name, keyT, i, et.ClusteringColumns[i].Type.Type(), at.ClusteringColumns[i].Type.Type())
- }
- if i != at.ClusteringColumns[i].ComponentIndex {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].ComponentIndex to be %v but was %v", expected.Name, keyT, i, i, at.ClusteringColumns[i].ComponentIndex)
- }
- if et.ClusteringColumns[i].Order != at.ClusteringColumns[i].Order {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Order to be %v but was %v", expected.Name, keyT, i, et.ClusteringColumns[i].Order, at.ClusteringColumns[i].Order)
- }
- if ColumnClusteringKey != at.ClusteringColumns[i].Kind {
- t.Errorf("Expected %s.Tables[%s].ClusteringColumns[%d].Kind to be '%v' but was '%v'", expected.Name, keyT, i, ColumnClusteringKey, at.ClusteringColumns[i].Kind)
- }
- }
- }
- if len(et.Columns) != len(at.Columns) {
- eKeys := make([]string, 0, len(et.Columns))
- for key := range et.Columns {
- eKeys = append(eKeys, key)
- }
- aKeys := make([]string, 0, len(at.Columns))
- for key := range at.Columns {
- aKeys = append(aKeys, key)
- }
- t.Errorf("Expected len(%s.Tables[%s].Columns) to be %v (keys:%v) but was %v (keys:%v)", expected.Name, keyT, len(et.Columns), eKeys, len(at.Columns), aKeys)
- } else {
- for keyC := range et.Columns {
- ec := et.Columns[keyC]
- ac, found := at.Columns[keyC]
- if !found {
- t.Errorf("Expected %s.Tables[%s].Columns[%s] but was not found", expected.Name, keyT, keyC)
- } else {
- if keyC != ac.Name {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Name to be '%v' but was '%v'", expected.Name, keyT, keyC, keyC, at.Name)
- }
- if expected.Name != ac.Keyspace {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Keyspace to be '%v' but was '%v'", expected.Name, keyT, keyC, expected.Name, ac.Keyspace)
- }
- if keyT != ac.Table {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Table to be '%v' but was '%v'", expected.Name, keyT, keyC, keyT, ac.Table)
- }
- if ec.Type.Type() != ac.Type.Type() {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Type.Type to be %v but was %v", expected.Name, keyT, keyC, ec.Type.Type(), ac.Type.Type())
- }
- if ec.Order != ac.Order {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Order to be %v but was %v", expected.Name, keyT, keyC, ec.Order, ac.Order)
- }
- if ec.Kind != ac.Kind {
- t.Errorf("Expected %s.Tables[%s].Columns[%s].Kind to be '%v' but was '%v'", expected.Name, keyT, keyC, ec.Kind, ac.Kind)
- }
- }
- }
- }
- }
- }
- }
- // Tests the cassandra type definition parser
- func TestTypeParser(t *testing.T) {
- // native type
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.UTF8Type",
- assertTypeInfo{Type: TypeVarchar},
- )
- // reversed
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UUIDType)",
- assertTypeInfo{Type: TypeUUID, Reversed: true},
- )
- // set
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.Int32Type)",
- assertTypeInfo{
- Type: TypeSet,
- Elem: &assertTypeInfo{Type: TypeInt},
- },
- )
- // list
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.TimeUUIDType)",
- assertTypeInfo{
- Type: TypeList,
- Elem: &assertTypeInfo{Type: TypeTimeUUID},
- },
- )
- // map
- assertParseNonCompositeType(
- t,
- " org.apache.cassandra.db.marshal.MapType( org.apache.cassandra.db.marshal.UUIDType , org.apache.cassandra.db.marshal.BytesType ) ",
- assertTypeInfo{
- Type: TypeMap,
- Key: &assertTypeInfo{Type: TypeUUID},
- Elem: &assertTypeInfo{Type: TypeBlob},
- },
- )
- // custom
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.UserType(sandbox,61646472657373,737472656574:org.apache.cassandra.db.marshal.UTF8Type,63697479:org.apache.cassandra.db.marshal.UTF8Type,7a6970:org.apache.cassandra.db.marshal.Int32Type)",
- assertTypeInfo{Type: TypeCustom, Custom: "org.apache.cassandra.db.marshal.UserType(sandbox,61646472657373,737472656574:org.apache.cassandra.db.marshal.UTF8Type,63697479:org.apache.cassandra.db.marshal.UTF8Type,7a6970:org.apache.cassandra.db.marshal.Int32Type)"},
- )
- assertParseNonCompositeType(
- t,
- "org.apache.cassandra.db.marshal.DynamicCompositeType(u=>org.apache.cassandra.db.marshal.UUIDType,d=>org.apache.cassandra.db.marshal.DateType,t=>org.apache.cassandra.db.marshal.TimeUUIDType,b=>org.apache.cassandra.db.marshal.BytesType,s=>org.apache.cassandra.db.marshal.UTF8Type,B=>org.apache.cassandra.db.marshal.BooleanType,a=>org.apache.cassandra.db.marshal.AsciiType,l=>org.apache.cassandra.db.marshal.LongType,i=>org.apache.cassandra.db.marshal.IntegerType,x=>org.apache.cassandra.db.marshal.LexicalUUIDType)",
- assertTypeInfo{Type: TypeCustom, Custom: "org.apache.cassandra.db.marshal.DynamicCompositeType(u=>org.apache.cassandra.db.marshal.UUIDType,d=>org.apache.cassandra.db.marshal.DateType,t=>org.apache.cassandra.db.marshal.TimeUUIDType,b=>org.apache.cassandra.db.marshal.BytesType,s=>org.apache.cassandra.db.marshal.UTF8Type,B=>org.apache.cassandra.db.marshal.BooleanType,a=>org.apache.cassandra.db.marshal.AsciiType,l=>org.apache.cassandra.db.marshal.LongType,i=>org.apache.cassandra.db.marshal.IntegerType,x=>org.apache.cassandra.db.marshal.LexicalUUIDType)"},
- )
- // composite defs
- assertParseCompositeType(
- t,
- "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type)",
- []assertTypeInfo{
- {Type: TypeVarchar},
- },
- nil,
- )
- assertParseCompositeType(
- t,
- "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.DateType),org.apache.cassandra.db.marshal.UTF8Type)",
- []assertTypeInfo{
- {Type: TypeTimestamp, Reversed: true},
- {Type: TypeVarchar},
- },
- nil,
- )
- assertParseCompositeType(
- t,
- "org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.ColumnToCollectionType(726f77735f6d6572676564:org.apache.cassandra.db.marshal.MapType(org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.LongType)))",
- []assertTypeInfo{
- {Type: TypeVarchar},
- },
- map[string]assertTypeInfo{
- "rows_merged": {
- Type: TypeMap,
- Key: &assertTypeInfo{Type: TypeInt},
- Elem: &assertTypeInfo{Type: TypeBigInt},
- },
- },
- )
- }
- // expected data holder
- type assertTypeInfo struct {
- Type Type
- Reversed bool
- Elem *assertTypeInfo
- Key *assertTypeInfo
- Custom string
- }
- // Helper function for asserting that the type parser returns the expected
- // results for the given definition
- func assertParseNonCompositeType(
- t *testing.T,
- def string,
- typeExpected assertTypeInfo,
- ) {
- result := parseType(def)
- if len(result.reversed) != 1 {
- t.Errorf("%s expected %d reversed values but there were %d", def, 1, len(result.reversed))
- }
- assertParseNonCompositeTypes(
- t,
- def,
- []assertTypeInfo{typeExpected},
- result.types,
- )
- // expect no composite part of the result
- if result.isComposite {
- t.Errorf("%s: Expected not composite", def)
- }
- if result.collections != nil {
- t.Errorf("%s: Expected nil collections: %v", def, result.collections)
- }
- }
- // Helper function for asserting that the type parser returns the expected
- // results for the given definition
- func assertParseCompositeType(
- t *testing.T,
- def string,
- typesExpected []assertTypeInfo,
- collectionsExpected map[string]assertTypeInfo,
- ) {
- result := parseType(def)
- if len(result.reversed) != len(typesExpected) {
- t.Errorf("%s expected %d reversed values but there were %d", def, len(typesExpected), len(result.reversed))
- }
- assertParseNonCompositeTypes(
- t,
- def,
- typesExpected,
- result.types,
- )
- // expect composite part of the result
- if !result.isComposite {
- t.Errorf("%s: Expected composite", def)
- }
- if result.collections == nil {
- t.Errorf("%s: Expected non-nil collections: %v", def, result.collections)
- }
- for name, typeExpected := range collectionsExpected {
- // check for an actual type for this name
- typeActual, found := result.collections[name]
- if !found {
- t.Errorf("%s.tcollections: Expected param named %s but there wasn't", def, name)
- } else {
- // remove the actual from the collection so we can detect extras
- delete(result.collections, name)
- // check the type
- assertParseNonCompositeTypes(
- t,
- def+"collections["+name+"]",
- []assertTypeInfo{typeExpected},
- []TypeInfo{typeActual},
- )
- }
- }
- if len(result.collections) != 0 {
- t.Errorf("%s.collections: Expected no more types in collections, but there was %v", def, result.collections)
- }
- }
- // Helper function for asserting that the type parser returns the expected
- // results for the given definition
- func assertParseNonCompositeTypes(
- t *testing.T,
- context string,
- typesExpected []assertTypeInfo,
- typesActual []TypeInfo,
- ) {
- if len(typesActual) != len(typesExpected) {
- t.Errorf("%s: Expected %d types, but there were %d", context, len(typesExpected), len(typesActual))
- }
- for i := range typesExpected {
- typeExpected := typesExpected[i]
- typeActual := typesActual[i]
- // shadow copy the context for local modification
- context := context
- if len(typesExpected) > 1 {
- context = context + "[" + strconv.Itoa(i) + "]"
- }
- // check the type
- if typeActual.Type() != typeExpected.Type {
- t.Errorf("%s: Expected to parse Type to %s but was %s", context, typeExpected.Type, typeActual.Type())
- }
- // check the custom
- if typeActual.Custom() != typeExpected.Custom {
- t.Errorf("%s: Expected to parse Custom %s but was %s", context, typeExpected.Custom, typeActual.Custom())
- }
- collection, _ := typeActual.(CollectionType)
- // check the elem
- if typeExpected.Elem != nil {
- if collection.Elem == nil {
- t.Errorf("%s: Expected to parse Elem, but was nil ", context)
- } else {
- assertParseNonCompositeTypes(
- t,
- context+".Elem",
- []assertTypeInfo{*typeExpected.Elem},
- []TypeInfo{collection.Elem},
- )
- }
- } else if collection.Elem != nil {
- t.Errorf("%s: Expected to not parse Elem, but was %+v", context, collection.Elem)
- }
- // check the key
- if typeExpected.Key != nil {
- if collection.Key == nil {
- t.Errorf("%s: Expected to parse Key, but was nil ", context)
- } else {
- assertParseNonCompositeTypes(
- t,
- context+".Key",
- []assertTypeInfo{*typeExpected.Key},
- []TypeInfo{collection.Key},
- )
- }
- } else if collection.Key != nil {
- t.Errorf("%s: Expected to not parse Key, but was %+v", context, collection.Key)
- }
- }
- }
|