private Type GetGenericTupleType(TupleColumnInfo tupleInfo)
        {
            switch (tupleInfo.Elements.Count)
            {
            case 1:
                return(typeof(Tuple <>));

            case 2:
                return(typeof(Tuple <,>));

            case 3:
                return(typeof(Tuple <, ,>));

            case 4:
                return(typeof(Tuple <, , ,>));

            case 5:
                return(typeof(Tuple <, , , ,>));

            case 6:
                return(typeof(Tuple <, , , , ,>));

            case 7:
                return(typeof(Tuple <, , , , , ,>));

            default:
                return(null);
            }
        }
Exemple #2
0
        /// <summary>
        /// Parses a given fully-qualified class type name to get the data type information
        /// </summary>
        /// <exception cref="ArgumentException" />
        internal static ColumnDesc ParseFqTypeName(string typeName, int startIndex = 0, int length = 0)
        {
            const StringComparison comparison = StringComparison.Ordinal;
            var dataType = new ColumnDesc();

            if (length == 0)
            {
                length = typeName.Length;
            }
            if (length > ReversedTypeName.Length && typeName.IndexOf(ReversedTypeName, startIndex, comparison) == startIndex)
            {
                //move the start index and subtract the length plus parenthesis
                startIndex         += ReversedTypeName.Length + 1;
                length             -= ReversedTypeName.Length + 2;
                dataType.IsReversed = true;
            }
            if (length > FrozenTypeName.Length && typeName.IndexOf(FrozenTypeName, startIndex, comparison) == startIndex)
            {
                //Remove the frozen
                startIndex       += FrozenTypeName.Length + 1;
                length           -= FrozenTypeName.Length + 2;
                dataType.IsFrozen = true;
            }
            if (typeName == EmptyTypeName)
            {
                dataType.TypeCode = ColumnTypeCode.Custom;
                dataType.TypeInfo = null;
                return(dataType);
            }
            //Quick check if its a single type
            if (length <= SingleFqTypeNamesLength)
            {
                ColumnTypeCode typeCode;
                if (startIndex > 0)
                {
                    typeName = typeName.Substring(startIndex, length);
                }
                if (SingleFqTypeNames.TryGetValue(typeName, out typeCode))
                {
                    dataType.TypeCode = typeCode;
                    return(dataType);
                }
                throw GetTypeException(typeName);
            }
            if (typeName.IndexOf(ListTypeName, startIndex, comparison) == startIndex)
            {
                //Its a list
                //org.apache.cassandra.db.marshal.ListType(innerType)
                //move cursor across the name and bypass the parenthesis
                startIndex += ListTypeName.Length + 1;
                length     -= ListTypeName.Length + 2;
                var innerTypes = ParseParams(typeName, startIndex, length);
                if (innerTypes.Count != 1)
                {
                    throw GetTypeException(typeName);
                }
                dataType.TypeCode = ColumnTypeCode.List;
                var subType = ParseFqTypeName(innerTypes[0]);
                dataType.TypeInfo = new ListColumnInfo()
                {
                    ValueTypeCode = subType.TypeCode,
                    ValueTypeInfo = subType.TypeInfo
                };
                return(dataType);
            }
            if (typeName.IndexOf(SetTypeName, startIndex, comparison) == startIndex)
            {
                //Its a set
                //org.apache.cassandra.db.marshal.SetType(innerType)
                //move cursor across the name and bypass the parenthesis
                startIndex += SetTypeName.Length + 1;
                length     -= SetTypeName.Length + 2;
                var innerTypes = ParseParams(typeName, startIndex, length);
                if (innerTypes.Count != 1)
                {
                    throw GetTypeException(typeName);
                }
                dataType.TypeCode = ColumnTypeCode.Set;
                var subType = ParseFqTypeName(innerTypes[0]);
                dataType.TypeInfo = new SetColumnInfo()
                {
                    KeyTypeCode = subType.TypeCode,
                    KeyTypeInfo = subType.TypeInfo
                };
                return(dataType);
            }
            if (typeName.IndexOf(MapTypeName, startIndex, comparison) == startIndex)
            {
                //org.apache.cassandra.db.marshal.MapType(keyType,valueType)
                //move cursor across the name and bypass the parenthesis
                startIndex += MapTypeName.Length + 1;
                length     -= MapTypeName.Length + 2;
                var innerTypes = ParseParams(typeName, startIndex, length);
                //It should contain the key and value types
                if (innerTypes.Count != 2)
                {
                    throw GetTypeException(typeName);
                }
                dataType.TypeCode = ColumnTypeCode.Map;
                var keyType   = ParseFqTypeName(innerTypes[0]);
                var valueType = ParseFqTypeName(innerTypes[1]);
                dataType.TypeInfo = new MapColumnInfo()
                {
                    KeyTypeCode   = keyType.TypeCode,
                    KeyTypeInfo   = keyType.TypeInfo,
                    ValueTypeCode = valueType.TypeCode,
                    ValueTypeInfo = valueType.TypeInfo
                };
                return(dataType);
            }
            if (typeName.IndexOf(UdtTypeName, startIndex, comparison) == startIndex)
            {
                //move cursor across the name and bypass the parenthesis
                startIndex += UdtTypeName.Length + 1;
                length     -= UdtTypeName.Length + 2;
                var udtParams = ParseParams(typeName, startIndex, length);
                if (udtParams.Count < 2)
                {
                    //It should contain at least the keyspace, name of the udt and a type
                    throw GetTypeException(typeName);
                }
                dataType.TypeCode = ColumnTypeCode.Udt;
                dataType.Keyspace = udtParams[0];
                dataType.Name     = HexToUtf8(udtParams[1]);
                var udtInfo = new UdtColumnInfo(dataType.Keyspace + "." + dataType.Name);
                for (var i = 2; i < udtParams.Count; i++)
                {
                    var p = udtParams[i];
                    var separatorIndex = p.IndexOf(':');
                    var c = ParseFqTypeName(p, separatorIndex + 1, p.Length - (separatorIndex + 1));
                    c.Name = HexToUtf8(p.Substring(0, separatorIndex));
                    udtInfo.Fields.Add(c);
                }
                dataType.TypeInfo = udtInfo;
                return(dataType);
            }
            if (typeName.IndexOf(TupleTypeName, startIndex, comparison) == startIndex)
            {
                //move cursor across the name and bypass the parenthesis
                startIndex += TupleTypeName.Length + 1;
                length     -= TupleTypeName.Length + 2;
                var tupleParams = ParseParams(typeName, startIndex, length);
                if (tupleParams.Count < 1)
                {
                    //It should contain at least the keyspace, name of the udt and a type
                    throw GetTypeException(typeName);
                }
                dataType.TypeCode = ColumnTypeCode.Tuple;
                var tupleInfo = new TupleColumnInfo();
                foreach (var subTypeName in tupleParams)
                {
                    tupleInfo.Elements.Add(ParseFqTypeName(subTypeName));
                }
                dataType.TypeInfo = tupleInfo;
                return(dataType);
            }
            throw GetTypeException(typeName);
        }
        public ColumnTypeCode GetCqlType(Type type, out IColumnInfo typeInfo)
        {
            typeInfo = null;
            ITypeSerializer typeSerializer;

            if (_primitiveSerializers.TryGetValue(type, out typeSerializer))
            {
                return(typeSerializer.CqlType);
            }
            if (_customSerializers.Count > 0 && _customSerializers.TryGetValue(type, out typeSerializer))
            {
                typeInfo = typeSerializer.TypeInfo;
                return(typeSerializer.CqlType);
            }
            if (type.IsArray)
            {
                IColumnInfo    valueTypeInfo;
                ColumnTypeCode valueTypeCode = GetCqlType(type.GetElementType(), out valueTypeInfo);
                typeInfo = new ListColumnInfo
                {
                    ValueTypeCode = valueTypeCode,
                    ValueTypeInfo = valueTypeInfo
                };
                return(ColumnTypeCode.List);
            }
            if (type.GetTypeInfo().IsGenericType)
            {
                if (type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    return(GetCqlType(type.GetTypeInfo().GetGenericArguments()[0], out typeInfo));
                }
                if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(type))
                {
                    IColumnInfo    valueTypeInfo;
                    ColumnTypeCode valueTypeCode;
                    var            interfaces = type.GetTypeInfo().GetInterfaces();
                    if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(type) &&
                        interfaces.Any(t => t.GetTypeInfo().IsGenericType&& t.GetGenericTypeDefinition() == typeof(IDictionary <,>)))
                    {
                        IColumnInfo keyTypeInfo;
                        var         keyTypeCode = GetCqlType(type.GetTypeInfo().GetGenericArguments()[0], out keyTypeInfo);
                        valueTypeCode = GetCqlType(type.GetTypeInfo().GetGenericArguments()[1], out valueTypeInfo);
                        typeInfo      = new MapColumnInfo
                        {
                            KeyTypeCode   = keyTypeCode,
                            KeyTypeInfo   = keyTypeInfo,
                            ValueTypeCode = valueTypeCode,
                            ValueTypeInfo = valueTypeInfo
                        };
                        return(ColumnTypeCode.Map);
                    }
                    if (interfaces.Any(t => t.GetTypeInfo().IsGenericType&& t.GetGenericTypeDefinition() == typeof(ISet <>)))
                    {
                        IColumnInfo keyTypeInfo;
                        var         keyTypeCode = GetCqlType(type.GetTypeInfo().GetGenericArguments()[0], out keyTypeInfo);
                        typeInfo = new SetColumnInfo
                        {
                            KeyTypeCode = keyTypeCode,
                            KeyTypeInfo = keyTypeInfo
                        };
                        return(ColumnTypeCode.Set);
                    }
                    valueTypeCode = GetCqlType(type.GetTypeInfo().GetGenericArguments()[0], out valueTypeInfo);
                    typeInfo      = new ListColumnInfo
                    {
                        ValueTypeCode = valueTypeCode,
                        ValueTypeInfo = valueTypeInfo
                    };
                    return(ColumnTypeCode.List);
                }
                if (typeof(IStructuralComparable).GetTypeInfo().IsAssignableFrom(type) && type.FullName.StartsWith("System.Tuple"))
                {
                    typeInfo = new TupleColumnInfo
                    {
                        Elements = type.GetTypeInfo().GetGenericArguments().Select(t =>
                        {
                            IColumnInfo tupleSubTypeInfo;
                            var dataType = new ColumnDesc
                            {
                                TypeCode = GetCqlType(t, out tupleSubTypeInfo),
                                TypeInfo = tupleSubTypeInfo
                            };
                            return(dataType);
                        }).ToList()
                    };
                    return(ColumnTypeCode.Tuple);
                }
            }
            //Determine if its a Udt type
            var udtMap = _udtSerializer.GetUdtMap(type);

            if (udtMap != null)
            {
                typeInfo = udtMap.Definition;
                return(ColumnTypeCode.Udt);
            }
            throw new InvalidTypeException("Unknown Cassandra target type for CLR type " + type.FullName);
        }
 /// <summary>
 /// Parses a given fully-qualified class type name to get the data type information
 /// </summary>
 /// <exception cref="ArgumentException" />
 internal static ColumnDesc ParseFqTypeName(string typeName, int startIndex = 0, int length = 0)
 {
     const StringComparison comparison = StringComparison.Ordinal;
     var dataType = new ColumnDesc();
     if (length == 0)
     {
         length = typeName.Length;
     }
     if (length > ReversedTypeName.Length && typeName.IndexOf(ReversedTypeName, startIndex, comparison) == startIndex)
     {
         //move the start index and subtract the length plus parenthesis
         startIndex += ReversedTypeName.Length + 1;
         length -= ReversedTypeName.Length + 2;
         dataType.IsReversed = true;
     }
     if (length > FrozenTypeName.Length && typeName.IndexOf(FrozenTypeName, startIndex, comparison) == startIndex)
     {
         //Remove the frozen
         startIndex += FrozenTypeName.Length + 1;
         length -= FrozenTypeName.Length + 2;
         dataType.IsFrozen = true;
     }
     if (typeName == EmptyTypeName)
     {
         dataType.TypeCode = ColumnTypeCode.Custom;
         dataType.TypeInfo = null;
         return dataType;
     }
     //Quick check if its a single type
     if (length <= SingleFqTypeNamesLength)
     {
         ColumnTypeCode typeCode;
         if (startIndex > 0)
         {
             typeName = typeName.Substring(startIndex, length);
         }
         if (SingleFqTypeNames.TryGetValue(typeName, out typeCode))
         {
             dataType.TypeCode = typeCode;
             return dataType;
         }
         throw GetTypeException(typeName);
     }
     if (typeName.IndexOf(ListTypeName, startIndex, comparison) == startIndex)
     {
         //Its a list
         //org.apache.cassandra.db.marshal.ListType(innerType)
         //move cursor across the name and bypass the parenthesis
         startIndex += ListTypeName.Length + 1;
         length -= ListTypeName.Length + 2;
         var innerTypes = ParseParams(typeName, startIndex, length);
         if (innerTypes.Count != 1)
         {
             throw GetTypeException(typeName);
         }
         dataType.TypeCode = ColumnTypeCode.List;
         var subType = ParseFqTypeName(innerTypes[0]);
         dataType.TypeInfo = new ListColumnInfo()
         {
             ValueTypeCode = subType.TypeCode,
             ValueTypeInfo = subType.TypeInfo
         };
         return dataType;
     }
     if (typeName.IndexOf(SetTypeName, startIndex, comparison) == startIndex)
     {
         //Its a set
         //org.apache.cassandra.db.marshal.SetType(innerType)
         //move cursor across the name and bypass the parenthesis
         startIndex += SetTypeName.Length + 1;
         length -= SetTypeName.Length + 2;
         var innerTypes = ParseParams(typeName, startIndex, length);
         if (innerTypes.Count != 1)
         {
             throw GetTypeException(typeName);
         }
         dataType.TypeCode = ColumnTypeCode.Set;
         var subType = ParseFqTypeName(innerTypes[0]);
         dataType.TypeInfo = new SetColumnInfo()
         {
             KeyTypeCode = subType.TypeCode,
             KeyTypeInfo = subType.TypeInfo
         };
         return dataType;
     }
     if (typeName.IndexOf(MapTypeName, startIndex, comparison) == startIndex)
     {
         //org.apache.cassandra.db.marshal.MapType(keyType,valueType)
         //move cursor across the name and bypass the parenthesis
         startIndex += MapTypeName.Length + 1;
         length -= MapTypeName.Length + 2;
         var innerTypes = ParseParams(typeName, startIndex, length);
         //It should contain the key and value types
         if (innerTypes.Count != 2)
         {
             throw GetTypeException(typeName);
         }
         dataType.TypeCode = ColumnTypeCode.Map;
         var keyType = ParseFqTypeName(innerTypes[0]);
         var valueType = ParseFqTypeName(innerTypes[1]);
         dataType.TypeInfo = new MapColumnInfo()
         {
             KeyTypeCode = keyType.TypeCode,
             KeyTypeInfo = keyType.TypeInfo,
             ValueTypeCode = valueType.TypeCode,
             ValueTypeInfo = valueType.TypeInfo
         };
         return dataType;
     }
     if (typeName.IndexOf(UdtTypeName, startIndex, comparison) == startIndex)
     {
         //move cursor across the name and bypass the parenthesis
         startIndex += UdtTypeName.Length + 1;
         length -= UdtTypeName.Length + 2;
         var udtParams = ParseParams(typeName, startIndex, length);
         if (udtParams.Count < 2)
         {
             //It should contain at least the keyspace, name of the udt and a type
             throw GetTypeException(typeName);
         }
         dataType.TypeCode = ColumnTypeCode.Udt;
         dataType.Keyspace = udtParams[0];
         dataType.Name = HexToUtf8(udtParams[1]);
         var udtInfo = new UdtColumnInfo(dataType.Keyspace + "." + dataType.Name);
         for (var i = 2; i < udtParams.Count; i++)
         {
             var p = udtParams[i];
             var separatorIndex = p.IndexOf(':');
             var c = ParseFqTypeName(p, separatorIndex + 1, p.Length - (separatorIndex + 1));
             c.Name = HexToUtf8(p.Substring(0, separatorIndex));
             udtInfo.Fields.Add(c);
         }
         dataType.TypeInfo = udtInfo;
         return dataType;
     }
     if (typeName.IndexOf(TupleTypeName, startIndex, comparison) == startIndex)
     {
         //move cursor across the name and bypass the parenthesis
         startIndex += TupleTypeName.Length + 1;
         length -= TupleTypeName.Length + 2;
         var tupleParams = ParseParams(typeName, startIndex, length);
         if (tupleParams.Count < 1)
         {
             //It should contain at least the keyspace, name of the udt and a type
             throw GetTypeException(typeName);
         }
         dataType.TypeCode = ColumnTypeCode.Tuple;
         var tupleInfo = new TupleColumnInfo();
         foreach (var subTypeName in tupleParams)
         {
             tupleInfo.Elements.Add(ParseFqTypeName(subTypeName));
         }
         dataType.TypeInfo = tupleInfo;
         return dataType;
     }
     throw GetTypeException(typeName);
 }
Exemple #5
0
 public ColumnTypeCode GetCqlType(Type type, out IColumnInfo typeInfo)
 {
     typeInfo = null;
     ITypeSerializer typeSerializer;
     if (_primitiveSerializers.TryGetValue(type, out typeSerializer))
     {
         return typeSerializer.CqlType;
     }
     if (_customSerializers.Count > 0 && _customSerializers.TryGetValue(type, out typeSerializer))
     {
         typeInfo = typeSerializer.TypeInfo;
         return typeSerializer.CqlType;
     }
     if (type.IsArray)
     {
         IColumnInfo valueTypeInfo;
         ColumnTypeCode valueTypeCode = GetCqlType(type.GetElementType(), out valueTypeInfo);
         typeInfo = new ListColumnInfo
         {
             ValueTypeCode = valueTypeCode,
             ValueTypeInfo = valueTypeInfo
         };
         return ColumnTypeCode.List;
     }
     if (type.IsGenericType)
     {
         if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
         {
             return GetCqlType(type.GetGenericArguments()[0], out typeInfo);
         }
         if (typeof(IEnumerable).IsAssignableFrom(type))
         {
             IColumnInfo valueTypeInfo;
             ColumnTypeCode valueTypeCode;
             var interfaces = type.GetInterfaces();
             if (typeof(IDictionary).IsAssignableFrom(type) && 
                 interfaces.Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>)))
             {
                 IColumnInfo keyTypeInfo;
                 var keyTypeCode = GetCqlType(type.GetGenericArguments()[0], out keyTypeInfo);
                 valueTypeCode = GetCqlType(type.GetGenericArguments()[1], out valueTypeInfo);
                 typeInfo = new MapColumnInfo
                 {
                     KeyTypeCode = keyTypeCode,
                     KeyTypeInfo = keyTypeInfo,
                     ValueTypeCode = valueTypeCode,
                     ValueTypeInfo = valueTypeInfo
                 };
                 return ColumnTypeCode.Map;
             }
             if (interfaces.Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISet<>)))
             {
                 IColumnInfo keyTypeInfo;
                 var keyTypeCode = GetCqlType(type.GetGenericArguments()[0], out keyTypeInfo);
                 typeInfo = new SetColumnInfo
                 {
                     KeyTypeCode = keyTypeCode,
                     KeyTypeInfo = keyTypeInfo
                 };
                 return ColumnTypeCode.Set;
             }
             valueTypeCode = GetCqlType(type.GetGenericArguments()[0], out valueTypeInfo);
             typeInfo = new ListColumnInfo
             {
                 ValueTypeCode = valueTypeCode,
                 ValueTypeInfo = valueTypeInfo
             };
             return ColumnTypeCode.List;
         }
         if (typeof(IStructuralComparable).IsAssignableFrom(type) && type.FullName.StartsWith("System.Tuple"))
         {
             typeInfo = new TupleColumnInfo
             {
                 Elements = type.GetGenericArguments().Select(t =>
                 {
                     IColumnInfo tupleSubTypeInfo;
                     var dataType = new ColumnDesc
                     {
                         TypeCode = GetCqlType(t, out tupleSubTypeInfo),
                         TypeInfo = tupleSubTypeInfo
                     };
                     return dataType;
                 }).ToList()
             };
             return ColumnTypeCode.Tuple;
         }
     }
     //Determine if its a Udt type
     var udtMap = _udtSerializer.GetUdtMap(type);
     if (udtMap != null)
     {
         typeInfo = udtMap.Definition;
         return ColumnTypeCode.Udt;
     }
     throw new InvalidTypeException("Unknown Cassandra target type for CLR type " + type.FullName);
 }