Esempio n. 1
0
        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;
                });
            }));
        }