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