Beispiel #1
0
        /// <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());
        }
Beispiel #3
0
        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());
        }
Beispiel #5
0
        /// <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());
        }
Beispiel #8
0
        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)));
        }