예제 #1
0
 public void ParseTypeName_Should_Parse_Collections()
 {
     {
         var type = DataTypeParser.ParseTypeName(null, null, "list<int>").Result;
         Assert.NotNull(type);
         Assert.AreEqual(ColumnTypeCode.List, type.TypeCode);
         var subTypeInfo = (ListColumnInfo)type.TypeInfo;
         Assert.AreEqual(ColumnTypeCode.Int, subTypeInfo.ValueTypeCode);
     }
     {
         var type = DataTypeParser.ParseTypeName(null, null, "set<uuid>").Result;
         Assert.NotNull(type);
         Assert.AreEqual(ColumnTypeCode.Set, type.TypeCode);
         var subTypeInfo = (SetColumnInfo)type.TypeInfo;
         Assert.AreEqual(ColumnTypeCode.Uuid, subTypeInfo.KeyTypeCode);
     }
     {
         var type = DataTypeParser.ParseTypeName(null, null, "map<text, timeuuid>").Result;
         Assert.NotNull(type);
         Assert.AreEqual(ColumnTypeCode.Map, type.TypeCode);
         var subTypeInfo = (MapColumnInfo)type.TypeInfo;
         Assert.AreEqual(ColumnTypeCode.Text, subTypeInfo.KeyTypeCode);
         Assert.AreEqual(ColumnTypeCode.Timeuuid, subTypeInfo.ValueTypeCode);
     }
     {
         var type = DataTypeParser.ParseTypeName(null, null, "map<text,frozen<list<int>>>").Result;
         Assert.NotNull(type);
         Assert.AreEqual(ColumnTypeCode.Map, type.TypeCode);
         var subTypeInfo = (MapColumnInfo)type.TypeInfo;
         Assert.AreEqual(ColumnTypeCode.Text, subTypeInfo.KeyTypeCode);
         Assert.AreEqual(ColumnTypeCode.List, subTypeInfo.ValueTypeCode);
         var subListTypeInfo = (ListColumnInfo)subTypeInfo.ValueTypeInfo;
         Assert.AreEqual(ColumnTypeCode.Int, subListTypeInfo.ValueTypeCode);
     }
 }
예제 #2
0
 public override Task <UdtColumnInfo> GetUdtDefinition(string keyspaceName, string typeName)
 {
     return(Cc
            .QueryAsync(string.Format(SelectUdts, keyspaceName, typeName), true)
            .Then(rs =>
     {
         var row = rs.FirstOrDefault();
         if (row == null)
         {
             return TaskHelper.ToTask <UdtColumnInfo>(null);
         }
         var udt = new UdtColumnInfo(row.GetValue <string>("keyspace_name") + "." + row.GetValue <string>("type_name"));
         var fieldTypeTasks = row.GetValue <string[]>("field_types")
                              .Select(name => DataTypeParser.ParseTypeName(_udtResolver, keyspaceName, name))
                              .ToArray();
         return Task.Factory.ContinueWhenAll(fieldTypeTasks, tasks =>
         {
             var ex = tasks.Select(t => t.Exception).FirstOrDefault(e => e != null);
             if (ex != null)
             {
                 throw ex.InnerException;
             }
             var fieldNames = row.GetValue <string[]>("field_names");
             for (var i = 0; i < fieldNames.Length && i < tasks.Length; i++)
             {
                 var field = tasks[i].Result;
                 field.Name = fieldNames[i];
                 udt.Fields.Add(field);
             }
             return udt;
         });
     }));
 }
예제 #3
0
        public void ParseTypeName_Should_Parse_Single_Cql_Types()
        {
            var cqlNames = new Dictionary <string, ColumnTypeCode>
            {
                { "varchar", ColumnTypeCode.Varchar },
                { "text", ColumnTypeCode.Text },
                { "ascii", ColumnTypeCode.Ascii },
                { "uuid", ColumnTypeCode.Uuid },
                { "timeuuid", ColumnTypeCode.Timeuuid },
                { "int", ColumnTypeCode.Int },
                { "blob", ColumnTypeCode.Blob },
                { "float", ColumnTypeCode.Float },
                { "double", ColumnTypeCode.Double },
                { "boolean", ColumnTypeCode.Boolean },
                { "inet", ColumnTypeCode.Inet },
                { "date", ColumnTypeCode.Date },
                { "time", ColumnTypeCode.Time },
                { "smallint", ColumnTypeCode.SmallInt },
                { "tinyint", ColumnTypeCode.TinyInt },
                { "timestamp", ColumnTypeCode.Timestamp },
                { "bigint", ColumnTypeCode.Bigint },
                { "decimal", ColumnTypeCode.Decimal },
                { "varint", ColumnTypeCode.Varint },
                { "counter", ColumnTypeCode.Counter }
            };

            foreach (var kv in cqlNames)
            {
                var type = DataTypeParser.ParseTypeName(null, null, kv.Key).Result;
                Assert.NotNull(type);
                Assert.AreEqual(kv.Value, type.TypeCode);
                Assert.Null(type.TypeInfo);
            }
        }
예제 #4
0
        public override Task <FunctionMetadata> GetFunctionAsync(string keyspaceName, string functionName, string signatureString)
        {
            var query = string.Format(SelectFunctions, keyspaceName, functionName, signatureString);

            return(Cc
                   .QueryAsync(query, true)
                   .Then(rs =>
            {
                var row = rs.FirstOrDefault();
                if (row == null)
                {
                    return TaskHelper.ToTask <FunctionMetadata>(null);
                }
                var argumentTypes = row.GetValue <string[]>("argument_types") ?? new string[0];
                var parseTasks = new Task <ColumnDesc> [1 + argumentTypes.Length];
                parseTasks[0] = DataTypeParser.ParseTypeName(_udtResolver, row.GetValue <string>("keyspace_name"), row.GetValue <string>("return_type"));
                for (var i = 0; i < argumentTypes.Length; i++)
                {
                    parseTasks[1 + i] = DataTypeParser.ParseTypeName(_udtResolver, row.GetValue <string>("keyspace_name"), argumentTypes[i]);
                }
                return Task.Factory.ContinueWhenAll(parseTasks, tasks =>
                {
                    var ex = tasks.Select(t => t.Exception).FirstOrDefault(e => e != null);
                    if (ex != null)
                    {
                        throw ex.InnerException;
                    }

                    var result = new FunctionMetadata
                    {
                        Name = row.GetValue <string>("function_name"),
                        KeyspaceName = row.GetValue <string>("keyspace_name"),
                        Signature = argumentTypes,
                        ArgumentNames = row.GetValue <string[]>("argument_names") ?? new string[0],
                        Body = row.GetValue <string>("body"),
                        CalledOnNullInput = row.GetValue <bool>("called_on_null_input"),
                        Language = row.GetValue <string>("language"),
                        ReturnType = tasks[0].Result,
                        ArgumentTypes = tasks.Skip(1).Select(t => t.Result).ToArray()
                    };

                    if (row.GetColumn("deterministic") != null)
                    {
                        // DSE 6.0+
                        result.Deterministic = row.GetValue <bool>("deterministic");
                        result.Monotonic = row.GetValue <bool>("monotonic");
                        result.MonotonicOn = row.GetValue <string[]>("monotonic_on");
                    }

                    return result;
                });
            }));
        }
예제 #5
0
        public async Task ParseTypeName_Should_Parse_Custom_Types()
        {
            var typeNames = new[]
            {
                "org.apache.cassandra.db.marshal.MyCustomType",
                "com.datastax.dse.whatever.TypeName"
            };

            foreach (var typeName in typeNames)
            {
                var type = await DataTypeParser.ParseTypeName(null, null, string.Format("'{0}'", typeName));

                Assert.AreEqual(ColumnTypeCode.Custom, type.TypeCode);
                var info = (CustomColumnInfo)type.TypeInfo;
                Assert.AreEqual(typeName, info.CustomTypeName);
            }
        }
예제 #6
0
        public void ParseTypeName_Should_Parse_Frozen_Cql_Types()
        {
            var cqlNames = new Dictionary <string, ColumnTypeCode>
            {
                { "frozen<varchar>", ColumnTypeCode.Varchar },
                { "frozen<list<int>>", ColumnTypeCode.List },
                { "frozen<map<text,frozen<list<int>>>>", ColumnTypeCode.Map }
            };

            foreach (var kv in cqlNames)
            {
                var type = DataTypeParser.ParseTypeName(null, null, kv.Key).Result;
                Assert.NotNull(type);
                Assert.AreEqual(kv.Value, type.TypeCode);
                Assert.AreEqual(true, type.IsFrozen);
            }
        }
예제 #7
0
        public override Task <AggregateMetadata> GetAggregateAsync(string keyspaceName, string aggregateName, string signatureString)
        {
            var query = string.Format(SelectAggregates, keyspaceName, aggregateName, signatureString);

            return(Cc
                   .QueryAsync(query, true)
                   .Then(rs =>
            {
                var row = rs.FirstOrDefault();
                if (row == null)
                {
                    return TaskHelper.ToTask <AggregateMetadata>(null);
                }
                var argumentTypes = row.GetValue <string[]>("argument_types") ?? new string[0];
                //state_type + return_type + amount of argument types
                var parseTasks = new Task <ColumnDesc> [2 + argumentTypes.Length];
                parseTasks[0] = DataTypeParser.ParseTypeName(_udtResolver, row.GetValue <string>("keyspace_name"), row.GetValue <string>("state_type"));
                parseTasks[1] = DataTypeParser.ParseTypeName(_udtResolver, row.GetValue <string>("keyspace_name"), row.GetValue <string>("return_type"));
                for (var i = 0; i < argumentTypes.Length; i++)
                {
                    parseTasks[2 + i] = DataTypeParser.ParseTypeName(_udtResolver, row.GetValue <string>("keyspace_name"), argumentTypes[i]);
                }
                return Task.Factory.ContinueWhenAll(parseTasks, tasks =>
                {
                    var ex = tasks.Select(t => t.Exception).FirstOrDefault(e => e != null);
                    if (ex != null)
                    {
                        throw ex.InnerException;
                    }
                    return new AggregateMetadata
                    {
                        Name = row.GetValue <string>("aggregate_name"),
                        KeyspaceName = row.GetValue <string>("keyspace_name"),
                        StateFunction = row.GetValue <string>("state_func"),
                        FinalFunction = row.GetValue <string>("final_func"),
                        InitialCondition = row.GetValue <string>("initcond"),
                        Deterministic = row.GetColumn("deterministic") != null &&
                                        row.GetValue <bool>("deterministic"),
                        Signature = argumentTypes,
                        StateType = tasks[0].Result,
                        ReturnType = tasks[1].Result,
                        ArgumentTypes = tasks.Skip(2).Select(t => t.Result).ToArray()
                    };
                }, TaskContinuationOptions.ExecuteSynchronously);
            }));
        }
예제 #8
0
        private Task <T> ParseTableOrView <T>(Func <Row, T> newInstance, Task <IEnumerable <Row> > getTableTask, Task <IEnumerable <Row> > getColumnsTask)
            where T : DataCollectionMetadata
        {
            var tableMetadataRow = getTableTask.Result.FirstOrDefault();

            if (tableMetadataRow == null)
            {
                return(TaskHelper.ToTask <T>(null));
            }
            var columns        = new Dictionary <string, TableColumn>();
            var partitionKeys  = new List <Tuple <int, TableColumn> >();
            var clusteringKeys = new List <Tuple <int, Tuple <TableColumn, SortOrder> > >();
            //Read table options
            var options = new TableOptions
            {
                isCompactStorage  = false,
                bfFpChance        = tableMetadataRow.GetValue <double>("bloom_filter_fp_chance"),
                caching           = "{" + string.Join(",", tableMetadataRow.GetValue <IDictionary <string, string> >("caching").Select(kv => "\"" + kv.Key + "\":\"" + kv.Value + "\"")) + "}",
                comment           = tableMetadataRow.GetValue <string>("comment"),
                gcGrace           = tableMetadataRow.GetValue <int>("gc_grace_seconds"),
                localReadRepair   = tableMetadataRow.GetValue <double>("dclocal_read_repair_chance"),
                readRepair        = tableMetadataRow.GetValue <double>("read_repair_chance"),
                compactionOptions = tableMetadataRow.GetValue <SortedDictionary <string, string> >("compaction"),
                compressionParams =
                    tableMetadataRow.GetValue <SortedDictionary <string, string> >("compression")
            };
            var columnsMetadata = getColumnsTask.Result;

            Task <Tuple <TableColumn, Row> >[] columnTasks = columnsMetadata
                                                             .Select(row =>
            {
                return(DataTypeParser.ParseTypeName(_udtResolver, tableMetadataRow.GetValue <string>("keyspace_name"), row.GetValue <string>("type")).
                       ContinueSync(type => Tuple.Create(new TableColumn
                {
                    Name = row.GetValue <string>("column_name"),
                    Keyspace = row.GetValue <string>("keyspace_name"),
                    Table = row.GetValue <string>("table_name"),
                    TypeCode = type.TypeCode,
                    TypeInfo = type.TypeInfo
                }, row)));
            }).ToArray();
            return(Task.Factory.ContinueWhenAll(columnTasks, tasks =>
            {
                var ex = tasks.Select(t => t.Exception).FirstOrDefault(e => e != null);
                if (ex != null)
                {
                    throw ex.InnerException;
                }
                foreach (var t in tasks)
                {
                    var col = t.Result.Item1;
                    var row = t.Result.Item2;
                    switch (row.GetValue <string>("kind"))
                    {
                    case "partition_key":
                        partitionKeys.Add(Tuple.Create(row.GetValue <int?>("position") ?? 0, col));
                        col.KeyType = KeyType.Partition;
                        break;

                    case "clustering":
                        clusteringKeys.Add(Tuple.Create(row.GetValue <int?>("position") ?? 0,
                                                        Tuple.Create(col, row.GetValue <string>("clustering_order") == "desc" ? SortOrder.Descending : SortOrder.Ascending)));
                        col.KeyType = KeyType.Clustering;
                        break;

                    case "static":
                        col.IsStatic = true;
                        break;
                    }
                    columns.Add(col.Name, col);
                }
                if (typeof(T) == typeof(TableMetadata))
                {
                    var flags = tableMetadataRow.GetValue <string[]>("flags");
                    var isDense = flags.Contains("dense");
                    var isSuper = flags.Contains("super");
                    var isCompound = flags.Contains("compound");
                    options.isCompactStorage = isSuper || isDense || !isCompound;
                    //remove the columns related to Thrift
                    var isStaticCompact = !isSuper && !isDense && !isCompound;
                    if (isStaticCompact)
                    {
                        PruneStaticCompactTableColumns(clusteringKeys, columns);
                    }
                    else if (isDense)
                    {
                        PruneDenseTableColumns(columns);
                    }
                }
                var result = newInstance(tableMetadataRow);
                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;
            }));
        }
예제 #9
0
        protected async Task <T> ParseTableOrView <T>(Func <Row, T> newInstance, IEnumerable <Row> tableRs,
                                                      IEnumerable <Row> columnsRs) where T : DataCollectionMetadata
        {
            var tableMetadataRow = tableRs.FirstOrDefault();

            if (tableMetadataRow == null)
            {
                return(null);
            }

            var          columns        = new Dictionary <string, TableColumn>();
            var          partitionKeys  = new List <Tuple <int, TableColumn> >();
            var          clusteringKeys = new List <Tuple <int, Tuple <TableColumn, SortOrder> > >();
            TableOptions options;

            if (tableMetadataRow.ContainsColumn("compression"))
            {
                // Options for normal tables and views
                options = new TableOptions
                {
                    isCompactStorage = false,
                    bfFpChance       = tableMetadataRow.GetValue <double>("bloom_filter_fp_chance"),
                    caching          = "{" + string.Join(",", tableMetadataRow.GetValue <IDictionary <string, string> >("caching")
                                                         .Select(kv => "\"" + kv.Key + "\":\"" + kv.Value + "\"")) + "}",
                    comment           = tableMetadataRow.GetValue <string>("comment"),
                    gcGrace           = tableMetadataRow.GetValue <int>("gc_grace_seconds"),
                    localReadRepair   = tableMetadataRow.GetValue <double>("dclocal_read_repair_chance"),
                    readRepair        = tableMetadataRow.GetValue <double>("read_repair_chance"),
                    compactionOptions = tableMetadataRow.GetValue <SortedDictionary <string, string> >("compaction"),
                    compressionParams =
                        tableMetadataRow.GetValue <SortedDictionary <string, string> >("compression")
                };
            }
            else
            {
                // Options for virtual tables
                options = new TableOptions {
                    comment = tableMetadataRow.GetValue <string>("comment")
                };
            }

            var columnTasks = columnsRs
                              .Select(async row =>
            {
                var type = await DataTypeParser
                           .ParseTypeName(
                    _udtResolver, tableMetadataRow.GetValue <string>("keyspace_name"),
                    row.GetValue <string>("type"))
                           .ConfigureAwait(false);

                return(Tuple.Create(new TableColumn
                {
                    Name = row.GetValue <string>("column_name"),
                    Keyspace = row.GetValue <string>("keyspace_name"),
                    Table = row.GetValue <string>("table_name"),
                    TypeCode = type.TypeCode,
                    TypeInfo = type.TypeInfo
                }, row));
            });

            var columnsTuples = await Task.WhenAll(columnTasks).ConfigureAwait(false);

            foreach (var t in columnsTuples)
            {
                var col = t.Item1;
                var row = t.Item2;

                switch (row.GetValue <string>("kind"))
                {
                case "partition_key":
                    partitionKeys.Add(Tuple.Create(row.GetValue <int?>("position") ?? 0, col));
                    col.KeyType = KeyType.Partition;
                    break;

                case "clustering":
                    clusteringKeys.Add(Tuple.Create(row.GetValue <int?>("position") ?? 0,
                                                    Tuple.Create(col, row.GetValue <string>("clustering_order") == "desc" ? SortOrder.Descending : SortOrder.Ascending)));
                    col.KeyType = KeyType.Clustering;
                    break;

                case "static":
                    col.IsStatic = true;
                    break;
                }
                columns.Add(col.Name, col);
            }

            if (tableMetadataRow.ContainsColumn("flags"))
            {
                // Normal tables
                var flags      = tableMetadataRow.GetValue <string[]>("flags");
                var isDense    = flags.Contains("dense");
                var isSuper    = flags.Contains("super");
                var isCompound = flags.Contains("compound");
                options.isCompactStorage = isSuper || isDense || !isCompound;
                //remove the columns related to Thrift
                var isStaticCompact = !isSuper && !isDense && !isCompound;
                if (isStaticCompact)
                {
                    PruneStaticCompactTableColumns(clusteringKeys, columns);
                }
                else if (isDense)
                {
                    PruneDenseTableColumns(columns);
                }
            }

            var result = newInstance(tableMetadataRow);

            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);
        }