/// <summary> /// Initializes a new instance of the <see cref="FunctionParameter"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="type">The type.</param> /// <param name="functionParameterAttribute">The function parameter attribute.</param> /// <param name="widgetProvider">The widget provider.</param> public FunctionParameter(string name, Type type, FunctionParameterAttribute functionParameterAttribute, WidgetFunctionProvider widgetProvider) { Name = name; Type = type; Attribute = functionParameterAttribute; WidgetProvider = widgetProvider; }
public static string GetSqlParameterResult_Text(ParameterInfo param, IDictionary <string, string> map) { StringBuilder sb = new StringBuilder(); FunctionParameterAttribute paramAttr = param.GetCustomAttribute <FunctionParameterAttribute>(); // Append result parameter name with type sb.AppendFormat("[{0}] {1}", paramAttr != null && !string.IsNullOrEmpty(paramAttr.Name) ? paramAttr.Name : param.Name, GetSqlType_Text(param.ParameterType, param, map)); return(sb.ToString()); }
private static IDictionary <string, FunctionParameter> GetModelParameters(Type modelType) { var dictionary = new Dictionary <string, FunctionParameter>(); foreach (var info in modelType.GetProperties(BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (((info.GetSetMethod(false) == null)) || info.GetCustomAttributes(typeof(FunctionParameterIgnoreAttribute), false).Any()) { continue; } var propertyType = info.PropertyType; var name = info.Name; FunctionParameterAttribute functionParameterAttribute = null; var source = info.GetCustomAttributes <FunctionParameterAttribute>(false).ToList(); if (source.Count > 1) { Log.LogWarning(LogTitle, String.Format("More than one '{0}' attribute defined on property '{1}'", typeof(FunctionParameterAttribute).Name, name)); } else { functionParameterAttribute = source.FirstOrDefault(); } WidgetFunctionProvider widgetProvider = null; if ((functionParameterAttribute != null) && functionParameterAttribute.HasWidgetMarkup) { try { widgetProvider = functionParameterAttribute.GetWidgetFunctionProvider(modelType, info); } catch (Exception exception) { Log.LogWarning(LogTitle, String.Format("Failed to get widget function provider for parameter property {0}.", info.Name)); Log.LogWarning(LogTitle, exception); } } if (!dictionary.ContainsKey(name)) { dictionary.Add(name, new FunctionParameter(name, propertyType, functionParameterAttribute, widgetProvider)); } } return(dictionary); }
public static string GetSqlParameterArgument_Text(ParameterInfo param, IDictionary <string, string> map) { StringBuilder sb = new StringBuilder(); FunctionParameterAttribute paramAttr = param.GetCustomAttribute <FunctionParameterAttribute>(); // Append parameter name with type sb.AppendFormat("@{0} {1}", paramAttr != null && !string.IsNullOrEmpty(paramAttr.Name) ? paramAttr.Name : param.Name, GetSqlType_Text(param.ParameterType, param, map)); // Append default value DefaultValueAttribute defaultValueAttr = param.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttr != null) { sb.AppendFormat(CultureInfo.InvariantCulture, " = {0}", defaultValueAttr.Value == null ? (object)"NULL" : defaultValueAttr.Value.GetType().IsEnum ? ((Enum)defaultValueAttr.Value).ToString("D") : defaultValueAttr.Value); } // Append OUT parameter if (param.IsOut || param.ParameterType.IsByRef) { sb.Append(" OUT"); } return(sb.ToString()); }
/// <summary> /// Extracts the function paramteres from an object that represents a function. /// </summary> /// <param name="functionObject">The object that represents a function.</param> /// <param name="baseFunctionType">Type of the base function.</param> /// <param name="filePath">Physical file location of the file behind the function, used for logging.</param> /// <returns></returns> public static IDictionary <string, FunctionParameter> GetParameters(object functionObject, Type baseFunctionType, string filePath) { var functionParameters = new Dictionary <string, FunctionParameter>(); IDictionary <string, WidgetFunctionProvider> parameterWidgets = GetParameterWidgets(functionObject); var type = functionObject.GetType(); while (type != baseFunctionType && type != null) { var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.DeclaredOnly); foreach (var property in properties) { // Skipping overriden base properties if (property.GetAccessors()[0].GetBaseDefinition().DeclaringType == baseFunctionType) { continue; } // Skipping private setters if (property.GetSetMethod(false) == null) { continue; } // Skipping explicitly ignored attributes if (property.GetCustomAttributes(typeof(FunctionParameterIgnoreAttribute), false).Any()) { continue; } var propType = property.PropertyType; var name = property.Name; FunctionParameterAttribute attr = null; var attributes = property.GetCustomAttributes(typeof(FunctionParameterAttribute), false).Cast <FunctionParameterAttribute>().ToList(); if (attributes.Count > 1) { Log.LogWarning(LogTitle, "More than one '{0}' attribute defined on property '{1}'. Location: '{2}'" .FormatWith(typeof(FunctionParameterAttribute).Name, name, filePath)); } else { attr = attributes.FirstOrDefault(); } WidgetFunctionProvider attibuteBasedWidgetProvider = null; WidgetFunctionProvider methodBasedWidgetProvider = null; if (attr != null && attr.HasWidgetMarkup) { try { attibuteBasedWidgetProvider = attr.GetWidgetFunctionProvider(type, property); } catch (Exception ex) { Log.LogWarning(LogTitle, "Failed to get widget function provider for parameter property {0}. Location: '{1}'" .FormatWith(property.Name, filePath)); Log.LogWarning(LogTitle, ex); } } parameterWidgets.TryGetValue(name, out methodBasedWidgetProvider); if (methodBasedWidgetProvider != null && attibuteBasedWidgetProvider != null) { Log.LogWarning(LogTitle, "Widget for property {0} is defined in both {1} attribute and in {2}() method. Remove one of the definitions. Location: '{3}'" .FormatWith(property.Name, nameof(FunctionParameterAttribute), nameof(IParameterWidgetsProvider.GetParameterWidgets), filePath)); } if (!functionParameters.ContainsKey(name)) { functionParameters.Add(name, new FunctionParameter(name, propType, attr, attibuteBasedWidgetProvider ?? methodBasedWidgetProvider)); } } type = type.BaseType; } return(functionParameters); }
internal static ParameterProfile BuildParameterProfile(string name, Type type, FunctionParameterAttribute attribute, Type controllerType) { BaseValueProvider defaultValueProvider = new NoValueValueProvider(); string label = name; string helpText = String.Empty; if (!attribute.Label.IsNullOrEmpty()) { label = attribute.Label; } if (!attribute.Help.IsNullOrEmpty()) { helpText = attribute.Help; } bool isRequired = !attribute.HasDefaultValue; if (!isRequired) { defaultValueProvider = new ConstantValueProvider(attribute.DefaultValue); } WidgetFunctionProvider widgetProvider = attribute.GetWidgetFunctionProvider(controllerType, null); bool hideInSimpleView = attribute.HideInSimpleView; if (widgetProvider == null) { widgetProvider = StandardWidgetFunctions.GetDefaultWidgetFunctionProviderByType(type, isRequired); } return(new ParameterProfile(name, type, isRequired, defaultValueProvider, widgetProvider, label, new HelpDefinition(helpText), hideInSimpleView)); }
public static string GetSqlType_Text(Type type, ICustomAttributeProvider provider, IDictionary <string, string> map) { StringBuilder sb = new StringBuilder(); SqlTypeInfo sqlTypeInfo; if (type.IsByRef) { type = type.GetElementType(); } type = Nullable.GetUnderlyingType(type) ?? type; if (type.IsEnum) { type = Enum.GetUnderlyingType(type); } if (typesMap.TryGetValue(type, out sqlTypeInfo)) { FunctionParameterAttribute paramAttr = provider != null ? (FunctionParameterAttribute)provider.GetCustomAttributes(typeof(FunctionParameterAttribute), false).FirstOrDefault() : null; SqlFacetAttribute facetAttr = provider != null ? (SqlFacetAttribute)provider.GetCustomAttributes(typeof(SqlFacetAttribute), false).FirstOrDefault() : null; sb.Append(paramAttr != null && !string.IsNullOrEmpty(paramAttr.TypeName) ? paramAttr.TypeName : facetAttr != null && facetAttr.IsFixedLength ? sqlTypeInfo.TypeNameFixed : sqlTypeInfo.TypeName); // Append type facets switch (sqlTypeInfo.Facet) { case SqlTypeFacet.Size: if (facetAttr != null && (facetAttr.MaxSize > 0 || facetAttr.MaxSize == -1)) { sb.AppendFormat(CultureInfo.InvariantCulture, "({0})", facetAttr.MaxSize == -1 ? (object)"max" : facetAttr.MaxSize); } else if (sqlTypeInfo.MaxSize.HasValue) { sb.AppendFormat(CultureInfo.InvariantCulture, "({0})", sqlTypeInfo.MaxSize == -1 ? (object)"max" : sqlTypeInfo.MaxSize); } break; case SqlTypeFacet.PrecisionScale: if (facetAttr != null && facetAttr.Precision > 0) { if (facetAttr.Scale > 0) { sb.AppendFormat(CultureInfo.InvariantCulture, "({0}, {1})", facetAttr.Precision, facetAttr.Scale); } else { sb.AppendFormat(CultureInfo.InvariantCulture, "({0})", facetAttr.Precision); } } else if (sqlTypeInfo.Precision.HasValue && sqlTypeInfo.Precision.Value > 0) { if (sqlTypeInfo.Scale.HasValue && sqlTypeInfo.Scale.Value > 0) { sb.AppendFormat(CultureInfo.InvariantCulture, "({0}, {1})", sqlTypeInfo.Precision.Value, sqlTypeInfo.Scale.Value); } else { sb.AppendFormat(CultureInfo.InvariantCulture, "({0})", sqlTypeInfo.Precision.Value); } } break; } } else if (type.IsDefined(typeof(SqlUserDefinedTypeAttribute))) { SqlUserDefinedTypeAttribute udt = type.GetCustomAttribute <SqlUserDefinedTypeAttribute>(); string schema; if (!map.TryGetValue(type.FullName, out schema)) { schema = "dbo"; } sb.AppendFormat("[{0}].[{1}]", schema, !string.IsNullOrEmpty(udt.Name) ? udt.Name : type.Name); } else { throw new ArgumentException(string.Format("Framework type '{0}' is not mapped to sql type", type.FullName)); } return(sb.ToString()); }
private FunctionDescriptor BuildFunctionDescriptor(MethodInfo mi) { DbFunctionAttribute attrFunction = mi.GetCustomAttribute <DbFunctionAttribute>(); if (attrFunction == null) { throw new InvalidOperationException(string.Format("Method {0} of type {1} must be marked by'DbFunction...' attribute.", mi.Name, mi.DeclaringType)); } DbFunctionExAttribute attrFunctionEx = attrFunction as DbFunctionExAttribute; string methodName = mi.Name; string functionName = !string.IsNullOrWhiteSpace(attrFunction.FunctionName) ? attrFunction.FunctionName : methodName; string databaseSchema = attrFunctionEx != null && !string.IsNullOrWhiteSpace(attrFunctionEx.Schema) ? attrFunctionEx.Schema : _databaseSchema; if (string.IsNullOrWhiteSpace(databaseSchema)) { throw new InvalidOperationException(string.Format("Database schema for method {0} of type {1} is not defined.", mi.Name, mi.DeclaringType)); } // bool isExtension = mi.IsDefined(typeof(ExtensionAttribute), false); ParameterDescriptor[] parameters = mi.GetParameters() .SkipWhile(pi => isExtension && pi.Position == 0 && pi.ParameterType.IsAssignableFrom(typeof(DbContext))) .OrderBy(pi => pi.Position) .Select((pi, i) => { FunctionParameterAttribute parameterAttr = pi.GetCustomAttribute <FunctionParameterAttribute>(); Type parameterType = pi.ParameterType == typeof(ObjectParameter) ? parameterAttr.Type : pi.ParameterType; if (parameterType == null) { throw new InvalidOperationException(string.Format("Method parameter '{0}' at position {1} is not defined.", pi.Name, pi.Position)); } // MinLengthAttribute minLengthAttr = pi.GetCustomAttribute <MinLengthAttribute>(); MaxLengthAttribute maxLengthAttr = pi.GetCustomAttribute <MaxLengthAttribute>(); FixedLengthAttribute fixedLengthAttr = pi.GetCustomAttribute <FixedLengthAttribute>(); PrecisionScaleAttribute precisionScaleAttr = pi.GetCustomAttribute <PrecisionScaleAttribute>(); // return(new ParameterDescriptor(i, parameterType.IsByRef ? pi.IsOut ? ParameterDirection.Output : ParameterDirection.InputOutput : ParameterDirection.Input, parameterType) { Name = parameterAttr != null && !string.IsNullOrWhiteSpace(parameterAttr.Name) ? parameterAttr.Name : pi.Name, StoreTypeName = parameterAttr != null && !string.IsNullOrWhiteSpace(parameterAttr.TypeName) ? parameterAttr.TypeName : null, Length = maxLengthAttr != null ? maxLengthAttr.Length : default(int?), IsFixedLength = minLengthAttr != null && maxLengthAttr != null ? minLengthAttr.Length == maxLengthAttr.Length : fixedLengthAttr != null ? fixedLengthAttr.IsFixedLength : default(bool?), Precision = precisionScaleAttr != null ? precisionScaleAttr.Precision : default(byte?), Scale = precisionScaleAttr != null ? precisionScaleAttr.Scale : default(byte?) }); }) .ToArray(); // IQueryable<> Type returnType = mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition() == typeof(IQueryable <>) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IQueryable <>)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); ResultDescriptor result = new ResultDescriptor(returnType.GetGenericArguments()[0]) { ColumnName = attrResult != null ? attrResult.ColumnName : _resultColumnName, StoreTypeName = attrResult != null ? attrResult.TypeName : null }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(result, 1))); } // IQueryable returnType = mi.ReturnType == typeof(IQueryable) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t == typeof(IQueryable)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); if (attrResult != null) { ResultDescriptor result = new ResultDescriptor(attrResult.Type) { ColumnName = attrResult.ColumnName ?? _resultColumnName, StoreTypeName = attrResult.TypeName }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(result, 1))); } throw new InvalidOperationException("Result type is not specified in function"); } // IEnumerable<> returnType = mi.ReturnType == typeof(string) || mi.ReturnType == typeof(byte[]) ? null : mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <>)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); IEnumerable <ResultDescriptor> results = Enumerable.Repeat(new ResultDescriptor(returnType.GetGenericArguments()[0]) { ColumnName = attrResult != null ? attrResult.ColumnName : _resultColumnName, StoreTypeName = attrResult != null ? attrResult.TypeName : null }, 1) .Concat(mi.GetCustomAttributes <FunctionResultAttribute>() .Select(a => new ResultDescriptor(a.Type) { ColumnName = a.ColumnName ?? _resultColumnName, StoreTypeName = a.TypeName })); return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, false, false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, results)); } // IEnumerable returnType = mi.ReturnType == typeof(string) || mi.ReturnType == typeof(byte[]) ? null : mi.ReturnType == typeof(IEnumerable) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t == typeof(IEnumerable)); if (returnType != null) { IEnumerable <ResultDescriptor> results = mi.GetCustomAttributes <FunctionResultAttribute>() .Select(a => new ResultDescriptor(a.Type) { ColumnName = a.ColumnName ?? _resultColumnName, StoreTypeName = a.TypeName }); return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, false, false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, results)); } // Scalar result returnType = mi.ReturnType; FunctionResultAttribute attr = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); ResultDescriptor resultDescriptor = new ResultDescriptor(mi.ReturnType) { StoreTypeName = attr != null ? attr.TypeName : null }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, false, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.IsAggregate : default(bool?), parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(resultDescriptor, 1))); }