Ver código fonte

Add keyspace name as a string parameter to the KeyspaceMetadata function for Session since the keyspace name is optional in the ClusterConfig.

- Also removed unused & untested column metadata kind constants CONSTANT_VALUE and STATIC
Justin Corpron 10 anos atrás
pai
commit
d93b3b69ad
3 arquivos alterados com 65 adições e 46 exclusões
  1. 4 4
      cassandra_test.go
  2. 45 37
      metadata.go
  3. 16 5
      session.go

+ 4 - 4
cassandra_test.go

@@ -1432,7 +1432,7 @@ func TestGetKeyspaceMetadata(t *testing.T) {
 	session := createSession(t)
 	defer session.Close()
 
-	keyspaceMetadata, err := getKeyspaceMetadata(session)
+	keyspaceMetadata, err := getKeyspaceMetadata(session, "gocql_test")
 	if err != nil {
 		t.Fatalf("failed to query the keyspace metadata with err: %v", err)
 	}
@@ -1469,7 +1469,7 @@ func TestGetTableMetadata(t *testing.T) {
 		t.Fatalf("failed to create table with error '%v'", err)
 	}
 
-	tables, err := getTableMetadata(session)
+	tables, err := getTableMetadata(session, "gocql_test")
 	if err != nil {
 		t.Fatalf("failed to query the table metadata with err: %v", err)
 	}
@@ -1554,7 +1554,7 @@ func TestGetColumnMetadata(t *testing.T) {
 		t.Fatalf("failed to create index with err: %v", err)
 	}
 
-	columns, err := getColumnMetadata(session)
+	columns, err := getColumnMetadata(session, "gocql_test")
 	if err != nil {
 		t.Fatalf("failed to query column metadata with err: %v", err)
 	}
@@ -1655,7 +1655,7 @@ func TestKeyspaceMetadata(t *testing.T) {
 		t.Fatalf("failed to create index with err: %v", err)
 	}
 
-	keyspaceMetadata, err := session.KeyspaceMetadata()
+	keyspaceMetadata, err := session.KeyspaceMetadata("gocql_test")
 	if err != nil {
 		t.Fatalf("failed to query keyspace metadata with err: %v", err)
 	}

+ 45 - 37
metadata.go

@@ -70,8 +70,6 @@ const (
 	PARTITION_KEY  = "partition_key"
 	CLUSTERING_KEY = "clustering_key"
 	REGULAR        = "regular"
-	COMPACT_VALUE  = "compact_value"
-	STATIC         = "static"
 )
 
 // default alias values
@@ -83,47 +81,53 @@ const (
 
 // queries the cluster for schema information for a specific keyspace
 type schemaDescriber struct {
-	session  *Session
-	mu       sync.Mutex
-	lazyInit sync.Once
+	session *Session
+	mu      sync.Mutex
 
-	current *KeyspaceMetadata
-	err     error
+	cache map[string]*KeyspaceMetadata
 }
 
-func (s *schemaDescriber) init() {
-	s.err = s.refreshSchema()
+func newSchemaDescriber(session *Session) *schemaDescriber {
+	return &schemaDescriber{
+		session: session,
+		cache:   map[string]*KeyspaceMetadata{},
+	}
 }
 
-func (s *schemaDescriber) getSchema() (*KeyspaceMetadata, error) {
-	// lazily-initialize the schema the first time
-	s.lazyInit.Do(s.init)
+func (s *schemaDescriber) getSchema(keyspaceName string) (*KeyspaceMetadata, error) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
 
 	// TODO handle schema change events
 
-	s.mu.Lock()
-	defer s.mu.Unlock()
+	metadata, found := s.cache[keyspaceName]
+	if !found {
+		// refresh the cache for this keyspace
+		err := s.refreshSchema(keyspaceName)
+		if err != nil {
+			return nil, err
+		}
 
-	return s.current, s.err
-}
+		metadata = s.cache[keyspaceName]
+	}
 
-func (s *schemaDescriber) refreshSchema() error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
+	return metadata, nil
+}
 
+func (s *schemaDescriber) refreshSchema(keyspaceName string) error {
 	var err error
 
 	// query the system keyspace for schema data
 	// TODO retrieve concurrently
-	keyspace, err := getKeyspaceMetadata(s.session)
+	keyspace, err := getKeyspaceMetadata(s.session, keyspaceName)
 	if err != nil {
 		return err
 	}
-	tables, err := getTableMetadata(s.session)
+	tables, err := getTableMetadata(s.session, keyspaceName)
 	if err != nil {
 		return err
 	}
-	columns, err := getColumnMetadata(s.session)
+	columns, err := getColumnMetadata(s.session, keyspaceName)
 	if err != nil {
 		return err
 	}
@@ -131,9 +135,8 @@ func (s *schemaDescriber) refreshSchema() error {
 	// organize the schema data
 	compileMetadata(s.session.cfg.ProtoVersion, keyspace, tables, columns)
 
-	// update the current
-	s.current = keyspace
-	s.err = nil
+	// update the cache
+	s.cache[keyspaceName] = keyspace
 
 	return nil
 }
@@ -315,9 +318,10 @@ func countColumnsOfKind(columns map[string]*ColumnMetadata, kind string) int {
 	return count
 }
 
-// query only for the keyspace metadata for the session's keyspace
+// query only for the keyspace metadata for the specified keyspace
 func getKeyspaceMetadata(
 	session *Session,
+	keyspaceName string,
 ) (*KeyspaceMetadata, error) {
 	query := session.Query(
 		`
@@ -325,10 +329,10 @@ func getKeyspaceMetadata(
 		FROM system.schema_keyspaces
 		WHERE keyspace_name = ?
 		`,
-		session.cfg.Keyspace,
+		keyspaceName,
 	)
 
-	keyspace := &KeyspaceMetadata{Name: session.cfg.Keyspace}
+	keyspace := &KeyspaceMetadata{Name: keyspaceName}
 	var strategyOptionsJSON []byte
 
 	err := query.Scan(
@@ -351,9 +355,10 @@ func getKeyspaceMetadata(
 	return keyspace, nil
 }
 
-// query for only the table metadata in the session's keyspace
+// query for only the table metadata in the specified keyspace
 func getTableMetadata(
 	session *Session,
+	keyspaceName string,
 ) ([]TableMetadata, error) {
 	query := session.Query(
 		`
@@ -368,12 +373,12 @@ func getTableMetadata(
 		FROM system.schema_columnfamilies
 		WHERE keyspace_name = ?
 		`,
-		session.cfg.Keyspace,
+		keyspaceName,
 	)
 	iter := query.Iter()
 
 	tables := []TableMetadata{}
-	table := TableMetadata{Keyspace: session.cfg.Keyspace}
+	table := TableMetadata{Keyspace: keyspaceName}
 
 	var keyAliasesJSON []byte
 	var columnAliasesJSON []byte
@@ -415,7 +420,7 @@ func getTableMetadata(
 		}
 
 		tables = append(tables, table)
-		table = TableMetadata{Keyspace: session.cfg.Keyspace}
+		table = TableMetadata{Keyspace: keyspaceName}
 	}
 
 	err := iter.Close()
@@ -426,8 +431,11 @@ func getTableMetadata(
 	return tables, nil
 }
 
-// query for only the table metadata in the session's keyspace
-func getColumnMetadata(session *Session) ([]ColumnMetadata, error) {
+// query for only the table metadata in the specified keyspace
+func getColumnMetadata(
+	session *Session,
+	keyspaceName string,
+) ([]ColumnMetadata, error) {
 	// Deal with differences in protocol versions
 	var stmt string
 	var scan func(*Iter, *ColumnMetadata, *[]byte) bool
@@ -498,11 +506,11 @@ func getColumnMetadata(session *Session) ([]ColumnMetadata, error) {
 
 	// get the columns metadata
 	columns := []ColumnMetadata{}
-	column := ColumnMetadata{Keyspace: session.cfg.Keyspace}
+	column := ColumnMetadata{Keyspace: keyspaceName}
 
 	var indexOptionsJSON []byte
 
-	query := session.Query(stmt, session.cfg.Keyspace)
+	query := session.Query(stmt, keyspaceName)
 	iter := query.Iter()
 
 	for scan(iter, &column, &indexOptionsJSON) {
@@ -524,7 +532,7 @@ func getColumnMetadata(session *Session) ([]ColumnMetadata, error) {
 		}
 
 		columns = append(columns, column)
-		column = ColumnMetadata{Keyspace: session.cfg.Keyspace}
+		column = ColumnMetadata{Keyspace: keyspaceName}
 	}
 
 	err := iter.Close()

+ 16 - 5
session.go

@@ -164,15 +164,25 @@ func (s *Session) executeQuery(qry *Query) *Iter {
 	return iter
 }
 
-// Returns the schema metadata for the keyspace of this session including
-// table and column schema metadata.
-func (s *Session) KeyspaceMetadata() (*KeyspaceMetadata, error) {
+// KeyspaceMetadata returns the schema metadata for the keyspace specified.
+func (s *Session) KeyspaceMetadata(keyspace string) (*KeyspaceMetadata, error) {
+	// fail fast
+	if s.Closed() {
+		return nil, ErrSessionClosed
+	}
+
+	if keyspace == "" {
+		return nil, ErrNoKeyspace
+	}
+
 	s.mu.Lock()
+	// lazy-init schemaDescriber
 	if s.schemaDescriber == nil {
-		s.schemaDescriber = &schemaDescriber{session: s}
+		s.schemaDescriber = newSchemaDescriber(s)
 	}
 	s.mu.Unlock()
-	return s.schemaDescriber.getSchema()
+
+	return s.schemaDescriber.getSchema(keyspace)
 }
 
 // ExecuteBatch executes a batch operation and returns nil if successful
@@ -671,6 +681,7 @@ var (
 	ErrUseStmt       = errors.New("use statements aren't supported. Please see https://github.com/gocql/gocql for explaination.")
 	ErrSessionClosed = errors.New("session has been closed")
 	ErrNoConnections = errors.New("no connections available")
+	ErrNoKeyspace    = errors.New("no keyspace provided")
 )
 
 type ErrProtocol struct{ error }