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