Example #1
0
        /// <summary>
        /// Finds all signatures for the given function name.
        /// Search in both BuiltIn uri functions and Custom uri functions.
        /// Combine and return the signatures overloads of the results.
        /// </summary>
        /// <param name="functionName">The function to get the signatures for.</param>
        /// <returns>The signatures which match the supplied function name.</returns>
        internal static FunctionSignatureWithReturnType[] GetUriFunctionSignatures(string functionName)
        {
            FunctionSignatureWithReturnType[] customUriFunctionsSignatures  = null;
            FunctionSignatureWithReturnType[] builtInUriFunctionsSignatures = null;

            // Try to find the function in the user custom functions and in our built-in functions
            bool customFound  = CustomUriFunctions.TryGetCustomFunction(functionName, out customUriFunctionsSignatures);
            bool builtInFound = BuiltInUriFunctions.TryGetBuiltInFunction(functionName, out builtInUriFunctionsSignatures);

            if (!customFound && !builtInFound)
            {
                // Not found in both built-in and custom.
                throw new ODataException(ODataErrorStrings.MetadataBinder_UnknownFunction(functionName));
            }

            if (!customFound)
            {
                Debug.Assert(builtInUriFunctionsSignatures != null, "No Built-in functions found");
                return(builtInUriFunctionsSignatures);
            }

            if (!builtInFound)
            {
                Debug.Assert(customUriFunctionsSignatures != null, "No Custom functions found");
                return(customUriFunctionsSignatures);
            }

            return(builtInUriFunctionsSignatures.Concat(customUriFunctionsSignatures).ToArray());
        }
Example #2
0
        /// <summary>
        /// Add a custom uri function to extend uri functions.
        /// In case the function name already exists as a custom function, the signature will be added as an another overload.
        /// </summary>
        /// <param name="functionName">The new custom function name</param>
        /// <param name="functionSignature">The new custom function signature</param>
        /// <exception cref="ArgumentNullException">Arguments are null, or function signature return type is null</exception>
        /// <exception cref="ODataException">Throws if built-in function name already exists.</exception>
        /// <exception cref="ODataException">Throws if built-in function signature overload already exists.</exception>
        /// <exception cref="ODataException">Throws if custom function signature overload already exists</exception>
        public static void AddCustomUriFunction(string functionName, FunctionSignatureWithReturnType functionSignature)
        {
            // Parameters validation
            ExceptionUtils.CheckArgumentStringNotNullOrEmpty(functionName, "customFunctionName");
            ExceptionUtils.CheckArgumentNotNull(functionSignature, "newCustomFunctionSignature");

            ValidateFunctionWithReturnType(functionSignature);

            // Thread saftey - before using the custom functions dictionary
            lock (Locker)
            {
                // Check if the function does already exists in the Built-In functions
                // If 'addAsOverloadToBuiltInFunction' parameter is false - throw expection
                // Else, add as a custom function
                FunctionSignatureWithReturnType[] existingBuiltInFunctionOverload;
                if (BuiltInUriFunctions.TryGetBuiltInFunction(functionName, out existingBuiltInFunctionOverload))
                {
                    // Function name exists, check if full signature exists among the overloads.
                    if (existingBuiltInFunctionOverload.Any(builtInFunction =>
                                                            AreFunctionsSignatureEqual(functionSignature, builtInFunction)))
                    {
                        throw new ODataException(Strings.CustomUriFunctions_AddCustomUriFunction_BuiltInExistsFullSignature(functionName));
                    }
                }

                AddCustomFunction(functionName, functionSignature);
            }
        }
Example #3
0
        internal static IList <KeyValuePair <string, FunctionSignatureWithReturnType> > GetUriFunctionSignatures(string functionCallToken, bool enableCaseInsensitive = false)
        {
            IList <KeyValuePair <string, FunctionSignatureWithReturnType> > customUriFunctionsNameSignatures = null;

            FunctionSignatureWithReturnType[] builtInUriFunctionsSignatures = null;
            IList <KeyValuePair <string, FunctionSignatureWithReturnType> > builtInUriFunctionsNameSignatures = null;

            // Try to find the function in the user custom functions
            bool customFound = CustomUriFunctions.TryGetCustomFunction(functionCallToken, out customUriFunctionsNameSignatures,
                                                                       enableCaseInsensitive);

            // And find in our built-in functions
            // Since list of all built-in functions is a fixed list and is initialized with names in lower case,
            // such as "endswith", "geo.distance", "maxdatetime" and "round",
            // => For case-insensitive searching, it is more efficient to convert the search key to lower case first
            //    and then do a case-sensitive match.
            string nameKey = enableCaseInsensitive
                ? functionCallToken.ToLowerInvariant()
                : functionCallToken;
            bool builtInFound = BuiltInUriFunctions.TryGetBuiltInFunction(nameKey, out builtInUriFunctionsSignatures);

            // Populate the matched names found for built-in function
            if (builtInFound)
            {
                builtInUriFunctionsNameSignatures =
                    builtInUriFunctionsSignatures.Select(sig => new KeyValuePair <string, FunctionSignatureWithReturnType>(nameKey, sig)).ToList();
            }

            if (!customFound && !builtInFound)
            {
                // Not found in both built-in and custom.
                throw new ODataException(ODataErrorStrings.MetadataBinder_UnknownFunction(functionCallToken));
            }

            if (!customFound)
            {
                Debug.Assert(builtInUriFunctionsNameSignatures != null, "No Built-in functions found");
                return(builtInUriFunctionsNameSignatures);
            }

            if (!builtInFound)
            {
                Debug.Assert(customUriFunctionsNameSignatures != null, "No Custom functions found");
                return(customUriFunctionsNameSignatures);
            }

            return(builtInUriFunctionsNameSignatures.Concat(customUriFunctionsNameSignatures).ToArray());
        }