{"action":"created","issue":{"url":"https://api.github.com/repos/gocql/gocql/issues/309","labels_url":"https://api.github.com/repos/gocql/gocql/issues/309/labels{/name}","comments_url":"https://api.github.com/repos/gocql/gocql/issues/309/comments","events_url":"https://api.github.com/repos/gocql/gocql/issues/309/events","html_url":"https://github.com/gocql/gocql/pull/309","id":56714735,"number":309,"title":"Adds a function to retrieve schema metadata of the session's keyspace","user":{"login":"justinretailnext","id":10342005,"avatar_url":"https://avatars.githubusercontent.com/u/10342005?v=3","gravatar_id":"","url":"https://api.github.com/users/justinretailnext","html_url":"https://github.com/justinretailnext","followers_url":"https://api.github.com/users/justinretailnext/followers","following_url":"https://api.github.com/users/justinretailnext/following{/other_user}","gists_url":"https://api.github.com/users/justinretailnext/gists{/gist_id}","starred_url":"https://api.github.com/users/justinretailnext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinretailnext/subscriptions","organizations_url":"https://api.github.com/users/justinretailnext/orgs","repos_url":"https://api.github.com/users/justinretailnext/repos","events_url":"https://api.github.com/users/justinretailnext/events{/privacy}","received_events_url":"https://api.github.com/users/justinretailnext/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-02-05T19:12:17Z","updated_at":"2015-02-26T16:13:36Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/gocql/gocql/pulls/309","html_url":"https://github.com/gocql/gocql/pull/309","diff_url":"https://github.com/gocql/gocql/pull/309.diff","patch_url":"https://github.com/gocql/gocql/pull/309.patch"},"body":"Adds a function to get the schema metadata from a Session for the session's current keyspace. Also includes a couple typo fixes in the TypeInfo code.\r\n\r\nThe implementation is based on the [DataStax Java Driver](https://github.com/datastax/java-driver), specifically the code found in these Java classes:\r\n* [ControlConnection.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/ControlConnection.java)\r\n* [Metadata.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/Metadata.java)\r\n* [KeyspaceMetadata.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/KeyspaceMetadata.java)\r\n* [TableMetadata.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/TableMetadata.java)\r\n* [ColumnMetadata.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/ColumnMetadata.java)\r\n* [CassandraTypeParser.java](https://github.com/datastax/java-driver/blob/2.1/driver-core/src/main/java/com/datastax/driver/core/CassandraTypeParser.java)\r\n\r\nI've tried to simplify and consolidate the ideas from the Java code into distinct steps which are:\r\n1. Get the keyspace schema row\r\n2. Get the table schema rows for the keyspace\r\n3. Get the column schema rows for the keyspace\r\n4. Compile/reason the previous information into a single result (the KeyspaceMetadata) and determine the PartitionKey and ClusteringColumns information\r\n\r\nThe [type parser code](https://github.com/retailnext/gocql/commit/4951424501dd747c1215d45709d715add95568b1#diff-86d6a6e453f6c762fa29b1272cc0faedR475) used to parse the key_validator, default_validator, and comparator column values from the table rows is basically a from-scratch implementation as the Java code in CassandraTypeParser was difficult to understand IMHO. The type parser is used to determine the TypeInfo's for each of the columns in a table.\r\n\r\nThere are a couple instances where the code for handling schema information from the V1 protocol differs from the V2+ protocol as indicated with comments. Specifically, these differences are because V1 protocol does not support the \"type\" field in the system.schema_columns table and that table only includes \"regular\" columns.\r\n\r\nOne limitation of note is that the typeParser code currently treats UDT(User), Tuple, and DynamicComposite types as Custom (specifically it treats everything it can't parse as custom); however, additional conditional branches can be added to detect these types and handle them appropriately once the Type enums and TypeInfo changes support these various types.\r\n\r\nFor testing there is a unit test for the type parser using various key validator, default validator and comparator values found in my development cassandra schema. There is also an integration test which tests the KeyspaceMetadata() function of Session, ensuring that PartionKey and ClusteringColumns information is filled out as expected.\r\n"},"comment":{"url":"https://api.github.com/repos/gocql/gocql/issues/comments/76206636","html_url":"https://github.com/gocql/gocql/pull/309#issuecomment-76206636","issue_url":"https://api.github.com/repos/gocql/gocql/issues/309","id":76206636,"user":{"login":"justinretailnext","id":10342005,"avatar_url":"https://avatars.githubusercontent.com/u/10342005?v=3","gravatar_id":"","url":"https://api.github.com/users/justinretailnext","html_url":"https://github.com/justinretailnext","followers_url":"https://api.github.com/users/justinretailnext/followers","following_url":"https://api.github.com/users/justinretailnext/following{/other_user}","gists_url":"https://api.github.com/users/justinretailnext/gists{/gist_id}","starred_url":"https://api.github.com/users/justinretailnext/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinretailnext/subscriptions","organizations_url":"https://api.github.com/users/justinretailnext/orgs","repos_url":"https://api.github.com/users/justinretailnext/repos","events_url":"https://api.github.com/users/justinretailnext/events{/privacy}","received_events_url":"https://api.github.com/users/justinretailnext/received_events","type":"User","site_admin":false},"created_at":"2015-02-26T16:13:36Z","updated_at":"2015-02-26T16:13:36Z","body":"Yes the code currently does expect that Keyspace in ClusterConfig is set to a non-empty keyspace name. \r\n\r\nThe KeyspaceMetadata() function could be modified to take the keyspace as a parameter, though it would also need a way to signal to the function that the keyspace in ClusterConfig should be used. This is because the user of the Session may not have access to the Session's keyspace since cfg is private.\r\n\r\n    // KeyspaceMetadata returns the schema metadata for the keyspace specified or if\r\n    // keyspace is \"\" returns the metadata for the keyspace specified in the \r\n    // ClusterConfig for this session.\r\n    func (s *Session) KeyspaceMetadata(keyspace string) (*KeyspaceMetadata, error)"}}