public override Task <TableMetadata> GetTable(string keyspaceName, string tableName) { var columns = new Dictionary <string, TableColumn>(); var partitionKeys = new List <Tuple <int, TableColumn> >(); var clusteringKeys = new List <Tuple <int, Tuple <TableColumn, SortOrder> > >(); return(Cc .QueryAsync(string.Format(SelectSingleTable, tableName, keyspaceName), true) .Then(rs => { var tableMetadataRow = rs.FirstOrDefault(); if (tableMetadataRow == null) { return NullTableTask; } //Read table options var options = new TableOptions { isCompactStorage = false, bfFpChance = tableMetadataRow.GetValue <double>("bloom_filter_fp_chance"), caching = tableMetadataRow.GetValue <string>("caching"), comment = tableMetadataRow.GetValue <string>("comment"), gcGrace = tableMetadataRow.GetValue <int>("gc_grace_seconds"), localReadRepair = tableMetadataRow.GetValue <double>("local_read_repair_chance"), readRepair = tableMetadataRow.GetValue <double>("read_repair_chance"), compactionOptions = GetCompactionStrategyOptions(tableMetadataRow), compressionParams = (SortedDictionary <string, string>)Utils.ConvertStringToMap(tableMetadataRow.GetValue <string>("compression_parameters")) }; //replicate_on_write column not present in C* >= 2.1 if (tableMetadataRow.GetColumn("replicate_on_write") != null) { options.replicateOnWrite = tableMetadataRow.GetValue <bool>("replicate_on_write"); } return Cc .QueryAsync(string.Format(SelectColumns, tableName, keyspaceName), true) .ContinueSync(columnsMetadata => { foreach (var row in columnsMetadata) { var dataType = DataTypeParser.ParseFqTypeName(row.GetValue <string>("validator")); var col = new TableColumn { Name = row.GetValue <string>("column_name"), Keyspace = row.GetValue <string>("keyspace_name"), Table = row.GetValue <string>("columnfamily_name"), TypeCode = dataType.TypeCode, TypeInfo = dataType.TypeInfo, #pragma warning disable 618 SecondaryIndexName = row.GetValue <string>("index_name"), SecondaryIndexType = row.GetValue <string>("index_type"), SecondaryIndexOptions = Utils.ParseJsonStringMap(row.GetValue <string>("index_options")), #pragma warning restore 618 KeyType = row.GetValue <string>("index_name") != null ? KeyType.SecondaryIndex : KeyType.None }; if (row.GetColumn("type") != null) { switch (row.GetValue <string>("type")) { case "partition_key": partitionKeys.Add(Tuple.Create(row.GetValue <int?>("component_index") ?? 0, col)); col.KeyType = KeyType.Partition; break; case "clustering_key": var sortOrder = dataType.IsReversed ? SortOrder.Descending : SortOrder.Ascending; clusteringKeys.Add(Tuple.Create(row.GetValue <int?>("component_index") ?? 0, Tuple.Create(col, sortOrder))); col.KeyType = KeyType.Clustering; break; case "static": col.IsStatic = true; break; } } columns.Add(col.Name, col); } var comparator = tableMetadataRow.GetValue <string>("comparator"); if (tableMetadataRow.GetColumn("key_aliases") != null && partitionKeys.Count == 0) { //In C* 1.2, keys are not stored on the schema_columns table var partitionKeyNames = Utils.ParseJsonStringArray(tableMetadataRow.GetValue <string>("key_aliases")); var types = AdaptKeyTypes(tableMetadataRow.GetValue <string>("key_validator")); for (var i = 0; i < partitionKeyNames.Length; i++) { var name = partitionKeyNames[i]; TableColumn c; if (!columns.TryGetValue(name, out c)) { c = new TableColumn { Name = name, Keyspace = keyspaceName, Table = tableName, TypeCode = types[i].TypeCode, TypeInfo = types[i].TypeInfo, KeyType = KeyType.Partition }; //The column is not part of columns metadata table columns.Add(name, c); } partitionKeys.Add(Tuple.Create(i, c)); } //In C* 1.2, keys are not stored on the schema_columns table var clusteringKeyNames = Utils.ParseJsonStringArray(tableMetadataRow.GetValue <string>("column_aliases")); if (clusteringKeyNames.Length > 0) { types = AdaptKeyTypes(comparator); for (var i = 0; i < clusteringKeyNames.Length; i++) { var name = clusteringKeyNames[i]; TableColumn c; var dataType = types[i]; if (!columns.TryGetValue(name, out c)) { c = new TableColumn { Name = name, Keyspace = keyspaceName, Table = tableName, TypeCode = dataType.TypeCode, TypeInfo = dataType.TypeInfo, KeyType = KeyType.Clustering }; //The column is not part of columns metadata table columns.Add(name, c); } clusteringKeys.Add(Tuple.Create(i, Tuple.Create(c, dataType.IsReversed ? SortOrder.Descending : SortOrder.Ascending))); } } } options.isCompactStorage = tableMetadataRow.GetColumn("is_dense") != null && tableMetadataRow.GetValue <bool>("is_dense"); if (!options.isCompactStorage) { //is_dense column does not exist in previous versions of Cassandra //also, compact pk, ck and val appear as is_dense false // clusteringKeys != comparator types - 1 // or not composite (comparator) options.isCompactStorage = !comparator.StartsWith(DataTypeParser.CompositeTypeName); } var result = new TableMetadata(tableName, GetIndexesFromColumns(columns.Values)); result.SetValues( columns, partitionKeys.OrderBy(p => p.Item1).Select(p => p.Item2).ToArray(), clusteringKeys.OrderBy(p => p.Item1).Select(p => p.Item2).ToArray(), options); return result; }); })); }