예제 #1
0
        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));
            }
        }
예제 #2
0
        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));
        }