private Func <object, byte[]> GenerateSerializer(Type type) { var typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Boolean: return(value => ValueSerialization.Serialize(ColumnType.Boolean, value)); case TypeCode.Decimal: return(value => ValueSerialization.Serialize(ColumnType.Decimal, value)); case TypeCode.Double: return(value => ValueSerialization.Serialize(ColumnType.Double, value)); case TypeCode.Single: return(value => ValueSerialization.Serialize(ColumnType.Float, value)); case TypeCode.Char: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(char)value)); case TypeCode.Byte: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(byte)value)); case TypeCode.SByte: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(sbyte)value)); case TypeCode.UInt16: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(ushort)value)); case TypeCode.Int16: return(value => ValueSerialization.Serialize(ColumnType.Int, (int)(short)value)); case TypeCode.Int32: return(value => ValueSerialization.Serialize(ColumnType.Int, value)); case TypeCode.UInt32: return(value => ValueSerialization.Serialize(ColumnType.Bigint, (long)(uint)value)); case TypeCode.Int64: return(value => ValueSerialization.Serialize(ColumnType.Bigint, value)); case TypeCode.String: return(value => ValueSerialization.Serialize(ColumnType.Varchar, value)); case TypeCode.DateTime: return(value => ValueSerialization.Serialize(ColumnType.Timestamp, value)); case TypeCode.Empty: return(null); default: return(GenerateObjectSerializer(type)); } }
private Func <byte[], object> GenerateObjectDeserializer(Type type) { var customSerializer = type.GetCustomAttributes(typeof(CassandraTypeSerializerAttribute), false).FirstOrDefault() as CassandraTypeSerializerAttribute; if (customSerializer != null) { return(value => customSerializer.Serializer.Deserialize(value)); } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(GenerateDeserializer(type.GetGenericArguments()[0])); } if (typeof(Guid).IsAssignableFrom(type)) { return(value => ValueSerialization.Deserialize(ColumnType.Uuid, value)); } if (typeof(IPAddress).IsAssignableFrom(type)) { return(value => ValueSerialization.Deserialize(ColumnType.Inet, value)); } if (typeof(Enum).IsAssignableFrom(type)) { var enumType = type.GetEnumUnderlyingType(); return(GenerateDeserializer(enumType)); } if (typeof(byte[]).IsAssignableFrom(type)) { return(value => ValueSerialization.Deserialize(ColumnType.Blob, value)); } if (typeof(IDictionary).IsAssignableFrom(type)) { var dictionaryTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary <,>)); if (dictionaryTypeDef != null) { var dictionaryArgs = dictionaryTypeDef.GetGenericArguments(); var keyDeserializer = GenerateDeserializer(dictionaryArgs[0]); var valueDeserializer = GenerateDeserializer(dictionaryArgs[1]); return(rawData => { var res = (IDictionary)Activator.CreateInstance(type); return ValueSerialization.DeserializeMap(rawData, res, keyDeserializer, valueDeserializer); }); } } if (typeof(IList).IsAssignableFrom(type)) { var listTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList <>)); if (listTypeDef != null) { var listItemType = listTypeDef.GetGenericArguments()[0]; var valueSerializer = GenerateDeserializer(listItemType); return(rawData => { var res = (IList)Activator.CreateInstance(type); return ValueSerialization.DeserializeList(rawData, res, valueSerializer); }); } } var hashSetTypeDef = type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ISet <>)); if (hashSetTypeDef != null) { var setItemType = hashSetTypeDef.GetGenericArguments()[0]; var valueDeserializer = GenerateDeserializer(setItemType); return(rawData => { var hashSet = Activator.CreateInstance(type); Type accessorType = typeof(HashSetAccessor <>).MakeGenericType(setItemType); var setAccessor = (IHashSetAccessor)Activator.CreateInstance(accessorType, hashSet); ValueSerialization.DeserializeSet(rawData, setAccessor, valueDeserializer); return hashSet; }); } throw new NotSupportedException(string.Format("Type {0} neither belongs to Cassandra native types nor has custom serializer defined. Use CassandraTypeSerializerAttribute to define custom type serializer to store data inside Blob column.", type.FullName)); }