コード例 #1
0
        public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
        {
            ISQLFunction sqlFunction = GetFunction(criteriaQuery);
            IType        type        = sqlFunction.ReturnType(returnType, criteriaQuery.Factory);

            return(new IType[] { type });
        }
コード例 #2
0
        /// <summary>
        /// Get the type that will be effectively returned by the underlying database.
        /// </summary>
        /// <param name="sqlFunction">The sql function.</param>
        /// <param name="argumentTypes">The types of arguments.</param>
        /// <param name="mapping">The mapping for retrieving the argument sql types.</param>
        /// <param name="throwOnError">Whether to throw when the number of arguments is invalid or they are not supported.</param>
        /// <returns>The type returned by the underlying database or <see langword="null"/> when the number of arguments
        /// is invalid or they are not supported.</returns>
        /// <exception cref="QueryException">When <paramref name="throwOnError"/> is set to <see langword="true"/> and the
        /// number of arguments is invalid or they are not supported.</exception>
        public static IType GetEffectiveReturnType(
            this ISQLFunction sqlFunction,
            IEnumerable <IType> argumentTypes,
            IMapping mapping,
            bool throwOnError)
        {
            if (!(sqlFunction is ISQLFunctionExtended extendedSqlFunction))
            {
                try
                {
                    return(sqlFunction.ReturnType(argumentTypes.FirstOrDefault(), mapping));
                }
                catch (QueryException)
                {
                    if (throwOnError)
                    {
                        throw;
                    }

                    return(null);
                }
            }

            return(extendedSqlFunction.GetEffectiveReturnType(argumentTypes, mapping, throwOnError));
        }
コード例 #3
0
        public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery,
                                              IDictionary <string, IFilter> enabledFilters)
        {
            ISQLFunction  sqlFunction     = GetFunction(criteriaQuery);
            List <string> tokens          = new List <string>();
            string        replacemenToken = Guid.NewGuid().ToString("n");

            for (int i = 0; i < args.Length; i++)
            {
                tokens.Add(replacemenToken);
            }
            string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory).ToString();

            string[] splitted = functionStatement.Split(new string[] { replacemenToken }, StringSplitOptions.RemoveEmptyEntries);

            SqlStringBuilder sb = new SqlStringBuilder();

            for (int i = 0; i < splitted.Length; i++)
            {
                sb.Add(splitted[i]);
                if (i < args.Length)
                {
                    int       loc        = (position + 1) * 1000 + i;
                    SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], loc, enabledFilters);
                    sb.Add(projectArg);
                }
            }
            sb.Add(" as ");
            sb.Add(GetColumnAliases(position)[0]);
            return(sb.ToSqlString());
        }
コード例 #4
0
ファイル: Fixture.cs プロジェクト: weelink/nhibernate-core
        protected override void Configure(Configuration configuration)
        {
            Dialect.Dialect d            = Dialect;
            ISQLFunction    toReRegister = d.Functions["current_timestamp"];

            configuration.AddSqlFunction("MyCurrentTime", toReRegister);
        }
コード例 #5
0
		public void Push(ISQLFunction sqlFunction)
		{
			if (sqlFunction == null)
			{
				throw new ArgumentNullException("sqlFunction");
			}
			stack.Push(new FunctionHolder(sqlFunction));
		}
コード例 #6
0
        private IType GetReturnType(ICriteria criteria, ICriteriaQuery criteriaQuery)
        {
            ISQLFunction sqlFunction = GetFunction(criteriaQuery);

            var resultType = returnType ?? returnTypeProjection?.GetTypes(criteria, criteriaQuery).FirstOrDefault();

            return(sqlFunction.GetReturnType(new[] { resultType }, criteriaQuery.Factory, true));
        }
コード例 #7
0
			public FunctionHolder(ISQLFunction sqlFunction)
			{
				pathExpressionParser.UseThetaStyleJoin = true;
				this.sqlFunction = sqlFunction;
				functionGrammar = sqlFunction as IFunctionGrammar;
				if (functionGrammar == null)
					functionGrammar = new CommonGrammar();
			}
コード例 #8
0
ファイル: FunctionStack.cs プロジェクト: ImanRezaeipour/GTS
 public void Push(ISQLFunction sqlFunction)
 {
     if (sqlFunction == null)
     {
         throw new ArgumentNullException("sqlFunction");
     }
     stack.Push(new FunctionHolder(sqlFunction));
 }
コード例 #9
0
        public static IProjection DateDiff(DatePart datepart, IProjection startDateProjection, IProjection endDateProjection)
        {
            string       part        = Enum.GetName(typeof(DatePart), datepart).ToLower();
            ISQLFunction sqlFunction = GetDateDiffFunction(part);

            var result = Projections.SqlFunction(sqlFunction, NHibernateUtil.Int32, startDateProjection, endDateProjection);

            return(result);
        }
コード例 #10
0
    public static IProjection DateDiff(string datepart, IProjection startDate, DateTime?endDate)
    {
        ISQLFunction sqlFunction = GetDateDiffFunction(datepart);

        return(Projections.SqlFunction(
                   sqlFunction,
                   NHibernateUtil.Int32,
                   startDate,
                   Projections.Constant(endDate)));
    }
コード例 #11
0
        /// <summary>
        /// Locate a registered sql function by name.
        /// </summary>
        /// <param name="functionName">The name of the function to locate</param>
        /// <returns>The sql function, or throws QueryException if no matching sql functions could be found.</returns>
        private ISQLFunction RequireSQLFunction(string functionName)
        {
            ISQLFunction f = FindSQLFunction(functionName);

            if (f == null)
            {
                throw new QueryException("Unable to find SQL function: " + functionName);
            }
            return(f);
        }
コード例 #12
0
        public String ToSqlString(RowCountProjection projection)
        {
            ISQLFunction func = _factory.Dialect.FindFunction("count");

            if (func == null)
            {
                throw new MappingException("count function not found");
            }
            return(Alias(func.Render(RowCountProjection.Arguments, _factory as IConnectionFactory), projection.Alias));
        }
コード例 #13
0
ファイル: FunctionStack.cs プロジェクト: ImanRezaeipour/GTS
 public FunctionHolder(ISQLFunction sqlFunction)
 {
     pathExpressionParser.UseThetaStyleJoin = true;
     this.sqlFunction = sqlFunction;
     functionGrammar  = sqlFunction as IFunctionGrammar;
     if (functionGrammar == null)
     {
         functionGrammar = new CommonGrammar();
     }
 }
コード例 #14
0
        public String ToSqlString(AggregateProjection aggregateProjection)
        {
            ISQLFunction func = _factory.Dialect.FindFunction(aggregateProjection.FunctionName);

            if (func == null)
            {
                // TODO throw an exception
                throw new MappingException("Function not found");
            }
            return(Alias(func.Render(aggregateProjection.BuildFunctionParameterList(this), _factory as IConnectionFactory), aggregateProjection.Alias));
        }
コード例 #15
0
        private string LocateAppropriateDialectFunctionNameForAliasTest()
        {
            foreach (KeyValuePair <string, ISQLFunction> de in Dialect.Functions)
            {
                ISQLFunction function = de.Value;
                if (!function.HasArguments && !function.HasParenthesesIfNoArguments)
                {
                    return(de.Key);
                }
            }

            return(null);
        }
コード例 #16
0
ファイル: MethodNode.cs プロジェクト: hazzik/nhibernate-core
        private void DialectFunction(IASTNode exprList)
        {
            _function = SessionFactoryHelper.FindSQLFunction(_methodName);

            if (_function != null)
            {
                DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, (IEnumerable <IASTNode>)exprList);
            }
            //TODO:

            /*else {
             *      methodName = (String) getWalker().getTokenReplacements().get( methodName );
             * }*/
        }
コード例 #17
0
            private readonly string _name;             // TODO 6.0: convert FunctionName to read-only auto property

            public RoundFunction(bool truncate)
            {
                if (truncate)
                {
                    _singleParamFunction = Truncate;
                    _twoParamFunction    = TruncateWith2Params;
                    _name = "truncate";
                }
                else
                {
                    _singleParamFunction = Round;
                    _twoParamFunction    = RoundWith2Params;
                    _name = "round";
                }
            }
コード例 #18
0
        private ISQLFunction GetFunction(ICriteriaQuery criteriaQuery)
        {
            if (function != null)
            {
                return(function);
            }
            ISQLFunction dialectFunction = criteriaQuery.Factory.SQLFunctionRegistry.FindSQLFunction(functionName);

            if (dialectFunction == null)
            {
                throw new HibernateException("Current dialect " + criteriaQuery.Factory.Dialect + " doesn't support the function: "
                                             + functionName);
            }
            return(dialectFunction);
        }
コード例 #19
0
        private void EndBitwiseOp(string op)
        {
            ISQLFunction function = sessionFactory.SQLFunctionRegistry.FindSQLFunction(op);

            if (function == null)
            {
                return;
            }

            var functionArguments = (BitwiseOpWriter)writer;

            writer = outputStack[0];
            outputStack.RemoveAt(0);

            Out(function.Render(functionArguments.Args, sessionFactory));
        }
コード例 #20
0
        private void VisitAritmaticOperation(BinaryExpression expr, ISQLFunction arithmaticOperation)
        {
            var leftVisitor  = new SelectArgumentsVisitor(_rootCriteria, _session);
            var rightVisitor = new SelectArgumentsVisitor(_rootCriteria, _session);

            leftVisitor.Visit(expr.Left);
            rightVisitor.Visit(expr.Right);

            var joinedProjections = new List <IProjection>();

            joinedProjections.AddRange(leftVisitor._projections);
            joinedProjections.AddRange(rightVisitor._projections);
            var types      = joinedProjections[0].GetTypes(_rootCriteria, CriteriaQuery);
            var projection = new SqlFunctionProjection(arithmaticOperation, types[0], joinedProjections.ToArray());

            _projections.Add(projection);
        }
コード例 #21
0
        public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery)
        {
            ISQLFunction sqlFunction = GetFunction(criteriaQuery);

            var arguments = new List <object>();

            for (int i = 0; i < args.Length; i++)
            {
                var projectArg = GetProjectionArguments(criteriaQuery, criteria, args[i]);
                arguments.AddRange(projectArg);
            }

            return(new SqlString(
                       sqlFunction.Render(arguments, criteriaQuery.Factory),
                       " as ",
                       GetColumnAliases(position, criteria, criteriaQuery)[0]));
        }
コード例 #22
0
        public String ToSqlString(Function function)
        {
            ISQLFunction func = _factory.Dialect.FindFunction(function.FunctionName);

            if (func == null)
            {
                // TODO throw an exception
                throw new MappingException("Function not found");
            }
            List <Object> list = new List <Object>();

            foreach (IExpression exp in function.Arguments)
            {
                list.Add(exp.Render(this));
            }
            return(func.Render(list, _factory as IConnectionFactory));
        }
コード例 #23
0
        /// <summary/>
        public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName)
        {
            leadingSpaceTrim = new SQLFunctionTemplate(
                DbType.String,
                LEADING_SPACE_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                );

            trailingSpaceTrim = new SQLFunctionTemplate(
                DbType.String,
                TRAILING_SPACE_TRIM_TEMPLATE.Replace(RTRIM, rtrimFunctionName)
                );

            bothSpaceTrim = new SQLFunctionTemplate(
                DbType.String,
                BOTH_SPACE_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                .Replace(RTRIM, rtrimFunctionName)
                );

            bothSpaceTrimFrom = new SQLFunctionTemplate(
                DbType.String,
                BOTH_SPACE_TRIM_FROM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                .Replace(RTRIM, rtrimFunctionName)
                );

            leadingTrim = new SQLFunctionTemplate(
                DbType.String,
                LEADING_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                .Replace(RTRIM, rtrimFunctionName)
                .Replace(REPLACE, replaceFunctionName)
                );

            trailingTrim = new SQLFunctionTemplate(
                DbType.String,
                TRAILING_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                .Replace(RTRIM, rtrimFunctionName)
                .Replace(REPLACE, replaceFunctionName)
                );

            bothTrim = new SQLFunctionTemplate(
                DbType.String,
                BOTH_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                .Replace(RTRIM, rtrimFunctionName)
                .Replace(REPLACE, replaceFunctionName)
                );
        }
コード例 #24
0
        public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery,
                                              IDictionary <string, IFilter> enabledFilters)
        {
            ISQLFunction sqlFunction = GetFunction(criteriaQuery);

            var arguments = new List <object>();

            for (int i = 0; i < args.Length; i++)
            {
                SqlString projectArg = GetProjectionArgument(criteriaQuery, criteria, args[i], 0, enabledFilters);                 // The loc parameter is unused.
                arguments.Add(projectArg);
            }

            return(new SqlString(
                       sqlFunction.Render(arguments, criteriaQuery.Factory),
                       " as ",
                       GetColumnAliases(position)[0]));
        }
コード例 #25
0
        private void EndFunctionTemplate(IASTNode m)
        {
            var          methodNode = (MethodNode)m;
            ISQLFunction template   = methodNode.SQLFunction;

            if (template == null)
            {
                Out(")");
            }
            else
            {
                // this function has a template -> restore output, apply the template and write the result out
                var functionArguments = (FunctionArguments)writer;                 // TODO: Downcast to avoid using an interface?  Yuck.
                writer = outputStack[0];
                outputStack.RemoveAt(0);
                Out(template.Render(functionArguments.Args, sessionFactory));
            }
        }
コード例 #26
0
 /// <summary>
 /// Constructor for supplying the name of the replace function to use.
 /// </summary>
 /// <param name="replaceFunction">The replace function.</param>
 public AnsiTrimEmulationFunction(string replaceFunction)
 {
     _leadingTrim =
         new SQLFunctionTemplate(
             NHibernateUtil.String,
             $"{replaceFunction}( {replaceFunction}( ltrim( {replaceFunction}( {replaceFunction}( ?1, ' ', " +
             "'${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )");
     _trailingTrim =
         new SQLFunctionTemplate(
             NHibernateUtil.String,
             $"{replaceFunction}( {replaceFunction}( rtrim( {replaceFunction}( {replaceFunction}( ?1, ' ', " +
             "'${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )");
     _bothTrim =
         new SQLFunctionTemplate(
             NHibernateUtil.String,
             $"{replaceFunction}( {replaceFunction}( ltrim( rtrim( {replaceFunction}( {replaceFunction}( ?1, ' ', " +
             "'${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )");
 }
コード例 #27
0
        private void BeginFunctionTemplate(IASTNode m, IASTNode i)
        {
            var          methodNode = (MethodNode)m;
            ISQLFunction template   = methodNode.SQLFunction;

            if (template == null)
            {
                // if template is null we just write the function out as it appears in the hql statement
                Out(i);
                Out("(");
            }
            else
            {
                // this function has a template -> redirect output and catch the arguments
                outputStack.Insert(0, writer);
                writer = new FunctionArguments();
            }
        }
コード例 #28
0
        private string GetSQLFunctionSQL(Type type)
        {
            ISQLFunction sqlFunction = Activator.CreateInstance(type) as ISQLFunction;
            string       name        = sqlFunction.GetFucntionName();
            Dictionary <string, SqlDbType> parameters  = sqlFunction.GetParameters();
            KeyValuePair <SqlDbType, int>  returnValue = sqlFunction.GetReturn();
            string        sql      = sqlFunction.GetFunctionBody();
            StringBuilder function = new StringBuilder();

            function.AppendLine($"Create function {name}");
            function.AppendLine("(");
            function.AppendLine(string.Join(",", parameters.Select(d => $"@{d.Key} {d.Value.ToString()}")));
            function.AppendLine(")");
            function.AppendLine($"returns {this.GetSQLReturn(returnValue)}");
            function.AppendLine("as");
            function.AppendLine("begin");
            function.AppendLine(sql);
            function.AppendLine("end");
            return(function.ToString());
        }
コード例 #29
0
ファイル: MethodNode.cs プロジェクト: jrauber/GH1429
        private void DialectFunction(IASTNode exprList)
        {
            _function = SessionFactoryHelper.FindSQLFunction(_methodName);

            if (_function != null)
            {
                IASTNode child = null;

                if (exprList != null)
                {
                    child = _methodName == "iif" ? exprList.GetChild(1) : exprList.GetChild(0);
                }

                DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, child);
            }
            //TODO:

            /*else {
             *      methodName = (String) getWalker().getTokenReplacements().get( methodName );
             * }*/
        }
コード例 #30
0
        public IType FindFunctionReturnType(String functionName, IASTNode first)
        {
            // locate the registered function by the given name
            ISQLFunction sqlFunction = RequireSQLFunction(functionName);

            // determine the type of the first argument...
            IType argumentType = null;

            if (first != null)
            {
                if (sqlFunction is CastFunction)
                {
                    argumentType = TypeFactory.HeuristicType(first.NextSibling.Text);
                }
                else if (first is SqlNode)
                {
                    argumentType = ((SqlNode)first).DataType;
                }
            }

            return(sqlFunction.ReturnType(argumentType, _sfi));
        }
コード例 #31
0
        /// <summary>
        /// This is the real core function that build the fragment of sql needed
        /// to build the criteria
        /// </summary>
        /// <param name="criteria"></param>
        /// <param name="criteriaQuery"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override NHibernate.SqlCommand.SqlString ToSqlString(
            NHibernate.ICriteria criteria,
            NHibernate.Expressions.ICriteriaQuery criteriaQuery,
            IDictionary <string, IFilter> enabledFilters)
        {
            //retrieve with projection the real name of the property.
            String[] PropertyColumn = criteriaQuery.GetColumnsUsingProjection(
                criteria, (String)mSqlFunctionParameter[mPropertyNamePosition]);
            NHibernate.Dialect.Dialect dialect = criteriaQuery.Factory.Dialect;
            mSqlFunctionParameter[mPropertyNamePosition] = PropertyColumn[0];
            if (!dialect.Functions.ContainsKey(mFunction))
            {
                //throw new ApplicationException("Current dialect does not support " + mFunction + " function");
                //Todo for now try to set the function but without the dialect.
                return(CreateQueryString(
                           BuildUnknownExpression(mFunction, mSqlFunctionParameter)));
            }
            ISQLFunction func             = (ISQLFunction)dialect.Functions[mFunction];
            String       functionResolved = func.Render(mSqlFunctionParameter, criteriaQuery.Factory);

            //Now we have the cast operation required.
            return(CreateQueryString(functionResolved));
        }
コード例 #32
0
        private void VisitAritmaticOperation(BinaryExpression expr, ISQLFunction arithmaticOperation)
        {
            var leftVisitor = new SelectArgumentsVisitor(_rootCriteria, _session);
            var rightVisitor = new SelectArgumentsVisitor(_rootCriteria, _session);
            leftVisitor.Visit(expr.Left);
            rightVisitor.Visit(expr.Right);

            var joinedProjections = new List<IProjection>();
            joinedProjections.AddRange(leftVisitor._projections);
            joinedProjections.AddRange(rightVisitor._projections);
            var types = joinedProjections[0].GetTypes(_rootCriteria, CriteriaQuery);
            var projection = new SqlFunctionProjection(arithmaticOperation, types[0], joinedProjections.ToArray());
            _projections.Add(projection);
        }
コード例 #33
0
		private void DialectFunction(IASTNode exprList)
		{
			_function = SessionFactoryHelper.FindSQLFunction(_methodName);

			if (_function != null)
			{
			    IASTNode child = null;

                if (exprList != null)
                {
                    child = _methodName == "iif" ? exprList.GetChild(1) : exprList.GetChild(0);
                }

                DataType = SessionFactoryHelper.FindFunctionReturnType(_methodName, child);
			}
			//TODO:
			/*else {
				methodName = (String) getWalker().getTokenReplacements().get( methodName );
			}*/
		}
コード例 #34
0
		public SqlFunctionProjection(ISQLFunction function, IType returnType, params IProjection[] args)
		{
			this.function = function;
			this.returnType = returnType;
			this.args = args;
		}
コード例 #35
0
ファイル: Configuration.cs プロジェクト: ray2006/WCell
		public void AddSqlFunction(string functionName, ISQLFunction sqlFunction)
		{
			sqlFunctions[functionName] = sqlFunction;
		}
コード例 #36
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="name"></param>
 /// <param name="function"></param>
 protected void RegisterFunction(string name, ISQLFunction function)
 {
     sqlFunctions[name] = function;
 }
コード例 #37
0
 /// <summary>
 /// Calls the specified <see cref="T:NHibernate.Dialect.Function.ISQLFunction" />
 /// </summary>
 /// <param name="function">the function.</param>
 /// <param name="type">The type.</param>
 /// <param name="projections">The projections.</param>
 /// <returns></returns>
 public static IProjection SqlFunction(ISQLFunction function, IType type, params IProjection[] projections)
 {
     return new SqlFunctionProjection(function, type, projections);
 }
コード例 #38
0
 public SqlFunctionProjection(ISQLFunction function, IType returnType, params IProjection[] args)
 {
     this.function   = function;
     this.returnType = returnType;
     this.args       = args;
 }
コード例 #39
0
        /// <summary/>
        public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName)
        {
            leadingSpaceTrim = new SQLFunctionTemplate(
                    DbType.String,
                    LEADING_SPACE_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
            );

            trailingSpaceTrim = new SQLFunctionTemplate(
                    DbType.String,
                    TRAILING_SPACE_TRIM_TEMPLATE.Replace(RTRIM, rtrimFunctionName)
            );

            bothSpaceTrim = new SQLFunctionTemplate(
                    DbType.String,
                    BOTH_SPACE_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                            .Replace(RTRIM, rtrimFunctionName)
            );

            bothSpaceTrimFrom = new SQLFunctionTemplate(
                    DbType.String,
                    BOTH_SPACE_TRIM_FROM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                            .Replace(RTRIM, rtrimFunctionName)
            );

            leadingTrim = new SQLFunctionTemplate(
                    DbType.String,
                    LEADING_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                            .Replace(RTRIM, rtrimFunctionName)
                            .Replace(REPLACE, replaceFunctionName)
            );

            trailingTrim = new SQLFunctionTemplate(
                    DbType.String,
                    TRAILING_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                            .Replace(RTRIM, rtrimFunctionName)
                            .Replace(REPLACE, replaceFunctionName)
            );

            bothTrim = new SQLFunctionTemplate(
                    DbType.String,
                    BOTH_TRIM_TEMPLATE.Replace(LTRIM, ltrimFunctionName)
                            .Replace(RTRIM, rtrimFunctionName)
                            .Replace(REPLACE, replaceFunctionName)
            );
        }
コード例 #40
0
ファイル: Configuration.cs プロジェクト: Rookian/Jericho
 public void AddSqlFunction(string functionName, ISQLFunction sqlFunction);
コード例 #41
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		/// <param name="function"></param>
		protected void RegisterFunction( string name, ISQLFunction function )
		{
			sqlFunctions.Add( name, function );
		}
コード例 #42
0
		private SqlString RenderFunctionClause(ISQLFunction func, IList<SqlString> tokens, ref int tokenIdx)
		{
			IList<SqlString> functionTokens;
			if (!func.HasArguments)
			{
				// The function doesn't work with arguments.
				if (func.HasParenthesesIfNoArguments)
					ExtractFunctionClause(tokens, ref tokenIdx);

				// The function render simply translate its name for a specific dialect.
				return func.Render(new List<object>(), Factory);
			}
			functionTokens = ExtractFunctionClause(tokens, ref tokenIdx);

			IFunctionGrammar fg = func as IFunctionGrammar;
			if (fg == null)
				fg = new CommonGrammar();

			IList args = new List<object>();
			SqlStringBuilder argBuf = new SqlStringBuilder();
			// Extract args splitting first 2 token because are: FuncName(
			// last token is ')'
			// To allow expressions like arg (ex:5+5) all tokens between 'argument separator' or
			// a 'know argument' are compacted in a string, 
			// because many HQL function expect IList<string> like args in Render method.
			// This solution give us the ability to use math expression in common function. 
			// Ex: sum(a.Prop+10), cast(yesterday-1 as date)
			for (int argIdx = 2; argIdx < functionTokens.Count - 1; argIdx++)
			{
				object token = functionTokens[argIdx];
				if (fg.IsKnownArgument(token.ToString()))
				{
					if (argBuf.Count > 0)
					{
						// end of the previous argument
						args.Add(argBuf.ToSqlString());
						argBuf = new SqlStringBuilder();
					}
					args.Add(token);
				}
				else if (fg.IsSeparator(token.ToString()))
				{
					// argument end
					if (argBuf.Count > 0)
					{
						args.Add(argBuf.ToSqlString());
						argBuf = new SqlStringBuilder();
					}
				}
				else
				{
					ISQLFunction nfunc = Factory.SQLFunctionRegistry.FindSQLFunction(token.ToString().ToLowerInvariant());
					if (nfunc != null)
					{
						// the token is a nested function call
						argBuf.Add(RenderFunctionClause(nfunc, functionTokens, ref argIdx));
					}
					else
					{
						// the token is a part of an argument (every thing else)
						argBuf.AddObject(token);
					}
				}
			}
			// Add the last arg
			if (argBuf.Count > 0)
				args.Add(argBuf.ToSqlString());
			return func.Render(args, Factory);
		}