Ejemplo n.º 1
0
 private static CoreType GetUnderlyingType(Type type)
 {
     return(underlyingTypes.GetOrAdd(type, (t) =>
     {
         if (!TypeLookup.CoreTypeLookup(Enum.GetUnderlyingType(t), out CoreType underlyingType))
         {
             throw new NotImplementedException("Should not happen");
         }
         return underlyingType;
     }));
 }
Ejemplo n.º 2
0
        protected override bool ConvertToSqlValueRender(MemberExpression memberProperty, Type type, object value, ref CharWriteBuffer sb, BuilderContext context)
        {
            var typeDetails = TypeAnalyzer.GetTypeDetail(type);

            if (value == null)
            {
                sb.Write("NULL");
                return(false);
            }

            if (typeDetails.IsNullable)
            {
                type        = typeDetails.InnerTypes[0];
                typeDetails = typeDetails.InnerTypeDetails[0];
            }

            if (type.IsEnum)
            {
                sb.Write('\'');
                sb.Write(value.ToString());
                sb.Write('\'');
                return(false);
            }

            if (type.IsArray)
            {
                Type arrayType = typeDetails.InnerTypes[0];
                if (arrayType == typeof(byte))
                {
                    sb.Write("0x");
                    sb.Write((byte[])value, ByteFormat.Hex);
                    return(false);
                }
                else
                {
                    sb.Write('(');

                    var builderLength = sb.Length;

                    bool first = true;
                    foreach (object item in (IEnumerable)value)
                    {
                        if (!first)
                        {
                            sb.Write(',');
                        }
                        ConvertToSqlValue(arrayType, item, ref sb, context);
                        first = false;
                    }

                    if (builderLength == sb.Length)
                    {
                        sb.Write("NULL");
                    }

                    sb.Write(')');
                    return(false);
                }
            }

            if (typeDetails.IsIEnumerableGeneric)
            {
                sb.Write('(');

                var builderLength = sb.Length;

                bool first = true;
                foreach (object item in (IEnumerable)value)
                {
                    if (!first)
                    {
                        sb.Write(',');
                    }
                    ConvertToSqlValue(typeDetails.IEnumerableGenericInnerType, item, ref sb, context);
                    first = false;
                }

                if (builderLength == sb.Length)
                {
                    sb.Write("NULL");
                }

                sb.Write(')');
                return(false);
            }

            if (TypeLookup.CoreTypeLookup(type, out CoreType coreType))
            {
                switch (coreType)
                {
                case CoreType.Boolean:
                    var lastOperator = context.MemberContext.OperatorStack.Peek();
                    if (lastOperator == Operator.And || lastOperator == Operator.Or || lastOperator == Operator.Lambda)
                    {
                        sb.Write((bool)value ? "1=1" : "1=0");
                    }
                    else
                    {
                        sb.Write((bool)value ? '1' : '0');
                    }
                    return(false);

                case CoreType.Byte: sb.Write((byte)value); return(false);

                case CoreType.SByte: sb.Write((sbyte)value); return(false);

                case CoreType.Int16: sb.Write((short)value); return(false);

                case CoreType.UInt16: sb.Write((ushort)value); return(false);

                case CoreType.Int32: sb.Write((int)value); return(false);

                case CoreType.UInt32: sb.Write((uint)value); return(false);

                case CoreType.Int64: sb.Write((long)value); return(false);

                case CoreType.UInt64: sb.Write((ulong)value); return(false);

                case CoreType.Single: sb.Write((float)value); return(false);

                case CoreType.Double: sb.Write((double)value); return(false);

                case CoreType.Decimal: sb.Write((decimal)value); return(false);

                case CoreType.Char:
                    if ((char)value == '\'')
                    {
                        sb.Write("\'\'\'\'");
                    }
                    else
                    {
                        sb.Write('\'');
                        sb.Write((char)value);
                        sb.Write('\'');
                    }
                    return(false);

                case CoreType.DateTime:
                    if (memberProperty != null)
                    {
                        switch (memberProperty.Member.Name)
                        {
                        case "Year":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Year);
                            sb.Write('\'');
                            return(true);

                        case "Month":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Month);
                            sb.Write('\'');
                            return(true);

                        case "Day":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Day);
                            sb.Write('\'');
                            return(true);

                        case "Hour":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Hour);
                            sb.Write('\'');
                            return(true);

                        case "Minute":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Minute);
                            sb.Write('\'');
                            return(true);

                        case "Second":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Second);
                            sb.Write('\'');
                            return(true);

                        case "Millisecond":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).Millisecond);
                            sb.Write('\'');
                            return(true);

                        case "DayOfYear":
                            sb.Write('\'');
                            sb.Write(((DateTime)value).DayOfYear);
                            sb.Write('\'');
                            return(true);

                        case "DayOfWeek":
                            sb.Write('\'');
                            sb.Write(((int)((DateTime)value).DayOfWeek).ToString());
                            sb.Write('\'');
                            return(true);
                        }
                    }
                    sb.Write('\'');
                    sb.Write((DateTime)value, DateTimeFormat.ISO8601);
                    sb.Write('\'');
                    return(false);

                case CoreType.DateTimeOffset:
                    if (memberProperty != null)
                    {
                        switch (memberProperty.Member.Name)
                        {
                        case "Year":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Year);
                            sb.Write('\'');
                            return(true);

                        case "Month":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Month);
                            sb.Write('\'');
                            return(true);

                        case "Day":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Day);
                            sb.Write('\'');
                            return(true);

                        case "Hour":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Hour);
                            sb.Write('\'');
                            return(true);

                        case "Minute":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Minute);
                            sb.Write('\'');
                            return(true);

                        case "Second":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Second);
                            sb.Write('\'');
                            return(true);

                        case "Millisecond":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).Millisecond);
                            sb.Write('\'');
                            return(true);

                        case "DayOfYear":
                            sb.Write('\'');
                            sb.Write(((DateTimeOffset)value).DayOfYear);
                            sb.Write('\'');
                            return(true);

                        case "DayOfWeek":
                            sb.Write('\'');
                            sb.Write(((int)((DateTimeOffset)value).DayOfWeek).ToString());
                            sb.Write('\'');
                            return(true);
                        }
                    }
                    sb.Write('\'');
                    sb.Write((DateTimeOffset)value, DateTimeFormat.ISO8601);
                    sb.Write('\'');
                    return(false);

                case CoreType.TimeSpan:
                    if (memberProperty != null)
                    {
                        switch (memberProperty.Member.Name)
                        {
                        case "Hours":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).Hours);
                            sb.Write('\'');
                            return(true);

                        case "Minutes":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).Minutes);
                            sb.Write('\'');
                            return(true);

                        case "Seconds":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).Seconds);
                            sb.Write('\'');
                            return(true);

                        case "Milliseconds":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).Milliseconds);
                            sb.Write('\'');
                            return(true);

                        case "TotalHours":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).TotalHours);
                            sb.Write('\'');
                            return(true);

                        case "TotalMinutes":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).TotalMinutes);
                            sb.Write('\'');
                            return(true);

                        case "TotalSeconds":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).TotalSeconds);
                            sb.Write('\'');
                            return(true);

                        case "TotalMilliseconds":
                            sb.Write('\'');
                            sb.Write(((TimeSpan)value).TotalMilliseconds);
                            sb.Write('\'');
                            return(true);
                        }
                    }
                    sb.Write('\'');
                    sb.Write((TimeSpan)value, TimeFormat.ISO8601);
                    sb.Write('\'');
                    return(false);

                case CoreType.Guid:
                    sb.Write('\'');
                    sb.Write(((Guid)value).ToString("N"));
                    sb.Write('\'');
                    return(false);

                case CoreType.String:
                    sb.Write('\'');
                    sb.Write(((string)value).Replace("'", "''"));
                    sb.Write('\''); return(false);
                }
            }

            if (type == typeof(object))
            {
                sb.Write('\'');
                sb.Write(value.ToString().Replace("\'", "''"));
                sb.Write('\'');
                return(false);
            }

            throw new NotImplementedException($"{type.GetNiceName()} value {value?.ToString()} not converted");
        }
Ejemplo n.º 3
0
        private static void ConvertToStringValueRender(Type type, object value, ConvertContext context)
        {
            var typeDetails = TypeAnalyzer.GetTypeDetail(type);

            if (value == null)
            {
                context.Builder.Append("null");
                ConvertToStringValueStack(context);
                return;
            }

            if (typeDetails.IsNullable)
            {
                type        = typeDetails.InnerTypes[0];
                typeDetails = typeDetails.InnerTypeDetails[0];
            }

            if (type.IsEnum)
            {
                context.Builder.Append(type.Name).Append('.').Append(value);
                return;
            }

            if (type.IsArray)
            {
                Type arrayType = typeDetails.InnerTypes[0];
                context.Builder.Append('[');
                bool first = true;
                foreach (object item in (IEnumerable)value)
                {
                    if (!first)
                    {
                        context.Builder.Append(',');
                    }
                    ConvertToStringValue(arrayType, item, context);
                    first = false;
                }
                context.Builder.Append(']');
                return;
            }

            if (typeDetails.IsIEnumerableGeneric)
            {
                context.Builder.Append('[');
                bool first = true;
                foreach (object item in (IEnumerable)value)
                {
                    if (!first)
                    {
                        context.Builder.Append(',');
                    }
                    ConvertToStringValue(typeDetails.IEnumerableGenericInnerType, item, context);
                    first = false;
                }
                context.Builder.Append(']');
                return;
            }

            if (TypeLookup.CoreTypeLookup(type, out CoreType coreType))
            {
                switch (coreType)
                {
                case CoreType.Boolean: context.Builder.Append((bool)value); return;

                case CoreType.Byte: context.Builder.Append((byte)value); return;

                case CoreType.SByte: context.Builder.Append((sbyte)value); return;

                case CoreType.Int16: context.Builder.Append((short)value); return;

                case CoreType.UInt16: context.Builder.Append((ushort)value); return;

                case CoreType.Int32: context.Builder.Append((int)value); return;

                case CoreType.UInt32: context.Builder.Append((uint)value); return;

                case CoreType.Int64: context.Builder.Append((long)value); return;

                case CoreType.UInt64: context.Builder.Append((ulong)value); return;

                case CoreType.Single: context.Builder.Append((float)value); return;

                case CoreType.Double: context.Builder.Append((double)value); return;

                case CoreType.Decimal: context.Builder.Append((decimal)value); return;

                case CoreType.Char: context.Builder.Append('\'').Append(value).Append('\''); return;

                case CoreType.DateTime: context.Builder.Append("DateTime.Parse(\"").Append(value).Append("\")"); return;

                case CoreType.DateTimeOffset: context.Builder.Append("DateTimeOffset.Parse(\"").Append(value).Append("\")"); return;

                case CoreType.TimeSpan: context.Builder.Append("TimeSpan.Parse(\"").Append(value).Append("\")"); return;

                case CoreType.Guid: context.Builder.Append('\'').Append(value.ToString()).Append('\''); return;

                case CoreType.String: context.Builder.Append('\'').Append(((string)value).Replace("'", "''")).Append('\''); return;
                }
            }

            if (type == typeof(object))
            {
                context.Builder.Append('\'').Append(value.ToString().Replace("'", "''")).Append('\'');
                return;
            }

            throw new NotImplementedException($"{type.GetNiceName()} value {value?.ToString()} not converted");
        }
Ejemplo n.º 4
0
        private static Type Generate(MemberInfo memberInfo, CoreType?coreType, bool isByteArray)
        {
            var interfaceType = TypeAnalyzer.GetGenericType(iCoreTypeSetterType, memberInfo.ReflectedType);

            string typeSignature = $"{interfaceType.FullName}_{memberInfo.Name}_CoreTypeSetterGenerator";

            var moduleBuilder = GeneratedAssembly.GetModuleBuilder();
            var typeBuilder   = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null);

            typeBuilder.AddInterfaceImplementation(interfaceType);

            _ = typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            var methods    = interfaceType.GetMethods().ToList();
            var properties = interfaceType.GetProperties().ToList();

            foreach (var @interface in interfaceType.GetInterfaces())
            {
                methods.AddRange(@interface.GetMethods());
                properties.AddRange(@interface.GetProperties());
            }

            foreach (var method in methods)
            {
                if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))
                {
                    continue;
                }

                Type[] parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();

                var methodBuilder = typeBuilder.DefineMethod(
                    method.Name,
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                    CallingConventions.HasThis,
                    null,
                    parameterTypes
                    );
                methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed);

                var il = methodBuilder.GetILGenerator();

                CoreType?methodCoreType;
                bool     methodIsByteArray;
                if (TypeLookup.CoreTypeLookup(parameterTypes[1], out CoreType coreTypeLookup))
                {
                    methodCoreType    = coreTypeLookup;
                    methodIsByteArray = false;
                }
                else
                {
                    methodCoreType    = null;
                    methodIsByteArray = parameterTypes[1] == byteArrayType;
                }

                if (coreType == methodCoreType && isByteArray == methodIsByteArray)
                {
                    if (memberInfo.MemberType == MemberTypes.Property)
                    {
                        var propertyInfo = (PropertyInfo)memberInfo;
                        var setMethod    = propertyInfo.GetSetMethod(true);
                        if (!setMethod.IsStatic)
                        {
                            il.Emit(OpCodes.Ldarg_1);
                        }

                        il.Emit(OpCodes.Ldarg_2);

                        if (setMethod.IsFinal || !setMethod.IsVirtual)
                        {
                            il.Emit(OpCodes.Call, setMethod);
                        }
                        else
                        {
                            il.Emit(OpCodes.Callvirt, setMethod);
                        }

                        il.Emit(OpCodes.Ret);
                    }
                    else if (memberInfo.MemberType == MemberTypes.Field)
                    {
                        var fieldInfo = (FieldInfo)memberInfo;
                        if (!fieldInfo.IsStatic)
                        {
                            il.Emit(OpCodes.Ldarg_1);
                            if (fieldInfo.ReflectedType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox, fieldInfo.ReflectedType);
                            }
                        }

                        il.Emit(OpCodes.Ldarg_2);

                        if (!fieldInfo.IsStatic)
                        {
                            il.Emit(OpCodes.Stfld, fieldInfo);
                        }
                        else
                        {
                            il.Emit(OpCodes.Stsfld, fieldInfo);
                        }

                        il.Emit(OpCodes.Ret);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    il.Emit(OpCodes.Newobj, notSupportedExceptionConstructor);
                    il.Emit(OpCodes.Throw);
                }

                typeBuilder.DefineMethodOverride(methodBuilder, method);
            }

            foreach (var property in properties)
            {
                var propertyBuilder = typeBuilder.DefineProperty(
                    property.Name,
                    PropertyAttributes.HasDefault,
                    property.PropertyType,
                    null
                    );

                var getMethodName    = "get_" + property.Name;
                var getMethodBuilder = typeBuilder.DefineMethod(
                    getMethodName,
                    MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                    property.PropertyType,
                    Type.EmptyTypes
                    );
                var getMethodBuilderIL = getMethodBuilder.GetILGenerator();


                if (property.Name == nameof(ICoreTypeSetter <object> .CoreType))
                {
                    if (coreType.HasValue)
                    {
                        getMethodBuilderIL.Emit(OpCodes.Ldc_I4, (int)coreType.Value);
                        getMethodBuilderIL.Emit(OpCodes.Newobj, coreTypeNullableConstructor);
                    }
                    else
                    {
                        getMethodBuilderIL.Emit(OpCodes.Ldnull);
                    }
                }
                else if (property.Name == nameof(ICoreTypeSetter <object> .IsByteArray))
                {
                    if (isByteArray)
                    {
                        getMethodBuilderIL.Emit(OpCodes.Ldc_I4_1);
                    }
                    else
                    {
                        getMethodBuilderIL.Emit(OpCodes.Ldc_I4_0);
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }

                getMethodBuilderIL.Emit(OpCodes.Ret);

                var getMethod = methods.FirstOrDefault(x => x.Name == getMethodName);
                typeBuilder.DefineMethodOverride(getMethodBuilder, getMethod);

                propertyBuilder.SetGetMethod(getMethodBuilder);
            }

            Type objectType = typeBuilder.CreateTypeInfo();

            return(objectType);
        }